diff --git a/Gamemode Mods/Starcore_Sharetrack/Data/Scripts/ShipPoints/API/StealthAPI.cs b/Gamemode Mods/Starcore_Sharetrack/Data/Scripts/ShipPoints/API/StealthAPI.cs new file mode 100644 index 000000000..8f62cc6da --- /dev/null +++ b/Gamemode Mods/Starcore_Sharetrack/Data/Scripts/ShipPoints/API/StealthAPI.cs @@ -0,0 +1,119 @@ +using Sandbox.ModAPI; +using System; +using System.Collections.Generic; +using VRage.Game.ModAPI; + +namespace StealthSystem +{ + internal class StealthAPI + { + /// Returns true if drive status was toggled successfully. + /// Ignore power requirements and overheat. + public bool ToggleStealth(IMyTerminalBlock drive, bool force) => _toggleStealth?.Invoke(drive, force) ?? false; + + /// Returns status of drive. 0 = Ready, 1 = Active, 2 = Cooldown, 3 = Not enough power, 4 = Offline + public int GetStatus(IMyTerminalBlock drive) => _getStatus?.Invoke(drive) ?? 4; + + /// Returns remaining duration of stealth/cooldown. + public int GetDuration(IMyTerminalBlock drive) => _getDuration?.Invoke(drive) ?? 0; + + /// Retuns active stealth drive on grid if one exists, otherwise returns null. + public IMyTerminalBlock GetMainDrive(IMyCubeGrid grid) => _getMainDrive?.Invoke(grid); + + /// Collection to populate with heat sinks on grid. + public void GetHeatSinks(IMyCubeGrid grid, ICollection sinks) => _getHeatSinks?.Invoke(grid, sinks); + + + + private const long CHANNEL = 2172757427; + private bool _isRegistered; + private bool _apiInit; + private Action _readyCallback; + + private Func _toggleStealth; + private Func _getStatus; + private Func _getDuration; + private Func _getMainDrive; + private Action> _getHeatSinks; + + public bool IsReady { get; private set; } + + + /// + /// Ask CoreSystems to send the API methods. + /// Throws an exception if it gets called more than once per session without . + /// + /// Method to be called when CoreSystems replies. + public void Load(Action readyCallback = null) + { + if (_isRegistered) + throw new Exception($"{GetType().Name}.Load() should not be called multiple times!"); + + _readyCallback = readyCallback; + _isRegistered = true; + MyAPIGateway.Utilities.RegisterMessageHandler(CHANNEL, HandleMessage); + MyAPIGateway.Utilities.SendModMessage(CHANNEL, "ApiEndpointRequest"); + } + + public void Unload() + { + MyAPIGateway.Utilities.UnregisterMessageHandler(CHANNEL, HandleMessage); + + ApiAssign(null); + + _isRegistered = false; + _apiInit = false; + IsReady = false; + } + + private void HandleMessage(object obj) + { + if (_apiInit || obj is string + ) // the sent "ApiEndpointRequest" will also be received here, explicitly ignoring that + return; + + var dict = obj as IReadOnlyDictionary; + + if (dict == null) + return; + + ApiAssign(dict); + + IsReady = true; + _readyCallback?.Invoke(); + } + + public void ApiAssign(IReadOnlyDictionary delegates) + { + _apiInit = (delegates != null); + /// base methods + AssignMethod(delegates, "ToggleStealth", ref _toggleStealth); + AssignMethod(delegates, "GetStatus", ref _getStatus); + AssignMethod(delegates, "GetDuration", ref _getDuration); + AssignMethod(delegates, "GetMainDrive", ref _getMainDrive); + AssignMethod(delegates, "GetHeatSinks", ref _getHeatSinks); + } + + private 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($"{GetType().Name} :: Couldn't find {name} delegate of type {typeof(T)}"); + + field = del as T; + + if (field == null) + throw new Exception( + $"{GetType().Name} :: Delegate {name} is not type {typeof(T)}, instead it's: {del.GetType()}"); + } + + } + +} \ No newline at end of file diff --git a/Gamemode Mods/Starcore_Sharetrack/Data/Scripts/ShipPoints/MasterSession.cs b/Gamemode Mods/Starcore_Sharetrack/Data/Scripts/ShipPoints/MasterSession.cs index 9d1c78f61..19d6edb72 100644 --- a/Gamemode Mods/Starcore_Sharetrack/Data/Scripts/ShipPoints/MasterSession.cs +++ b/Gamemode Mods/Starcore_Sharetrack/Data/Scripts/ShipPoints/MasterSession.cs @@ -4,6 +4,7 @@ using StarCore.ShareTrack.HeartNetworking; using StarCore.ShareTrack.ShipTracking; using StarCore.ShareTrack.TrackerApi; +using StealthSystem; using VRage.Game.Components; using VRageMath; @@ -20,6 +21,7 @@ internal class MasterSession : MySessionComponentBase public static MasterSession I; public static SharetrackConfig Config; + public StealthAPI StealthApi = new StealthAPI(); public HudAPIv2 TextHudApi; public Action HudRegistered = () => { }; @@ -46,6 +48,8 @@ public override void LoadData() _buildingBlockPoints = new BuildingBlockPoints(); TrackingManager.Init(); // Initialize TrackingManager, but don't start tracking yet + StealthApi.Load(); + if (!MyAPIGateway.Utilities.IsDedicated) // Initialize the sphere entities // Initialize the text_api with the HUDRegistered callback