From c59b9759574e5bb65980fd37d485780d7c776f26 Mon Sep 17 00:00:00 2001 From: Aristeas <94058548+Jnick-24@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:41:28 -0600 Subject: [PATCH] New API methods --- .../Definitions/ApiHandler/HeartApiMethods.cs | 62 ++++++++++++++++++- .../HeartModule/Network/HeartNetwork.cs | 2 +- .../HeartModule/Projectiles/Projectile.cs | 6 +- .../ProjectileDefinitionManager.cs | 24 ++++++- .../Weapons/WeaponDefinitionManager.cs | 37 ++++++++++- .../HeartModule/Weapons/WeaponManager.cs | 18 ++++++ 6 files changed, 141 insertions(+), 8 deletions(-) diff --git a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Definitions/ApiHandler/HeartApiMethods.cs b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Definitions/ApiHandler/HeartApiMethods.cs index 1cc635f4..05a9b48e 100644 --- a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Definitions/ApiHandler/HeartApiMethods.cs +++ b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Definitions/ApiHandler/HeartApiMethods.cs @@ -2,6 +2,7 @@ using Heart_Module.Data.Scripts.HeartModule.Projectiles; using Heart_Module.Data.Scripts.HeartModule.Projectiles.StandardClasses; using Heart_Module.Data.Scripts.HeartModule.Weapons; +using Heart_Module.Data.Scripts.HeartModule.Weapons.StandardClasses; using Sandbox.ModAPI; using System; using System.Collections.Generic; @@ -15,6 +16,9 @@ namespace Heart_Module.Data.Scripts.HeartModule.Definitions.ApiHandler { + /// + /// Contains every HeartApi method. + /// internal class HeartApiMethods { internal readonly Dictionary ModApiMethods; @@ -37,9 +41,15 @@ internal HeartApiMethods() // Weapon Generics ["BlockHasWeapon"] = new Func(HasWeapon), + ["SubtypeHasDefinition"] = new Func(SubtypeHasDefinition), + ["GetWeaponDefinitions"] = new Func(GetWeaponDefinitions), + ["GetWeaponDefinition"] = new Func(GetWeaponDefinition), + ["RegisterWeaponDefinition"] = new Func(RegisterWeaponDefinition), + ["UpdateWeaponDefinition"] = new Func(UpdateWeaponDefinition), // Standard ["LogWriteLine"] = new Action(HeartData.I.Log.Log), + ["GetNetworkLoad"] = new Func(GetNetworkLoad), }; } @@ -118,7 +128,7 @@ public int RegisterProjectileDefinition(byte[] serialized) ProjectileDefinitionBase def = MyAPIGateway.Utilities.SerializeFromBinary(serialized); if (def == null) return -1; - return ProjectileDefinitionManager.RegisterDefinition(def, true); + return ProjectileDefinitionManager.RegisterModApiDefinition(def); } public bool UpdateProjectileDefinition(int definitionId, byte[] serialized) { @@ -136,6 +146,56 @@ public bool HasWeapon(MyEntity block) { return block is IMyConveyorSorter && ((IMyConveyorSorter) block).GameLogic is SorterWeaponLogic; } + + public bool SubtypeHasDefinition(string subtype) + { + return WeaponDefinitionManager.HasDefinition(subtype); + } + + public string[] GetWeaponDefinitions() => WeaponDefinitionManager.GetAllDefinitions(); + + public byte[] GetWeaponDefinition(string subtype) + { + if (WeaponDefinitionManager.HasDefinition(subtype)) + return MyAPIGateway.Utilities.SerializeToBinary(WeaponDefinitionManager.GetDefinition(subtype)); + return null; + } + + public bool RegisterWeaponDefinition(byte[] definition) + { + if (definition == null || definition.Length == 0) + return false; + + WeaponDefinitionBase weaponDef = MyAPIGateway.Utilities.SerializeFromBinary(definition); + if (definition == null) + { + SoftHandle.RaiseException("Invalid weapon definition!"); + return false; + } + + return WeaponDefinitionManager.RegisterModApiDefinition(weaponDef); + } + + public bool UpdateWeaponDefinition(byte[] definition) + { + if (definition == null || definition.Length == 0) + return false; + + WeaponDefinitionBase weaponDef = MyAPIGateway.Utilities.SerializeFromBinary(definition); + if (definition == null) + { + SoftHandle.RaiseException("Invalid weapon definition!"); + return false; + } + + return WeaponDefinitionManager.UpdateDefinition(weaponDef); + } + #endregion + + #region Debug Methods + + public int GetNetworkLoad() => HeartData.I.Net.NetworkLoad; + #endregion } } diff --git a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Network/HeartNetwork.cs b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Network/HeartNetwork.cs index e2d402ea..099c5dd5 100644 --- a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Network/HeartNetwork.cs +++ b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Network/HeartNetwork.cs @@ -9,7 +9,7 @@ namespace Heart_Module.Data.Scripts.HeartModule.Network public class HeartNetwork { public int NetworkLoadTicks = 240; - public int NetworkLoad { get; private set; } = 0; + public int NetworkLoad { get; private set; } = 0; // TODO: Per-packet type network load private List networkLoadArray = new List(); private int networkLoadUpdate = 0; diff --git a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/Projectile.cs b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/Projectile.cs index c1f671d1..477342d5 100644 --- a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/Projectile.cs +++ b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/Projectile.cs @@ -148,7 +148,7 @@ public void TickUpdate(float delta) { Guidance?.RunGuidance(delta); - CheckHits(delta); + CheckHits(); Velocity += Definition.PhysicalProjectile.Acceleration * delta; Position += (InheritedVelocity + Direction * Velocity) * delta; DistanceTravelled += Velocity * delta; @@ -169,7 +169,7 @@ public void TickUpdate(float delta) if (RemainingImpacts > 0) { - MaxBeamLength = CheckHits(delta); // Set visual beam length + MaxBeamLength = CheckHits(); // Set visual beam length if (MaxBeamLength == -1) MaxBeamLength = Definition.PhysicalProjectile.MaxTrajectory; } @@ -178,7 +178,7 @@ public void TickUpdate(float delta) UpdateAudio(); } - public float CheckHits(float delta) + public float CheckHits() { if (NextMoveStep == Vector3D.Zero) return -1; diff --git a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileDefinitionManager.cs b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileDefinitionManager.cs index 3dd8e4a8..d3966d00 100644 --- a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileDefinitionManager.cs +++ b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileDefinitionManager.cs @@ -5,14 +5,18 @@ namespace Heart_Module.Data.Scripts.HeartModule.Projectiles { + /// + /// Collects and distributes all projectile definitions. + /// internal class ProjectileDefinitionManager { public static ProjectileDefinitionManager I; - private List Definitions = new List(); + private List Definitions = new List(); // TODO: Store serialized versions of definitions in case of modded functionality private Dictionary DefinitionNamePairs = new Dictionary(); /// /// Changes the ID of a projectile definition. If the ID is already occupied, swaps the two definitions. DO NOT CALL ON SERVER! + /// Unused. /// /// /// @@ -67,6 +71,24 @@ public static bool HasDefinition(int id) return I.Definitions.Count > id && id >= 0; } + /// + /// Use this when creating a definiton live. + /// + /// + /// + public static int RegisterModApiDefinition(ProjectileDefinitionBase definition) + { + if (HasDefinition(definition.Name)) + throw new System.Exception("Attempted to assign ProjectileDefinition to existing ID!"); + return RegisterDefinition(definition, true); + } + + /// + /// Registers a projectile definition. + /// + /// + /// + /// public static int RegisterDefinition(ProjectileDefinitionBase definition, bool syncToClients = false) { if (I.DefinitionNamePairs.ContainsKey(definition.Name)) diff --git a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/WeaponDefinitionManager.cs b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/WeaponDefinitionManager.cs index 77033e51..7082aa17 100644 --- a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/WeaponDefinitionManager.cs +++ b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/WeaponDefinitionManager.cs @@ -1,13 +1,18 @@ -using Heart_Module.Data.Scripts.HeartModule.Weapons.StandardClasses; +using Heart_Module.Data.Scripts.HeartModule.ErrorHandler; +using Heart_Module.Data.Scripts.HeartModule.Weapons.StandardClasses; using System.Collections.Generic; +using System.Linq; namespace Heart_Module.Data.Scripts.HeartModule.Weapons { + /// + /// Collects and distributes all weapon definitions. + /// internal class WeaponDefinitionManager { public static WeaponDefinitionManager I; - private Dictionary Definitions = new Dictionary(); + private Dictionary Definitions = new Dictionary(); // TODO: Store serialized versions of definitions in case of modded functionality. public static WeaponDefinitionBase GetDefinition(string subTypeId) { @@ -22,6 +27,26 @@ public static bool HasDefinition(string subTypeId) return I.Definitions.ContainsKey(subTypeId); } + public static bool UpdateDefinition(WeaponDefinitionBase definition) + { + if (!HasDefinition(definition.Assignments.BlockSubtype)) + return false; + + I.Definitions[definition.Assignments.BlockSubtype] = definition; + return true; + } + + public static bool RegisterModApiDefinition(WeaponDefinitionBase definition) + { + if (HasDefinition(definition.Assignments.BlockSubtype)) + { + SoftHandle.RaiseException("Attempted to assign WeaponDefinition to existing ID!", callingType: typeof(WeaponDefinitionManager)); + return false; + } + RegisterDefinition(definition); + return true; + } + public static void RegisterDefinition(WeaponDefinitionBase definition) { if (definition == null) @@ -37,11 +62,19 @@ public static void RegisterDefinition(WeaponDefinitionBase definition) HeartData.I.OrreryBlockCategory.AddBlock(definition.Assignments.BlockSubtype); HeartData.I.Log.Log($"Registered weapon definition {definition.Assignments.BlockSubtype}."); + + if (HeartData.I.IsLoaded) + WeaponManager.I.UpdateLogicOnExistingBlocks(definition); } public static int DefinitionCount() { return I.Definitions.Count; } + + public static string[] GetAllDefinitions() + { + return I.Definitions.Keys.ToArray(); + } } } diff --git a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/WeaponManager.cs b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/WeaponManager.cs index e3692712..6275e0a1 100644 --- a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/WeaponManager.cs +++ b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/WeaponManager.cs @@ -31,6 +31,24 @@ public override void LoadData() HeartData.I.OnGridRemove += OnGridRemove; } + /// + /// Check for blocks already in the world without weapon logic. + /// + /// + public void UpdateLogicOnExistingBlocks(WeaponDefinitionBase definition) + { + foreach (var grid in GridWeapons.Keys) + { + foreach (var block in grid.GetFatBlocks()) + { + if (block.BlockDefinition.SubtypeName != definition.Assignments.BlockSubtype || block.GameLogic?.GetAs() != null) + continue; + + AddWeapon(block); + } + } + } + /// /// Check if new grids contain valid weapons. ///