From 4f8feaa24ba942fe5d550621ad63553959994d89 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 10 Nov 2020 16:37:20 +0100 Subject: [PATCH] Add new blocks and some blueprint/block group support --- GamecraftModdingAPI/Block.cs | 13 +++- GamecraftModdingAPI/BlockGroup.cs | 46 +++++++++++ GamecraftModdingAPI/Blocks/BlockIDs.cs | 2 + GamecraftModdingAPI/Blocks/BlueprintEngine.cs | 77 +++++++++++++++++++ GamecraftModdingAPI/Blueprint.cs | 20 +++++ GamecraftModdingAPI/Main.cs | 1 + 6 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 GamecraftModdingAPI/BlockGroup.cs create mode 100644 GamecraftModdingAPI/Blocks/BlueprintEngine.cs create mode 100644 GamecraftModdingAPI/Blueprint.cs diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 81d6439..862db3f 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -3,12 +3,12 @@ using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; +using Gamecraft.Blocks.BlockGroups; using Svelto.ECS; using Svelto.ECS.EntityStructs; using RobocraftX.Common; using RobocraftX.Blocks; using Unity.Mathematics; -using Unity.Entities; using Gamecraft.Blocks.GUI; using GamecraftModdingAPI.Blocks; @@ -354,6 +354,17 @@ 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. + /// + public BlockGroup BlockGroup + { + get => BlockEngine.GetBlockInfo(this, + (BlockGroupEntityComponent bgec) => + bgec.currentBlockGroup == -1 ? null : new BlockGroup(bgec.currentBlockGroup, this)); + } + /// /// Whether the block exists. The other properties will return a default value if the block doesn't exist. /// If the block was just placed, then this will also return false but the properties will work correctly. diff --git a/GamecraftModdingAPI/BlockGroup.cs b/GamecraftModdingAPI/BlockGroup.cs new file mode 100644 index 0000000..2cd0f42 --- /dev/null +++ b/GamecraftModdingAPI/BlockGroup.cs @@ -0,0 +1,46 @@ +using Gamecraft.Blocks.BlockGroups; +using GamecraftModdingAPI.Blocks; +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI +{ + /// + /// A group of blocks that can be selected together. The placed version of blueprints. + /// + public class BlockGroup + { + internal static BlueprintEngine _engine = new BlueprintEngine(); + public int Id { get; } + private Block _sourceBlock; + + internal BlockGroup(int id, Block block) + { + if (id == BlockGroupUtility.GROUP_UNASSIGNED) + throw new BlockException("Cannot create a block group for blocks without a group!"); + Id = id; + _sourceBlock = block; + } + + /// + /// Collects each block that is a part of this group. + /// + /// An array of blocks + public Block[] GetBlocks() + { + return _engine.GetBlocksFromGroup(_sourceBlock.Id); + } + + /// + /// Removes all of the blocks in this group from the world. + /// + public void Remove() + { + _engine.RemoveBlockGroup(Id); + } + + public static void Init() + { + GameEngineManager.AddGameEngine(_engine); + } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/BlockIDs.cs b/GamecraftModdingAPI/Blocks/BlockIDs.cs index d867ce0..1d55b29 100644 --- a/GamecraftModdingAPI/Blocks/BlockIDs.cs +++ b/GamecraftModdingAPI/Blocks/BlockIDs.cs @@ -327,6 +327,8 @@ namespace GamecraftModdingAPI.Blocks SpotLightInvisible, UnlitSlope, UnlitGlowSlope, + Fog, + Sky, MagmaRockCube = 777, MagmaRockCubeSliced, MagmaRockSlope, diff --git a/GamecraftModdingAPI/Blocks/BlueprintEngine.cs b/GamecraftModdingAPI/Blocks/BlueprintEngine.cs new file mode 100644 index 0000000..7f0a616 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/BlueprintEngine.cs @@ -0,0 +1,77 @@ +using System.Reflection; +using Gamecraft.Blocks.BlockGroups; +using Gamecraft.GUI.Blueprints; +using GamecraftModdingAPI.Engines; +using HarmonyLib; +using RobocraftX.Blocks; +using Svelto.DataStructures; +using Svelto.ECS; +using Svelto.ECS.DataStructures; +using Unity.Collections; + +namespace GamecraftModdingAPI.Blocks +{ + public class BlueprintEngine : IApiEngine + { + private readonly MethodInfo getBlocksFromGroup = + AccessTools.Method("RobocraftX.CR.MachineEditing.PlaceBlockUtility:GetBlocksSharingBlockgroup"); + private readonly NativeDynamicArray selectedBlocksInGroup = new NativeDynamicArray(); + private readonly NativeHashSet removedConnections = new NativeHashSet(); + + private static NativeEntityRemove nativeRemove; + private static MachineGraphConnectionEntityFactory connectionFactory; + + public void Ready() + { + } + + public EntitiesDB entitiesDB { get; set; } + public void Dispose() + { + } + + public Block[] GetBlocksFromGroup(EGID blockID) + { + var list = new FasterList(); + object blockPos = null, blockRot = null; + getBlocksFromGroup.Invoke(null, new[] {blockID, selectedBlocksInGroup, entitiesDB, blockPos, blockRot}); + for (uint i = 0; i < selectedBlocksInGroup.Count(); i++) + list.Add(new Block(selectedBlocksInGroup.Get(i))); + selectedBlocksInGroup.FastClear(); + return list.ToArray(); + } + + public void RemoveBlockGroup(int id) + { + BlockGroupUtility.RemoveAllBlocksInBlockGroup(id, entitiesDB, removedConnections, nativeRemove, + connectionFactory, default).Complete(); + } + + public void SelectBlueprint(uint resourceID) + { + BlueprintUtil.SelectBlueprint(null, new BlueprintInventoryItemEntityStruct + { + blueprintResourceId = resourceID, + }); + } + + public string Name { get; } = "GamecraftModdingAPIBlueprintGameEngine"; + public bool isRemovable { get; } + + [HarmonyPatch] + private static class RemoveEnginePatch + { + public static void Prefix(IEntityFunctions entityFunctions, + MachineGraphConnectionEntityFactory machineGraphConnectionEntityFactory) + { + nativeRemove = entityFunctions.ToNativeRemove("GCAPI" + nameof(BlueprintEngine)); + connectionFactory = machineGraphConnectionEntityFactory; + } + + public static MethodBase TargetMethod() + { + return AccessTools.Constructor(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.RemoveBlockEngine")); + } + } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Blueprint.cs b/GamecraftModdingAPI/Blueprint.cs new file mode 100644 index 0000000..de6d65e --- /dev/null +++ b/GamecraftModdingAPI/Blueprint.cs @@ -0,0 +1,20 @@ +using Gamecraft.GUI.Blueprints; + +namespace GamecraftModdingAPI +{ + /// + /// Represents a blueprint in the inventory. When placed it becomes a block group. + /// + public class Blueprint + { + public uint Id { get; } + + /*public static void SelectBlueprint(Blueprint blueprint) + { + BlueprintUtil.SelectBlueprint(null, new BlueprintInventoryItemEntityStruct + { + blueprintResourceId = blueprint.Id + }); + }*/ + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Main.cs b/GamecraftModdingAPI/Main.cs index 98fb6f6..584ae90 100644 --- a/GamecraftModdingAPI/Main.cs +++ b/GamecraftModdingAPI/Main.cs @@ -83,6 +83,7 @@ namespace GamecraftModdingAPI // init object-oriented classes Player.Init(); Block.Init(); + BlockGroup.Init(); Wire.Init(); GameClient.Init(); AsyncUtils.Init();