diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 59914fd..0fecf40 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -244,6 +244,7 @@ namespace GamecraftModdingAPI MovementEngine.MoveBlock(Id, InitData, value); if (blockGroup != null) blockGroup.PosAndRotCalculated = false; + BlockEngine.UpdateDisplayedBlock(Id); } } @@ -258,6 +259,7 @@ namespace GamecraftModdingAPI RotationEngine.RotateBlock(Id, InitData, value); if (blockGroup != null) blockGroup.PosAndRotCalculated = false; + BlockEngine.UpdateDisplayedBlock(Id); } } @@ -273,6 +275,7 @@ namespace GamecraftModdingAPI BlockEngine.SetBlockInfo(this, (ref ScalingEntityStruct st, float3 val) => st.scale = val, value); if (!Exists) return; //UpdateCollision needs the block to exist ScalingEngine.UpdateCollision(Id); + BlockEngine.UpdateDisplayedBlock(Id); } } @@ -364,8 +367,10 @@ namespace GamecraftModdingAPI /// /// Returns the block group this block is a part of. Block groups can be placed using blueprints. /// Returns null if not part of a group.
- /// Setting the group after the block has been initialized will not update everything properly. - /// You should only set this property on blocks newly placed by your code. + /// Setting the group after the block has been initialized will not update everything properly, + /// so you can only set this property on blocks newly placed by your code.
+ /// To set it for existing blocks, you can use the Copy() method and set the property on the resulting block + /// (and remove this block). ///
public BlockGroup BlockGroup { @@ -378,6 +383,15 @@ namespace GamecraftModdingAPI } set { + if (Exists) + { + /*var copy = Copy(); + copy.BlockGroup = value; //It won't run this on the new instance as it won't 'exist' yet + Remove();*/ + Logging.LogWarning("Attempted to set group of existing block. This is not supported." + + " Copy the block and set the group of the resulting block."); + return; + } blockGroup?.RemoveInternal(this); BlockEngine.SetBlockInfo(this, (ref BlockGroupEntityComponent bgec, BlockGroup val) => bgec.currentBlockGroup = val?.Id ?? -1, @@ -418,7 +432,7 @@ namespace GamecraftModdingAPI } /// - /// Creates a copy of the block in the game with the same basic properties and tweakable stats. + /// Creates a copy of the block in the game with the same properties, stats and wires. /// /// public T Copy() where T : Block diff --git a/GamecraftModdingAPI/BlockGroup.cs b/GamecraftModdingAPI/BlockGroup.cs index a82e776..4a0d994 100644 --- a/GamecraftModdingAPI/BlockGroup.cs +++ b/GamecraftModdingAPI/BlockGroup.cs @@ -12,9 +12,9 @@ using GamecraftModdingAPI.Utility; namespace GamecraftModdingAPI { /// - /// A group of blocks that can be selected together. The placed version of blueprints. + /// A group of blocks that can be selected together. The placed version of blueprints. Dispose after usage. /// - public class BlockGroup : ICollection + public class BlockGroup : ICollection, IDisposable { internal static BlueprintEngine _engine = new BlueprintEngine(); public int Id { get; } @@ -30,8 +30,30 @@ namespace GamecraftModdingAPI Id = id; sourceBlock = block; blocks = new List(GetBlocks()); + Block.Removed += OnBlockRemoved; } - + + private void OnBlockRemoved(object sender, BlockPlacedRemovedEventArgs e) + { + //blocks.RemoveAll(block => block.Id == e.ID); - Allocation heavy + int index = -1; + for (int i = 0; i < blocks.Count; i++) + { + if (blocks[i].Id == e.ID) + { + index = i; + break; + } + } + + if (index != -1) blocks.RemoveAt(index); + } + + public void Dispose() + { + Block.Removed -= OnBlockRemoved; + } + /// /// The position of the block group (center). Recalculated if blocks have been added/removed since the last query. /// diff --git a/GamecraftModdingAPI/Blocks/BlockCloneEngine.cs b/GamecraftModdingAPI/Blocks/BlockCloneEngine.cs index d4d16f1..0acf44d 100644 --- a/GamecraftModdingAPI/Blocks/BlockCloneEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockCloneEngine.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.Reflection; +using Gamecraft.Wires; using GamecraftModdingAPI.Engines; using HarmonyLib; using RobocraftX.Blocks; @@ -15,9 +17,15 @@ namespace GamecraftModdingAPI.Blocks { private static Type copyEngineType = AccessTools.TypeByName("Gamecraft.GUI.Tweaks.Engines.CopyTweaksOnPickEngine"); + private static Type copyWireEngineType = + AccessTools.TypeByName("Gamecraft.Wires.WireConnectionCopyOnPickEngine"); + private static Type createWireEngineType = + AccessTools.TypeByName("RobocraftX.GUI.Wires.WireConnectionCreateOnPlaceEngine"); private MethodBase copyFromBlock = AccessTools.Method(copyEngineType, "CopyTweaksFromBlock"); private MethodBase copyToBlock = AccessTools.Method(copyEngineType, "ApplyTweaksToPlacedBlock"); + private MethodBase copyWireFromBlock = AccessTools.Method(copyWireEngineType, "CopyWireInputsAndOutputs"); + private MethodBase copyWireToBlock = AccessTools.Method(createWireEngineType, "PlaceWiresOnPlaceNewCube"); public void Ready() { @@ -45,13 +53,23 @@ namespace GamecraftModdingAPI.Blocks if (entitiesDB.Exists(pickedBlock.pickedBlockEntityID) && entitiesDB.Exists(pickedBlock.placedBlockEntityID)) { - copyFromBlock.Invoke(Patch.instance, new object[] {pickedBlock.ID, pickedBlock}); - copyToBlock.Invoke(Patch.instance, new object[] {pickedBlock.ID, pickedBlock}); + copyFromBlock.Invoke(Patch.copyEngine, new object[] {pickedBlock.ID, pickedBlock}); + + uint playerID = Player.LocalPlayer.Id; + var parameters = new object[] {playerID, pickedBlock}; + copyWireFromBlock.Invoke(Patch.copyWireEngine, parameters); + pickedBlock = (PickedBlockExtraDataStruct) parameters[1]; //ref arg + + copyToBlock.Invoke(Patch.copyEngine, new object[] {pickedBlock.ID, pickedBlock}); + + ExclusiveGroupStruct group = WiresExclusiveGroups.WIRES_COPY_GROUP + playerID; + copyWireToBlock.Invoke(Patch.createWireEngine, new object[] {group, pickedBlock.ID}); + pickedBlock.placedBlockTweaksMustCopy = false; pickedBlock.placedBlockTweaksCopied = false; } - pickedBlock = oldStruct; //Make sure to not interfere with the game + pickedBlock = oldStruct; //Make sure to not interfere with the game - Although that might not be the case with the wire copying } } } @@ -59,16 +77,28 @@ namespace GamecraftModdingAPI.Blocks [HarmonyPatch] private static class Patch { - public static object instance; + public static object copyEngine; + public static object copyWireEngine; + public static object createWireEngine; public static void Postfix(object __instance) { - instance = __instance; + if (__instance.GetType() == copyEngineType) + copyEngine = __instance; + else if (__instance.GetType() == copyWireEngineType) + copyWireEngine = __instance; + else if (__instance.GetType() == createWireEngineType) + createWireEngine = __instance; } - public static MethodBase TargetMethod() + public static IEnumerable TargetMethods() { - return AccessTools.GetDeclaredConstructors(copyEngineType)[0]; + return new[] + { + AccessTools.GetDeclaredConstructors(copyEngineType)[0], + AccessTools.GetDeclaredConstructors(copyWireEngineType)[0], + AccessTools.GetDeclaredConstructors(createWireEngineType)[0] + }; } } diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index 351d686..2da04a3 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -8,6 +8,8 @@ using Gamecraft.Wires; using RobocraftX.Blocks; using RobocraftX.Common; using RobocraftX.Physics; +using RobocraftX.Rendering; +using Svelto.ECS.EntityStructs; using Svelto.DataStructures; using Svelto.ECS; @@ -149,6 +151,15 @@ namespace GamecraftModdingAPI.Blocks } } + public void UpdateDisplayedBlock(EGID id) + { + if (!BlockExists(id)) return; + var pos = entitiesDB.QueryEntity(id); + var rot = entitiesDB.QueryEntity(id); + var scale = entitiesDB.QueryEntity(id); + entitiesDB.QueryEntity(id).matrix = float4x4.TRS(pos.position, rot.rotation, scale.scale); + } + public bool BlockExists(EGID blockID) { return entitiesDB.Exists(blockID); diff --git a/GamecraftModdingAPI/Blocks/PlacementEngine.cs b/GamecraftModdingAPI/Blocks/PlacementEngine.cs index 5357e7f..fab9c62 100644 --- a/GamecraftModdingAPI/Blocks/PlacementEngine.cs +++ b/GamecraftModdingAPI/Blocks/PlacementEngine.cs @@ -101,6 +101,13 @@ namespace GamecraftModdingAPI.Blocks loadedFromDisk = false, placedBy = playerId }); + + /*structInitializer.Init(new CollisionFilterOverride + { + belongsTo = 32U, + collidesWith = 239532U + });*/ + PrimaryRotationUtility.InitialisePrimaryDirection(rotation.rotation, ref structInitializer); EGID playerEGID = new EGID(playerId, CharacterExclusiveGroups.OnFootGroup); ref PickedBlockExtraDataStruct pickedBlock = ref entitiesDB.QueryEntity(playerEGID);