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.
///