|
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- using Gamecraft.Blocks.BlockGroups;
- using Gamecraft.GUI.Blueprints;
- using GamecraftModdingAPI.Engines;
- using GamecraftModdingAPI.Utility;
- using HarmonyLib;
- using RobocraftX.Blocks;
- using RobocraftX.Common;
- using RobocraftX.CR.MachineEditing.BoxSelect;
- using RobocraftX.CR.MachineEditing.BoxSelect.ClipboardOperations;
- using Svelto.DataStructures;
- using Svelto.ECS;
- using Svelto.ECS.DataStructures;
- using Svelto.ECS.EntityStructs;
- using Svelto.ECS.Serialization;
- using Unity.Collections;
- using Unity.Mathematics;
- using UnityEngine;
- using Allocator = Svelto.Common.Allocator;
-
- namespace GamecraftModdingAPI.Blocks
- {
- public class BlueprintEngine : IFactoryEngine
- {
- private readonly MethodInfo getBlocksFromGroup =
- AccessTools.Method("RobocraftX.CR.MachineEditing.PlaceBlockUtility:GetBlocksSharingBlockgroup");
-
- private NativeDynamicArray selectedBlocksInGroup;
- private NativeHashSet<ulong> removedConnections = new NativeHashSet<ulong>();
- private int addingToBlockGroup = -1;
-
- private static readonly Type PlaceBlueprintUtilityType =
- AccessTools.TypeByName("RobocraftX.CR.MachineEditing.PlaceBlueprintUtility");
- private static readonly FieldInfo LocalBlockMap =
- AccessTools.DeclaredField(PlaceBlueprintUtilityType, "_localBlockMap");
- private static readonly MethodInfo BuildBlock = AccessTools.Method(PlaceBlueprintUtilityType, "BuildBlock");
- private static readonly MethodInfo BuildWires = AccessTools.Method(PlaceBlueprintUtilityType, "BuildWires");
- private static readonly Type SerializeGhostBlueprintType =
- AccessTools.TypeByName("RobocraftX.CR.MachineEditing.BoxSelect.SerializeGhostChildrenOnAddEngine");
- private static readonly MethodInfo SerializeGhostBlueprint =
- AccessTools.Method(SerializeGhostBlueprintType, "SerializeClipboardGhostEntities");
-
- private static NativeEntityRemove nativeRemove;
- private static MachineGraphConnectionEntityFactory connectionFactory;
- private static IEntityFunctions entityFunctions;
- private static ClipboardSerializationDataResourceManager clipboardManager;
- private static IEntitySerialization entitySerialization;
- private static IEntityFactory entityFactory;
- private static FasterList<EGID> globalBlockMap;
- private static object SerializeGhostBlueprintInstance;
- private static GhostChildEntityFactory BuildGhostBlueprintFactory;
-
- public void Ready()
- {
- selectedBlocksInGroup = NativeDynamicArray.Alloc<EGID>(Allocator.Persistent);
- }
-
- public EntitiesDB entitiesDB { get; set; }
-
- public void Dispose()
- {
- selectedBlocksInGroup.Dispose();
- }
-
- public Block[] GetBlocksFromGroup(EGID blockID, out float3 pos, out quaternion rot)
- {
- var blockPos = default(float3);
- var blockRot = default(quaternion);
- var parameters = new object[] {blockID, selectedBlocksInGroup, entitiesDB, blockPos, blockRot};
- getBlocksFromGroup.Invoke(null, parameters);
- pos = (float3) parameters[3];
- rot = (quaternion) parameters[4];
- int count = selectedBlocksInGroup.Count<EGID>();
- var ret = new Block[count];
- for (uint i = 0; i < count; i++)
- ret[i] = new Block(selectedBlocksInGroup.Get<EGID>(i));
- selectedBlocksInGroup.FastClear();
- return ret;
- }
-
- public void RemoveBlockGroup(int id)
- {
- BlockGroupUtility.RemoveAllBlocksInBlockGroup(id, entitiesDB, removedConnections, nativeRemove,
- connectionFactory, default).Complete();
- }
-
- public int CreateBlockGroup(float3 position, quaternion rotation)
- {
- int nextFilterId = BlockGroupUtility.NextFilterId;
- Factory.BuildEntity<BlockGroupEntityDescriptor>((uint) nextFilterId,
- BlockGroupExclusiveGroups.BlockGroupEntityGroup).Init(new BlockGroupTransformEntityComponent
- {
- blockGroupGridRotation = rotation,
- blockGroupGridPosition = position
- });
- return nextFilterId;
- }
-
- public void AddBlockToGroup(EGID blockID, int groupID)
- {
- if (globalBlockMap == null)
- globalBlockMap = FullGameFields._deserialisedBlockMap;
- if (groupID != addingToBlockGroup)
- {
- Logging.MetaDebugLog("Changing current block group from " + addingToBlockGroup + " to " + groupID);
- addingToBlockGroup = groupID;
- globalBlockMap.Clear();
- }
-
- globalBlockMap.Add(blockID);
- }
-
- public void SelectBlueprint(uint resourceID)
- {
- if (resourceID == uint.MaxValue)
- BlueprintUtil.UnselectBlueprint(entitiesDB);
- else
- BlueprintUtil.SelectBlueprint(entitiesDB, resourceID, false, -1);
- }
-
- public uint CreateBlueprint()
- {
- uint index = clipboardManager.AllocateSerializationData();
- return index;
- }
-
- public void ReplaceBlueprint(uint playerID, uint blueprintID, ICollection<Block> selected, float3 pos, quaternion rot)
- {
- var blockIDs = new EGID[selected.Count];
- using (var enumerator = selected.GetEnumerator())
- {
- for (var i = 0; enumerator.MoveNext(); i++)
- {
- var block = enumerator.Current;
- blockIDs[i] = block.Id;
- }
- }
-
- var serializationData = clipboardManager.GetSerializationData(blueprintID);
- SelectionSerializationUtility.ClearClipboard(playerID, entitiesDB, entityFunctions, serializationData.blueprintData, -1);
- if (selected.Count == 0)
- return;
- //ref BlockGroupTransformEntityComponent groupTransform = ref EntityNativeDBExtensions.QueryEntity<BlockGroupTransformEntityComponent>(entitiesDb, (uint) local1.currentBlockGroup, BlockGroupExclusiveGroups.BlockGroupEntityGroup);
- //ref ColliderAabb collider = ref EntityNativeDBExtensions.QueryEntity<ColliderAabb>(entitiesDB, (uint) groupID, BlockGroupExclusiveGroups.BlockGroupEntityGroup);
- //float3 bottomOffset = PlaceBlockUtility.GetBottomOffset(collider);
- //var rootPosition = math.mul(groupTransform.blockGroupGridRotation, bottomOffset) + groupTransform.blockGroupGridPosition;
- //var rootRotation = groupTransform.blockGroupGridRotation;
-
- clipboardManager.SetGhostSerialized(blueprintID, false);
- SelectionSerializationUtility.CopySelectionToClipboard(playerID, entitiesDB,
- serializationData.blueprintData, entitySerialization, entityFactory, blockIDs,
- (uint) blockIDs.Length, pos, rot, -1);
- BuildGhostBlueprint(selected, pos, rot, playerID);
- SerializeGhostBlueprint.Invoke(SerializeGhostBlueprintInstance, new object[] {playerID, blueprintID});
-
- }
-
- private void BuildGhostBlueprint(ICollection<Block> blocks, float3 pos, quaternion rot, uint playerID)
- {
- GhostChildUtility.ClearGhostChildren(playerID, entitiesDB, entityFunctions);
- foreach (var block in blocks)
- {
- GhostChildUtility.BuildGhostChild(in playerID, block.Id, in pos, in rot, entitiesDB,
- BuildGhostBlueprintFactory, false);
- }
- }
-
- public Block[] PlaceBlueprintBlocks(uint blueprintID, uint playerID, float3 pos, float3 rot)
- { //RobocraftX.CR.MachineEditing.PlaceBlueprintUtility.PlaceBlocksFromSerialisedData
- var serializationData = clipboardManager.GetSerializationData(blueprintID);
- var blueprintData = serializationData.blueprintData;
- blueprintData.dataPos = 0U;
- uint selectionSize;
- PositionEntityStruct selectionPosition;
- RotationEntityStruct selectionRotation;
- uint version;
- BoxSelectSerializationUtilities.ReadClipboardHeader(blueprintData, out selectionSize, out selectionPosition, out selectionRotation, out version);
- ((FasterList<EGID>) LocalBlockMap.GetValue(null)).Clear();
- if (version <= 1U)
- {
- uint groupsCount;
- BoxSelectSerializationUtilities.ReadBlockGroupData(blueprintData, out groupsCount);
- for (int index = 0; (long) index < (long) groupsCount; ++index)
- {
- int nextFilterId = BlockGroupUtility.NextFilterId;
- entitySerialization.DeserializeNewEntity(new EGID((uint) nextFilterId, BlockGroupExclusiveGroups.BlockGroupEntityGroup), blueprintData, 1);
- }
- }
- int nextFilterId1 = BlockGroupUtility.NextFilterId;
- entityFactory.BuildEntity<BlockGroupEntityDescriptor>(new EGID((uint) nextFilterId1,
- BlockGroupExclusiveGroups.BlockGroupEntityGroup)).Init(new BlockGroupTransformEntityComponent
- {
- blockGroupGridPosition = selectionPosition.position,
- blockGroupGridRotation = selectionRotation.rotation
- });
- var frot = Quaternion.Euler(rot);
- var grid = new GridRotationStruct {position = pos, rotation = frot};
- var poss = new PositionEntityStruct {position = pos};
- var rots = new RotationEntityStruct {rotation = frot};
- for (int index = 0; (long) index < (long) selectionSize; ++index)
- BuildBlock.Invoke(null,
- new object[]
- {
- playerID, grid, poss, rots, selectionPosition, selectionRotation, blueprintData,
- entitySerialization, nextFilterId1
- });
- /*
- uint playerId, in GridRotationStruct ghostParentGrid,
- in PositionEntityStruct ghostParentPosition, in RotationEntityStruct ghostParentRotation,
- in PositionEntityStruct selectionPosition, in RotationEntityStruct selectionRotation,
- ISerializationData serializationData, EntitiesDB entitiesDb,
- IEntitySerialization entitySerialization, int blockGroupId
- */
- if (globalBlockMap == null)
- globalBlockMap = FullGameFields._deserialisedBlockMap;
- var placedBlocks = (FasterList<EGID>) LocalBlockMap.GetValue(null);
- globalBlockMap.Clear();
- globalBlockMap.AddRange(placedBlocks);
- BuildWires.Invoke(null,
- new object[] {playerID, blueprintData, entitySerialization, entitiesDB, entityFactory});
- var blocks = new Block[placedBlocks.count];
- for (int i = 0; i < blocks.Length; i++)
- blocks[i] = new Block(placedBlocks[i]);
- return blocks;
- }
-
- public void GetBlueprintInfo(uint blueprintID, out float3 pos, out quaternion rot, out uint selectionSize)
- {
- var serializationData = clipboardManager.GetSerializationData(blueprintID);
- var blueprintData = serializationData.blueprintData;
- blueprintData.dataPos = 0U;
- BoxSelectSerializationUtilities.ReadClipboardHeader(blueprintData, out selectionSize, out var posst,
- out var rotst, out _);
- blueprintData.dataPos = 0U; //Just to be sure, it gets reset when it's read anyway
- pos = posst.position;
- rot = rotst.rotation;
- }
-
- public void InitBlueprint(uint blueprintID)
- {
- clipboardManager.IncrementRefCount(blueprintID);
- }
-
- public void DisposeBlueprint(uint blueprintID)
- {
- clipboardManager.DecrementRefCount(blueprintID);
- }
-
- public string Name { get; } = "GamecraftModdingAPIBlueprintGameEngine";
- public bool isRemovable { get; } = false;
-
- [HarmonyPatch]
- private static class RemoveEnginePatch
- {
- public static void Prefix(IEntityFunctions entityFunctions,
- MachineGraphConnectionEntityFactory machineGraphConnectionEntityFactory)
- {
- nativeRemove = entityFunctions.ToNativeRemove<BlockEntityDescriptor>("GCAPI" + nameof(BlueprintEngine));
- connectionFactory = machineGraphConnectionEntityFactory;
- BlueprintEngine.entityFunctions = entityFunctions;
- }
-
- public static MethodBase TargetMethod()
- {
- return AccessTools.GetDeclaredConstructors(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.RemoveBlockEngine"))[0];
- }
- }
-
- [HarmonyPatch]
- private static class SelectEnginePatch
- {
- public static void Prefix(ClipboardSerializationDataResourceManager clipboardSerializationDataResourceManager,
- IEntitySerialization entitySerialization,
- IEntityFactory entityFactory)
- {
- clipboardManager = clipboardSerializationDataResourceManager;
- BlueprintEngine.entitySerialization = entitySerialization;
- BlueprintEngine.entityFactory = entityFactory;
- }
-
- public static MethodBase TargetMethod()
- {
- return AccessTools.GetDeclaredConstructors(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.SelectBlockEngine"))[0];
- }
- }
-
- [HarmonyPatch]
- private static class SerializeGhostBlueprintPatch
- {
- public static void Postfix(object __instance)
- {
- SerializeGhostBlueprintInstance = __instance;
- }
-
- public static MethodBase TargetMethod()
- {
- return AccessTools.GetDeclaredConstructors(SerializeGhostBlueprintType)[0];
- }
- }
-
- [HarmonyPatch]
- private static class BuildGhostBlueprintPatch
- {
- public static void Postfix(GhostChildEntityFactory ghostChildEntityFactory)
- {
- BuildGhostBlueprintFactory = ghostChildEntityFactory;
- }
-
- public static MethodBase TargetMethod()
- {
- return AccessTools.GetDeclaredConstructors(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.BuildGhostChildForMultiblockPickEngine"))[0];
- }
- }
-
- public IEntityFactory Factory { get; set; }
- }
- }
|