Blueprint fixes, bump version, add block copy support

Fixed getting the selected blueprint
Fixed block groups not being assigned to first block
This commit is contained in:
Norbi Peti 2020-11-13 21:35:53 +01:00
parent d744aaab79
commit 64b42830a3
8 changed files with 857 additions and 656 deletions

View file

@ -29,6 +29,7 @@ namespace GamecraftModdingAPI
protected static readonly SignalEngine SignalEngine = new SignalEngine(); protected static readonly SignalEngine SignalEngine = new SignalEngine();
protected static readonly BlockEventsEngine BlockEventsEngine = new BlockEventsEngine(); protected static readonly BlockEventsEngine BlockEventsEngine = new BlockEventsEngine();
protected static readonly ScalingEngine ScalingEngine = new ScalingEngine(); protected static readonly ScalingEngine ScalingEngine = new ScalingEngine();
protected static readonly BlockCloneEngine BlockCloneEngine = new BlockCloneEngine();
protected internal static readonly BlockEngine BlockEngine = new BlockEngine(); protected internal static readonly BlockEngine BlockEngine = new BlockEngine();
@ -229,6 +230,7 @@ namespace GamecraftModdingAPI
public EGID Id { get; } public EGID Id { get; }
internal BlockEngine.BlockInitData InitData; internal BlockEngine.BlockInitData InitData;
private EGID copiedFrom;
/// <summary> /// <summary>
/// The block's current position or zero if the block no longer exists. /// The block's current position or zero if the block no longer exists.
@ -415,11 +417,34 @@ namespace GamecraftModdingAPI
: null); : null);
} }
/// <summary>
/// Creates a copy of the block in the game with the same basic properties and tweakable stats.
/// </summary>
/// <returns></returns>
public T Copy<T>() where T : Block
{
var block = PlaceNew<T>(Type, Position, Rotation, Color.Color, Color.Darkness, UniformScale, Scale);
block.copiedFrom = Id;
if (Type == BlockIDs.ConsoleBlock
&& (this is ConsoleBlock srcCB || (srcCB = Specialise<ConsoleBlock>()) != null)
&& (block is ConsoleBlock dstCB || (dstCB = block.Specialise<ConsoleBlock>()) != null))
{
//Console block properties are set by a separate engine in the game
dstCB.Arg1 = srcCB.Arg1;
dstCB.Arg2 = srcCB.Arg2;
dstCB.Arg3 = srcCB.Arg3;
dstCB.Command = srcCB.Command;
}
return block;
}
private void OnPlacedInit(object sender, BlockPlacedRemovedEventArgs e) private void OnPlacedInit(object sender, BlockPlacedRemovedEventArgs e)
{ //Member method instead of lambda to avoid constantly creating delegates { //Member method instead of lambda to avoid constantly creating delegates
if (e.ID != Id) return; if (e.ID != Id) return;
Placed -= OnPlacedInit; //And we can reference it Placed -= OnPlacedInit; //And we can reference it
InitData = default; //Remove initializer as it's no longer valid - if the block gets removed it shouldn't be used again InitData = default; //Remove initializer as it's no longer valid - if the block gets removed it shouldn't be used again
if (copiedFrom != EGID.Empty)
BlockCloneEngine.CopyBlockStats(copiedFrom, Id);
} }
public override string ToString() public override string ToString()
@ -462,6 +487,7 @@ namespace GamecraftModdingAPI
GameEngineManager.AddGameEngine(BlockEventsEngine); GameEngineManager.AddGameEngine(BlockEventsEngine);
GameEngineManager.AddGameEngine(ScalingEngine); GameEngineManager.AddGameEngine(ScalingEngine);
GameEngineManager.AddGameEngine(SignalEngine); GameEngineManager.AddGameEngine(SignalEngine);
GameEngineManager.AddGameEngine(BlockCloneEngine);
Wire.signalEngine = SignalEngine; // requires same functionality, no need to duplicate the engine Wire.signalEngine = SignalEngine; // requires same functionality, no need to duplicate the engine
} }

View file

@ -99,7 +99,9 @@ namespace GamecraftModdingAPI
/// <returns>A new block group containing the given block</returns> /// <returns>A new block group containing the given block</returns>
public static BlockGroup Create(Block block) public static BlockGroup Create(Block block)
{ {
return new BlockGroup(_engine.CreateBlockGroup(default, default), block); var bg = new BlockGroup(_engine.CreateBlockGroup(default, default), block);
block.BlockGroup = bg;
return bg;
} }
/// <summary> /// <summary>

View file

@ -0,0 +1,78 @@
using System;
using System.Reflection;
using GamecraftModdingAPI.Engines;
using HarmonyLib;
using RobocraftX.Blocks;
using RobocraftX.Character;
using RobocraftX.Common;
using RobocraftX.Common.Players;
using Svelto.DataStructures;
using Svelto.ECS;
namespace GamecraftModdingAPI.Blocks
{
public class BlockCloneEngine : IApiEngine
{
private static Type copyEngineType =
AccessTools.TypeByName("Gamecraft.GUI.Tweaks.Engines.CopyTweaksOnPickEngine");
private MethodBase copyFromBlock = AccessTools.Method(copyEngineType, "CopyTweaksFromBlock");
private MethodBase copyToBlock = AccessTools.Method(copyEngineType, "ApplyTweaksToPlacedBlock");
public void Ready()
{
}
public EntitiesDB entitiesDB { get; set; }
public void Dispose()
{
}
public void CopyBlockStats(EGID sourceID, EGID targetID)
{
var allCharacters = (LocalFasterReadOnlyList<ExclusiveGroupStruct>) CharacterExclusiveGroups.AllCharacters;
foreach (var ((pickedBlockColl, count), _) in entitiesDB.QueryEntities<PickedBlockExtraDataStruct>(allCharacters))
{
for (int i = 0; i < count; ++i)
{
ref PickedBlockExtraDataStruct pickedBlock = ref pickedBlockColl[i];
var oldStruct = pickedBlock;
pickedBlock.pickedBlockEntityID = sourceID;
pickedBlock.placedBlockEntityID = targetID;
pickedBlock.placedBlockTweaksCopied = false;
pickedBlock.placedBlockTweaksMustCopy = true;
if (entitiesDB.Exists<DBEntityStruct>(pickedBlock.pickedBlockEntityID)
&& entitiesDB.Exists<DBEntityStruct>(pickedBlock.placedBlockEntityID))
{
copyFromBlock.Invoke(Patch.instance, new object[] {pickedBlock.ID, pickedBlock});
copyToBlock.Invoke(Patch.instance, new object[] {pickedBlock.ID, pickedBlock});
pickedBlock.placedBlockTweaksMustCopy = false;
pickedBlock.placedBlockTweaksCopied = false;
}
pickedBlock = oldStruct; //Make sure to not interfere with the game
}
}
}
[HarmonyPatch]
private static class Patch
{
public static object instance;
public static void Postfix(object __instance)
{
instance = __instance;
}
public static MethodBase TargetMethod()
{
return AccessTools.GetDeclaredConstructors(copyEngineType)[0];
}
}
public string Name { get; } = "GamecraftModdingAPIBlockCloneGameEngine";
public bool isRemovable { get; } = false;
}
}

View file

@ -8,7 +8,7 @@ using Gamecraft.Wires;
using RobocraftX.Blocks; using RobocraftX.Blocks;
using RobocraftX.Common; using RobocraftX.Common;
using RobocraftX.Physics; using RobocraftX.Physics;
using RobocraftX.Scene.Simulation;
using Svelto.DataStructures; using Svelto.DataStructures;
using Svelto.ECS; using Svelto.ECS;
using Svelto.ECS.Hybrid; using Svelto.ECS.Hybrid;

View file

@ -95,12 +95,7 @@ namespace GamecraftModdingAPI.Blocks
if (resourceID == uint.MaxValue) if (resourceID == uint.MaxValue)
BlueprintUtil.UnselectBlueprint(entitiesDB); BlueprintUtil.UnselectBlueprint(entitiesDB);
else else
{ BlueprintUtil.SelectBlueprint(entitiesDB, resourceID, false, -1);
BlueprintUtil.SelectBlueprint(entitiesDB, new BlueprintInventoryItemEntityStruct
{
blueprintResourceId = resourceID,
});
}
} }
public uint CreateBlueprint() public uint CreateBlueprint()
@ -122,7 +117,7 @@ namespace GamecraftModdingAPI.Blocks
} }
var serializationData = clipboardManager.GetSerializationData(blueprintID); var serializationData = clipboardManager.GetSerializationData(blueprintID);
SelectionSerializationUtility.ClearClipboard(playerID, entitiesDB, entityFunctions, serializationData.blueprintData); SelectionSerializationUtility.ClearClipboard(playerID, entitiesDB, entityFunctions, serializationData.blueprintData, -1);
if (selected.Count == 0) if (selected.Count == 0)
return; return;
//ref BlockGroupTransformEntityComponent groupTransform = ref EntityNativeDBExtensions.QueryEntity<BlockGroupTransformEntityComponent>(entitiesDb, (uint) local1.currentBlockGroup, BlockGroupExclusiveGroups.BlockGroupEntityGroup); //ref BlockGroupTransformEntityComponent groupTransform = ref EntityNativeDBExtensions.QueryEntity<BlockGroupTransformEntityComponent>(entitiesDb, (uint) local1.currentBlockGroup, BlockGroupExclusiveGroups.BlockGroupEntityGroup);
@ -134,7 +129,7 @@ namespace GamecraftModdingAPI.Blocks
clipboardManager.SetGhostSerialized(blueprintID, false); clipboardManager.SetGhostSerialized(blueprintID, false);
SelectionSerializationUtility.CopySelectionToClipboard(playerID, entitiesDB, SelectionSerializationUtility.CopySelectionToClipboard(playerID, entitiesDB,
serializationData.blueprintData, entitySerialization, entityFactory, blockIDs, serializationData.blueprintData, entitySerialization, entityFactory, blockIDs,
(uint) blockIDs.Length, pos, rot); (uint) blockIDs.Length, pos, rot, -1);
} }
public Block[] PlaceBlueprintBlocks(uint blueprintID, uint playerID, float3 pos, float3 rot) public Block[] PlaceBlueprintBlocks(uint blueprintID, uint playerID, float3 pos, float3 rot)
@ -173,7 +168,7 @@ namespace GamecraftModdingAPI.Blocks
new object[] new object[]
{ {
playerID, grid, poss, rots, selectionPosition, selectionRotation, blueprintData, playerID, grid, poss, rots, selectionPosition, selectionRotation, blueprintData,
entitiesDB, entitySerialization, nextFilterId1 entitySerialization, nextFilterId1
}); });
/* /*
uint playerId, in GridRotationStruct ghostParentGrid, uint playerId, in GridRotationStruct ghostParentGrid,

File diff suppressed because it is too large Load diff

View file

@ -348,8 +348,8 @@ namespace GamecraftModdingAPI
/// </summary> /// </summary>
public Blueprint SelectedBlueprint public Blueprint SelectedBlueprint
{ {
get => playerEngine.GetPlayerStruct(Id, out BlueprintInventoryItemEntityStruct biies) get => playerEngine.GetPlayerStruct(Id, out LocalBlueprintInputStruct lbis)
? new Blueprint(biies.blueprintResourceId) ? new Blueprint(lbis.selectedBlueprintId)
: null; : null;
set => BlockGroup._engine.SelectBlueprint(value?.Id ?? uint.MaxValue); set => BlockGroup._engine.SelectBlueprint(value?.Id ?? uint.MaxValue);
} }

View file

@ -38,7 +38,7 @@ PROJECT_NAME = "GamecraftModdingAPI"
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = "v1.5.0" PROJECT_NUMBER = "v1.8.0"
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a