From 8326d70cbf799901a1763ad9136f77a7a494f665 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Thu, 21 May 2020 15:04:55 -0400 Subject: [PATCH] Integrate tweak and signal functionality into Blocks --- GamecraftModdingAPI/Block.cs | 1 + GamecraftModdingAPI/Blocks/BlockEngine.cs | 4 +- GamecraftModdingAPI/Blocks/Motor.cs | 113 +++++ GamecraftModdingAPI/Blocks/Piston.cs | 90 ++++ GamecraftModdingAPI/Blocks/Servo.cs | 118 +++++ GamecraftModdingAPI/Blocks/SignalEngine.cs | 67 ++- GamecraftModdingAPI/Blocks/SignalingBlock.cs | 131 +++++ GamecraftModdingAPI/Blocks/Signals.cs | 177 ------- GamecraftModdingAPI/Blocks/Tweakable.cs | 98 ---- GamecraftModdingAPI/Blocks/TweakableEngine.cs | 452 ------------------ GamecraftModdingAPI/Blocks/TweakableStat.cs | 13 - GamecraftModdingAPI/Main.cs | 2 - .../Tests/GamecraftModdingAPIPluginTest.cs | 29 -- doxygen.conf | 2 +- 14 files changed, 519 insertions(+), 778 deletions(-) create mode 100644 GamecraftModdingAPI/Blocks/Motor.cs create mode 100644 GamecraftModdingAPI/Blocks/Piston.cs create mode 100644 GamecraftModdingAPI/Blocks/Servo.cs create mode 100644 GamecraftModdingAPI/Blocks/SignalingBlock.cs delete mode 100644 GamecraftModdingAPI/Blocks/Signals.cs delete mode 100644 GamecraftModdingAPI/Blocks/Tweakable.cs delete mode 100644 GamecraftModdingAPI/Blocks/TweakableEngine.cs delete mode 100644 GamecraftModdingAPI/Blocks/TweakableStat.cs diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 88932da..1a8673a 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -23,6 +23,7 @@ namespace GamecraftModdingAPI protected static readonly RotationEngine RotationEngine = new RotationEngine(); protected static readonly RemovalEngine RemovalEngine = new RemovalEngine(); protected static readonly BlockEngine BlockEngine = new BlockEngine(); + protected static readonly SignalEngine SignalEngine = new SignalEngine(); /// /// Place a new block at the given position. If scaled, position means the center of the block. The default block size is 0.2 in terms of position. diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index 377fa5b..6275ca1 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -74,8 +74,8 @@ namespace GamecraftModdingAPI.Blocks if (exists) return ref entitiesDB.QueryEntity(blockID); T[] structHolder = new T[1]; - ref T structRef = ref structHolder[0]; - return ref structRef; + //ref T defRef = ref structHolder[0]; + return ref structHolder[0]; } public bool BlockExists(EGID id) diff --git a/GamecraftModdingAPI/Blocks/Motor.cs b/GamecraftModdingAPI/Blocks/Motor.cs new file mode 100644 index 0000000..13a246f --- /dev/null +++ b/GamecraftModdingAPI/Blocks/Motor.cs @@ -0,0 +1,113 @@ +using System; + +using RobocraftX.Blocks; +using Svelto.ECS; +using Unity.Mathematics; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + public class Motor : Block + { + /// + /// Places a new motor. + /// Any valid motor type is accepted. + /// This re-implements Block.PlaceNew(...) + /// + public static new Motor PlaceNew(BlockIDs block, float3 position, + float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, + int uscale = 1, float3 scale = default, Player player = null) + { + if (!(block == BlockIDs.MotorS || block == BlockIDs.MotorM)) + { + throw new BlockTypeException($"Block is not a {typeof(Motor).Name} block"); + } + if (PlacementEngine.IsInGame && GameState.IsBuildMode()) + { + try + { + EGID id = PlacementEngine.PlaceBlock(block, color, darkness, + position, uscale, scale, player, rotation); + Sync(); + return new Motor(id); + } + catch (Exception e) + { + Logging.MetaDebugLog(e); + } + } + + return null; + } + + public Motor(EGID id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + public Motor(uint id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + // custom motor properties + + /// + /// The motor's maximum rotational velocity. + /// + public float TopSpeed + { + get + { + return BlockEngine.GetBlockInfo(Id).maxVelocity; + } + + set + { + ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo(Id); + motor.maxVelocity = value; + } + } + + /// + /// The motor's maximum rotational force. + /// + public float Torque + { + get + { + return BlockEngine.GetBlockInfo(Id).maxForce; + } + + set + { + ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo(Id); + motor.maxForce = value; + } + } + + /// + /// The motor's direction. + /// + public bool Reverse + { + get + { + return BlockEngine.GetBlockInfo(Id).reverse; + } + + set + { + ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo(Id); + motor.reverse = value; + } + } + } +} diff --git a/GamecraftModdingAPI/Blocks/Piston.cs b/GamecraftModdingAPI/Blocks/Piston.cs new file mode 100644 index 0000000..1e69df6 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/Piston.cs @@ -0,0 +1,90 @@ +using System; + +using RobocraftX.Blocks; +using Svelto.ECS; +using Unity.Mathematics; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + public class Piston : Block + { + /// + /// Places a new piston. + /// Any valid piston type is accepted. + /// This re-implements Block.PlaceNew(...) + /// + public static new Piston PlaceNew(BlockIDs block, float3 position, + float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, + int uscale = 1, float3 scale = default, Player player = null) + { + if (!(block == BlockIDs.ServoPiston || block == BlockIDs.StepperPiston || block == BlockIDs.PneumaticPiston)) + { + throw new BlockTypeException($"Block is not a {typeof(Piston).Name} block"); + } + if (PlacementEngine.IsInGame && GameState.IsBuildMode()) + { + try + { + EGID id = PlacementEngine.PlaceBlock(block, color, darkness, + position, uscale, scale, player, rotation); + Sync(); + return new Piston(id); + } + catch (Exception e) + { + Logging.MetaDebugLog(e); + } + } + + return null; + } + + public Piston(EGID id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + public Piston(uint id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + // custom piston properties + + /// + /// The piston's max extension distance. + /// + public float MaximumExtension + { + get => BlockEngine.GetBlockInfo(Id).maxDeviation; + + set + { + ref PistonReadOnlyStruct piston = ref BlockEngine.GetBlockInfo(Id); + piston.maxDeviation = value; + } + } + + /// + /// The piston's max extension force. + /// + public float MaximumForce + { + get => BlockEngine.GetBlockInfo(Id).maxForce; + + set + { + ref PistonReadOnlyStruct piston = ref BlockEngine.GetBlockInfo(Id); + piston.maxForce = value; + } + } + } +} diff --git a/GamecraftModdingAPI/Blocks/Servo.cs b/GamecraftModdingAPI/Blocks/Servo.cs new file mode 100644 index 0000000..1c22d0b --- /dev/null +++ b/GamecraftModdingAPI/Blocks/Servo.cs @@ -0,0 +1,118 @@ +using System; + +using RobocraftX.Blocks; +using Svelto.ECS; +using Unity.Mathematics; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + public class Servo : Block + { + /// + /// Places a new servo. + /// Any valid servo type is accepted. + /// This re-implements Block.PlaceNew(...) + /// + public static new Servo PlaceNew(BlockIDs block, float3 position, + float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, + int uscale = 1, float3 scale = default, Player player = null) + { + if (!(block == BlockIDs.ServoAxle || block == BlockIDs.ServoHinge || block == BlockIDs.ServoPiston)) + { + throw new BlockTypeException($"Block is not a {typeof(Servo).Name} block"); + } + if (PlacementEngine.IsInGame && GameState.IsBuildMode()) + { + try + { + EGID id = PlacementEngine.PlaceBlock(block, color, darkness, + position, uscale, scale, player, rotation); + Sync(); + return new Servo(id); + } + catch (Exception e) + { + Logging.MetaDebugLog(e); + } + } + + return null; + } + + public Servo(EGID id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + public Servo(uint id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + // custom servo properties + + /// + /// The servo's minimum angle. + /// + public float MinimumAngle + { + get => BlockEngine.GetBlockInfo(Id).minDeviation; + + set + { + ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo(Id); + servo.minDeviation = value; + } + } + + /// + /// The servo's maximum angle. + /// + public float MaximumAngle + { + get => BlockEngine.GetBlockInfo(Id).maxDeviation; + + set + { + ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo(Id); + servo.maxDeviation = value; + } + } + + /// + /// The servo's maximum force. + /// + public float MaximumForce + { + get => BlockEngine.GetBlockInfo(Id).maxForce; + + set + { + ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo(Id); + servo.maxForce = value; + } + } + + /// + /// The servo's direction. + /// + public bool Reverse + { + get => BlockEngine.GetBlockInfo(Id).reverse; + + set + { + ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo(Id); + servo.reverse = value; + } + } + } +} diff --git a/GamecraftModdingAPI/Blocks/SignalEngine.cs b/GamecraftModdingAPI/Blocks/SignalEngine.cs index 90343e2..36716af 100644 --- a/GamecraftModdingAPI/Blocks/SignalEngine.cs +++ b/GamecraftModdingAPI/Blocks/SignalEngine.cs @@ -10,6 +10,11 @@ namespace GamecraftModdingAPI.Blocks /// public class SignalEngine : IApiEngine { + public const float POSITIVE_HIGH = 1.0f; + public const float NEGATIVE_HIGH = -1.0f; + public const float HIGH = 1.0f; + public const float ZERO = 0.0f; + public string Name { get; } = "GamecraftModdingAPISignalGameEngine"; public EntitiesDB entitiesDB { set; private get; } @@ -58,13 +63,13 @@ namespace GamecraftModdingAPI.Blocks channelData.valueAsFloat += signal; if (clamp) { - if (channelData.valueAsFloat > Signals.POSITIVE_HIGH) + if (channelData.valueAsFloat > POSITIVE_HIGH) { - channelData.valueAsFloat = Signals.POSITIVE_HIGH; + channelData.valueAsFloat = POSITIVE_HIGH; } - else if (channelData.valueAsFloat < Signals.NEGATIVE_HIGH) + else if (channelData.valueAsFloat < NEGATIVE_HIGH) { - channelData.valueAsFloat = Signals.NEGATIVE_HIGH; + channelData.valueAsFloat = NEGATIVE_HIGH; } return channelData.valueAsFloat; @@ -106,6 +111,60 @@ namespace GamecraftModdingAPI.Blocks return signals; } + public EGID[] GetSignalInputs(EGID blockID) + { + BlockPortsStruct ports = entitiesDB.QueryEntity(blockID); + EGID[] inputs = new EGID[ports.inputCount]; + for (uint i = 0; i < ports.inputCount; i++) + { + inputs[i] = new EGID(i + ports.firstInputID, NamedExclusiveGroup.Group); + } + return inputs; + } + + public EGID[] GetSignalOutputs(EGID blockID) + { + BlockPortsStruct ports = entitiesDB.QueryEntity(blockID); + EGID[] outputs = new EGID[ports.outputCount]; + for (uint i = 0; i < ports.outputCount; i++) + { + outputs[i] = new EGID(i + ports.firstOutputID, NamedExclusiveGroup.Group); + } + return outputs; + } + + public ref WireEntityStruct MatchPortToWire(EGID portID, EGID blockID, out bool exists) + { + ref PortEntityStruct port = ref entitiesDB.QueryEntity(portID); + WireEntityStruct[] wires = entitiesDB.QueryEntities(NamedExclusiveGroup.Group).ToFastAccess(out uint count); + for (uint i = 0; i < count; i++) + { + if ((wires[i].destinationPortUsage == port.usage && wires[i].destinationBlockEGID == blockID) + || (wires[i].sourcePortUsage == port.usage && wires[i].sourceBlockEGID == blockID)) + { + exists = true; + return ref wires[i]; + } + } + exists = false; + WireEntityStruct[] defRef = new WireEntityStruct[1]; + return ref defRef[0]; + } + + public ref ChannelDataStruct GetChannelDataStruct(EGID portID, out bool exists) + { + ref PortEntityStruct port = ref entitiesDB.QueryEntity(portID); + ChannelDataStruct[] channels = entitiesDB.QueryEntities(NamedExclusiveGroup.Group).ToFastAccess(out uint count); + if (port.firstChannelIndexCachedInSim < count) + { + exists = true; + return ref channels[port.firstChannelIndexCachedInSim]; + } + exists = false; + ChannelDataStruct[] defRef = new ChannelDataStruct[1]; + return ref defRef[0]; + } + public EGID[] GetElectricBlocks() { uint count = entitiesDB.Count(BlockIdentifiers.OWNED_BLOCKS) + entitiesDB.Count(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS); diff --git a/GamecraftModdingAPI/Blocks/SignalingBlock.cs b/GamecraftModdingAPI/Blocks/SignalingBlock.cs new file mode 100644 index 0000000..d654ca9 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/SignalingBlock.cs @@ -0,0 +1,131 @@ +using System; + +using Gamecraft.Wires; +using Svelto.ECS; +using Unity.Mathematics; + +using GamecraftModdingAPI; +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + /// + /// Common implementation for blocks that support wiring. + /// + public class SignalingBlock : Block + { + /// + /// Places a new signaling block. + /// Any valid functional block type with IO ports will work. + /// This re-implements Block.PlaceNew(...) + /// + public static new SignalingBlock PlaceNew(BlockIDs block, float3 position, + float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, + int uscale = 1, float3 scale = default, Player player = null) + { + if (PlacementEngine.IsInGame && GameState.IsBuildMode()) + { + try + { + EGID id = PlacementEngine.PlaceBlock(block, color, darkness, + position, uscale, scale, player, rotation); + Sync(); + return new SignalingBlock(id); + } + catch (Exception e) + { + Logging.MetaDebugLog(e); + } + } + + return null; + } + + public SignalingBlock(EGID id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + public SignalingBlock(uint id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + protected ref BlockPortsStruct GetBlockPortsStruct() + { + return ref BlockEngine.GetBlockInfo(Id); + } + + /// + /// Generates the input port identifiers. + /// + /// The input identifiers. + protected EGID[] GetInputIds() + { + return SignalEngine.GetSignalInputs(Id); + } + + /// + /// Generates the output port identifiers. + /// + /// The output identifiers. + protected EGID[] GetOutputIds() + { + return SignalEngine.GetSignalOutputs(Id); + } + + /// + /// Gets the port struct. + /// + /// The port struct. + /// Port identifier. + protected ref PortEntityStruct GetPortStruct(EGID portId) + { + return ref BlockEngine.GetBlockInfo(portId); + } + + /// + /// Gets the connected wire. + /// + /// The connected wire. + /// Port identifier. + /// Whether the port has a wire connected to it. + protected ref WireEntityStruct GetConnectedWire(EGID portId, out bool connected) + { + return ref SignalEngine.MatchPortToWire(portId, Id, out connected); + } + + /// + /// [EXPERIMENTAL] Gets the channel data. + /// + /// The channel data. + /// Port identifier. + /// Whether the channel actually exists. + protected ref ChannelDataStruct GetChannelData(EGID portId, out bool exists) + { + return ref SignalEngine.GetChannelDataStruct(portId, out exists); + } + + /// + /// The input port count. + /// + public uint InputCount + { + get => GetBlockPortsStruct().inputCount; + } + + /// + /// The output port count. + /// + public uint OutputCount + { + get => GetBlockPortsStruct().outputCount; + } + } +} diff --git a/GamecraftModdingAPI/Blocks/Signals.cs b/GamecraftModdingAPI/Blocks/Signals.cs deleted file mode 100644 index 6adf670..0000000 --- a/GamecraftModdingAPI/Blocks/Signals.cs +++ /dev/null @@ -1,177 +0,0 @@ -using Svelto.ECS; - -using GamecraftModdingAPI.Utility; - -namespace GamecraftModdingAPI.Blocks -{ - /// - /// [EXPERIMENTAL] Common block signal operations - /// The functionality in this class only works when in a game. - /// - public static class Signals - { - // Signal constants - public static readonly float HIGH = 1.0f; - public static readonly float POSITIVE_HIGH = HIGH; - public static readonly float NEGATIVE_HIGH = -1.0f; - public static readonly float LOW = 0.0f; - - private static SignalEngine signalEngine = new SignalEngine(); - - /// - /// Set the electric block's (first) signal value. - /// - /// The block's id. - /// The signal value (-1 to 1; not enforced). - /// Whether to retrieve input IDs (true) or output IDs (false). - /// Whether the block is in the owned group (true) or functional group (false) - public static void SetSignalByBlock(uint blockID, float signal, bool input = true, bool owned = true) - { - EGID egid = new EGID(blockID, owned ? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS); - if (signalEngine.IsInGame && GameState.IsSimulationMode()) - { - signalEngine.SetSignal(egid, signal, out uint _, input); - } - } - - public static void SetSignalByBlock(EGID blockID, float signal, bool input = true) - { - if (signalEngine.IsInGame && GameState.IsSimulationMode()) - { - signalEngine.SetSignal(blockID, signal, out uint _, input); - } - } - - /// - /// Set the signal's value. - /// - /// The channel cluster's id. - /// The signal value (-1 to 1; not enforced). - /// Whether to retrieve input IDs (true) or output IDs (false). - public static void SetSignalByID(uint signalID, float signal, bool input = true) - { - if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) - { - signalEngine.SetSignal(signalID, signal, input); - } - } - - /// - /// Add a value to an electric block's signal. - /// - /// The block's id. - /// The signal value to add. - /// Whether to clamp the resulting signal value between -1 and 1. - /// Whether to retrieve input IDs (true) or output IDs (false). - /// Whether the block is in the owned group (true) or functional group (false) - /// The signal's new value. - public static float AddSignalByBlock(uint blockID, float signal, bool clamp = true, bool input = true, bool owned = true) - { - EGID egid = new EGID(blockID, owned ? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS); - if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) - { - return signalEngine.AddSignal(egid, signal, out uint _, clamp, input); - } - return 0f; - } - - public static float AddSignalByBlock(EGID blockID, float signal, bool clamp = true, bool input = true) - { - if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) - { - return signalEngine.AddSignal(blockID, signal, out uint _, clamp, input); - } - return 0f; - } - - /// - /// Add a value to a conductive cluster channel. - /// - /// The channel cluster's id. - /// The signal value to add. - /// Whether to clamp the resulting signal value between -1 and 1. - /// Whether to retrieve input IDs (true) or output IDs (false). - /// The signal's new value. - public static float AddSignalByID(uint signalID, float signal, bool clamp = true, bool input = true) - { - if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) - { - return signalEngine.AddSignal(signalID, signal, clamp, input); - } - return 0f; - } - - /// - /// Get a electric block's signal's (first) value. - /// - /// The block's id. - /// Whether to retrieve input IDs (true) or output IDs (false). - /// Whether the block is in the owned group (true) or functional group (false) - /// The signal's value. - public static float GetSignalByBlock(uint blockID, bool input = true, bool owned = true) - { - EGID egid = new EGID(blockID, owned? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS); - if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) - { - return signalEngine.GetSignal(egid, out uint _, input); - } - return 0f; - } - - public static float GetSignalByBlock(EGID blockID, bool input = true) - { - if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) - { - return signalEngine.GetSignal(blockID, out uint _, input); - } - return 0f; - } - - /// - /// Get a signal's value. - /// - /// The signal's id. - /// Whether to retrieve input IDs (true) or output IDs (false). - /// The signal's value. - public static float GetSignalByID(uint signalID, bool input = true) - { - if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) - { - return signalEngine.GetSignal(signalID, input); - } - return 0f; - } - - /// - /// Get the ID of every electric block in the game world. - /// - /// The block IDs. - public static EGID[] GetElectricBlocks() - { - return signalEngine.GetElectricBlocks(); - } - - /// - /// Get the unique identifiers for the input wires connected to an electric block. - /// - /// The block's id. - /// Whether to retrieve input IDs (true) or output IDs (false). - /// Whether the block is in the owned group (true) or functional group (false) - /// The unique IDs. - public static uint[] GetSignalIDs(uint blockID, bool input = true, bool owned = true) - { - EGID egid = new EGID(blockID, owned ? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS); - return signalEngine.GetSignalIDs(egid, input); - } - - public static uint[] GetSignalIDs(EGID blockID, bool input = true, bool owned = true) - { - return signalEngine.GetSignalIDs(blockID, input); - } - - public static void Init() - { - GameEngineManager.AddGameEngine(signalEngine); - } - } -} diff --git a/GamecraftModdingAPI/Blocks/Tweakable.cs b/GamecraftModdingAPI/Blocks/Tweakable.cs deleted file mode 100644 index 6405ac3..0000000 --- a/GamecraftModdingAPI/Blocks/Tweakable.cs +++ /dev/null @@ -1,98 +0,0 @@ -namespace GamecraftModdingAPI.Blocks -{ - /// - /// Common tweakable stats operations. - /// The functionality of this class works best in build mode. - /// - public static class Tweakable - { - private static TweakableEngine tweakableEngine = new TweakableEngine(); - - /// - /// Get the tweakable stat's value using a dynamic variable type. - /// This is similar to GetStat but without strong type enforcement. - /// This should be used in dynamically-typed languages like Python. - /// - /// The stat's value. - /// The block's id. - /// The stat's enumerated id. - public static dynamic GetStatD(uint blockID, TweakableStat stat) - { - return tweakableEngine.GetStatDynamic(blockID, stat); - } - - /// - /// Get the tweakable stat's value. - /// If T is not the same type as the stat, an InvalidCastException will be thrown. - /// - /// The stat's value. - /// The block's id. - /// The stat's enumerated id. - /// The stat's type. - public static T GetStat(uint blockID, TweakableStat stat) - { - return tweakableEngine.GetStatAny(blockID, stat); - } - - /// - /// Set the tweakable stat's value using dynamically-typed variables. - /// This is similar to SetStat but without strong type enforcement. - /// This should be used in dynamically-typed languages like Python. - /// - /// The stat's new value. - /// The block's id. - /// The stat's enumerated id. - /// The stat's new value. - public static dynamic SetStatD(uint blockID, TweakableStat stat, dynamic value) - { - return tweakableEngine.SetStatDynamic(blockID, stat, value); - } - - /// - /// Set the tweakable stat's value. - /// If T is not the stat's actual type, an InvalidCastException will be thrown. - /// - /// The stat's new value. - /// The block's id. - /// The stat's enumerated id. - /// The stat's new value. - /// The stat's type. - public static T SetStat(uint blockID, TweakableStat stat, T value) - { - return tweakableEngine.SetStatAny(blockID, stat, value); - } - - /// - /// Add another value to the tweakable stat's value using dynamically-typed variables. - /// This is similar to AddStat but without strong type enforcement. - /// This should be used in dynamically-typed languages like Python. - /// - /// The stat's new value. - /// The block's id. - /// The stat's enumerated id. - /// The value to be added to the stat. - public static dynamic AddStatD(uint blockID, TweakableStat stat, dynamic value) - { - return tweakableEngine.AddStatDynamic(blockID, stat, value); - } - - /// - /// Add another value to the tweakable stat's value. - /// If T is not the stat's actual type, an InvalidCastException will be thrown. - /// - /// The stat's new value. - /// The block's id. - /// The stat's enumerated id. - /// The value to be added to the stat. - /// The stat's type. - public static T AddStat(uint blockID, TweakableStat stat, T value) - { - return tweakableEngine.AddStatAny(blockID, stat, value); - } - - public static void Init() - { - GamecraftModdingAPI.Utility.GameEngineManager.AddGameEngine(tweakableEngine); - } - } -} diff --git a/GamecraftModdingAPI/Blocks/TweakableEngine.cs b/GamecraftModdingAPI/Blocks/TweakableEngine.cs deleted file mode 100644 index 36ace8a..0000000 --- a/GamecraftModdingAPI/Blocks/TweakableEngine.cs +++ /dev/null @@ -1,452 +0,0 @@ -using RobocraftX.Blocks; -using Gamecraft.Wires; -using Svelto.ECS; - -using GamecraftModdingAPI.Engines; - - -namespace GamecraftModdingAPI.Blocks -{ - public class TweakableEngine : IApiEngine - { - public string Name { get; } = "GamecraftModdingAPITweakableGameEngine"; - - public EntitiesDB entitiesDB { set; private get; } - - public bool isRemovable => false; - - public bool IsInGame = false; - - public void Dispose() - { - IsInGame = false; - } - - public void Ready() - { - IsInGame = true; - } - - // Implementations for Tweakable static class - - public T GetStatAny(EGID blockID, TweakableStat stat) - { - switch (stat) - { - case TweakableStat.TopSpeed: - if (entitiesDB.Exists(blockID)) - { - return (T)(object)entitiesDB.QueryEntity(blockID).maxVelocity; - } - break; - case TweakableStat.Torque: - if (entitiesDB.Exists(blockID)) - { - return (T)(object)entitiesDB.QueryEntity(blockID).maxForce; - } - break; - case TweakableStat.MaxExtension: - if (entitiesDB.Exists(blockID)) - { - return (T)(object)entitiesDB.QueryEntity(blockID).maxDeviation; - } - break; - case TweakableStat.MinAngle: - if (entitiesDB.Exists(blockID)) - { - return (T)(object)entitiesDB.QueryEntity(blockID).minDeviation; - } - break; - case TweakableStat.MaxAngle: - if (entitiesDB.Exists(blockID)) - { - return (T)(object)entitiesDB.QueryEntity(blockID).maxDeviation; - } - break; - case TweakableStat.Reverse: - if (entitiesDB.Exists(blockID)) - { - return (T)(object)entitiesDB.QueryEntity(blockID).reverse; - } - else if (entitiesDB.Exists(blockID)) - { - return (T)(object)entitiesDB.QueryEntity(blockID).reverse; - } - break; - case TweakableStat.StartValue: - if (entitiesDB.Exists(blockID)) - { - return (T)(object)entitiesDB.QueryEntity(blockID).startValue; - } - break; - } - return default(T); - } - - public T GetStatAny(uint blockID, TweakableStat stat) - { - return GetStatAny(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat); - } - - public dynamic GetStatDynamic(EGID blockID, TweakableStat stat) - { - switch (stat) - { - case TweakableStat.TopSpeed: - if (entitiesDB.Exists(blockID)) - { - return entitiesDB.QueryEntity(blockID).maxVelocity; - } - break; - case TweakableStat.Torque: - if (entitiesDB.Exists(blockID)) - { - return entitiesDB.QueryEntity(blockID).maxForce; - } - break; - case TweakableStat.MaxExtension: - if (entitiesDB.Exists(blockID)) - { - return entitiesDB.QueryEntity(blockID).maxDeviation; - } - break; - case TweakableStat.MinAngle: - if (entitiesDB.Exists(blockID)) - { - return entitiesDB.QueryEntity(blockID).minDeviation; - } - break; - case TweakableStat.MaxAngle: - if (entitiesDB.Exists(blockID)) - { - return entitiesDB.QueryEntity(blockID).maxDeviation; - } - break; - case TweakableStat.Reverse: - if (entitiesDB.Exists(blockID)) - { - return entitiesDB.QueryEntity(blockID).reverse; - } - else if (entitiesDB.Exists(blockID)) - { - return entitiesDB.QueryEntity(blockID).reverse; - } - break; - case TweakableStat.StartValue: - if (entitiesDB.Exists(blockID)) - { - return entitiesDB.QueryEntity(blockID).startValue; - } - break; - } - return null; - } - - public dynamic GetStatDynamic(uint blockID, TweakableStat stat) - { - return GetStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat); - } - - public T SetStatAny(EGID blockID, TweakableStat stat, T value) - { - switch (stat) - { - case TweakableStat.TopSpeed: - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxVelocity = (float)(object)value; - return (T)(object)refStruct.maxVelocity; - } - break; - case TweakableStat.Torque: - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxForce = (float)(object)value; - return (T)(object)refStruct.maxForce; - } - break; - case TweakableStat.MaxExtension: - if (entitiesDB.Exists(blockID)) - { - ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxDeviation = (float)(object)value; - return (T)(object)refStruct.maxDeviation; - } - break; - case TweakableStat.MinAngle: - if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.minDeviation = (float)(object)value; - return (T)(object)refStruct.minDeviation; - } - break; - case TweakableStat.MaxAngle: - if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxDeviation = (float)(object)value; - return (T)(object)refStruct.maxDeviation; - } - break; - case TweakableStat.Reverse: - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.reverse = (bool)(object)value; - return (T)(object)refStruct.reverse; - } - else if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.reverse = (bool)(object)value; - return (T)(object)refStruct.reverse; - } - break; - case TweakableStat.StartValue: - if (entitiesDB.Exists(blockID)) - { - ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.startValue = (float)(object)value; - return (T)(object)refStruct.startValue; - } - break; - } - return default(T); - } - - public T SetStatAny(uint blockID, TweakableStat stat, T value) - { - return SetStatAny(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value); - } - - public dynamic SetStatDynamic(EGID blockID, TweakableStat stat, dynamic value) - { - switch (stat) - { - case TweakableStat.TopSpeed: - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxVelocity = value; - return refStruct.maxVelocity; - } - break; - case TweakableStat.Torque: - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxForce = value; - return refStruct.maxForce; - } - break; - case TweakableStat.MaxExtension: - if (entitiesDB.Exists(blockID)) - { - ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxDeviation = value; - return refStruct.maxDeviation; - } - break; - case TweakableStat.MinAngle: - if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.minDeviation = value; - return refStruct.minDeviation; - } - break; - case TweakableStat.MaxAngle: - if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxDeviation = value; - return refStruct.maxDeviation; - } - break; - case TweakableStat.Reverse: - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.reverse = value; - return refStruct.reverse; - } - else if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.reverse = value; - return refStruct.reverse; - } - break; - case TweakableStat.StartValue: - if (entitiesDB.Exists(blockID)) - { - ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.startValue = value; - return refStruct.startValue; - } - break; - } - return null; - } - - public dynamic SetStatDynamic(uint blockID, TweakableStat stat, dynamic value) - { - return SetStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value); - } - - public T AddStatAny(EGID blockID, TweakableStat stat, T value) - { - switch (stat) - { - case TweakableStat.TopSpeed: - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxVelocity += (float)(object)value; - return (T)(object)refStruct.maxVelocity; - } - break; - case TweakableStat.Torque: - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxForce += (float)(object)value; - return (T)(object)refStruct.maxForce; - } - break; - case TweakableStat.MaxExtension: - if (entitiesDB.Exists(blockID)) - { - ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxDeviation += (float)(object)value; - return (T)(object)refStruct.maxDeviation; - } - break; - case TweakableStat.MinAngle: - if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.minDeviation += (float)(object)value; - return (T)(object)refStruct.minDeviation; - } - break; - case TweakableStat.MaxAngle: - if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxDeviation += (float)(object)value; - return (T)(object)refStruct.maxDeviation; - } - break; - case TweakableStat.Reverse: - // '+' is associated with logical OR in some fields, so it technically isn't invalid to "add" booleans - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.reverse = refStruct.reverse || (bool)(object)value; - return (T)(object)refStruct.reverse; - } - else if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.reverse = refStruct.reverse || (bool)(object)value; - return (T)(object)refStruct.reverse; - } - break; - case TweakableStat.StartValue: - if (entitiesDB.Exists(blockID)) - { - ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.startValue += (float)(object)value; - return (T)(object)refStruct.startValue; - } - break; - } - return default(T); - } - - public T AddStatAny(uint blockID, TweakableStat stat, T value) - { - return AddStatAny(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value); - } - - public dynamic AddStatDynamic(EGID blockID, TweakableStat stat, dynamic value) - { - switch (stat) - { - case TweakableStat.TopSpeed: - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxVelocity += value; - return refStruct.maxVelocity; - } - break; - case TweakableStat.Torque: - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxForce += value; - return refStruct.maxForce; - } - break; - case TweakableStat.MaxExtension: - if (entitiesDB.Exists(blockID)) - { - ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxDeviation += value; - return refStruct.maxDeviation; - } - break; - case TweakableStat.MinAngle: - if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.minDeviation += value; - return refStruct.minDeviation; - } - break; - case TweakableStat.MaxAngle: - if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.maxDeviation += value; - return refStruct.maxDeviation; - } - break; - case TweakableStat.Reverse: - // '+' is associated with logical OR in some fields, so it technically isn't invalid to "add" booleans - if (entitiesDB.Exists(blockID)) - { - ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.reverse = refStruct.reverse || value; - return refStruct.reverse; - } - else if (entitiesDB.Exists(blockID)) - { - ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.reverse = refStruct.reverse || value; - return refStruct.reverse; - } - break; - case TweakableStat.StartValue: - if (entitiesDB.Exists(blockID)) - { - ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(blockID); - refStruct.startValue += value; - return refStruct.startValue; - } - break; - } - return null; - } - - public dynamic AddStatDynamic(uint blockID, TweakableStat stat, dynamic value) - { - return AddStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value); - } - } -} diff --git a/GamecraftModdingAPI/Blocks/TweakableStat.cs b/GamecraftModdingAPI/Blocks/TweakableStat.cs deleted file mode 100644 index 228c89d..0000000 --- a/GamecraftModdingAPI/Blocks/TweakableStat.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace GamecraftModdingAPI.Blocks -{ - public enum TweakableStat - { - TopSpeed, // MotorReadOnlyStruct - Torque, // MotorReadOnlyStruct - MaxExtension, // PistonReadOnlyStruct - MinAngle, // ServoReadOnlyStruct - MaxAngle, // ServoReadOnlyStruct - Reverse, // MotorReadOnlyStruct or ServoReadOnlyStruct - StartValue, // SignalGeneratorEntityStruct - } -} diff --git a/GamecraftModdingAPI/Main.cs b/GamecraftModdingAPI/Main.cs index 5a65baf..56f481f 100644 --- a/GamecraftModdingAPI/Main.cs +++ b/GamecraftModdingAPI/Main.cs @@ -63,8 +63,6 @@ namespace GamecraftModdingAPI EventManager.AddEventEmitter(GameHostTransitionDeterministicGroupEnginePatch.simEngine); // init block implementors Logging.MetaDebugLog($"Initializing Blocks"); - Blocks.Signals.Init(); - Blocks.Tweakable.Init(); // init inventory Inventory.Hotbar.Init(); // init input diff --git a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs index 9d180ea..8576f97 100644 --- a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs +++ b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs @@ -146,35 +146,6 @@ namespace GamecraftModdingAPI.Tests .Action((float x, float y, float z) => { Block.PlaceNew(Blocks.BlockIDs.AluminiumCube, new Unity.Mathematics.float3(x, y, z)); }) .Build(); - System.Random random = new System.Random(); // for command below - CommandBuilder.Builder() - .Name("RandomizeSignalsInputs") - .Description("Do the thing") - .Action(() => { - if (!GameState.IsSimulationMode()) - { - Logging.CommandLogError("You must be in simulation mode for this to work!"); - return; - } - Tasks.Repeatable task = new Tasks.Repeatable( - () => { - uint count = 0; - EGID[] eBlocks = Blocks.Signals.GetElectricBlocks(); - for (uint i = 0u; i < eBlocks.Length; i++) - { - uint[] ids = Blocks.Signals.GetSignalIDs(eBlocks[i]); - for (uint j = 0u; j < ids.Length; j++) - { - Blocks.Signals.SetSignalByID(ids[j], (float)random.NextDouble()); - count++; - } - } - Logging.MetaDebugLog($"Did the thing on {count} inputs"); - }, - () => { return GameState.IsSimulationMode(); }); - Tasks.Scheduler.Schedule(task); - }).Build(); - CommandBuilder.Builder("getBlock") .Action(() => uREPL.Log.Output(new Player(Players.PlayerType.Local).GetBlockLookedAt()+"")).Build(); diff --git a/doxygen.conf b/doxygen.conf index 0535320..bdd0ed0 100644 --- a/doxygen.conf +++ b/doxygen.conf @@ -38,7 +38,7 @@ PROJECT_NAME = "GamecraftModdingAPI" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "v1.0.0" +PROJECT_NUMBER = "v1.1.0" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a