2020-11-10 18:28:36 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Reflection;
|
2020-11-10 15:37:20 +00:00
|
|
|
|
using Gamecraft.Blocks.BlockGroups;
|
|
|
|
|
using Gamecraft.GUI.Blueprints;
|
|
|
|
|
using GamecraftModdingAPI.Engines;
|
2020-11-10 18:28:36 +00:00
|
|
|
|
using GamecraftModdingAPI.Utility;
|
2020-11-10 15:37:20 +00:00
|
|
|
|
using HarmonyLib;
|
|
|
|
|
using RobocraftX.Blocks;
|
2020-11-10 18:28:36 +00:00
|
|
|
|
using RobocraftX.Common;
|
|
|
|
|
using RobocraftX.CR.MachineEditing.BoxSelect;
|
|
|
|
|
using RobocraftX.CR.MachineEditing.BoxSelect.ClipboardOperations;
|
2020-11-10 15:37:20 +00:00
|
|
|
|
using Svelto.DataStructures;
|
|
|
|
|
using Svelto.ECS;
|
|
|
|
|
using Svelto.ECS.DataStructures;
|
2020-11-10 18:28:36 +00:00
|
|
|
|
using Svelto.ECS.EntityStructs;
|
|
|
|
|
using Svelto.ECS.Serialization;
|
2020-11-10 15:37:20 +00:00
|
|
|
|
using Unity.Collections;
|
2020-11-10 18:28:36 +00:00
|
|
|
|
using Unity.Mathematics;
|
|
|
|
|
using UnityEngine;
|
2020-11-10 15:37:20 +00:00
|
|
|
|
|
|
|
|
|
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<ulong> removedConnections = new NativeHashSet<ulong>();
|
|
|
|
|
|
2020-11-10 18:28:36 +00:00
|
|
|
|
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");
|
|
|
|
|
|
2020-11-10 15:37:20 +00:00
|
|
|
|
private static NativeEntityRemove nativeRemove;
|
|
|
|
|
private static MachineGraphConnectionEntityFactory connectionFactory;
|
2020-11-10 18:28:36 +00:00
|
|
|
|
private static IEntityFunctions entityFunctions;
|
|
|
|
|
private static ClipboardSerializationDataResourceManager clipboardManager;
|
|
|
|
|
private static IEntitySerialization entitySerialization;
|
|
|
|
|
private static IEntityFactory entityFactory;
|
|
|
|
|
private static FasterList<EGID> globalBlockMap;
|
2020-11-10 15:37:20 +00:00
|
|
|
|
|
|
|
|
|
public void Ready()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public EntitiesDB entitiesDB { get; set; }
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Block[] GetBlocksFromGroup(EGID blockID)
|
|
|
|
|
{
|
|
|
|
|
var list = new FasterList<Block>();
|
|
|
|
|
object blockPos = null, blockRot = null;
|
|
|
|
|
getBlocksFromGroup.Invoke(null, new[] {blockID, selectedBlocksInGroup, entitiesDB, blockPos, blockRot});
|
|
|
|
|
for (uint i = 0; i < selectedBlocksInGroup.Count<EGID>(); i++)
|
|
|
|
|
list.Add(new Block(selectedBlocksInGroup.Get<EGID>(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,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-10 18:28:36 +00:00
|
|
|
|
public uint CreateBlueprint()
|
|
|
|
|
{
|
|
|
|
|
uint index = clipboardManager.AllocateSerializationData();
|
|
|
|
|
return index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ReplaceBlueprint(uint playerID, uint blueprintID, Block[] selected, float3 pos, quaternion rot)
|
|
|
|
|
{
|
|
|
|
|
var blockIDs = new EGID[selected.Length];
|
|
|
|
|
for (var i = 0; i < selected.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
var block = selected[i];
|
|
|
|
|
blockIDs[i] = block.Id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var serializationData = clipboardManager.GetSerializationData(blueprintID);
|
|
|
|
|
SelectionSerializationUtility.ClearClipboard(playerID, entitiesDB, entityFunctions, serializationData.blueprintData);
|
|
|
|
|
if (selected.Length == 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;
|
|
|
|
|
if (math.all(pos == default))
|
|
|
|
|
pos = selected[0].Position;
|
|
|
|
|
if (math.all(rot.value == default))
|
|
|
|
|
rot = Quaternion.Euler(selected[0].Rotation);
|
|
|
|
|
|
|
|
|
|
clipboardManager.SetGhostSerialized(blueprintID, false);
|
|
|
|
|
SelectionSerializationUtility.CopySelectionToClipboard(playerID, entitiesDB,
|
|
|
|
|
serializationData.blueprintData, entitySerialization, entityFactory, blockIDs,
|
|
|
|
|
(uint) blockIDs.Length, pos, rot);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
entitiesDB, 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 InitBlueprint(uint blueprintID)
|
|
|
|
|
{
|
|
|
|
|
clipboardManager.IncrementRefCount(blueprintID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DisposeBlueprint(uint blueprintID)
|
|
|
|
|
{
|
|
|
|
|
clipboardManager.DecrementRefCount(blueprintID);
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-10 15:37:20 +00:00
|
|
|
|
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<BlockEntityDescriptor>("GCAPI" + nameof(BlueprintEngine));
|
|
|
|
|
connectionFactory = machineGraphConnectionEntityFactory;
|
2020-11-10 18:28:36 +00:00
|
|
|
|
BlueprintEngine.entityFunctions = entityFunctions;
|
2020-11-10 15:37:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static MethodBase TargetMethod()
|
|
|
|
|
{
|
|
|
|
|
return AccessTools.Constructor(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.RemoveBlockEngine"));
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-11-10 18:28:36 +00:00
|
|
|
|
|
|
|
|
|
[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.Constructor(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.SelectBlockEngine"));
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-11-10 15:37:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|