diff --git a/BlockMod/BlockMod.cs b/BlockMod/BlockMod.cs index 11c5d3b..f08ed93 100644 --- a/BlockMod/BlockMod.cs +++ b/BlockMod/BlockMod.cs @@ -16,25 +16,26 @@ using RobocraftX.Common.Players; using Svelto.ECS; using Svelto.ECS.Internal; using Unity.Mathematics; +using uREPL; using Main = GamecraftModdingAPI.Main; namespace BlockMod { public class BlockMod : IPlugin { + private Block[] blocks = new Block[0]; + private Block refBlock; public void OnApplicationStart() { Main.Init(); GameClient.SetDebugInfo("BlockModInfo", GetBlockInfo); - Block[] blocks = new Block[0]; - Block refBlock = null; - CommandBuilder.Builder("scaleBlocks", - "Scales the blocks you're looking at, relative to current size (current scale * new scale)." + - " The block you're looking at stays where it is, everything else is moved next to it." + - " The command remembers the cluster of blocks, use forgetBlocks to forget it.") - .Action((scaleX, scaleY, scaleZ) => + RegisterBlockCommand("scaleBlocks", + "Scales the blocks you're looking at, relative to current size (current scale * new scale)." + + " The block you're looking at stays where it is, everything else is moved next to it.", + (scaleX, scaleY, scaleZ, blocks, refBlock) => { - if(CheckNoBlocks(blocks)) return; + if (!GameState.IsBuildMode()) return; //Scaling & positioning is weird in simulation + if (CheckNoBlocks(blocks)) return; // ReSharper disable once PossibleNullReferenceException float3 reference = refBlock.Position; float3 scale = new float3(scaleX, scaleY, scaleZ); @@ -45,38 +46,36 @@ namespace BlockMod } Logging.CommandLog("Blocks scaled."); - }).Build(); - CommandBuilder.Builder("scaleIndividually", "Scales the blocks you're looking at, but doesn't move them." + - "The scale is relative, 1 means no change. Look at a block previously scaled to scale all of the blocks that were connected to it.") - .Action((scaleX, scaleY, scaleZ) => + }); + RegisterBlockCommand("scaleIndividually", "Scales the blocks you're looking at, but doesn't move them." + + "The scale is relative, 1 means no change. Look at a block previously scaled to scale all of the blocks that were connected to it.", + (scaleX, scaleY, scaleZ, blocks, refBlock) => { - if(CheckNoBlocks(blocks)) return; + if (!GameState.IsBuildMode()) return; //Scaling & positioning is weird in simulation float3 scale = new float3(scaleX, scaleY, scaleZ); foreach (var block in blocks) block.Scale *= scale; - }).Build(); - CommandBuilder.Builder("moveBlocks", "Moves the blocks around.") - .Action((x, y, z) => - { - if (CheckNoBlocks(blocks)) return; - if (GameState.IsBuildMode()) - foreach (var block in blocks) - block.Position += new float3(x, y, z); - else if (GameState.IsSimulationMode()) - foreach (var body in GetSimBodies(blocks)) - body.Position += new float3(x, y, z); - }).Build(); - CommandBuilder.Builder("colorBlocks", "Colors the blocks you're looking at") - .Action((color, darkness) => + }); + RegisterBlockCommand("moveBlocks", "Moves the blocks around.", (x, y, z, blocks, refBlock) => + { + if (GameState.IsBuildMode()) + foreach (var block in blocks) + block.Position += new float3(x, y, z); + else if (GameState.IsSimulationMode()) + foreach (var body in GetSimBodies(blocks)) + body.Position += new float3(x, y, z); + }); + RegisterBlockCommand("colorBlocks", "Colors the blocks you're looking at", + (color, darkness, blocks, refBlock) => { - if(CheckNoBlocks(blocks)) return; if (!Enum.TryParse(color, true, out BlockColors clr)) { Logging.CommandLogWarning("Color " + color + " not found"); } + foreach (var block in blocks) block.Color = new BlockColor {Color = clr, Darkness = darkness}; - }).Build(); + }); CommandBuilder.Builder("selectBlocksLookedAt", "Selects blocks (1 or more) to change. Only works in build mode, however the blocks can be changed afterwards." + " Paramter: whether one (true) or all connected (false) blocks should be selected.") @@ -90,24 +89,20 @@ namespace BlockMod .Action(id => blocks = (refBlock = ObjectIdentifier.GetByID(id).FirstOrDefault())?.GetConnectedCubes() ?? new Block[0]).Build(); - ConsoleCommands.RegisterWithChannel("selectBlocksFromChannel", id => - { - blocks = ObjectIdentifier.GetBySimID(id).SelectMany(block => block.GetConnectedCubes()).ToArray(); - }, - BinaryChannelUtilities.ChannelType.Object); - CommandBuilder.Builder("pushBlocks", "Adds velocity to the selected blocks. Only works in simulation.") - .Action((x, y, z) => + RegisterBlockCommand("pushBlocks", "Adds velocity to the selected blocks. Only works in simulation.", + (x, y, z, blocks, refBlock) => { foreach (var block in GetSimBodies(blocks)) block.Velocity += new float3(x, y, z); - }).Build(); - CommandBuilder.Builder("pushRotateBlocks", "Adds angular velocity to the selected blocks. Only works in simulation.") - .Action((x, y, z) => + }); + RegisterBlockCommand("pushRotateBlocks", + "Adds angular velocity to the selected blocks. Only works in simulation.", + (x, y, z, blocks, refBlock) => { foreach (var block in GetSimBodies(blocks)) block.AngularVelocity += new float3(x, y, z); - }).Build(); + }); CommandBuilder.Builder("pushPlayer", "Adds velocity to the player.") .Action((x, y, z) => { @@ -118,66 +113,8 @@ namespace BlockMod { new Player(PlayerType.Local).AngularVelocity += new float3(x, y, z); }).Build(); - GameEngineManager.AddGameEngine(new Test()); - } - - private class Test : IApiEngine - { - public void Ready() - { - try - { - CommandBuilder.Builder("weaponTest").Action(() => - { - var type = AccessTools.TypeByName("RobocraftX.Character.Weapons.CharacterEquippedWeaponStruct"); - var dict = QueryEntitiesAndIndexInternal( - new EGID(new Player(PlayerType.Local).Id, PlayersExclusiveGroups.LocalPlayers), - out uint i, type); - var dtype = typeof(ITypeSafeDictionary<>).MakeGenericType(type); - var obj = Convert.ChangeType(dict, dtype); - Array arr = (Array) AccessTools.PropertyGetter(dtype, "unsafeValues") - .Invoke(obj, new object[0]); - foreach (var element in arr) - element.GetType().GetField("equippedWeaponType") - .SetValue(element, WeaponType.PISTOL); - }).Build(); - } - catch - { - // ignored - } - } - - private ITypeSafeDictionary QueryEntitiesAndIndexInternal(EGID entityGID, out uint index, Type type) - { - index = 0U; - ITypeSafeDictionary typeSafeDictionary; - if (!QueryEntityDictionary(entityGID.groupID, out typeSafeDictionary, type)) - return null; - return !typeSafeDictionary.TryFindIndex(entityGID.entityID, out index) ? null : typeSafeDictionary; - } - - private bool QueryEntityDictionary( - uint group, - out ITypeSafeDictionary typeSafeDictionary, - Type type) - { - object[] ps = {group, type, null}; - bool ret = (bool) AccessTools.Method("Svelto.ECS.EntitiesDB:UnsafeQueryEntityDictionary") - .Invoke(entitiesDB, ps); - typeSafeDictionary = (ITypeSafeDictionary) ps[2]; - return ret; - } - - public EntitiesDB entitiesDB { get; set; } - public void Dispose() - { - } - - public string Name { get; } = "TestEngine"; - public bool isRemovable { get; } = true; } - + private string GetBlockInfo() { if (GameState.IsBuildMode()) @@ -221,9 +158,57 @@ namespace BlockMod return false; } - public IEnumerable GetSimBodies(Block[] blocks) + private IEnumerable GetSimBodies(Block[] blocks) => blocks.Select(block => block.GetSimBody()).Distinct(); + private Block[] SelectBlocks(byte id) + { + var blocks = ObjectIdentifier.GetBySimID(id).SelectMany(block => block.GetConnectedCubes()).ToArray(); + return blocks; + } + + //private void RegisterBlockCommand(string name, string desc, T action) where T : Delegate + private void RegisterBlockCommand(string name, string desc, Action action) + { + /*switch (action) + { + case Action act + break; + case Action act: + break; + default: + Logging.LogWarning("Unexpected parameters for command: " + name); + break; + }*/ + RuntimeCommands.Register(name, (a1, a2) => + { + if (CheckNoBlocks(blocks)) return; + action(a1, a2, blocks, refBlock); + }, desc); + ConsoleCommands.RegisterWithChannel(name, (a1, a2, ch) => + { + var blks = SelectBlocks(ch); + if (CheckNoBlocks(blks)) return; + action(a1, a2, blks, blks[0]); + }, BinaryChannelUtilities.ChannelType.Object, desc); + } + + private void RegisterBlockCommand(string name, string desc, Action action) + { + RuntimeCommands.Register(name, (x, y, z) => + { + if (CheckNoBlocks(blocks)) return; + action(x, y, z, blocks, refBlock); + }, + desc); + ConsoleCommands.RegisterWithChannel(name, (x, y, z, ch) => + { + var blks = SelectBlocks(ch); + if (CheckNoBlocks(blks)) return; + action(x, y, z, blks, blks[0]); + }, BinaryChannelUtilities.ChannelType.Object, desc); + } + public void OnApplicationQuit() { }