Update script.cs

This commit is contained in:
2026-06-25 22:59:00 +02:00
parent a8e129e5e9
commit ca97f3274d

216
script.cs
View File

@@ -1,5 +1,30 @@
using Sandbox.Game.EntityComponents;
using Sandbox.ModAPI.Ingame;
using Sandbox.ModAPI.Interfaces;
using SpaceEngineers.Game.ModAPI.Ingame;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using VRage;
using VRage.Collections;
using VRage.Game;
using VRage.Game.Components;
using VRage.Game.GUI.TextPanel;
using VRage.Game.ModAPI.Ingame;
using VRage.Game.ModAPI.Ingame.Utilities;
using VRage.Game.ObjectBuilders.Definitions;
using VRage.Scripting.MemorySafeTypes;
using VRageMath;
string Ver = "1.1.295-R";
namespace IngameScript
{
public partial class Program : MyGridProgram
{
#region mdk preserve
string Ver = "1.1.295-R";
// This is a version of TGP adapted to work with Nebulous Radar
//
@@ -7,7 +32,6 @@
// Steam WS: https://steamcommunity.com/sharedfiles/filedetails/?id=3158039679
static int LOGGER_MAX_CHARS = 5000;
// no toggle support yet
Dictionary<string, string> keyUpBindings = new Dictionary<string, string>()
{
@@ -49,7 +73,7 @@
public enum TargetSelection { First, Closest, Random, Loop }
public enum MultiTrackingSelector { Selected, AllOffsets, AllTargets, Everything }
#endregion
// further down code can be minified
// TODO: rumors say static refs are not released on script recompile, refactor to instance
@@ -418,19 +442,15 @@
Targeters.Add(targeterWc);
}
}
PbNebRadarAPI RadarApi = new PbNebRadarAPI();
if (RadarApi.Load(Me))
{
E.DebugLog("Nebulous Radar detected.");
E.DebugLog("Creating RadarTargeter.");
targeterRadar = new RadarTargeter(TTPool, Tom, RadarApi, Me.CubeGrid);
Targeters.Add(targeterRadar);
}
dict = Me.GetProperty("GrubenRadarAPI")?.As<IReadOnlyDictionary<string, Delegate>>().GetValue(Me);
if(dict?.ContainsKey("GetDetectedRadarTargets") == true)
{
E.DebugLog("Nebulous Radar detected.");
var radarDataProvider = dict["GetDetectedRadarTargets"] as Func<IMyProgrammableBlock, List<MyDetectedEntityInfo>>;
if (radarDataProvider != null)
{
E.DebugLog("Creating RadarTargeter.");
targeterRadar = new RadarTargeter(TTPool, Tom, radarDataProvider, Me);
Targeters.Add(targeterRadar);
}
}
}
@@ -2377,7 +2397,7 @@
{
continue;
}
_tom.ConsiderOffset(mdei.EntityId, mdei.Orientation, mdei.Position, mdei.HitPosition ?? mdei.Position, true);
//VRageRender.MyRenderProxy.DebugDrawText3D(_mdei.HitPosition.Value, $"x", Color.Red, 1f, false, persistent: true);
tt = new TrackedTarget(mdei, E.T, Vector3D.Zero, this.GetTypeName);
@@ -2413,33 +2433,36 @@
public string GetTypeName => "RadarTargeter";
TrackedTargetsPool _pool;
TargetOffsetManager _tom;
Func<IMyProgrammableBlock, List<MyDetectedEntityInfo>> _getDetectedRadarTargets;
IMyProgrammableBlock _me;
IMyCubeGrid _grid;
PbNebRadarAPI _radarApi;
public RadarTargeter(TrackedTargetsPool pool, TargetOffsetManager tom, Func<IMyProgrammableBlock, List<MyDetectedEntityInfo>> provider, IMyProgrammableBlock me)
public RadarTargeter(TrackedTargetsPool pool, TargetOffsetManager tom, PbNebRadarAPI radarApi, IMyCubeGrid grid)
{
_pool = pool;
_getDetectedRadarTargets = provider;
_me = me;
_radarApi = radarApi;
_grid = grid;
_tom = tom;
}
List<MyDetectedEntityInfo> _buffer = new List<MyDetectedEntityInfo>();
MemorySafeList<RadarEntry> _buffer = new MemorySafeList<RadarEntry>();
public void Update(int tick, TargetGatingComponent tgc)
{
_buffer.Clear();
try
{
_buffer = _getDetectedRadarTargets(_me);
_radarApi.GetAllRadarEntries(_grid, _buffer);
}
catch (Exception e)
{
E.Fail(e.ToString());
}
foreach (var t in _buffer)
foreach (var entry in _buffer)
{
var mdei = t;
MyRelationsBetweenPlayerAndBlock relation = ConvertRelations(entry.relation);
BoundingBoxD box = new BoundingBoxD(Vector3D.One * 10, Vector3D.One * 10);
MyDetectedEntityInfo mdei = new MyDetectedEntityInfo(entry.EntityId, entry.Name, MyDetectedEntityType.Unknown, entry.Position, MatrixD.Identity, entry.Velocity, relation , box, DateTime.Now.Millisecond);
if (mdei.EntityId == 0 || !ValidateRelations(mdei.Relationship))
continue;
var tt = _pool.GetById(mdei.EntityId);
@@ -2449,7 +2472,7 @@
{
continue;
}
_tom.ConsiderOffset(mdei.EntityId, mdei.Orientation, mdei.Position, mdei.HitPosition ?? mdei.Position, true);
tt = new TrackedTarget(mdei, E.T, Vector3D.Zero, this.GetTypeName);
_pool.Targets.Add(mdei.EntityId, tt);
@@ -2553,6 +2576,7 @@
E.DebugLog($"{t.Source}.TargetGatingComponent: banned {t.Info.EntityId}, reason: {reason}");
return true;
}
return false;
}
bool IsGoingToViolateMySpace(MyDetectedEntityInfo mdei, Vector3D gridTrans)
@@ -3476,3 +3500,143 @@
public static Action LockOnTickStart;
}
public class PbNebRadarAPI
{
public const string ModAPIVersion = "v1.1";
public const string PbTerminalId = "NRadar_PbAPI";
public bool Load(Sandbox.ModAPI.Ingame.IMyProgrammableBlock pbBlock)
{
IsReady = false;
var dict = pbBlock.GetProperty(PbTerminalId)?.As<IReadOnlyDictionary<string, Delegate>>().GetValue(pbBlock);
if (dict == null)
return false;
try
{
ApiAssign(dict);
}
catch (Exception e)
{
throw e;
}
_TupleRadarEntryDumpList = new MemorySafeList<MyTuple<ushort, string, MyTuple<Vector3D, Vector3, float, float>, long, byte, byte>>();
_TupleJammingEntryV2DumpList = new MemorySafeList<MyTuple<Vector3D, float>>();
_TuplePassiveRadarEntryDumpList = new MemorySafeList<MyTuple<byte, float, float, long, Vector3D, Vector3D>>();
IsReady = true;
return true;
}
public bool IsReady
{
get; private set;
}
public void GetAllRadarEntries(VRage.Game.ModAPI.Ingame.IMyCubeGrid grid, MemorySafeList<RadarEntry> returnList)
{
_getAllRadarEntries.Invoke(grid, _TupleRadarEntryDumpList);
foreach (var entry in _TupleRadarEntryDumpList)
{
returnList.Add(new RadarEntry(entry));
}
_TupleRadarEntryDumpList.Clear();
}
private MemorySafeList<MyTuple<ushort, string, MyTuple<Vector3D, Vector3, float, float>, long, byte, byte>> _TupleRadarEntryDumpList;
private MemorySafeList<MyTuple<Vector3D, float>> _TupleJammingEntryV2DumpList;
private MemorySafeList<MyTuple<byte, float, float, long, Vector3D, Vector3D>> _TuplePassiveRadarEntryDumpList;
private Action<VRage.Game.ModAPI.Ingame.IMyCubeGrid, MemorySafeList<MyTuple<ushort, string, MyTuple<Vector3D, Vector3, float, float>, long, byte, byte>>> _getAllRadarEntries;
private void ApiAssign(IReadOnlyDictionary<string, Delegate> delegates)
{
AssignMethod(delegates, "GetAllRadarEntriesPb", ref _getAllRadarEntries);
}
protected void AssignMethod<T>(IReadOnlyDictionary<string, Delegate> delegates, string name, ref T field) where T : class
{
if (delegates == null)
{
field = null;
return;
}
Delegate del;
if (!delegates.TryGetValue(name, out del))
throw new Exception($"PbNebRadarAPI ERROR: Couldn't find {name} delegate of type {typeof(T)}");
field = del as T;
if (field == null)
throw new Exception($"PbNebRadarAPI ERROR: Delegate {name} is not type {typeof(T)}, instead it's: {del.GetType()}");
}
}
public enum Relation : byte
{
Neutral,
Enemy,
Allied
}
[Flags]
public enum StateFlags : byte
{
None = 0,
Jumping = 1 << 0,
Delete = 1 << 7,
}
public struct RadarEntry
{
public Relation relation;
public StateFlags RadarFlags;
public ushort TrackNumber;
public float PositionError;
public float VelocityError;
public string Name;
public long EntityId;
public Vector3D Position;
public Vector3 Velocity;
public bool IsLocked => PositionError + VelocityError == 0;
public RadarEntry(MyTuple<ushort, string, MyTuple<Vector3D, Vector3, float, float>, long, byte, byte> data)
{
TrackNumber = data.Item1;
Name = data.Item2;
Position = data.Item3.Item1;
Velocity = data.Item3.Item2;
PositionError = data.Item3.Item3;
VelocityError = data.Item3.Item4;
EntityId = data.Item4;
relation = (Relation)data.Item5;
RadarFlags = (StateFlags)data.Item6;
}
public override string ToString()
{
return $"[{TrackNumber}]: {Name} [{relation}] / s={Position} (E={PositionError}) / v={Velocity} (E={VelocityError}) / {RadarFlags}";
}
}
[Flags]
public enum PassiveStateFlags : byte
{
None = 0,
Position = 1 << 0,
Delete = 1 << 7
}
public static MyRelationsBetweenPlayerAndBlock ConvertRelations(Relation relation)
{
switch (relation)
{
case Relation.Neutral:
return MyRelationsBetweenPlayerAndBlock.Neutral;
case Relation.Allied:
return MyRelationsBetweenPlayerAndBlock.Friends;
case Relation.Enemy:
return MyRelationsBetweenPlayerAndBlock.Enemies;
default:
return MyRelationsBetweenPlayerAndBlock.NoOwnership;
}
}
}
}