diff --git a/script.cs b/script.cs index 230a460..0123f75 100644 --- a/script.cs +++ b/script.cs @@ -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 keyUpBindings = new Dictionary() { @@ -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>().GetValue(Me); - if(dict?.ContainsKey("GetDetectedRadarTargets") == true) - { - E.DebugLog("Nebulous Radar detected."); - var radarDataProvider = dict["GetDetectedRadarTargets"] as Func>; - 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> _getDetectedRadarTargets; - IMyProgrammableBlock _me; + IMyCubeGrid _grid; + PbNebRadarAPI _radarApi; + - public RadarTargeter(TrackedTargetsPool pool, TargetOffsetManager tom, Func> 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 _buffer = new List(); + MemorySafeList _buffer = new MemorySafeList(); 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>().GetValue(pbBlock); + + if (dict == null) + return false; + + try + { + ApiAssign(dict); + } + catch (Exception e) + { + throw e; + } + _TupleRadarEntryDumpList = new MemorySafeList, long, byte, byte>>(); + _TupleJammingEntryV2DumpList = new MemorySafeList>(); + _TuplePassiveRadarEntryDumpList = new MemorySafeList>(); + + IsReady = true; + + return true; + } + public bool IsReady + { + get; private set; + } + public void GetAllRadarEntries(VRage.Game.ModAPI.Ingame.IMyCubeGrid grid, MemorySafeList returnList) + { + _getAllRadarEntries.Invoke(grid, _TupleRadarEntryDumpList); + foreach (var entry in _TupleRadarEntryDumpList) + { + returnList.Add(new RadarEntry(entry)); + } + _TupleRadarEntryDumpList.Clear(); + } + private MemorySafeList, long, byte, byte>> _TupleRadarEntryDumpList; + private MemorySafeList> _TupleJammingEntryV2DumpList; + private MemorySafeList> _TuplePassiveRadarEntryDumpList; + + private Action, long, byte, byte>>> _getAllRadarEntries; + private void ApiAssign(IReadOnlyDictionary delegates) + { + AssignMethod(delegates, "GetAllRadarEntriesPb", ref _getAllRadarEntries); + } + protected void AssignMethod(IReadOnlyDictionary 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, 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; + } + } + + + } + + +}