diff --git a/extracommands/ChainCommandEngine.cs b/extracommands/ChainCommandEngine.cs index 869d324..7cac7ee 100644 --- a/extracommands/ChainCommandEngine.cs +++ b/extracommands/ChainCommandEngine.cs @@ -14,25 +14,31 @@ using Svelto.Tasks.ExtraLean; using RobocraftX; using RobocraftX.Schedulers; +using GamecraftModdingAPI.Commands; +using GamecraftModdingAPI.Tasks; +using GamecraftModdingAPI.Utility; + namespace ExtraCommands.Basics { - [CustomCommand("Chain")] - class ChainCommandEngine : CustomCommandEngine + //[CustomCommand("Chain")] + class ChainCommandEngine : ICustomCommandEngine { - public ChainCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) - { - } + public string Description => "Run two commands one after the other"; + + public string Name => "Chain"; + + public IEntitiesDB entitiesDB { set; private get; } - public override void Ready() + public void Ready() { - CustomCommandUtility.Register("Chain", ChainCommand, "Run two commands, one after the other"); + CommandRegistrationHelper.Register(Name, ChainCommand, Description); } private void ChainCommand(string command1, string command2) { string command1a = decomma(command1); string command2a = decomma(command2); - ScheduleCommands(command1a, command2a).RunOn(ExtraLean.CharacterUpdateScheduler); + ScheduleCommands(command1a, command2a).RunOn(Scheduler.extraLeanRunner); } private IEnumerator ScheduleCommands(string c1, string c2) @@ -41,12 +47,12 @@ namespace ExtraCommands.Basics bool success1 = uREPL.Evaluator.Evaluate(c1).type == CompileResult.Type.Success; if (!success1) { - uREPL.Log.Error("First command was not executed successfully"); + Logging.CommandLogError("First command was not executed successfully"); } bool success2 = uREPL.Evaluator.Evaluate(c2).type == CompileResult.Type.Success; if (!success2) { - uREPL.Log.Error("Second command was not executed successfully"); + Logging.CommandLogError("Second command was not executed successfully"); } } @@ -55,9 +61,9 @@ namespace ExtraCommands.Basics return strIn.Replace(", ", " "); } - public override void Dispose() + public void Dispose() { - CustomCommandUtility.Unregister("Chain"); + CommandRegistrationHelper.Unregister("Chain"); } } } diff --git a/extracommands/CommandLineCompositionRootSaveCommandPatch.cs b/extracommands/CommandLineCompositionRootSaveCommandPatch.cs index 168e40f..5f28270 100644 --- a/extracommands/CommandLineCompositionRootSaveCommandPatch.cs +++ b/extracommands/CommandLineCompositionRootSaveCommandPatch.cs @@ -1,57 +1 @@ -using System; -using System.Reflection; -using Harmony; -using UnityEngine; -using Unity.Entities; -using RobocraftX; -using RobocraftX.GUI.CommandLine; -using RobocraftX.Multiplayer; -using RobocraftX.StateSync; -using Svelto.ECS; -using Svelto.Context; - -namespace ExtraCommands -{ - [HarmonyPatch] - class CommandLineCompositionRootSaveCommandPatch - { - static void Postfix(UnityContext contextHolder, EnginesRoot enginesRoot, World physicsWorld, Action reloadGame, MultiplayerInitParameters multiplayerParameters) - { - int engineCount = 0; - MethodInfo commandHelp = Harmony.AccessTools.Method(Harmony.AccessTools.TypeByName("RobocraftX.GUI.CommandLine.CommandLineUtility"), "SaveCommandHelp", new Type[] { typeof(string), typeof(string) }); - foreach (Type t in typeof(CustomCommandEngine).Assembly.GetTypes()) - { - CustomCommandAttribute[] attributes = (CustomCommandAttribute[])t.GetCustomAttributes(typeof(CustomCommandAttribute), false); - CustomCommandEngine inst = null; - foreach (CustomCommandAttribute attr in attributes) - { - if (attr != null && t.IsSubclassOf(typeof(CustomCommandEngine))) - { - if (inst == null) - { - // create instance by getting the constructor through reflection - inst = (CustomCommandEngine)t.GetConstructor(new Type[] { typeof(UnityContext), typeof(EnginesRoot), typeof(World), typeof(Action), typeof(MultiplayerInitParameters) }) - .Invoke(new object[] { contextHolder, enginesRoot, physicsWorld, reloadGame, multiplayerParameters }); - // add to engineRoot - enginesRoot.AddEngine(inst); - engineCount++; - } - } - } - } - Debug.Log($"Added {engineCount} custom command engines"); - } - - static MethodBase TargetMethod(HarmonyInstance instance) - { - return _ComposeMethodInfo(CommandLineCompositionRoot.Compose); - } - - private delegate void ComposeAction(UnityContext c, EnginesRoot r, World w, Action a, - MultiplayerInitParameters mip, ref StateSyncRegistrationHelper ssrh); //Ref params can't be used with Actions - private static MethodInfo _ComposeMethodInfo(ComposeAction a) - { - return a.Method; - } - } -} + \ No newline at end of file diff --git a/extracommands/CustomCommandAttribute.cs b/extracommands/CustomCommandAttribute.cs index df7cb5c..6e3ddb4 100644 --- a/extracommands/CustomCommandAttribute.cs +++ b/extracommands/CustomCommandAttribute.cs @@ -1,18 +1,35 @@ using System; +using GamecraftModdingAPI.Commands; + namespace ExtraCommands { [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class CustomCommandAttribute: Attribute { - public string Name { get; protected set; } + public readonly string Name; + + public readonly string Description; - public string Description { get; protected set; } + public readonly bool IsFactory; - public CustomCommandAttribute(string name = "", string description = "") + public CustomCommandAttribute(string name = "", string description = "", bool factory = false) { this.Name = name; this.Description = description; + this.IsFactory = factory; } + + public static bool IsCompatible(Type t) + { + foreach (var i in t.GetInterfaces()) + { + if (i == typeof(ICustomCommandEngine)) + { + return true; + } + } + return false; + } } } diff --git a/extracommands/CustomCommandEngine.cs b/extracommands/CustomCommandEngine.cs deleted file mode 100644 index 8963275..0000000 --- a/extracommands/CustomCommandEngine.cs +++ /dev/null @@ -1,39 +0,0 @@ -using RobocraftX.GUI.CommandLine; -using RobocraftX.Multiplayer; -using Svelto.Context; -using Svelto.ECS; -using System; -using Unity.Entities; -using RobocraftX; - -namespace ExtraCommands -{ - class CustomCommandEngine : IQueryingEntitiesEngine, IEngine, IDisposable - { - protected UnityContext context; - - protected EnginesRoot enginesRoot; - - protected World physWorld; - - protected Action reloadGame; - - protected MultiplayerInitParameters multiplayerInitParameters; - - public CustomCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) - { - this.context = ctxHolder; - this.enginesRoot = enginesRoot; - this.physWorld = physW; - this.reloadGame = reloadGame; - this.multiplayerInitParameters = mpParams; - } - - public IEntitiesDB entitiesDB { set; get; } - - virtual public void Dispose() { } - - // NOTE: Ready() should call CustomCommandUtility.Register to add the command to the command line - virtual public void Ready() { } - } -} diff --git a/extracommands/CustomCommandUtility.cs b/extracommands/CustomCommandUtility.cs deleted file mode 100644 index 2a8ac87..0000000 --- a/extracommands/CustomCommandUtility.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using uREPL; -using RobocraftX.CommandLine.Custom; - -namespace ExtraCommands -{ - static class CustomCommandUtility - { - public static void Register(string name, Action action, string desc) - { - RuntimeCommands.Register(name, action, desc); - ConsoleCommands.Register(name, action, desc); - } - - public static void Register(string name, Action action, string desc) - { - RuntimeCommands.Register(name, action, desc); - } - - public static void Register(string name, Action action, string desc) - { - RuntimeCommands.Register(name, action, desc); - ConsoleCommands.Register(name, action, desc); - } - - public static void Register(string name, Action action, string desc) - { - RuntimeCommands.Register(name, action, desc); - ConsoleCommands.Register(name, action, desc); - } - - public static void Register(string name, Action action, string desc) - { - RuntimeCommands.Register(name, action, desc); - ConsoleCommands.Register(name, action, desc); - } - - public static void Register(string name, Action action, string desc) - { - RuntimeCommands.Register(name, action, desc); - ConsoleCommands.Register(name, action, desc); - } - - public static void Unregister(string name) - { - RuntimeCommands.Unregister(name); - ConsoleCommands.Unregister(name); - } - } -} diff --git a/extracommands/ExampleCommandEngine.cs b/extracommands/ExampleCommandEngine.cs index 2e27db0..dfb57aa 100644 --- a/extracommands/ExampleCommandEngine.cs +++ b/extracommands/ExampleCommandEngine.cs @@ -10,6 +10,8 @@ using uREPL; using Svelto.Context; using RobocraftX; +using GamecraftModdingAPI.Commands; + // checklist of things to rename to make this command your own: // [ ] namespace ExtraCommands.Example -> namespace ExtraCommands.[your command's namespace] // [ ] class ExampleCommandEngine : CustomCommandEngine -> class [your command name]CommandEngine : CustomCommandEngine @@ -25,24 +27,26 @@ namespace ExtraCommands.Example { // !!! Uncomment the line below this !!! // [CustomCommand("Example")] - class ExampleCommandEngine : CustomCommandEngine + class ExampleCommandEngine : ICustomCommandEngine { - // This class is a custom implementation of CustomCommandEngine specific to this command - // You can use Svelto.ECS.IEntityDB entitiesDB to query game entities or one of the protected variables for other things - // More documentation on Svelto.ECS: https://github.com/sebas77/Svelto.ECS - // Unfortunately the documentation is severely lacking and out of date; you may have better luck decompiling Svelto.ECS.dll - // See CustomCommandEngine.cs for more information on the super class + public string Description => "This is an example command which does nothing!"; - public ExampleCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) - { - } + public string Name => "Example"; + + public IEntitiesDB entitiesDB { set; private get; } + + // This class is a custom implementation of CustomCommandEngine specific to this command + // You can use Svelto.ECS.IEntityDB entitiesDB to query game entities or one of the protected variables for other things + // More documentation on Svelto.ECS: https://github.com/sebas77/Svelto.ECS + // Unfortunately the documentation is severely lacking and out of date; you may have better luck decompiling Svelto.ECS.dll + // See CustomCommandEngine.cs for more information on the super class - // Ready() is called when the command is registered in-game (this happens whenever you load a game) - public override void Ready() + // Ready() is called when the command is registered in-game (this happens whenever you load a game) + public void Ready() { // CustomCommandUtility.Register has multiple overloads depending on how many parameters you want to pass to your command // See CustomCommandUtility.cs for more information - CustomCommandUtility.Register("Example", ExampleCommand, "This is an example command which does nothing!"); + CommandRegistrationHelper.Register(Name, ExampleCommand, Description); } // ExampleCommand() is called whenever the command is executed. This can accept up to three parameters @@ -53,11 +57,11 @@ namespace ExtraCommands.Example } // Dispose() is called when the command is unregistered in-game (this happens whenever you leave a game) - public override void Dispose() + public void Dispose() { // You must unregister the command so it doesn't waste memory and so // it can be re-registered next time - CustomCommandUtility.Unregister("Example"); + CommandRegistrationHelper.Unregister(Name); } } } diff --git a/extracommands/ExitCommandEngine.cs b/extracommands/ExitCommandEngine.cs index e2caa2b..d21187f 100644 --- a/extracommands/ExitCommandEngine.cs +++ b/extracommands/ExitCommandEngine.cs @@ -10,18 +10,22 @@ using uREPL; using Svelto.Context; using RobocraftX; +using GamecraftModdingAPI.Commands; + namespace ExtraCommands.Basics { [CustomCommand("Exit")] - class ExitCommandEngine : CustomCommandEngine + class ExitCommandEngine : ICustomCommandEngine { - public ExitCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) - { - } + public string Description => "Close Gamecraft without any prompts"; + + public string Name => "Exit"; + + public IEntitiesDB entitiesDB { set; private get; } - public override void Ready() + public void Ready() { - CustomCommandUtility.Register("Exit", ExitCommand, "Forcefully close Gamecraft"); + CommandRegistrationHelper.Register(Name, ExitCommand, Description); } private void ExitCommand() @@ -29,9 +33,9 @@ namespace ExtraCommands.Basics Application.Quit(); } - public override void Dispose() + public void Dispose() { - CustomCommandUtility.Unregister("Exit"); + CommandRegistrationHelper.Unregister(Name); } } } diff --git a/extracommands/ExtraCommands.csproj b/extracommands/ExtraCommands.csproj index 6991e54..c51e9b7 100644 --- a/extracommands/ExtraCommands.csproj +++ b/extracommands/ExtraCommands.csproj @@ -1,7 +1,7 @@  - net48 + net472 true @@ -10,101 +10,104 @@ + + ..\ref\Plugins\GamecraftModdingAPI.dll + - ..\ref\CommandLine.dll + ..\ref\Gamecraft_Data\Managed\CommandLine.dll - ..\ref\Facepunch.Steamworks.Win64.dll + ..\ref\Gamecraft_Data\Managed\Facepunch.Steamworks.Win64.dll - ..\ref\FullGame.dll + ..\ref\Gamecraft_Data\Managed\FullGame.dll - ..\IllusionPlugin.dll + ..\ref\Gamecraft_Data\Managed\IllusionPlugin.dll - ..\ref\RobocraftX.Character.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.Character.dll - ..\ref\RobocraftX.Common.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.Common.dll - ..\ref\RobocraftX.Blocks.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.dll - ..\ref\RobocraftX.Blocks.Ghost.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.Ghost.dll - ..\ref\RobocraftX.Character.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.Character.dll - ..\ref\RobocraftX.Input.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.Input.dll ..\ref\RobocraftX.MachineEditor.dll - ..\ref\RobocraftX.MainGame.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.MainGame.dll - ..\ref\RobocraftX.Multiplayer.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.dll - ..\ref\RobocraftX.Multiplayer.NetworkEntityStream.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll - ..\ref\RobocraftX.MultiplayerInput.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.MultiplayerInput.dll - ..\ref\RobocraftX.Physics.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.Physics.dll ..\ref\RobocraftX.Services.dll - ..\ref\RobocraftX.StateSync.dll + ..\ref\Gamecraft_Data\Managed\RobocraftX.StateSync.dll - ..\ref\Svelto.Common.dll + ..\ref\Gamecraft_Data\Managed\Svelto.Common.dll - ..\ref\Svelto.ECS.dll + ..\ref\Gamecraft_Data\Managed\Svelto.ECS.dll - ..\ref\Svelto.Tasks.dll + ..\ref\Gamecraft_Data\Managed\Svelto.Tasks.dll - ..\ref\Unity.Entities.dll + ..\ref\Gamecraft_Data\Managed\Unity.Entities.dll - ..\ref\Unity.Entities.Hybrid.dll + ..\ref\Gamecraft_Data\Managed\Unity.Entities.Hybrid.dll - ..\ref\Unity.Entities.Properties.dll + ..\ref\Gamecraft_Data\Managed\Unity.Entities.Properties.dll - ..\ref\Unity.Entities.StaticTypeRegistry.dll + ..\ref\Gamecraft_Data\Managed\Unity.Entities.StaticTypeRegistry.dll - ..\ref\Unity.Mathematics.dll + ..\ref\Gamecraft_Data\Managed\Unity.Mathematics.dll - ..\ref\Unity.Mathematics.Extensions.dll + ..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.dll - ..\ref\Unity.Mathematics.Extensions.Hybrid.dll + ..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - ..\ref\Unity.Transforms.dll + ..\ref\Gamecraft_Data\Managed\Unity.Transforms.dll - ..\ref\UnityEngine.dll + ..\ref\Gamecraft_Data\Managed\UnityEngine.dll - ..\ref\UnityEngine.CoreModule.dll + ..\ref\Gamecraft_Data\Managed\UnityEngine.CoreModule.dll - ..\ref\uREPL.dll + ..\ref\Gamecraft_Data\Managed\uREPL.dll diff --git a/extracommands/ExtraCommandsPlugin.cs b/extracommands/ExtraCommandsPlugin.cs index e4e61c5..2f795ec 100644 --- a/extracommands/ExtraCommandsPlugin.cs +++ b/extracommands/ExtraCommandsPlugin.cs @@ -1,38 +1,53 @@ using System; using IllusionPlugin; -using UnityEngine; -using Harmony; +//using UnityEngine; using System.Reflection; +using GamecraftModdingAPI.Commands; +using GamecraftModdingAPI.Utility; + namespace ExtraCommands { public class Plugin : IllusionPlugin.IEnhancedPlugin { - public static HarmonyInstance harmony { get; protected set; } - public string[] Filter { get; } = new string[] { "RobocraftX", "Gamecraft", "GamecraftPreview" }; public string Name { get; } = "ExtraCommands"; - public string Version { get; } = "v0.0.3a"; + public string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString(); public string HarmonyID { get; } = "org.git.exmods.extracommands.extracommands"; public void OnApplicationQuit() { - harmony.UnpatchAll(HarmonyID); - Debug.Log("ExtraCommands shutdown & unpatch complete"); + GamecraftModdingAPI.Main.Shutdown(); } - public void OnApplicationStart() - { - if (harmony == null) - { - harmony = HarmonyInstance.Create(HarmonyID); - harmony.PatchAll(Assembly.GetExecutingAssembly()); - } - Debug.Log("ExtraCommands start & patch complete"); - } + public void OnApplicationStart() + { + GamecraftModdingAPI.Main.Init(); + object[] empty = new object[] { }; + int engineCount = 0; + foreach (Type t in Assembly.GetExecutingAssembly().GetTypes()) + { + CustomCommandAttribute[] attributes = (CustomCommandAttribute[])t.GetCustomAttributes(typeof(CustomCommandAttribute), false); + ICustomCommandEngine inst = null; + foreach (CustomCommandAttribute attr in attributes) + { + if (attr != null && CustomCommandAttribute.IsCompatible(t)) + { + if (inst == null) + { + // create instance by getting the constructor through reflection + inst = (ICustomCommandEngine)t.GetConstructor(new Type[] { }).Invoke(empty); + CommandManager.AddCommand(inst); + engineCount++; + } + } + } + } + Logging.MetaLog($"Added {engineCount} custom command engines"); + } public void OnFixedUpdate() { diff --git a/extracommands/MoveBlocksCommandEngine.cs b/extracommands/MoveBlocksCommandEngine.cs index a70b72a..d5e2c4b 100644 --- a/extracommands/MoveBlocksCommandEngine.cs +++ b/extracommands/MoveBlocksCommandEngine.cs @@ -16,184 +16,37 @@ using Unity.Transforms; using Unity.Mathematics; using UnityEngine; +using GamecraftModdingAPI.Blocks; +using GamecraftModdingAPI.Commands; + namespace ExtraCommands.Building { - [CustomCommand("MoveBlocks", "Move all blocks (including ground) from their original position")] - [CustomCommand("MoveLastBlock", "Move last block from their original position")] - [CustomCommand("MoveNearBlock", "Move blocks attached to your ghost block from their original position")] - [CustomCommand("SetNearThreshold", "Set the threshold for a block to be considered 'near' to the ghost block")] - class MoveBlocksCommandEngine : CustomCommandEngine + //[CustomCommand("MoveBlocks", "Move all blocks (including ground) from their original position")] + [CustomCommand("MoveLastBlock", "Move last block from original position")] + class MoveBlocksCommandEngine : ICustomCommandEngine { - private float nearbyThreshold = 0.2f; - public MoveBlocksCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) - { - } + public string Description => "Move blocks"; - public override void Ready() - { - CustomCommandUtility.Register("MoveBlocks", MoveBlocksCommand, "Move all blocks (including ground) from their original position"); - CustomCommandUtility.Register("MoveLastBlock", MoveLastBlockCommand, "Move last block from their original position"); - //CustomCommandUtility.Register("MoveNearBlock", MoveNearbyBlockCommand, "Move blocks near your ghost block from their original position"); - //CustomCommandUtility.Register("SetNearThreshold", (float t)=> { this.nearbyThreshold = t; }, "Set the threshold for a block to be considered 'near' to the ghost block"); - } + public string Name => "MoveBlocks"; - // Move every block by vector (x,y,z) - private void MoveBlocksCommand(float x, float y, float z) - { - ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP); - if (simMode.simulationMode != SimulationMode.Build) - { - uREPL.Log.Error("Blocks can only be moved in Build Mode"); - return; - } - uint count = this.entitiesDB.Count(CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - float3 translationVector = new float3(x,y,z); - for (uint i = 0; i < count; i++) - { - TranslateSingleBlock(i, translationVector); - } - uREPL.Log.Output($"Moved {count} blocks"); - } + public IEntitiesDB entitiesDB { set; private get; } - // Move block with highest index by vector (x,y,z) - private void MoveLastBlockCommand(float x, float y, float z) - { - //uint count = entitiesDB.Count(CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP); - if (simMode.simulationMode != SimulationMode.Build) - { - uREPL.Log.Error("Blocks can only be moved in Build Mode"); - return; - } - float3 newPos = TranslateConnectedBlocks(CommonExclusiveGroups.CurrentBlockEntityID-1, new float3(x,y,z)); - uREPL.Log.Output($"Moved block to ({newPos.x},{newPos.y},{newPos.z})"); - } + public void Ready() + { + //CustomCommandUtility.Register("MoveBlocks", MoveBlocksCommand, "Move all blocks (including ground) from their original position"); + CommandRegistrationHelper.Register("MoveLastBlock", MoveLastBlockCommand, "Move last block from original position"); + } - private void MoveNearbyBlockCommand(float x, float y, float z) - { - ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP); - if (simMode.simulationMode != SimulationMode.Build) - { - uREPL.Log.Error("Blocks can only be moved in Build Mode"); - return; - } - // get ghost block data - uint ghostCount; - uint ghostBlockIndex = 0; - Vector3 ghostLocation = Vector3.zero; - PositionEntityStruct[] ghostBlockPositions = entitiesDB.QueryEntities(GHOST_BLOCKS.GHOST_GROUPS_INCLUDING_INVISIBLE[0], out ghostCount); - for (uint i = 0; i < ghostCount; i++) - { - ref PositionEntityStruct pacman = ref ghostBlockPositions[i]; - if ((Vector3)pacman.position != Vector3.zero) - { - ghostLocation = pacman.position; - ghostBlockIndex = i; - break; - } - } - if (ghostLocation == Vector3.zero) - { - uREPL.Log.Output("Ghost block not found; nothing moved"); - return; - } - uint count; - PositionEntityStruct[] positions = entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out count); - for (uint i = 0; i < count; i++) - { - if (Math.Abs(positions[i].position.x - ghostLocation.x) < nearbyThreshold - && Math.Abs(positions[i].position.y - ghostLocation.y) < nearbyThreshold - && Math.Abs(positions[i].position.z - ghostLocation.z) < nearbyThreshold) - { - float3 newPos = TranslateConnectedBlocks(i, new float3(x, y, z)); - uREPL.Log.Output($"Moved block to ({newPos.x},{newPos.y},{newPos.z})"); - return; - } - } - uREPL.Log.Output("No block found near ghost block"); - } - - // Move the block denoted by blockID by translationVector (old_position += translationVector) - private float3 TranslateSingleBlock(uint blockID, float3 translationVector) - { - ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - // main (persistent) position - posStruct.position.x += translationVector.x; - posStruct.position.y += translationVector.y; - posStruct.position.z += translationVector.z; - // placement grid position - gridStruct.position.x += translationVector.x; - gridStruct.position.y += translationVector.y; - gridStruct.position.z += translationVector.z; - // rendered position - transStruct.position.x += translationVector.x; - transStruct.position.y += translationVector.y; - transStruct.position.z += translationVector.z; - // collision position - this.physWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation - { - Value = posStruct.position - }); - return posStruct.position; - } - - private float3 TranslateConnectedBlocks(uint blockID, float3 translationVector) - { - uREPL.Log.Output($"Last block id {CommonExclusiveGroups.CurrentBlockEntityID}, chosen {blockID}"); - //float3 newPosition = TranslateSingleBlock(blockID, translationVector); - //HashSet processedCubes = new HashSet(); - Stack cubeStack = new Stack(); - //cubeStack.Push(blockID); - //uint count; - //GridConnectionsEntityStruct[] blockConnections; - //MachineGraphConnectionEntityStruct[] connections; - - Gamecraft.DataStructures.FasterList cubesToMove = new Gamecraft.DataStructures.FasterList(); - ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubeStack, cubesToMove, (in GridConnectionsEntityStruct g) => { return false; }); - for(int i = 0; i < cubesToMove.Count; i++) { - TranslateSingleBlock(cubesToMove[i], translationVector); - entitiesDB.QueryEntity(cubesToMove[i], CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false; - } - /* - while (cubeStack.Count > 0) // find all inter-connected blocks - { - uint connectedBlockID = cubeStack.Pop(); - processedCubes.Add(connectedBlockID); - //ScalingEntityStruct scale = entitiesDB.QueryEntity(connectedBlockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - //uREPL.Log.Output($"Catching {connectedBlockID} with scale {scale.scale}"); - uint index; - blockConnections = entitiesDB.QueryEntitiesAndIndex(connectedBlockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out index); - connections = entitiesDB.QueryEntities(blockConnections[(int)index].connectionGroup, out count); - - foreach (MachineGraphConnectionEntityStruct conn in connections) - { - if (!processedCubes.Contains(conn.connectedBlock.entityID) - && blockConnections[(int)index].isConnectionGroupAssigned - && (conn.oppositeConnectionEgid.entityID != 0u - || conn.oppositeConnectionEgid.entityID != conn.connectedBlock.entityID)) - { - //uREPL.Log.Output($"Block {connectedBlockID} connects to {conn.connectedBlock.entityID} (opposite {conn.oppositeConnectionEgid.entityID})"); - cubeStack.Push(conn.connectedBlock.entityID); - } - } - } - foreach (uint id in processedCubes) - { - TranslateSingleBlock(id, translationVector); - }*/ - uREPL.Log.Output($"Found {cubesToMove.Count} connected blocks"); - return this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).position; - } + private void MoveLastBlockCommand(float x, float y, float z) + { + float3 vector = new float3(x, y, z); + Movement.MoveConnectedBlocks(BlockIdentifiers.LatestBlockID, vector); + } - public override void Dispose() + public void Dispose() { - CustomCommandUtility.Unregister("MoveBlocks"); - CustomCommandUtility.Unregister("MoveLastBlock"); - //CustomCommandUtility.Unregister("MoveNearBlock"); - //CustomCommandUtility.Unregister("SetNearThreshold"); + //CommandRegistrationHelper.Unregister("MoveBlocks"); + CommandRegistrationHelper.Unregister("MoveLastBlock"); } } } diff --git a/extracommands/RotateBlocksCommandEngine.cs b/extracommands/RotateBlocksCommandEngine.cs index f379b90..65982dd 100644 --- a/extracommands/RotateBlocksCommandEngine.cs +++ b/extracommands/RotateBlocksCommandEngine.cs @@ -14,137 +14,37 @@ using Unity.Transforms; using Unity.Mathematics; using UnityEngine; +using GamecraftModdingAPI.Commands; +using GamecraftModdingAPI.Blocks; + namespace ExtraCommands.Building { //[CustomCommand("RotateBlocks", "Rotate all blocks (including ground) from their original position")] [CustomCommand("RotateLastBlock", "Rotate last block from original position")] - class RotateBlocksCommandEngine : CustomCommandEngine + class RotateBlocksCommandEngine : ICustomCommandEngine { - public RotateBlocksCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) - { - } + public string Description => "Rotate last block from original position"; - public override void Ready() - { - //CustomCommandUtility.Register("RotateBlocks", RotateBlocksCommand, "Rotate all blocks (including ground) from their original position"); - CustomCommandUtility.Register("RotateLastBlock", RotateLastBlockCommand, "Rotate last block from original position"); - } + public string Name => "RotateLastBlock"; - // Move every block by vector (x,y,z) - private void RotateBlocksCommand(float x, float y, float z) + public IEntitiesDB entitiesDB { set; private get; } + + public void Ready() { - Vector3 eulerAngles = new Vector3(x, y, z); - ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP); - if (simMode.simulationMode != SimulationMode.Build) - { - uREPL.Log.Error("Blocks can only be moved in Build Mode"); - return; - } - uint count = entitiesDB.Count(CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - for (uint i = 0; i < count; i++) - { - RotateSingleBlock(i, eulerAngles); - } - uREPL.Log.Output($"Moved {count} blocks"); + CommandRegistrationHelper.Register(Name, RotateLastBlockCommand, Description); } // Move block with highest index by vector (x,y,z) private void RotateLastBlockCommand(float x, float y, float z) { - Vector3 eulerAngles = new Vector3(x, y, z); - ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP); - if (simMode.simulationMode != SimulationMode.Build) - { - uREPL.Log.Error("Blocks can only be moved in Build Mode"); - return; - } - uint count = entitiesDB.Count(CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - if (count == 0) - { - uREPL.Log.Error("No block found"); - return; - } - Vector3 newRotation = RotateSingleBlock(count - 1, eulerAngles); - uREPL.Log.Output($"Rotated block to ({newRotation.x},{newRotation.y},{newRotation.z})"); - } - - private float3 RotateSingleBlock(uint blockID, Vector3 rotationVector) - { - ref RotationEntityStruct rotStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); - // main (persistent) position - Quaternion newRotation = (Quaternion)rotStruct.rotation; - newRotation.eulerAngles += rotationVector; - rotStruct.rotation = (quaternion)newRotation; - // placement grid rotation - Quaternion newGridRotation = (Quaternion)gridStruct.rotation; - newGridRotation.eulerAngles += rotationVector; - gridStruct.rotation = (quaternion)newGridRotation; - // rendered position - Quaternion newTransRotation = (Quaternion)rotStruct.rotation; - newTransRotation.eulerAngles += rotationVector; - transStruct.rotation = newTransRotation; - // collision position - this.physWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Rotation - { - Value = rotStruct.rotation - }); - return ((Quaternion)rotStruct.rotation).eulerAngles; - } - - // unused; for future reference - private void ToggleMode() - { - ref SimulationModeStateEntityStruct ptr = ref this.entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP); - ref SimulationFrameEntityStruct ptr2 = ref this.entitiesDB.QueryUniqueEntity(SimulationFrame.SimulationFrameGroup); - switch (ptr.simulationMode) - { - case SimulationMode.Build: - ptr.nextSimulationMode = SimulationMode.SwitchToSim; - return; - case SimulationMode.SwitchToSim: - case SimulationMode.SwitchToBuild: - return; - case SimulationMode.Simulation: - ptr.nextSimulationMode = SimulationMode.SwitchToBuild; - ptr.rigidBodiesCreated = false; - return; - default: - throw new ArgumentOutOfRangeException(); - } - } - - // unused; for future reference - private IEnumerator TriggerSwitchToSimTask() - { - this.ToggleMode(); - yield break; - } - - // unused; for future reference - private IEnumerator WaitThenTriggerSwitchToBuildTask() - { - while (true) - { - SimulationModeStateEntityStruct modeStruct = this.entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP); - if (modeStruct.simulationMode == SimulationMode.Simulation) - { - this.ToggleMode(); - break; - } else - { - yield return Yield.It; - } - } - yield break; + float3 eulerAngles = new float3(x, y, z); + GamecraftModdingAPI.Blocks.Rotation.RotateBlock(BlockIdentifiers.LatestBlockID, eulerAngles); } - public override void Dispose() + public void Dispose() { //CustomCommandUtility.Unregister("RotateBlocks"); - CustomCommandUtility.Unregister("RotateLastBlock"); + CommandRegistrationHelper.Unregister("RotateLastBlock"); } } } diff --git a/extracommands/RotatePlayerCommandEngine.cs b/extracommands/RotatePlayerCommandEngine.cs index f386fa8..3a0da6e 100644 --- a/extracommands/RotatePlayerCommandEngine.cs +++ b/extracommands/RotatePlayerCommandEngine.cs @@ -14,20 +14,23 @@ using Unity.Mathematics; using RobocraftX.Character.Camera; using RobocraftX.Character.Factories; +using GamecraftModdingAPI.Commands; + namespace ExtraCommands.Basics { - [CustomCommand("RotateTo")] - class RotatePlayerCommandEngine : CustomCommandEngine + [CustomCommand("Rotation")] + class RotatePlayerCommandEngine : ICustomCommandEngine { + public string Description => "Rotation"; - public RotatePlayerCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) - { - } + public string Name => "Rotation commands"; + + public IEntitiesDB entitiesDB { set; private get; } - public override void Ready() + public void Ready() { - CustomCommandUtility.Register("RotateAbsolute", RotateAbsoluteCommand, "Rotate the player camera to the entered rotation"); - CustomCommandUtility.Register("RotateRelative", RotateRelativeCommand, "Rotate the player camera by the entered rotation"); + CommandRegistrationHelper.Register("RotateAbsolute", RotateAbsoluteCommand, "Rotate the player camera to the entered rotation"); + CommandRegistrationHelper.Register("RotateRelative", RotateRelativeCommand, "Rotate the player camera by the entered rotation"); } @@ -79,10 +82,10 @@ namespace ExtraCommands.Basics } } - public override void Dispose() + public void Dispose() { - CustomCommandUtility.Unregister("RotateAbsolute"); - CustomCommandUtility.Unregister("RotateRelative"); + CommandRegistrationHelper.Unregister("RotateAbsolute"); + CommandRegistrationHelper.Unregister("RotateRelative"); } } } diff --git a/extracommands/SetFOVCommandEngine.cs b/extracommands/SetFOVCommandEngine.cs index b4f7b45..dce351e 100644 --- a/extracommands/SetFOVCommandEngine.cs +++ b/extracommands/SetFOVCommandEngine.cs @@ -10,18 +10,22 @@ using uREPL; using Svelto.Context; using RobocraftX; +using GamecraftModdingAPI.Commands; + namespace ExtraCommands.Basics { [CustomCommand("SetFieldOfView")] - class SetFOVCommandEngine : CustomCommandEngine + class SetFOVCommandEngine : ICustomCommandEngine { - public SetFOVCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) - { - } + public string Description => "Set the camera's field of view"; + + public string Name => "SetFieldOfView"; + + public IEntitiesDB entitiesDB { set; private get; } - public override void Ready() + public void Ready() { - CustomCommandUtility.Register("SetFieldOfView", SetFieldOfViewCommand, "Set the camera's field of view"); + CommandRegistrationHelper.Register(Name, SetFieldOfViewCommand, Description); } private void SetFieldOfViewCommand(float newFoV) @@ -29,9 +33,9 @@ namespace ExtraCommands.Basics Camera.main.fieldOfView = newFoV; } - public override void Dispose() + public void Dispose() { - CustomCommandUtility.Unregister("SetFieldOfView"); + CommandRegistrationHelper.Unregister(Name); } } } diff --git a/extracommands/SetTargetFramerateCommandEngine.cs b/extracommands/SetTargetFramerateCommandEngine.cs index 378d404..ef4930f 100644 --- a/extracommands/SetTargetFramerateCommandEngine.cs +++ b/extracommands/SetTargetFramerateCommandEngine.cs @@ -10,18 +10,22 @@ using uREPL; using Svelto.Context; using RobocraftX; +using GamecraftModdingAPI.Commands; + namespace ExtraCommands.Basics { [CustomCommand("SetTargetFPS")] - class SetTargetFramerateCommandEngine : CustomCommandEngine + class SetTargetFramerateCommandEngine : ICustomCommandEngine { - public SetTargetFramerateCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) - { - } + public string Description => "Set Gamecraft's target FPS'"; + + public string Name => "SetTargetFPS"; + + public IEntitiesDB entitiesDB { set; private get; } - public override void Ready() + public void Ready() { - CustomCommandUtility.Register("SetTargetFPS", SetFramerateCommand, "Set Gamecraft's target FPS"); + CommandRegistrationHelper.Register(Name, SetFramerateCommand, Description); } private void SetFramerateCommand(int newFoV) @@ -29,9 +33,9 @@ namespace ExtraCommands.Basics Application.targetFrameRate = newFoV; } - public override void Dispose() + public void Dispose() { - CustomCommandUtility.Unregister("SetTargetFPS"); + CommandRegistrationHelper.Unregister(Name); } } } diff --git a/extracommands/TeleportWaypointCommandEngine.cs b/extracommands/TeleportWaypointCommandEngine.cs index 950326b..d1a96b8 100644 --- a/extracommands/TeleportWaypointCommandEngine.cs +++ b/extracommands/TeleportWaypointCommandEngine.cs @@ -11,20 +11,25 @@ using Svelto.Context; using RobocraftX; using RobocraftX.Physics; +using GamecraftModdingAPI.Commands; + namespace ExtraCommands.Waypoints { - [CustomCommand] - class TeleportWaypointCommandEngine : CustomCommandEngine + [CustomCommand("Waypoints")] + class TeleportWaypointCommandEngine : ICustomCommandEngine { private Dictionary _waypoints = new Dictionary(); - public TeleportWaypointCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) - { - } - public override void Ready() + public string Description => ""; + + public string Name => "Waypoints"; + + public IEntitiesDB entitiesDB { set; private get; } + + public void Ready() { - CustomCommandUtility.Register("CreateWaypoint", CreateWaypointCommand, "Create a waypoint in your current location"); - CustomCommandUtility.Register("TeleportPlayerWaypoint", TeleportToWaypointCommand, "Teleport to a waypoint"); + CommandRegistrationHelper.Register("CreateWaypoint", CreateWaypointCommand, "Create a waypoint in your current location"); + CommandRegistrationHelper.Register("TeleportPlayerWaypoint", TeleportToWaypointCommand, "Teleport to a waypoint"); } private void CreateWaypointCommand(object name) @@ -45,10 +50,10 @@ namespace ExtraCommands.Waypoints uREPL.RuntimeCommands.Call("TeleportPlayerAbsolute", loc[0], loc[1], loc[2]); } - public override void Dispose() + public void Dispose() { - CustomCommandUtility.Unregister("CreateWaypoint"); - CustomCommandUtility.Unregister("TeleportPlayerWaypoint"); + CommandRegistrationHelper.Unregister("CreateWaypoint"); + CommandRegistrationHelper.Unregister("TeleportPlayerWaypoint"); } } } diff --git a/extracommands/ToggleJumpCommandEngine.cs b/extracommands/ToggleJumpCommandEngine.cs deleted file mode 100644 index 6cc4c6d..0000000 --- a/extracommands/ToggleJumpCommandEngine.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Reflection; -using Harmony; -using RobocraftX.GUI.CommandLine; -using RobocraftX.Multiplayer; -using RobocraftX.StateSync; -using RobocraftX.Character; -using RobocraftX.Character.Movement; -using RobocraftX.Common.Input; -using Svelto.ECS; -using Unity.Entities; -using UnityEngine; -using uREPL; -using Svelto.Context; -using RobocraftX; - -namespace ExtraCommands.Basics -{ - //[HarmonyPatch] - //[CustomCommand("ToggleJumpEnabled")] - class ToggleJumpCommandEngine : CustomCommandEngine - { - private static bool isJumpEnabled = false; - public ToggleJumpCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) - { - } - - public override void Ready() - { - CustomCommandUtility.Register("ToggleJumpEnabled", ToggleJumpCommand, "Enable or disable the character's ability to jump"); - } - - private void ToggleJumpCommand(bool isEnabled) - { - isJumpEnabled = isEnabled; - } - - public override void Dispose() - { - CustomCommandUtility.Unregister("ToggleJumpEnabled"); - } - - public static void Postfix (ref CharacterInputEntityStruct input, InputStruct entity) - { - if (entity.CheckInputAction(ActionInput.Up) && !isJumpEnabled) - { - input.action.y -= 1f; - } - } - - public static MethodBase TargetMethod(HarmonyInstance instance) - { - Type targetType = Harmony.AccessTools.TypeByName("RobocraftX.Character.Input.CharacterInputEngine"); - return Harmony.AccessTools.Method(targetType, "SaveInput", new Type[] { typeof(CharacterInputEntityStruct), typeof(InputStruct) }); - } - } -} diff --git a/extracommands/WaitCommandEngine.cs b/extracommands/WaitCommandEngine.cs index c5fd0f1..b61dc41 100644 --- a/extracommands/WaitCommandEngine.cs +++ b/extracommands/WaitCommandEngine.cs @@ -10,18 +10,22 @@ using uREPL; using Svelto.Context; using RobocraftX; +using GamecraftModdingAPI.Commands; + namespace ExtraCommands.Basics { [CustomCommand("Wait")] - class WaitCommandEngine : CustomCommandEngine + class WaitCommandEngine : ICustomCommandEngine { - public WaitCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) - { - } + public string Description => "Delay execution (freeze the game) for a length of time (ms)"; + + public string Name => "Wait"; + + public IEntitiesDB entitiesDB { set; private get; } - public override void Ready() + public void Ready() { - CustomCommandUtility.Register("Wait", WaitCommand, "Delay execution (freeze the game) for a length of time (ms)"); + CommandRegistrationHelper.Register("Wait", WaitCommand, "Delay execution (freeze the game) for a length of time (ms)"); } private void WaitCommand(int ms) @@ -29,9 +33,9 @@ namespace ExtraCommands.Basics System.Threading.Thread.Sleep(ms); } - public override void Dispose() + public void Dispose() { - CustomCommandUtility.Unregister("Wait"); + CommandRegistrationHelper.Unregister("Wait"); } } }