From 5bbb54c0c58075d4795bbed4bed006a8b64cc149 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 13 Jul 2020 21:55:48 +0200 Subject: [PATCH 01/32] Automatically invoke the correct block constructor And store delegates of dynamic methods invoking constructors Tested with the automated tests --- GamecraftModdingAPI/Block.cs | 107 +++++++++++++----- GamecraftModdingAPI/Blocks/BlockTests.cs | 3 +- GamecraftModdingAPI/Blocks/ConsoleBlock.cs | 30 ++--- GamecraftModdingAPI/Blocks/Motor.cs | 23 ---- GamecraftModdingAPI/Blocks/Piston.cs | 25 +--- GamecraftModdingAPI/Blocks/Servo.cs | 23 ---- GamecraftModdingAPI/Blocks/SignalingBlock.cs | 19 ---- GamecraftModdingAPI/Blocks/SpawnPoint.cs | 25 +--- GamecraftModdingAPI/Blocks/TextBlock.cs | 15 --- GamecraftModdingAPI/Blocks/Timer.cs | 17 --- .../Tests/GamecraftModdingAPIPluginTest.cs | 22 ++++ 11 files changed, 114 insertions(+), 195 deletions(-) diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 16a0c81..673ef49 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -1,6 +1,7 @@ using System; -using System.Reflection; -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Emit; using Svelto.ECS; using Svelto.ECS.EntityStructs; @@ -67,10 +68,6 @@ namespace GamecraftModdingAPI /// Place a new block at the given position. If scaled, position means the center of the block. The default block size is 0.2 in terms of position. /// Place blocks next to each other to connect them. /// The placed block will be a complete block with a placement grid and collision which will be saved along with the game. - /// - /// This method waits for the block to be constructed in the game which may take a significant amount of time. - /// Only use this to place a single block. - /// For placing multiple blocks, use PlaceNew() then AsyncUtils.WaitForSubmission() when done with placing blocks. /// /// The block's type /// The block's color @@ -81,23 +78,15 @@ namespace GamecraftModdingAPI /// The block's non-uniform scale - 0 means is used /// The player who placed the block /// The placed block or null if failed - public static async Task PlaceNewAsync(BlockIDs block, float3 position, + public static T PlaceNew(BlockIDs block, float3 position, float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, - int uscale = 1, float3 scale = default, Player player = null) + int uscale = 1, float3 scale = default, Player player = null) where T : Block { if (PlacementEngine.IsInGame && GameState.IsBuildMode()) { - try - { - var ret = new Block(PlacementEngine.PlaceBlock(block, color, darkness, - position, uscale, scale, player, rotation)); - await AsyncUtils.WaitForSubmission(); - return ret; - } - catch (Exception e) - { - Logging.MetaDebugLog(e); - } + var egid = PlacementEngine.PlaceBlock(block, color, darkness, + position, uscale, scale, player, rotation); + return New(egid.entityID, egid.groupID); } return null; @@ -109,7 +98,7 @@ namespace GamecraftModdingAPI /// The block object public static Block GetLastPlacedBlock() { - return new Block(BlockIdentifiers.LatestBlockID); + return New(BlockIdentifiers.LatestBlockID); } /// @@ -130,6 +119,75 @@ namespace GamecraftModdingAPI remove => BlockEventsEngine.Removed -= value; } + private static Dictionary> initializers = new Dictionary>(); + + private static Dictionary typeToGroup = + new Dictionary + { + {typeof(ConsoleBlock), new[] {CommonExclusiveGroups.BUILD_CONSOLE_BLOCK_GROUP}}, + {typeof(Motor), new[] {CommonExclusiveGroups.BUILD_MOTOR_BLOCK_GROUP}}, + {typeof(Piston), new[] {CommonExclusiveGroups.BUILD_PISTON_BLOCK_GROUP}}, + {typeof(Servo), new[] {CommonExclusiveGroups.BUILD_SERVO_BLOCK_GROUP}}, + { + typeof(SpawnPoint), + new[] + { + CommonExclusiveGroups.BUILD_SPAWNPOINT_BLOCK_GROUP, + CommonExclusiveGroups.BUILD_BUILDINGSPAWN_BLOCK_GROUP + } + }, + {typeof(TextBlock), new[] {CommonExclusiveGroups.BUILD_TEXT_BLOCK_GROUP}}, + {typeof(Timer), new[] {CommonExclusiveGroups.BUILD_TIMER_BLOCK_GROUP}} + }; + + private static T New(uint id, ExclusiveGroupStruct? group = null) where T : Block + { + var type = typeof(T); + EGID egid; + if (!group.HasValue) + { + if (typeToGroup.TryGetValue(type, out var gr) && gr.Length == 1) + egid = new EGID(id, gr[0]); + else + egid = BlockEngine.FindBlockEGID(id) ?? throw new BlockTypeException("Could not find block group!"); + } + else + { + egid = new EGID(id, group.Value); + if (typeToGroup.TryGetValue(type, out var gr) + && gr.All(egs => egs != group.Value)) //If this subclass has a specific group, then use that - so Block should still work + throw new BlockTypeException($"Incompatible block type! Type {type.Name} belongs to group {gr.Select(g => g.ToString()).Aggregate((a, b) => a + ", " + b)} instead of {group.Value}"); + } + + if (initializers.TryGetValue(type, out var func)) + { + var bl = (T) func(egid); + return bl; + } + + //https://stackoverflow.com/a/10593806/2703239 + var ctor = type.GetConstructor(new[] {typeof(EGID)}); + if (ctor == null) + throw new MissingMethodException("There is no constructor with an EGID parameter for this object"); + DynamicMethod dynamic = new DynamicMethod(string.Empty, + type, + new[] {typeof(EGID)}, + type); + ILGenerator il = dynamic.GetILGenerator(); + + il.DeclareLocal(type); + il.Emit(OpCodes.Ldarg_0); //Load EGID and pass to constructor + il.Emit(OpCodes.Newobj, ctor); //Call constructor + il.Emit(OpCodes.Stloc_0); + il.Emit(OpCodes.Ldloc_0); + il.Emit(OpCodes.Ret); + + func = (Func) dynamic.CreateDelegate(typeof(Func)); + initializers.Add(type, func); + var block = (T) func(egid); + return block; + } + public Block(EGID id) { Id = id; @@ -344,12 +402,9 @@ namespace GamecraftModdingAPI // C# can't cast to a child of Block unless the object was originally that child type // And C# doesn't let me make implicit cast operators for child types // So thanks to Microsoft, we've got this horrible implementation using reflection - ConstructorInfo ctor = typeof(T).GetConstructor(types: new System.Type[] { typeof(EGID) }); - if (ctor == null) - { - throw new BlockSpecializationException("Specialized block constructor does not accept an EGID"); - } - return (T)ctor.Invoke(new object[] { Id }); + + //Lets improve that using delegates + return New(Id.entityID, Id.groupID); } #if DEBUG diff --git a/GamecraftModdingAPI/Blocks/BlockTests.cs b/GamecraftModdingAPI/Blocks/BlockTests.cs index 418fa43..133db5e 100644 --- a/GamecraftModdingAPI/Blocks/BlockTests.cs +++ b/GamecraftModdingAPI/Blocks/BlockTests.cs @@ -30,9 +30,8 @@ namespace GamecraftModdingAPI.Blocks [APITestCase(TestType.EditMode)] public static void TestTextBlock() { - Block newBlock = Block.PlaceNew(BlockIDs.TextBlock, Unity.Mathematics.float3.zero + 1); TextBlock textBlock = null; // Note: the assignment operation is a lambda, which slightly confuses the compiler - Assert.Errorless(() => { textBlock = newBlock.Specialise(); }, "Block.Specialize() raised an exception: ", "Block.Specialize() completed without issue."); + Assert.Errorless(() => { textBlock = Block.PlaceNew(BlockIDs.TextBlock, Unity.Mathematics.float3.zero + 1); }, "Block.PlaceNew() raised an exception: ", "Block.PlaceNew() completed without issue."); if (!Assert.NotNull(textBlock, "Block.Specialize() returned null, possibly because it failed silently.", "Specialized TextBlock is not null.")) return; if (!Assert.NotNull(textBlock.Text, "TextBlock.Text is null, possibly because it failed silently.", "TextBlock.Text is not null.")) return; if (!Assert.NotNull(textBlock.TextBlockId, "TextBlock.TextBlockId is null, possibly because it failed silently.", "TextBlock.TextBlockId is not null.")) return; diff --git a/GamecraftModdingAPI/Blocks/ConsoleBlock.cs b/GamecraftModdingAPI/Blocks/ConsoleBlock.cs index 6d4217d..e132029 100644 --- a/GamecraftModdingAPI/Blocks/ConsoleBlock.cs +++ b/GamecraftModdingAPI/Blocks/ConsoleBlock.cs @@ -12,33 +12,19 @@ namespace GamecraftModdingAPI.Blocks { public class ConsoleBlock : Block { - public static ConsoleBlock PlaceNew(float3 position, - float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, - int uscale = 1, float3 scale = default, Player player = null) + public ConsoleBlock(EGID id): base(id) { - if (PlacementEngine.IsInGame && GameState.IsBuildMode()) - { - EGID id = PlacementEngine.PlaceBlock(BlockIDs.ConsoleBlock, color, darkness, - position, uscale, scale, player, rotation); - return new ConsoleBlock(id); - } - - return null; + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } } - public ConsoleBlock(EGID id): base(id) + public ConsoleBlock(uint id): base(new EGID(id, CommonExclusiveGroups.BUILD_CONSOLE_BLOCK_GROUP)) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } - } - - public ConsoleBlock(uint id): base(new EGID(id, CommonExclusiveGroups.BUILD_CONSOLE_BLOCK_GROUP)) - { - if (!BlockEngine.GetBlockInfoExists(this.Id)) + if (!BlockEngine.GetBlockInfoExists(this.Id)) { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); } } diff --git a/GamecraftModdingAPI/Blocks/Motor.cs b/GamecraftModdingAPI/Blocks/Motor.cs index 55f3649..fde2920 100644 --- a/GamecraftModdingAPI/Blocks/Motor.cs +++ b/GamecraftModdingAPI/Blocks/Motor.cs @@ -11,29 +11,6 @@ namespace GamecraftModdingAPI.Blocks { public class Motor : Block { - /// - /// Places a new motor. - /// Any valid motor type is accepted. - /// This re-implements Block.PlaceNew(...) - /// - public static new Motor PlaceNew(BlockIDs block, float3 position, - float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, - int uscale = 1, float3 scale = default, Player player = null) - { - if (!(block == BlockIDs.MotorS || block == BlockIDs.MotorM)) - { - throw new BlockTypeException($"Block is not a {typeof(Motor).Name} block"); - } - if (PlacementEngine.IsInGame && GameState.IsBuildMode()) - { - EGID id = PlacementEngine.PlaceBlock(block, color, darkness, - position, uscale, scale, player, rotation); - return new Motor(id); - } - - return null; - } - public Motor(EGID id) : base(id) { if (!BlockEngine.GetBlockInfoExists(this.Id)) diff --git a/GamecraftModdingAPI/Blocks/Piston.cs b/GamecraftModdingAPI/Blocks/Piston.cs index b96a806..2586b60 100644 --- a/GamecraftModdingAPI/Blocks/Piston.cs +++ b/GamecraftModdingAPI/Blocks/Piston.cs @@ -11,30 +11,7 @@ namespace GamecraftModdingAPI.Blocks { public class Piston : Block { - /// - /// Places a new piston. - /// Any valid piston type is accepted. - /// This re-implements Block.PlaceNew(...) - /// - public static new Piston PlaceNew(BlockIDs block, float3 position, - float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, - int uscale = 1, float3 scale = default, Player player = null) - { - if (!(block == BlockIDs.ServoPiston || block == BlockIDs.StepperPiston || block == BlockIDs.PneumaticPiston)) - { - throw new BlockTypeException($"Block is not a {typeof(Piston).Name} block"); - } - if (PlacementEngine.IsInGame && GameState.IsBuildMode()) - { - EGID id = PlacementEngine.PlaceBlock(block, color, darkness, - position, uscale, scale, player, rotation); - return new Piston(id); - } - - return null; - } - - public Piston(EGID id) : base(id) + public Piston(EGID id) : base(id) { if (!BlockEngine.GetBlockInfoExists(this.Id)) { diff --git a/GamecraftModdingAPI/Blocks/Servo.cs b/GamecraftModdingAPI/Blocks/Servo.cs index ef7225b..c4b57fb 100644 --- a/GamecraftModdingAPI/Blocks/Servo.cs +++ b/GamecraftModdingAPI/Blocks/Servo.cs @@ -11,29 +11,6 @@ namespace GamecraftModdingAPI.Blocks { public class Servo : Block { - /// - /// Places a new servo. - /// Any valid servo type is accepted. - /// This re-implements Block.PlaceNew(...) - /// - public static new Servo PlaceNew(BlockIDs block, float3 position, - float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, - int uscale = 1, float3 scale = default, Player player = null) - { - if (!(block == BlockIDs.ServoAxle || block == BlockIDs.ServoHinge || block == BlockIDs.ServoPiston)) - { - throw new BlockTypeException($"Block is not a {nameof(Servo)} block"); - } - if (PlacementEngine.IsInGame && GameState.IsBuildMode()) - { - EGID id = PlacementEngine.PlaceBlock(block, color, darkness, - position, uscale, scale, player, rotation); - return new Servo(id); - } - - return null; - } - public Servo(EGID id) : base(id) { if (!BlockEngine.GetBlockInfoExists(this.Id)) diff --git a/GamecraftModdingAPI/Blocks/SignalingBlock.cs b/GamecraftModdingAPI/Blocks/SignalingBlock.cs index f8006f6..8a62d64 100644 --- a/GamecraftModdingAPI/Blocks/SignalingBlock.cs +++ b/GamecraftModdingAPI/Blocks/SignalingBlock.cs @@ -14,25 +14,6 @@ namespace GamecraftModdingAPI.Blocks /// public class SignalingBlock : Block { - /// - /// Places a new signaling block. - /// Any valid functional block type with IO ports will work. - /// This re-implements Block.PlaceNew(...) - /// - public static new SignalingBlock PlaceNew(BlockIDs block, float3 position, - float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, - int uscale = 1, float3 scale = default, Player player = null) - { - if (PlacementEngine.IsInGame && GameState.IsBuildMode()) - { - EGID id = PlacementEngine.PlaceBlock(block, color, darkness, - position, uscale, scale, player, rotation); - return new SignalingBlock(id); - } - - return null; - } - public SignalingBlock(EGID id) : base(id) { if (!BlockEngine.GetBlockInfoExists(this.Id)) diff --git a/GamecraftModdingAPI/Blocks/SpawnPoint.cs b/GamecraftModdingAPI/Blocks/SpawnPoint.cs index 65ef750..4419e38 100644 --- a/GamecraftModdingAPI/Blocks/SpawnPoint.cs +++ b/GamecraftModdingAPI/Blocks/SpawnPoint.cs @@ -13,30 +13,7 @@ namespace GamecraftModdingAPI.Blocks { public class SpawnPoint : Block { - /// - /// Places a new spawn point. - /// Any valid spawn block type is accepted. - /// This re-implements Block.PlaceNew(...) - /// - public static new SpawnPoint PlaceNew(BlockIDs block, float3 position, - float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, - int uscale = 1, float3 scale = default, Player player = null) - { - if (!(block == BlockIDs.LargeSpawn || block == BlockIDs.SmallSpawn || block == BlockIDs.MediumSpawn || block == BlockIDs.PlayerSpawn)) - { - throw new BlockTypeException($"Block is not a {nameof(SpawnPoint)} block"); - } - if (PlacementEngine.IsInGame && GameState.IsBuildMode()) - { - EGID id = PlacementEngine.PlaceBlock(block, color, darkness, - position, uscale, scale, player, rotation); - return new SpawnPoint(id); - } - - return null; - } - - public SpawnPoint(EGID id) : base(id) + public SpawnPoint(EGID id) : base(id) { if (!BlockEngine.GetBlockInfoExists(this.Id)) { diff --git a/GamecraftModdingAPI/Blocks/TextBlock.cs b/GamecraftModdingAPI/Blocks/TextBlock.cs index c1a9344..94cf212 100644 --- a/GamecraftModdingAPI/Blocks/TextBlock.cs +++ b/GamecraftModdingAPI/Blocks/TextBlock.cs @@ -12,21 +12,6 @@ namespace GamecraftModdingAPI.Blocks { public class TextBlock : Block { - - public static TextBlock PlaceNew(float3 position, - float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, - int uscale = 1, float3 scale = default, Player player = null) - { - if (PlacementEngine.IsInGame && GameState.IsBuildMode()) - { - EGID id = PlacementEngine.PlaceBlock(BlockIDs.TextBlock, color, darkness, - position, uscale, scale, player, rotation); - return new TextBlock(id); - } - - return null; - } - public TextBlock(EGID id) : base(id) { if (!BlockEngine.GetBlockInfoExists(this.Id)) diff --git a/GamecraftModdingAPI/Blocks/Timer.cs b/GamecraftModdingAPI/Blocks/Timer.cs index 0e7f744..2acab5b 100644 --- a/GamecraftModdingAPI/Blocks/Timer.cs +++ b/GamecraftModdingAPI/Blocks/Timer.cs @@ -13,23 +13,6 @@ namespace GamecraftModdingAPI.Blocks { public class Timer : Block { - /// - /// Places a new timer block. - /// - public static Timer PlaceNew(float3 position, - float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, - int uscale = 1, float3 scale = default, Player player = null) - { - if (PlacementEngine.IsInGame && GameState.IsBuildMode()) - { - EGID id = PlacementEngine.PlaceBlock(BlockIDs.Timer, color, darkness, - position, uscale, scale, player, rotation); - return new Timer(id); - } - - return null; - } - public Timer(EGID id) : base(id) { if (!BlockEngine.GetBlockInfoExists(this.Id)) diff --git a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs index fa65ebb..d5cf714 100644 --- a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs +++ b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs @@ -232,6 +232,28 @@ namespace GamecraftModdingAPI.Tests } }).Build(); + CommandBuilder.Builder() + .Name("PlaceConsole") + .Description("Place a bunch of console block with a given text") + .Action((float x, float y, float z) => + { + Stopwatch sw = new Stopwatch(); + sw.Start(); + for (int i = 0; i < 100; i++) + { + for (int j = 0; j < 100; j++) + { + var block = Block.PlaceNew(BlockIDs.ConsoleBlock, + new float3(x + i, y, z + j)); + block.Command = "test_command"; + } + } + + sw.Stop(); + Logging.CommandLog($"Blocks placed in {sw.ElapsedMilliseconds} ms"); + }) + .Build(); + GameClient.SetDebugInfo("InstalledMods", InstalledMods); Block.Placed += (sender, args) => Logging.MetaDebugLog("Placed block " + args.Type + " with ID " + args.ID); From 3592c6f464abde1588a184af34a5f5a36d7b84b4 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 15 Jul 2020 21:58:24 +0200 Subject: [PATCH 02/32] Add support for initializing blocks with properties Newly created blocks use the initializer to set properties, allowing the user to set per-block properties --- GamecraftModdingAPI/Block.cs | 76 ++++++++-------- GamecraftModdingAPI/Blocks/BlockEngine.cs | 89 +++++++------------ GamecraftModdingAPI/Blocks/BlockEngineInit.cs | 46 ++++++++++ .../Blocks/BlockEventsEngine.cs | 52 ++++++++++- GamecraftModdingAPI/Blocks/BlockIDs.cs | 2 +- GamecraftModdingAPI/Blocks/ConsoleBlock.cs | 40 ++++----- GamecraftModdingAPI/Blocks/Motor.cs | 23 ++--- .../Blocks/ObjectIdentifier.cs | 19 ++-- GamecraftModdingAPI/Blocks/Piston.cs | 23 ++--- GamecraftModdingAPI/Blocks/PlacementEngine.cs | 9 +- GamecraftModdingAPI/Blocks/Servo.cs | 48 ++++------ GamecraftModdingAPI/Blocks/SignalingBlock.cs | 27 ++---- GamecraftModdingAPI/Blocks/SpawnPoint.cs | 64 +++++-------- GamecraftModdingAPI/Blocks/TextBlock.cs | 53 +++++------ GamecraftModdingAPI/Blocks/Timer.cs | 68 +++++--------- 15 files changed, 301 insertions(+), 338 deletions(-) create mode 100644 GamecraftModdingAPI/Blocks/BlockEngineInit.cs diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 673ef49..c3e0393 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -55,13 +55,7 @@ namespace GamecraftModdingAPI float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, int uscale = 1, float3 scale = default, Player player = null) { - if (PlacementEngine.IsInGame && GameState.IsBuildMode()) - { - return new Block(PlacementEngine.PlaceBlock(block, color, darkness, - position, uscale, scale, player, rotation)); - } - - return null; + return PlaceNew(block, position, rotation, color, darkness, uscale, scale, player); } /// @@ -85,8 +79,10 @@ namespace GamecraftModdingAPI if (PlacementEngine.IsInGame && GameState.IsBuildMode()) { var egid = PlacementEngine.PlaceBlock(block, color, darkness, - position, uscale, scale, player, rotation); - return New(egid.entityID, egid.groupID); + position, uscale, scale, player, rotation, out var initializer); + var bl = New(egid.entityID, egid.groupID); + bl.InitData.Group = BlockEngine.InitGroup(initializer); + return bl; } return null; @@ -205,6 +201,8 @@ namespace GamecraftModdingAPI public EGID Id { get; } + internal BlockEngine.BlockInitData InitData; + /// /// The block's current position or zero if the block no longer exists. /// A block is 0.2 wide by default in terms of position. @@ -236,12 +234,11 @@ namespace GamecraftModdingAPI /// public float3 Scale { - get => BlockEngine.GetBlockInfo(Id).scale; + get => BlockEngine.GetBlockInfo(this, (ScalingEntityStruct st) => st.scale); set { + BlockEngine.SetBlockInfo(this, (ref ScalingEntityStruct st, float3 val) => st.scale = val, value); if (!Exists) return; //UpdateCollision needs the block to exist - ref var scaling = ref BlockEngine.GetBlockInfo(Id); - scaling.scale = value; ScalingEngine.UpdateCollision(Id); } } @@ -252,11 +249,11 @@ namespace GamecraftModdingAPI /// public int UniformScale { - get => BlockEngine.GetBlockInfo(Id).scaleFactor; + get => BlockEngine.GetBlockInfo(this, (UniformBlockScaleEntityStruct st) => st.scaleFactor); set { - ref var scaleStruct = ref BlockEngine.GetBlockInfo(Id); - scaleStruct.scaleFactor = value; + BlockEngine.SetBlockInfo(this, (ref UniformBlockScaleEntityStruct st, int val) => st.scaleFactor = val, + value); Scale = new float3(value, value, value); } } @@ -268,8 +265,7 @@ namespace GamecraftModdingAPI { get { - var id = (BlockIDs) BlockEngine.GetBlockInfo(Id, out var exists).DBID; - return exists ? id : BlockIDs.Invalid; + return BlockEngine.GetBlockInfo(this, (DBEntityStruct st) => (BlockIDs) st.DBID, BlockIDs.Invalid); } } @@ -280,17 +276,19 @@ namespace GamecraftModdingAPI { get { - byte index = BlockEngine.GetBlockInfo(Id, out var exists).indexInPalette; - if (!exists) index = byte.MaxValue; + byte index = BlockEngine.GetBlockInfo(this, (ColourParameterEntityStruct st) => st.indexInPalette, + byte.MaxValue); return new BlockColor(index); } set { - ref var color = ref BlockEngine.GetBlockInfo(Id); - color.indexInPalette = (byte)(value.Color + value.Darkness * 10); - color.overridePaletteColour = false; - color.needsUpdate = true; - BlockEngine.SetBlockColorFromPalette(ref color); + BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, BlockColor val) => + { + color.indexInPalette = (byte) (val.Color + val.Darkness * 10); + color.overridePaletteColour = false; + color.needsUpdate = true; + BlockEngine.SetBlockColorFromPalette(ref color); + }, value); } } @@ -299,27 +297,31 @@ namespace GamecraftModdingAPI /// public float4 CustomColor { - get => BlockEngine.GetBlockInfo(Id).overriddenColour; + get => BlockEngine.GetBlockInfo(this, (ColourParameterEntityStruct st) => st.overriddenColour); set { - ref var color = ref BlockEngine.GetBlockInfo(Id); - color.overriddenColour = value; - color.overridePaletteColour = true; - color.needsUpdate = true; + BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, float4 val) => + { + color.overriddenColour = val; + color.overridePaletteColour = true; + color.needsUpdate = true; + }, value); } } /// - /// The short text displayed on the block if applicable, or null. + /// The text displayed on the block if applicable, or null. /// Setting it is temporary to the session, it won't be saved. /// public string Label { - get => BlockEngine.GetBlockInfo(Id).textLabelComponent?.text; + get => BlockEngine.GetBlockInfo(this, (TextLabelEntityViewStruct st) => st.textLabelComponent?.text); set { - ref var text = ref BlockEngine.GetBlockInfo(Id); - if (text.textLabelComponent != null) text.textLabelComponent.text = value; + BlockEngine.SetBlockInfo(this, (ref TextLabelEntityViewStruct text, string val) => + { + if (text.textLabelComponent != null) text.textLabelComponent.text = val; + }, value); } } @@ -346,8 +348,8 @@ namespace GamecraftModdingAPI /// The SimBody of the cluster or null if the block doesn't exist. public SimBody GetSimBody() { - uint id = BlockEngine.GetBlockInfo(Id, out var exists).machineRigidBodyId; - return exists ? new SimBody(id) : null; + return BlockEngine.GetBlockInfo(this, + (GridConnectionsEntityStruct st) => new SimBody(st.machineRigidBodyId)); } public override string ToString() @@ -404,7 +406,9 @@ namespace GamecraftModdingAPI // So thanks to Microsoft, we've got this horrible implementation using reflection //Lets improve that using delegates - return New(Id.entityID, Id.groupID); + var block = New(Id.entityID, Id.groupID); + block.InitData = this.InitData; + return block; } #if DEBUG diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index 81a1630..d6f4907 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using Gamecraft.Wires; @@ -10,14 +11,13 @@ using Svelto.DataStructures; using Svelto.ECS; using GamecraftModdingAPI.Engines; -using GamecraftModdingAPI.Utility; namespace GamecraftModdingAPI.Blocks { /// /// Engine for executing general block actions /// - public class BlockEngine : IApiEngine + public partial class BlockEngine : IApiEngine { public string Name { get; } = "GamecraftModdingAPIBlockGameEngine"; @@ -61,66 +61,54 @@ namespace GamecraftModdingAPI.Blocks color.paletteColour = paletteEntry.Colour; } - /// - /// Get a struct of a block. Can be used to set properties. - /// Returns a default value if not found. - /// - /// The block's ID - /// The struct to query - /// An editable reference to the struct public ref T GetBlockInfo(EGID blockID) where T : struct, IEntityComponent { - if (!Synced) - { - Sync(); - Synced = true; - } if (entitiesDB.Exists(blockID)) return ref entitiesDB.QueryEntity(blockID); T[] structHolder = new T[1]; //Create something that can be referenced return ref structHolder[0]; //Gets a default value automatically } - /// - /// Get a struct of a block. Can be used to set properties. - /// Returns a default value if not found. - /// - /// The block's ID - /// Whether the specified struct exists for the block - /// The struct to query - /// An editable reference to the struct - public ref T GetBlockInfo(EGID blockID, out bool exists) where T : struct, IEntityComponent + public U GetBlockInfo(Block block, Func getter, + U def = default) where T : struct, IEntityComponent { - if (!Synced) + if (entitiesDB.Exists(block.Id)) + return getter(entitiesDB.QueryEntity(block.Id)); + if (block.InitData.Group == null) return def; + var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group); + if (initializer.Has()) + return getter(initializer.Get()); + return def; + } + + public delegate void Setter(ref T component, U value) where T : struct, IEntityComponent; + + public void SetBlockInfo(Block block, Setter setter, U value) where T : struct, IEntityComponent + { + if (entitiesDB.Exists(block.Id)) + setter(ref entitiesDB.QueryEntity(block.Id), value); + if (block.InitData.Group != null) { - Sync(); - Synced = true; + var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group); + ref T structRef = ref (new T[1])[0]; //A reference for a default value for struct + setter(ref structRef, value); + initializer.Init(structRef); } - exists = entitiesDB.Exists(blockID); - if (exists) - return ref entitiesDB.QueryEntity(blockID); - T[] structHolder = new T[1]; - return ref structHolder[0]; } - public bool BlockExists(EGID id) + public bool BlockExists(EGID blockID) { - if (!Synced) - { - Sync(); - Synced = true; - } - return entitiesDB.Exists(id); + return entitiesDB.Exists(blockID); } - public bool GetBlockInfoExists(EGID blockID) where T : struct, IEntityComponent + public bool GetBlockInfoExists(Block block) where T : struct, IEntityComponent { - if (!Synced) - { - Sync(); - Synced = true; - } - return entitiesDB.Exists(blockID); + if (entitiesDB.Exists(block.Id)) + return true; + if (block.InitData.Group == null) + return false; + var init = new EntityComponentInitializer(block.Id, block.InitData.Group); + return init.Has(); } public SimBody[] GetSimBodiesFromID(byte id) @@ -183,17 +171,6 @@ namespace GamecraftModdingAPI.Blocks return null; } - /// - /// Synchronize newly created entity components with entities DB. - /// This forces a partial game tick, so it may be slow. - /// This also has the potential to make Gamecraft unstable. - /// Use this sparingly. - /// - private static void Sync() - { - DeterministicStepCompositionRootPatch.SubmitEntitiesNow(); - } - #if DEBUG public EntitiesDB GetEntitiesDB() { diff --git a/GamecraftModdingAPI/Blocks/BlockEngineInit.cs b/GamecraftModdingAPI/Blocks/BlockEngineInit.cs new file mode 100644 index 0000000..4be9a98 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/BlockEngineInit.cs @@ -0,0 +1,46 @@ +using System; +using System.Linq.Expressions; + +using Svelto.DataStructures; +using Svelto.ECS; +using Svelto.ECS.Internal; + +namespace GamecraftModdingAPI.Blocks +{ + public partial class BlockEngine + { + internal struct BlockInitData + { + public FasterDictionary, ITypeSafeDictionary> Group; + } + + internal delegate FasterDictionary, ITypeSafeDictionary> GetInitGroup( + EntityComponentInitializer initializer); + + internal GetInitGroup InitGroup = CreateAccessor("_group"); + + //https://stackoverflow.com/questions/55878525/unit-testing-ref-structs-with-private-fields-via-reflection + internal static TDelegate CreateAccessor(string memberName) where TDelegate : Delegate + { + var invokeMethod = typeof(TDelegate).GetMethod("Invoke"); + if (invokeMethod == null) + throw new InvalidOperationException($"{typeof(TDelegate)} signature could not be determined."); + + var delegateParameters = invokeMethod.GetParameters(); + if (delegateParameters.Length != 1) + throw new InvalidOperationException("Delegate must have a single parameter."); + + var paramType = delegateParameters[0].ParameterType; + + var objParam = Expression.Parameter(paramType, "obj"); + var memberExpr = Expression.PropertyOrField(objParam, memberName); + Expression returnExpr = memberExpr; + if (invokeMethod.ReturnType != memberExpr.Type) + returnExpr = Expression.ConvertChecked(memberExpr, invokeMethod.ReturnType); + + var lambda = + Expression.Lambda(returnExpr, $"Access{paramType.Name}_{memberName}", new[] {objParam}); + return lambda.Compile(); + } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs b/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs index 3c34b65..0a205f0 100644 --- a/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs @@ -1,9 +1,11 @@ using System; -using GamecraftModdingAPI.Engines; -using GamecraftModdingAPI.Utility; + using RobocraftX.Common; using Svelto.ECS; +using GamecraftModdingAPI.Engines; +using GamecraftModdingAPI.Utility; + namespace GamecraftModdingAPI.Blocks { public class BlockEventsEngine : IReactionaryEngine @@ -11,11 +13,18 @@ namespace GamecraftModdingAPI.Blocks public event EventHandler Placed; public event EventHandler Removed; + public BlockEventsEngine() + { + //Console.WriteLine("Creating BlockEventsEngine\n" + Environment.StackTrace); + } + public void Ready() { + //Console.WriteLine("BlockEventsEngine registered"); } public EntitiesDB entitiesDB { get; set; } + public void Dispose() { } @@ -23,17 +32,52 @@ namespace GamecraftModdingAPI.Blocks public string Name { get; } = "GamecraftModdingAPIBlockEventsEngine"; public bool isRemovable { get; } = false; + private bool shouldAddRemove; public void Add(ref DBEntityStruct entityComponent, EGID egid) { - ExceptionUtil.InvokeEvent(Placed, this, new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID}); + if (!(shouldAddRemove = !shouldAddRemove)) + return; + ExceptionUtil.InvokeEvent(Placed, this, + new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID}); } public void Remove(ref DBEntityStruct entityComponent, EGID egid) { - ExceptionUtil.InvokeEvent(Removed, this, new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID}); + if (!(shouldAddRemove = !shouldAddRemove)) + return; + ExceptionUtil.InvokeEvent(Removed, this, + new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID}); } } + /*[HarmonyPatch] + public static class TestPatch + { + public static void Postfix(FasterDictionary, FasterList> engines, + ExclusiveGroupStruct? previousGroup, in PlatformProfiler profiler, EGID egid) + { + if (!engines.TryGetValue(new RefWrapper(TypeSafeDictionary._type), out result)) + return; + } + public static MethodBase TargetMethod() + { + return AccessTools.Method("Svelto.ECS.Internal.TypeSafeDictionary:AddEntityComponentToEngines"); + } + }*/ + + /*[HarmonyPatch] + public static class TestPatch + { + public static void Postfix(EGID basePartEGID) + { + Console.WriteLine("Patched Add method: " + basePartEGID); + } + public static MethodBase TargetMethod() + { + return AccessTools.Method("RobocraftX.CR.MachineEditing.BuildBlockAdditionalPartEngine:Add"); + } + }*/ + public struct BlockPlacedRemovedEventArgs { public EGID ID; diff --git a/GamecraftModdingAPI/Blocks/BlockIDs.cs b/GamecraftModdingAPI/Blocks/BlockIDs.cs index b0eca31..596fb38 100644 --- a/GamecraftModdingAPI/Blocks/BlockIDs.cs +++ b/GamecraftModdingAPI/Blocks/BlockIDs.cs @@ -6,7 +6,7 @@ namespace GamecraftModdingAPI.Blocks public enum BlockIDs : ushort { /// - /// A custom value for the API. Doesn't exist for Gamecraft. + /// Called "nothing" in Gamecraft. (DBID.NOTHING) /// Invalid = ushort.MaxValue, AluminiumCube = 0, diff --git a/GamecraftModdingAPI/Blocks/ConsoleBlock.cs b/GamecraftModdingAPI/Blocks/ConsoleBlock.cs index e132029..4425a1e 100644 --- a/GamecraftModdingAPI/Blocks/ConsoleBlock.cs +++ b/GamecraftModdingAPI/Blocks/ConsoleBlock.cs @@ -14,18 +14,10 @@ namespace GamecraftModdingAPI.Blocks { public ConsoleBlock(EGID id): base(id) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } public ConsoleBlock(uint id): base(new EGID(id, CommonExclusiveGroups.BUILD_CONSOLE_BLOCK_GROUP)) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } // custom console block properties @@ -34,43 +26,47 @@ namespace GamecraftModdingAPI.Blocks { get { - return BlockEngine.GetBlockInfo(Id).commandName; + return BlockEngine.GetBlockInfo(this, (ConsoleBlockEntityStruct st) => st.commandName); } set { - BlockEngine.GetBlockInfo(Id).commandName.Set(value); + BlockEngine.SetBlockInfo(this, (ref ConsoleBlockEntityStruct st, string val) => st.commandName.Set(val), + value); } } public string Arg1 { - get => BlockEngine.GetBlockInfo(Id).arg1; + get => BlockEngine.GetBlockInfo(this, (ConsoleBlockEntityStruct st) => st.arg1); set { - BlockEngine.GetBlockInfo(Id).arg1.Set(value); + BlockEngine.SetBlockInfo(this, (ref ConsoleBlockEntityStruct st, string val) => st.arg1.Set(val), + value); } } public string Arg2 { - get => BlockEngine.GetBlockInfo(Id).arg2; + get => BlockEngine.GetBlockInfo(this, (ConsoleBlockEntityStruct st) => st.arg2); - set - { - BlockEngine.GetBlockInfo(Id).arg2.Set(value); - } + set + { + BlockEngine.SetBlockInfo(this, (ref ConsoleBlockEntityStruct st, string val) => st.arg2.Set(val), + value); + } } public string Arg3 { - get => BlockEngine.GetBlockInfo(Id).arg3; + get => BlockEngine.GetBlockInfo(this, (ConsoleBlockEntityStruct st) => st.arg3); - set - { - BlockEngine.GetBlockInfo(Id).arg3.Set(value); - } + set + { + BlockEngine.SetBlockInfo(this, (ref ConsoleBlockEntityStruct st, string val) => st.arg3.Set(val), + value); + } } } } diff --git a/GamecraftModdingAPI/Blocks/Motor.cs b/GamecraftModdingAPI/Blocks/Motor.cs index fde2920..fdadd26 100644 --- a/GamecraftModdingAPI/Blocks/Motor.cs +++ b/GamecraftModdingAPI/Blocks/Motor.cs @@ -13,18 +13,10 @@ namespace GamecraftModdingAPI.Blocks { public Motor(EGID id) : base(id) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } public Motor(uint id): base(new EGID(id, CommonExclusiveGroups.BUILD_MOTOR_BLOCK_GROUP)) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } // custom motor properties @@ -36,13 +28,12 @@ namespace GamecraftModdingAPI.Blocks { get { - return BlockEngine.GetBlockInfo(Id).maxVelocity; + return BlockEngine.GetBlockInfo(this, (MotorReadOnlyStruct st) => st.maxVelocity); } set { - ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo(Id); - motor.maxVelocity = value; + BlockEngine.SetBlockInfo(this, (ref MotorReadOnlyStruct st, float val) => st.maxVelocity = val, value); } } @@ -53,13 +44,12 @@ namespace GamecraftModdingAPI.Blocks { get { - return BlockEngine.GetBlockInfo(Id).maxForce; + return BlockEngine.GetBlockInfo(this, (MotorReadOnlyStruct st) => st.maxForce); } set { - ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo(Id); - motor.maxForce = value; + BlockEngine.SetBlockInfo(this, (ref MotorReadOnlyStruct st, float val) => st.maxForce = val, value); } } @@ -70,13 +60,12 @@ namespace GamecraftModdingAPI.Blocks { get { - return BlockEngine.GetBlockInfo(Id).reverse; + return BlockEngine.GetBlockInfo(this, (MotorReadOnlyStruct st) => st.reverse); } set { - ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo(Id); - motor.reverse = value; + BlockEngine.SetBlockInfo(this, (ref MotorReadOnlyStruct st, bool val) => st.reverse = val, value); } } } diff --git a/GamecraftModdingAPI/Blocks/ObjectIdentifier.cs b/GamecraftModdingAPI/Blocks/ObjectIdentifier.cs index 9af96c2..0dc835a 100644 --- a/GamecraftModdingAPI/Blocks/ObjectIdentifier.cs +++ b/GamecraftModdingAPI/Blocks/ObjectIdentifier.cs @@ -8,27 +8,22 @@ namespace GamecraftModdingAPI.Blocks { public ObjectIdentifier(EGID id) : base(id) { - if (!BlockEngine.GetBlockInfoExists(Id)) - { - throw new BlockTypeException($"Block is not a {GetType().Name} block"); - } } public ObjectIdentifier(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP)) { - if (!BlockEngine.GetBlockInfoExists(Id)) - { - throw new BlockTypeException($"Block is not a {GetType().Name} block"); - } } public char Identifier { - get => (char) (BlockEngine.GetBlockInfo(Id).objectId + 'A'); + get => (char) BlockEngine.GetBlockInfo(this, (ObjectIdEntityStruct st) => st.objectId + 'A'); set { - BlockEngine.GetBlockInfo(Id).objectId = (byte) (value - 'A'); - Label = value + ""; //The label isn't updated automatically + BlockEngine.SetBlockInfo(this, (ref ObjectIdEntityStruct st, char val) => + { + st.objectId = (byte) (val - 'A'); + Label = val + ""; //The label isn't updated automatically + }, value); } } @@ -37,7 +32,7 @@ namespace GamecraftModdingAPI.Blocks /// public byte SimID { - get => BlockEngine.GetBlockInfo(Id).simObjectId; + get => BlockEngine.GetBlockInfo(this, (ObjectIdEntityStruct st) => st.simObjectId); } /// diff --git a/GamecraftModdingAPI/Blocks/Piston.cs b/GamecraftModdingAPI/Blocks/Piston.cs index 2586b60..aed8c33 100644 --- a/GamecraftModdingAPI/Blocks/Piston.cs +++ b/GamecraftModdingAPI/Blocks/Piston.cs @@ -13,18 +13,10 @@ namespace GamecraftModdingAPI.Blocks { public Piston(EGID id) : base(id) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } public Piston(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_PISTON_BLOCK_GROUP)) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } // custom piston properties @@ -33,13 +25,13 @@ namespace GamecraftModdingAPI.Blocks /// The piston's max extension distance. /// public float MaximumExtension - { - get => BlockEngine.GetBlockInfo(Id).maxDeviation; + { + get => BlockEngine.GetBlockInfo(this, (PistonReadOnlyStruct st) => st.maxDeviation); set { - ref PistonReadOnlyStruct piston = ref BlockEngine.GetBlockInfo(Id); - piston.maxDeviation = value; + BlockEngine.SetBlockInfo(this, (ref PistonReadOnlyStruct st, float val) => st.maxDeviation = val, + value); } } @@ -47,13 +39,12 @@ namespace GamecraftModdingAPI.Blocks /// The piston's max extension force. /// public float MaximumForce - { - get => BlockEngine.GetBlockInfo(Id).maxForce; + { + get => BlockEngine.GetBlockInfo(this, (PistonReadOnlyStruct st) => st.maxForce); set { - ref PistonReadOnlyStruct piston = ref BlockEngine.GetBlockInfo(Id); - piston.maxForce = value; + BlockEngine.SetBlockInfo(this, (ref PistonReadOnlyStruct st, float val) => st.maxForce = val, value); } } } diff --git a/GamecraftModdingAPI/Blocks/PlacementEngine.cs b/GamecraftModdingAPI/Blocks/PlacementEngine.cs index 2297d90..61834b0 100644 --- a/GamecraftModdingAPI/Blocks/PlacementEngine.cs +++ b/GamecraftModdingAPI/Blocks/PlacementEngine.cs @@ -40,15 +40,16 @@ namespace GamecraftModdingAPI.Blocks private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine public EGID PlaceBlock(BlockIDs block, BlockColors color, byte darkness, float3 position, int uscale, - float3 scale, Player player, float3 rotation) + float3 scale, Player player, float3 rotation, out EntityComponentInitializer initializer) { //It appears that only the non-uniform scale has any visible effect, but if that's not given here it will be set to the uniform one if (darkness > 9) throw new Exception("That is too dark. Make sure to use 0-9 as darkness. (0 is default.)"); - return BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation, + initializer = BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation, (player ?? new Player(PlayerType.Local)).Id); + return initializer.EGID; } - private EGID BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot, uint playerId) + private EntityComponentInitializer BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot, uint playerId) { if (_blockEntityFactory == null) throw new Exception("The factory is null."); @@ -107,7 +108,7 @@ namespace GamecraftModdingAPI.Blocks pickedBlock.placedBlockEntityID = structInitializer.EGID; pickedBlock.placedBlockWasAPickedBlock = false; Block.BlockEngine.Synced = false; // Block entities will need to be submitted before properties can be used - return structInitializer.EGID; + return structInitializer; } public string Name { get; } = "GamecraftModdingAPIPlacementGameEngine"; diff --git a/GamecraftModdingAPI/Blocks/Servo.cs b/GamecraftModdingAPI/Blocks/Servo.cs index c4b57fb..730749a 100644 --- a/GamecraftModdingAPI/Blocks/Servo.cs +++ b/GamecraftModdingAPI/Blocks/Servo.cs @@ -13,18 +13,10 @@ namespace GamecraftModdingAPI.Blocks { public Servo(EGID id) : base(id) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } public Servo(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_SERVO_BLOCK_GROUP)) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } // custom servo properties @@ -33,13 +25,12 @@ namespace GamecraftModdingAPI.Blocks /// The servo's minimum angle. /// public float MinimumAngle - { - get => BlockEngine.GetBlockInfo(Id).minDeviation; + { + get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.minDeviation); set { - ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo(Id); - servo.minDeviation = value; + BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, float val) => st.minDeviation = val, value); } } @@ -48,13 +39,12 @@ namespace GamecraftModdingAPI.Blocks /// public float MaximumAngle { - get => BlockEngine.GetBlockInfo(Id).maxDeviation; + get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.maxDeviation); - set - { - ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo(Id); - servo.maxDeviation = value; - } + set + { + BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, float val) => st.maxDeviation = val, value); + } } /// @@ -62,13 +52,12 @@ namespace GamecraftModdingAPI.Blocks /// public float MaximumForce { - get => BlockEngine.GetBlockInfo(Id).maxForce; + get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.maxForce); - set - { - ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo(Id); - servo.maxForce = value; - } + set + { + BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, float val) => st.maxForce = val, value); + } } /// @@ -76,13 +65,12 @@ namespace GamecraftModdingAPI.Blocks /// public bool Reverse { - get => BlockEngine.GetBlockInfo(Id).reverse; + get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.reverse); - set - { - ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo(Id); - servo.reverse = value; - } + set + { + BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, bool val) => st.reverse = val, value); + } } } } diff --git a/GamecraftModdingAPI/Blocks/SignalingBlock.cs b/GamecraftModdingAPI/Blocks/SignalingBlock.cs index 8a62d64..149e450 100644 --- a/GamecraftModdingAPI/Blocks/SignalingBlock.cs +++ b/GamecraftModdingAPI/Blocks/SignalingBlock.cs @@ -16,7 +16,7 @@ namespace GamecraftModdingAPI.Blocks { public SignalingBlock(EGID id) : base(id) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) + if (!BlockEngine.GetBlockInfoExists(this)) { throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); } @@ -24,17 +24,12 @@ namespace GamecraftModdingAPI.Blocks public SignalingBlock(uint id) : base(id) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) + if (!BlockEngine.GetBlockInfoExists(this)) { throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); } } - protected ref BlockPortsStruct GetBlockPortsStruct() - { - return ref BlockEngine.GetBlockInfo(Id); - } - /// /// Generates the input port identifiers. /// @@ -53,16 +48,6 @@ namespace GamecraftModdingAPI.Blocks return SignalEngine.GetSignalOutputs(Id); } - /// - /// Gets the port struct. - /// - /// The port struct. - /// Port identifier. - protected ref PortEntityStruct GetPortStruct(EGID portId) - { - return ref BlockEngine.GetBlockInfo(portId); - } - /// /// Gets the connected wire. /// @@ -89,16 +74,16 @@ namespace GamecraftModdingAPI.Blocks /// The input port count. /// public uint InputCount - { - get => GetBlockPortsStruct().inputCount; - } + { + get => BlockEngine.GetBlockInfo(this, (BlockPortsStruct st) => st.inputCount); + } /// /// The output port count. /// public uint OutputCount { - get => GetBlockPortsStruct().outputCount; + get => BlockEngine.GetBlockInfo(this, (BlockPortsStruct st) => st.outputCount); } } } diff --git a/GamecraftModdingAPI/Blocks/SpawnPoint.cs b/GamecraftModdingAPI/Blocks/SpawnPoint.cs index 4419e38..7616acb 100644 --- a/GamecraftModdingAPI/Blocks/SpawnPoint.cs +++ b/GamecraftModdingAPI/Blocks/SpawnPoint.cs @@ -15,18 +15,10 @@ namespace GamecraftModdingAPI.Blocks { public SpawnPoint(EGID id) : base(id) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } public SpawnPoint(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_SPAWNPOINT_BLOCK_GROUP)) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } // custom spawn point properties @@ -36,16 +28,12 @@ namespace GamecraftModdingAPI.Blocks /// public uint Lives { - get - { - return BlockEngine.GetBlockInfo(Id).lives; - } + get => BlockEngine.GetBlockInfo(this, (SpawnPointStatsEntityStruct st) => st.lives); - set - { - ref SpawnPointStatsEntityStruct spses = ref BlockEngine.GetBlockInfo(Id); - spses.lives = value; - } + set + { + BlockEngine.SetBlockInfo(this, (ref SpawnPointStatsEntityStruct st, uint val) => st.lives = val, value); + } } /// @@ -53,16 +41,12 @@ namespace GamecraftModdingAPI.Blocks /// public bool Damageable { - get - { - return BlockEngine.GetBlockInfo(Id).canTakeDamage; - } + get => BlockEngine.GetBlockInfo(this, (SpawnPointStatsEntityStruct st) => st.canTakeDamage); - set - { - ref SpawnPointStatsEntityStruct spses = ref BlockEngine.GetBlockInfo(Id); - spses.canTakeDamage = value; - } + set + { + BlockEngine.SetBlockInfo(this, (ref SpawnPointStatsEntityStruct st, bool val) => st.canTakeDamage = val, value); + } } /// @@ -70,16 +54,12 @@ namespace GamecraftModdingAPI.Blocks /// public bool GameOverEnabled { - get - { - return BlockEngine.GetBlockInfo(Id).gameOverScreen; - } + get => BlockEngine.GetBlockInfo(this, (SpawnPointStatsEntityStruct st) => st.gameOverScreen); - set - { - ref SpawnPointStatsEntityStruct spses = ref BlockEngine.GetBlockInfo(Id); - spses.gameOverScreen = value; - } + set + { + BlockEngine.SetBlockInfo(this, (ref SpawnPointStatsEntityStruct st, bool val) => st.gameOverScreen = val, value); + } } /// @@ -87,16 +67,12 @@ namespace GamecraftModdingAPI.Blocks /// public byte Team { - get - { - return BlockEngine.GetBlockInfo(Id).teamId; - } + get => BlockEngine.GetBlockInfo(this, (SpawnPointIdsEntityStruct st) => st.teamId); - set - { - ref SpawnPointIdsEntityStruct spses = ref BlockEngine.GetBlockInfo(Id); - spses.teamId = value; - } + set + { + BlockEngine.SetBlockInfo(this, (ref SpawnPointIdsEntityStruct st, byte val) => st.teamId = val, value); + } } } } diff --git a/GamecraftModdingAPI/Blocks/TextBlock.cs b/GamecraftModdingAPI/Blocks/TextBlock.cs index 94cf212..6096dd4 100644 --- a/GamecraftModdingAPI/Blocks/TextBlock.cs +++ b/GamecraftModdingAPI/Blocks/TextBlock.cs @@ -14,18 +14,10 @@ namespace GamecraftModdingAPI.Blocks { public TextBlock(EGID id) : base(id) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } public TextBlock(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_TEXT_BLOCK_GROUP)) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } // custom text block properties @@ -35,35 +27,34 @@ namespace GamecraftModdingAPI.Blocks /// public string Text { - get - { - return BlockEngine.GetBlockInfo(Id).textCurrent; - } + get => BlockEngine.GetBlockInfo(this, (TextBlockDataStruct st) => st.textCurrent); - set - { - ref TextBlockDataStruct tbds = ref BlockEngine.GetBlockInfo(Id); - tbds.textCurrent.Set(value); - tbds.textStored.Set(value); - BlockEngine.GetBlockInfo(Id).newTextBlockStringContent.Set(value); - } - } + set + { + BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) => + { + tbds.textCurrent.Set(val); + tbds.textStored.Set(val); + }, value); + BlockEngine.SetBlockInfo(this, + (ref TextBlockNetworkDataStruct st, string val) => st.newTextBlockStringContent.Set(val), value); + } + } /// - /// The text block's current text block ID (used in ChangeTextBlockCommand). + /// The text block's current text block ID (used in ChangeTextBlockCommand). /// - public string TextBlockId + public string TextBlockId { - get - { - return BlockEngine.GetBlockInfo(Id).textBlockID; - } + get => BlockEngine.GetBlockInfo(this, (TextBlockDataStruct st) => st.textBlockID); - set - { - BlockEngine.GetBlockInfo(Id).textBlockID.Set(value); - BlockEngine.GetBlockInfo(Id).newTextBlockID.Set(value); - } + set + { + BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) => + tbds.textBlockID.Set(val), value); + BlockEngine.SetBlockInfo(this, + (ref TextBlockNetworkDataStruct st, string val) => st.newTextBlockID.Set(val), value); + } } } } diff --git a/GamecraftModdingAPI/Blocks/Timer.cs b/GamecraftModdingAPI/Blocks/Timer.cs index 2acab5b..5766a41 100644 --- a/GamecraftModdingAPI/Blocks/Timer.cs +++ b/GamecraftModdingAPI/Blocks/Timer.cs @@ -15,18 +15,10 @@ namespace GamecraftModdingAPI.Blocks { public Timer(EGID id) : base(id) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } public Timer(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_TIMER_BLOCK_GROUP)) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } // custom timer properties @@ -36,16 +28,13 @@ namespace GamecraftModdingAPI.Blocks /// public float Start { - get - { - return BlockEngine.GetBlockInfo(Id).startTime; - } + get => BlockEngine.GetBlockInfo(this, (TimerBlockDataStruct st) => st.startTime); - set - { - ref TimerBlockDataStruct tbds = ref BlockEngine.GetBlockInfo(Id); - tbds.startTime = value; - } + set + { + BlockEngine.SetBlockInfo(this, (ref TimerBlockDataStruct tbds, float val) => tbds.startTime = val, + value); + } } /// @@ -53,16 +42,13 @@ namespace GamecraftModdingAPI.Blocks /// public float End { - get - { - return BlockEngine.GetBlockInfo(Id).endTime; - } + get => BlockEngine.GetBlockInfo(this, (TimerBlockDataStruct st) => st.endTime); - set - { - ref TimerBlockDataStruct tbds = ref BlockEngine.GetBlockInfo(Id); - tbds.endTime = value; - } + set + { + BlockEngine.SetBlockInfo(this, (ref TimerBlockDataStruct tbds, float val) => tbds.endTime = val, + value); + } } /// @@ -70,16 +56,13 @@ namespace GamecraftModdingAPI.Blocks /// public bool DisplayMilliseconds { - get - { - return BlockEngine.GetBlockInfo(Id).outputFormatHasMS; - } + get => BlockEngine.GetBlockInfo(this, (TimerBlockDataStruct st) => st.outputFormatHasMS); - set - { - ref TimerBlockDataStruct tbds = ref BlockEngine.GetBlockInfo(Id); - tbds.outputFormatHasMS = value; - } + set + { + BlockEngine.SetBlockInfo(this, (ref TimerBlockDataStruct tbds, bool val) => tbds.outputFormatHasMS = val, + value); + } } /// @@ -87,16 +70,13 @@ namespace GamecraftModdingAPI.Blocks /// public int CurrentTime { - get - { - return BlockEngine.GetBlockInfo(Id).timeLastRenderFrameMS; - } + get => BlockEngine.GetBlockInfo(this, (TimerBlockLabelCacheEntityStruct st) => st.timeLastRenderFrameMS); - set - { - ref TimerBlockLabelCacheEntityStruct tblces = ref BlockEngine.GetBlockInfo(Id); - tblces.timeLastRenderFrameMS = value; - } + set + { + BlockEngine.SetBlockInfo(this, (ref TimerBlockLabelCacheEntityStruct tbds, int val) => tbds.timeLastRenderFrameMS = val, + value); + } } } } From d842df7681206f6c30e16fb098a912e971b47f19 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 15 Jul 2020 22:46:48 +0200 Subject: [PATCH 03/32] Implement init for position and rotation --- GamecraftModdingAPI/Block.cs | 8 ++--- GamecraftModdingAPI/Blocks/ConsoleBlock.cs | 3 ++ GamecraftModdingAPI/Blocks/MovementEngine.cs | 19 ++++++++-- GamecraftModdingAPI/Blocks/RotationEngine.cs | 38 ++++++++++++++------ 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index c3e0393..f334c30 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -209,10 +209,10 @@ namespace GamecraftModdingAPI /// public float3 Position { - get => Exists ? MovementEngine.GetPosition(Id) : float3.zero; + get => MovementEngine.GetPosition(Id, InitData); set { - if (Exists) MovementEngine.MoveBlock(Id, value); + MovementEngine.MoveBlock(Id, InitData, value); } } @@ -221,10 +221,10 @@ namespace GamecraftModdingAPI /// public float3 Rotation { - get => Exists ? RotationEngine.GetRotation(Id) : float3.zero; + get => RotationEngine.GetRotation(Id, InitData); set { - if (Exists) RotationEngine.RotateBlock(Id, value); + RotationEngine.RotateBlock(Id, InitData, value); } } diff --git a/GamecraftModdingAPI/Blocks/ConsoleBlock.cs b/GamecraftModdingAPI/Blocks/ConsoleBlock.cs index 4425a1e..edf3e76 100644 --- a/GamecraftModdingAPI/Blocks/ConsoleBlock.cs +++ b/GamecraftModdingAPI/Blocks/ConsoleBlock.cs @@ -22,6 +22,9 @@ namespace GamecraftModdingAPI.Blocks // custom console block properties + /// + /// Setting a nonexistent command will crash the game when switching to simulation + /// public string Command { get diff --git a/GamecraftModdingAPI/Blocks/MovementEngine.cs b/GamecraftModdingAPI/Blocks/MovementEngine.cs index 0ff119a..a4ac0fa 100644 --- a/GamecraftModdingAPI/Blocks/MovementEngine.cs +++ b/GamecraftModdingAPI/Blocks/MovementEngine.cs @@ -35,8 +35,17 @@ namespace GamecraftModdingAPI.Blocks // implementations for Movement static class - public float3 MoveBlock(EGID blockID, float3 vector) + internal float3 MoveBlock(EGID blockID, BlockEngine.BlockInitData data, float3 vector) { + if (!entitiesDB.Exists(blockID)) + { + if (data.Group == null) return float3.zero; + var init = new EntityComponentInitializer(blockID, data.Group); + init.Init(new PositionEntityStruct {position = vector}); + init.Init(new GridRotationStruct {position = vector}); + init.Init(new LocalTransformEntityStruct {position = vector}); + return vector; + } ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity(blockID); ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity(blockID); ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity(blockID); @@ -56,8 +65,14 @@ namespace GamecraftModdingAPI.Blocks return posStruct.position; } - public float3 GetPosition(EGID blockID) + internal float3 GetPosition(EGID blockID, BlockEngine.BlockInitData data) { + if (!entitiesDB.Exists(blockID)) + { + if (data.Group == null) return float3.zero; + var init = new EntityComponentInitializer(blockID, data.Group); + return init.Has() ? init.Get().position : float3.zero; + } ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity(blockID); return posStruct.position; } diff --git a/GamecraftModdingAPI/Blocks/RotationEngine.cs b/GamecraftModdingAPI/Blocks/RotationEngine.cs index e9cd1ef..ca97874 100644 --- a/GamecraftModdingAPI/Blocks/RotationEngine.cs +++ b/GamecraftModdingAPI/Blocks/RotationEngine.cs @@ -35,23 +35,32 @@ namespace GamecraftModdingAPI.Blocks // implementations for Rotation static class - public float3 RotateBlock(EGID blockID, Vector3 vector) + internal float3 RotateBlock(EGID blockID, BlockEngine.BlockInitData data, Vector3 vector) { + if (!entitiesDB.Exists(blockID)) + { + if (data.Group == null) return float3.zero; + var init = new EntityComponentInitializer(blockID, data.Group); + init.Init(new RotationEntityStruct {rotation = new Quaternion {eulerAngles = vector}}); + init.Init(new GridRotationStruct {rotation = new Quaternion {eulerAngles = vector}}); + init.Init(new LocalTransformEntityStruct {rotation = new Quaternion {eulerAngles = vector}}); + return vector; + } ref RotationEntityStruct rotStruct = ref this.entitiesDB.QueryEntity(blockID); ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity(blockID); ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity(blockID); ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity(blockID); // main (persistent) position - Quaternion newRotation = (Quaternion)rotStruct.rotation; - newRotation.eulerAngles += vector; - rotStruct.rotation = (quaternion)newRotation; + Quaternion newRotation = rotStruct.rotation; + newRotation.eulerAngles = vector; + rotStruct.rotation = newRotation; // placement grid rotation - Quaternion newGridRotation = (Quaternion)gridStruct.rotation; - newGridRotation.eulerAngles += vector; - gridStruct.rotation = (quaternion)newGridRotation; + Quaternion newGridRotation = gridStruct.rotation; + newGridRotation.eulerAngles = vector; + gridStruct.rotation = newGridRotation; // rendered position - Quaternion newTransRotation = (Quaternion)rotStruct.rotation; - newTransRotation.eulerAngles += vector; + Quaternion newTransRotation = rotStruct.rotation; + newTransRotation.eulerAngles = vector; transStruct.rotation = newTransRotation; // collision position FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Unity.Transforms.Rotation @@ -63,8 +72,17 @@ namespace GamecraftModdingAPI.Blocks } - public float3 GetRotation(EGID blockID) + internal float3 GetRotation(EGID blockID, BlockEngine.BlockInitData data) { + if (!entitiesDB.Exists(blockID)) + { + if (data.Group == null) return float3.zero; + var init = new EntityComponentInitializer(blockID, data.Group); + return init.Has() + ? (float3) ((Quaternion) init.Get().rotation).eulerAngles + : float3.zero; + } + ref RotationEntityStruct rotStruct = ref entitiesDB.QueryEntity(blockID); return ((Quaternion) rotStruct.rotation).eulerAngles; } From e0aa052305d750d147872e2348baf33e3b3eacba Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Thu, 16 Jul 2020 20:38:51 -0400 Subject: [PATCH 04/32] Fix dev tools for preview changes --- Automation/gen_csproj.py | 2 +- .../GamecraftModdingAPI.csproj | 1133 +++++++++-------- GamecraftModdingAPI/Tests/TestRoot.cs | 11 +- 3 files changed, 592 insertions(+), 554 deletions(-) diff --git a/Automation/gen_csproj.py b/Automation/gen_csproj.py index d0f18c4..1180d71 100644 --- a/Automation/gen_csproj.py +++ b/Automation/gen_csproj.py @@ -32,7 +32,7 @@ if __name__ == "__main__": args = parser.parse_args() print("Building Assembly references") - asmXml = buildReferencesXml("../ref/Gamecraft_Data/Managed") + asmXml = buildReferencesXml("../ref/GamecraftPreview_Data/Managed") # print(asmXml) with open("../GamecraftModdingAPI/GamecraftModdingAPI.csproj", "r") as xmlFile: diff --git a/GamecraftModdingAPI/GamecraftModdingAPI.csproj b/GamecraftModdingAPI/GamecraftModdingAPI.csproj index 29cc08f..46dffee 100644 --- a/GamecraftModdingAPI/GamecraftModdingAPI.csproj +++ b/GamecraftModdingAPI/GamecraftModdingAPI.csproj @@ -2,7 +2,7 @@ net472 true - 1.3.0 + 1.4.0-preview Exmods GNU General Public Licence 3+ https://git.exmods.org/modtainers/GamecraftModdingAPI @@ -22,808 +22,847 @@ - + + + + - - ..\ref\Gamecraft_Data\Managed\IllusionInjector.dll - ..\..\ref\Gamecraft_Data\Managed\IllusionInjector.dll - - - ..\ref\Gamecraft_Data\Managed\IllusionPlugin.dll - ..\..\ref\Gamecraft_Data\Managed\IllusionPlugin.dll - - - ..\ref\Gamecraft_Data\Managed\JWT.dll - ..\..\ref\Gamecraft_Data\Managed\JWT.dll - - - ..\ref\Gamecraft_Data\Managed\Unity.Burst.Unsafe.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Burst.Unsafe.dll - - - ..\ref\Gamecraft_Data\Managed\Rewired_Core.dll - ..\..\ref\Gamecraft_Data\Managed\Rewired_Core.dll - - - ..\ref\Gamecraft_Data\Managed\Rewired_Windows.dll - ..\..\ref\Gamecraft_Data\Managed\Rewired_Windows.dll - - - ..\ref\Gamecraft_Data\Managed\mscorlib.dll - ..\..\ref\Gamecraft_Data\Managed\mscorlib.dll - - - ..\ref\Gamecraft_Data\Managed\Accessibility.dll - ..\..\ref\Gamecraft_Data\Managed\Accessibility.dll - - ..\ref\Gamecraft_Data\Managed\Analytics.dll - ..\..\ref\Gamecraft_Data\Managed\Analytics.dll + ..\ref\GamecraftPreview_Data\Managed\Analytics.dll + ..\..\ref\GamecraftPreview_Data\Managed\Analytics.dll - ..\ref\Gamecraft_Data\Managed\Assembly-CSharp-firstpass.dll - ..\..\ref\Gamecraft_Data\Managed\Assembly-CSharp-firstpass.dll + ..\ref\GamecraftPreview_Data\Managed\Assembly-CSharp-firstpass.dll + ..\..\ref\GamecraftPreview_Data\Managed\Assembly-CSharp-firstpass.dll - ..\ref\Gamecraft_Data\Managed\Assembly-CSharp.dll - ..\..\ref\Gamecraft_Data\Managed\Assembly-CSharp.dll + ..\ref\GamecraftPreview_Data\Managed\Assembly-CSharp.dll + ..\..\ref\GamecraftPreview_Data\Managed\Assembly-CSharp.dll - ..\ref\Gamecraft_Data\Managed\Authentication.dll - ..\..\ref\Gamecraft_Data\Managed\Authentication.dll + ..\ref\GamecraftPreview_Data\Managed\Authentication.dll + ..\..\ref\GamecraftPreview_Data\Managed\Authentication.dll - ..\ref\Gamecraft_Data\Managed\BlockEntityFactory.dll - ..\..\ref\Gamecraft_Data\Managed\BlockEntityFactory.dll + ..\ref\GamecraftPreview_Data\Managed\BlockEntityFactory.dll + ..\..\ref\GamecraftPreview_Data\Managed\BlockEntityFactory.dll - ..\ref\Gamecraft_Data\Managed\Blocks.HUDFeedbackBlocks.dll - ..\..\ref\Gamecraft_Data\Managed\Blocks.HUDFeedbackBlocks.dll + ..\ref\GamecraftPreview_Data\Managed\Blocks.HUDFeedbackBlocks.dll + ..\..\ref\GamecraftPreview_Data\Managed\Blocks.HUDFeedbackBlocks.dll - ..\ref\Gamecraft_Data\Managed\CommandLine.dll - ..\..\ref\Gamecraft_Data\Managed\CommandLine.dll + ..\ref\GamecraftPreview_Data\Managed\CommandLine.dll + ..\..\ref\GamecraftPreview_Data\Managed\CommandLine.dll - ..\ref\Gamecraft_Data\Managed\DataLoader.dll - ..\..\ref\Gamecraft_Data\Managed\DataLoader.dll + ..\ref\GamecraftPreview_Data\Managed\DataLoader.dll + ..\..\ref\GamecraftPreview_Data\Managed\DataLoader.dll - ..\ref\Gamecraft_Data\Managed\DDNA.dll - ..\..\ref\Gamecraft_Data\Managed\DDNA.dll - - - ..\ref\Gamecraft_Data\Managed\Facepunch.Steamworks.Win64.dll - ..\..\ref\Gamecraft_Data\Managed\Facepunch.Steamworks.Win64.dll + ..\ref\GamecraftPreview_Data\Managed\DDNA.dll + ..\..\ref\GamecraftPreview_Data\Managed\DDNA.dll - ..\ref\Gamecraft_Data\Managed\FMOD.dll - ..\..\ref\Gamecraft_Data\Managed\FMOD.dll + ..\ref\GamecraftPreview_Data\Managed\FMOD.dll + ..\..\ref\GamecraftPreview_Data\Managed\FMOD.dll - ..\ref\Gamecraft_Data\Managed\FullGame.dll - ..\..\ref\Gamecraft_Data\Managed\FullGame.dll + ..\ref\GamecraftPreview_Data\Managed\FullGame.dll + ..\..\ref\GamecraftPreview_Data\Managed\FullGame.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.AudioBlocks.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.AudioBlocks.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.AudioBlocks.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.AudioBlocks.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.ConsoleBlock.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.ConsoleBlock.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.ConsoleBlock.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.ConsoleBlock.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.DamagingSurfaceBlock.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.DamagingSurfaceBlock.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.DamagingSurfaceBlock.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.DamagingSurfaceBlock.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.GenericPhysicsBlocks.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.GenericPhysicsBlocks.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.GenericPhysicsBlocks.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.GenericPhysicsBlocks.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.LogicBlock.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.LogicBlock.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.LogicBlock.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.LogicBlock.dll - ..\ref\Gamecraft_Data\Managed\GameCraft.Blocks.ProjectileBlock.dll - ..\..\ref\Gamecraft_Data\Managed\GameCraft.Blocks.ProjectileBlock.dll + ..\ref\GamecraftPreview_Data\Managed\GameCraft.Blocks.ProjectileBlock.dll + ..\..\ref\GamecraftPreview_Data\Managed\GameCraft.Blocks.ProjectileBlock.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.TimerBlock.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.TimerBlock.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.TimerBlock.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.TimerBlock.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.CharacterVulnerability.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.CharacterVulnerability.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.CharacterVulnerability.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.CharacterVulnerability.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.CharacterVulnerabilityGui.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.CharacterVulnerabilityGui.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.CharacterVulnerabilityGui.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.CharacterVulnerabilityGui.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Effects.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Effects.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Effects.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Effects.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.ConsoleBlock.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.ConsoleBlock.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.ConsoleBlock.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.ConsoleBlock.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.HUDFeedbackBlocks.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.HUDFeedbackBlocks.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.HUDFeedbackBlocks.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.HUDFeedbackBlocks.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.Tweaks.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.Tweaks.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.Tweaks.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.Tweaks.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.Wires.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.Wires.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.Wires.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.Wires.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.Wires.Mockup.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.Wires.Mockup.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.Wires.Mockup.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.Wires.Mockup.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Music.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Music.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Music.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Music.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.PerformanceWarnings.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.PerformanceWarnings.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.PerformanceWarnings.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.PerformanceWarnings.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Tweaks.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Tweaks.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Tweaks.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Tweaks.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Tweaks.Mockup.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Tweaks.Mockup.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Tweaks.Mockup.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Tweaks.Mockup.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.VisualEffects.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.VisualEffects.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.VisualEffects.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.VisualEffects.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Wires.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Wires.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Wires.Input.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Wires.Input.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.Input.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.Input.dll - ..\ref\Gamecraft_Data\Managed\Gamecraft.Wires.Mockup.dll - ..\..\ref\Gamecraft_Data\Managed\Gamecraft.Wires.Mockup.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.Mockup.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.Mockup.dll - ..\ref\Gamecraft_Data\Managed\GameState.dll - ..\..\ref\Gamecraft_Data\Managed\GameState.dll + ..\ref\GamecraftPreview_Data\Managed\GameState.dll + ..\..\ref\GamecraftPreview_Data\Managed\GameState.dll - ..\ref\Gamecraft_Data\Managed\GPUInstancer.dll - ..\..\ref\Gamecraft_Data\Managed\GPUInstancer.dll + ..\ref\GamecraftPreview_Data\Managed\GPUInstancer.dll + ..\..\ref\GamecraftPreview_Data\Managed\GPUInstancer.dll - ..\ref\Gamecraft_Data\Managed\Havok.Physics.dll - ..\..\ref\Gamecraft_Data\Managed\Havok.Physics.dll + ..\ref\GamecraftPreview_Data\Managed\Havok.Physics.dll + ..\..\ref\GamecraftPreview_Data\Managed\Havok.Physics.dll - ..\ref\Gamecraft_Data\Managed\Havok.Physics.Hybrid.dll - ..\..\ref\Gamecraft_Data\Managed\Havok.Physics.Hybrid.dll + ..\ref\GamecraftPreview_Data\Managed\Havok.Physics.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Havok.Physics.Hybrid.dll - ..\ref\Gamecraft_Data\Managed\LZ4.dll - ..\..\ref\Gamecraft_Data\Managed\LZ4.dll + ..\ref\GamecraftPreview_Data\Managed\LZ4.dll + ..\..\ref\GamecraftPreview_Data\Managed\LZ4.dll - ..\ref\Gamecraft_Data\Managed\MultiplayerNetworking.dll - ..\..\ref\Gamecraft_Data\Managed\MultiplayerNetworking.dll + ..\ref\GamecraftPreview_Data\Managed\MultiplayerNetworking.dll + ..\..\ref\GamecraftPreview_Data\Managed\MultiplayerNetworking.dll - ..\ref\Gamecraft_Data\Managed\MultiplayerTest.dll - ..\..\ref\Gamecraft_Data\Managed\MultiplayerTest.dll - - - ..\ref\Gamecraft_Data\Managed\netstandard.dll - ..\..\ref\Gamecraft_Data\Managed\netstandard.dll - - - ..\ref\Gamecraft_Data\Managed\Newtonsoft.Json.dll - ..\..\ref\Gamecraft_Data\Managed\Newtonsoft.Json.dll - - - ..\ref\Gamecraft_Data\Managed\Novell.Directory.Ldap.dll - ..\..\ref\Gamecraft_Data\Managed\Novell.Directory.Ldap.dll + ..\ref\GamecraftPreview_Data\Managed\MultiplayerTest.dll + ..\..\ref\GamecraftPreview_Data\Managed\MultiplayerTest.dll - ..\ref\Gamecraft_Data\Managed\RCX.ScreenshotTaker.dll - ..\..\ref\Gamecraft_Data\Managed\RCX.ScreenshotTaker.dll + ..\ref\GamecraftPreview_Data\Managed\RCX.ScreenshotTaker.dll + ..\..\ref\GamecraftPreview_Data\Managed\RCX.ScreenshotTaker.dll - ..\ref\Gamecraft_Data\Managed\RobocraftECS.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftECS.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftECS.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftECS.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.AccountPreferences.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.AccountPreferences.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.AccountPreferences.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.AccountPreferences.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Blocks.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Blocks.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.Ghost.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.Ghost.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Blocks.Ghost.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Blocks.Ghost.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.Triggers.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.Triggers.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Blocks.Triggers.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Blocks.Triggers.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Building.BoxSelect.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Building.BoxSelect.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Building.BoxSelect.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Building.BoxSelect.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Building.Jobs.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Building.Jobs.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Building.Jobs.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Building.Jobs.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Character.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Character.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Character.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Character.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.ClusterToWireConversion.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.ClusterToWireConversion.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.ClusterToWireConversion.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.ClusterToWireConversion.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Common.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Common.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Common.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Common.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.ControlsScreen.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.ControlsScreen.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.ControlsScreen.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.ControlsScreen.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Crosshair.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Crosshair.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Crosshair.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Crosshair.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.FrontEnd.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.FrontEnd.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.FrontEnd.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.FrontEnd.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.BlockLabel.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.BlockLabel.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUI.BlockLabel.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUI.BlockLabel.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.DebugDisplay.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.DebugDisplay.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUI.DebugDisplay.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUI.DebugDisplay.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUI.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUI.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.RemoveBlock.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.RemoveBlock.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUI.RemoveBlock.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUI.RemoveBlock.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.ScaleGhost.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.ScaleGhost.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUI.ScaleGhost.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUI.ScaleGhost.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.GUIs.WorkshopPrefabs.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.GUIs.WorkshopPrefabs.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUIs.WorkshopPrefabs.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUIs.WorkshopPrefabs.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Input.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Input.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Input.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Input.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.MachineEditor.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.MachineEditor.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.MachineEditor.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.MachineEditor.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.MainGame.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.MainGame.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.MainGame.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.MainGame.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.MainSimulation.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.MainSimulation.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.MainSimulation.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.MainSimulation.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.MockCharacter.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.MockCharacter.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.MockCharacter.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.MockCharacter.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Multiplayer.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Multiplayer.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.MultiplayerInput.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.MultiplayerInput.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.MultiplayerInput.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.MultiplayerInput.dll - ..\ref\Gamecraft_Data\Managed\Robocraftx.ObjectIdBlocks.dll - ..\..\ref\Gamecraft_Data\Managed\Robocraftx.ObjectIdBlocks.dll + ..\ref\GamecraftPreview_Data\Managed\Robocraftx.ObjectIdBlocks.dll + ..\..\ref\GamecraftPreview_Data\Managed\Robocraftx.ObjectIdBlocks.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Party.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Party.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Party.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Party.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.PartyGui.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.PartyGui.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.PartyGui.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.PartyGui.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Physics.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Physics.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Physics.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Physics.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.PilotSeat.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.PilotSeat.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.PilotSeat.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.PilotSeat.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Player.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Player.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Player.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Player.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Rendering.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Rendering.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Rendering.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Rendering.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Rendering.Mock.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Rendering.Mock.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Rendering.Mock.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Rendering.Mock.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.SaveAndLoad.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.SaveAndLoad.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.SaveAndLoad.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.SaveAndLoad.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.SaveGameDialog.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.SaveGameDialog.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.SaveGameDialog.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.SaveGameDialog.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Serializers.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Serializers.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Serializers.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Serializers.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.Services.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.Services.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Services.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Services.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.SignalHandling.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.SignalHandling.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.SignalHandling.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.SignalHandling.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX.StateSync.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX.StateSync.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.StateSync.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.StateSync.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX_SpawnPoints.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX_SpawnPoints.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX_SpawnPoints.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX_SpawnPoints.dll - ..\ref\Gamecraft_Data\Managed\RobocraftX_TextBlock.dll - ..\..\ref\Gamecraft_Data\Managed\RobocraftX_TextBlock.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX_TextBlock.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX_TextBlock.dll - ..\ref\Gamecraft_Data\Managed\RobocratX.SimulationCompositionRoot.dll - ..\..\ref\Gamecraft_Data\Managed\RobocratX.SimulationCompositionRoot.dll + ..\ref\GamecraftPreview_Data\Managed\RobocratX.SimulationCompositionRoot.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocratX.SimulationCompositionRoot.dll - ..\ref\Gamecraft_Data\Managed\StringFormatter.dll - ..\..\ref\Gamecraft_Data\Managed\StringFormatter.dll + ..\ref\GamecraftPreview_Data\Managed\StringFormatter.dll + ..\..\ref\GamecraftPreview_Data\Managed\StringFormatter.dll - ..\ref\Gamecraft_Data\Managed\Svelto.Common_3.dll - ..\..\ref\Gamecraft_Data\Managed\Svelto.Common_3.dll + ..\ref\GamecraftPreview_Data\Managed\Svelto.Common_3.dll + ..\..\ref\GamecraftPreview_Data\Managed\Svelto.Common_3.dll - ..\ref\Gamecraft_Data\Managed\Svelto.ECS.dll - ..\..\ref\Gamecraft_Data\Managed\Svelto.ECS.dll + ..\ref\GamecraftPreview_Data\Managed\Svelto.ECS.dll + ..\..\ref\GamecraftPreview_Data\Managed\Svelto.ECS.dll - ..\ref\Gamecraft_Data\Managed\Svelto.Services.dll - ..\..\ref\Gamecraft_Data\Managed\Svelto.Services.dll + ..\ref\GamecraftPreview_Data\Managed\Svelto.Services.dll + ..\..\ref\GamecraftPreview_Data\Managed\Svelto.Services.dll - ..\ref\Gamecraft_Data\Managed\Svelto.Tasks.dll - ..\..\ref\Gamecraft_Data\Managed\Svelto.Tasks.dll + ..\ref\GamecraftPreview_Data\Managed\Svelto.Tasks.dll + ..\..\ref\GamecraftPreview_Data\Managed\Svelto.Tasks.dll - ..\ref\Gamecraft_Data\Managed\Unity.Addressables.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Addressables.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Addressables.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Addressables.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Animation.Curves.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Animation.Curves.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Animation.Curves.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Animation.Curves.Hybrid.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Animation.DefaultGraphPipeline.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Animation.DefaultGraphPipeline.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Animation.DefaultGraphPipeline.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Animation.DefaultGraphPipeline.Hybrid.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Animation.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Animation.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Animation.Graph.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Animation.Graph.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Animation.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Animation.Hybrid.dll - ..\ref\Gamecraft_Data\Managed\Unity.Build.SlimPlayerRuntime.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Build.SlimPlayerRuntime.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Build.SlimPlayerRuntime.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Build.SlimPlayerRuntime.dll - ..\ref\Gamecraft_Data\Managed\Unity.Burst.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Burst.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Burst.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Burst.dll - ..\ref\Gamecraft_Data\Managed\Unity.Collections.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Collections.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Collections.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Collections.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.DataFlowGraph.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.DataFlowGraph.dll - ..\ref\Gamecraft_Data\Managed\Unity.Deformations.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Deformations.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Deformations.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Deformations.dll - ..\ref\Gamecraft_Data\Managed\Unity.Entities.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Entities.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Entities.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Entities.dll - ..\ref\Gamecraft_Data\Managed\Unity.Entities.Hybrid.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Entities.Hybrid.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Entities.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Entities.Hybrid.dll - ..\ref\Gamecraft_Data\Managed\Unity.Jobs.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Jobs.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Jobs.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Jobs.dll - ..\ref\Gamecraft_Data\Managed\Unity.Mathematics.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Mathematics.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.dll - ..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.dll - ..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.MemoryProfiler.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.MemoryProfiler.dll - ..\ref\Gamecraft_Data\Managed\Unity.Physics.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Physics.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Physics.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Physics.dll - ..\ref\Gamecraft_Data\Managed\Unity.Physics.Hybrid.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Physics.Hybrid.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Physics.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Physics.Hybrid.dll - ..\ref\Gamecraft_Data\Managed\Unity.Platforms.Common.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Platforms.Common.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Platforms.Common.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Platforms.Common.dll - ..\ref\Gamecraft_Data\Managed\Unity.Postprocessing.Runtime.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Postprocessing.Runtime.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Postprocessing.Runtime.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Postprocessing.Runtime.dll - ..\ref\Gamecraft_Data\Managed\Unity.Properties.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Properties.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Properties.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Properties.dll - ..\ref\Gamecraft_Data\Managed\Unity.Properties.Reflection.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Properties.Reflection.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Properties.Reflection.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Properties.Reflection.dll - ..\ref\Gamecraft_Data\Managed\Unity.Properties.UI.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Properties.UI.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Properties.UI.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Properties.UI.dll - ..\ref\Gamecraft_Data\Managed\Unity.RenderPipeline.Universal.ShaderLibrary.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipeline.Universal.ShaderLibrary.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipeline.Universal.ShaderLibrary.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipeline.Universal.ShaderLibrary.dll - ..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - ..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - ..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - ..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Universal.Runtime.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Universal.Runtime.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Runtime.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Runtime.dll - ..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Universal.Shaders.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Universal.Shaders.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Shaders.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Shaders.dll - ..\ref\Gamecraft_Data\Managed\Unity.ResourceManager.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.ResourceManager.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.ResourceManager.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.ResourceManager.dll - ..\ref\Gamecraft_Data\Managed\Unity.Scenes.Hybrid.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Scenes.Hybrid.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Scenes.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Scenes.Hybrid.dll - ..\ref\Gamecraft_Data\Managed\Unity.ScriptableBuildPipeline.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.ScriptableBuildPipeline.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.ScriptableBuildPipeline.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.ScriptableBuildPipeline.dll - ..\ref\Gamecraft_Data\Managed\Unity.Serialization.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Serialization.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Serialization.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Serialization.dll - ..\ref\Gamecraft_Data\Managed\Unity.TextMeshPro.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.TextMeshPro.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.TextMeshPro.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.TextMeshPro.dll - ..\ref\Gamecraft_Data\Managed\Unity.Timeline.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Timeline.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Timeline.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Timeline.dll - ..\ref\Gamecraft_Data\Managed\Unity.Transforms.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Transforms.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.dll - ..\ref\Gamecraft_Data\Managed\Unity.Transforms.Hybrid.dll - ..\..\ref\Gamecraft_Data\Managed\Unity.Transforms.Hybrid.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.AccessibilityModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.AccessibilityModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.AIModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.AIModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.AndroidJNIModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.AndroidJNIModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.AnimationModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.AnimationModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.ARModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.ARModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.AssetBundleModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.AssetBundleModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.AudioModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.AudioModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.ClothModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.ClothModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.ClusterInputModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.ClusterInputModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.ClusterRendererModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.ClusterRendererModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.CoreModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.CoreModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.CrashReportingModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.CrashReportingModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.DirectorModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.DirectorModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.DSPGraphModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.DSPGraphModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.GameCenterModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.GameCenterModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.GridModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.GridModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.HotReloadModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.HotReloadModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.ImageConversionModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.ImageConversionModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.IMGUIModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.IMGUIModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.InputLegacyModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.InputLegacyModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.InputModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.InputModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.JSONSerializeModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.JSONSerializeModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.LocalizationModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.LocalizationModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.ParticleSystemModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.ParticleSystemModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.PerformanceReportingModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.PerformanceReportingModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.Physics2DModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.Physics2DModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.PhysicsModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.PhysicsModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.ProfilerModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.ProfilerModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.ScreenCaptureModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.ScreenCaptureModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.SharedInternalsModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.SharedInternalsModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.SpriteMaskModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.SpriteMaskModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.SpriteShapeModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.SpriteShapeModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.StreamingModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.StreamingModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.SubstanceModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.SubstanceModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.SubsystemsModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.SubsystemsModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.TerrainModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.TerrainModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.TextCoreModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.TextCoreModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.TextRenderingModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.TextRenderingModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.TilemapModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.TilemapModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.TLSModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.TLSModule.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.Hybrid.dll - ..\ref\Gamecraft_Data\Managed\UnityEngine.UI.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UI.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UIElementsModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UIElementsModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UIModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UIModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UmbraModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UmbraModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UNETModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UNETModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityConnectModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UnityConnectModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.VehiclesModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.VehiclesModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.VFXModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.VFXModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.VideoModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.VideoModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.VRModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.VRModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.WindModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.WindModule.dll - - - ..\ref\Gamecraft_Data\Managed\UnityEngine.XRModule.dll - ..\..\ref\Gamecraft_Data\Managed\UnityEngine.XRModule.dll + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UI.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UI.dll - ..\ref\Gamecraft_Data\Managed\uREPL.dll - ..\..\ref\Gamecraft_Data\Managed\uREPL.dll + ..\ref\GamecraftPreview_Data\Managed\uREPL.dll + ..\..\ref\GamecraftPreview_Data\Managed\uREPL.dll - ..\ref\Gamecraft_Data\Managed\VisualProfiler.dll - ..\..\ref\Gamecraft_Data\Managed\VisualProfiler.dll + ..\ref\GamecraftPreview_Data\Managed\VisualProfiler.dll + ..\..\ref\GamecraftPreview_Data\Managed\VisualProfiler.dll + + + ..\ref\GamecraftPreview_Data\Managed\Accessibility.dll + ..\..\ref\GamecraftPreview_Data\Managed\Accessibility.dll + + + ..\ref\GamecraftPreview_Data\Managed\Facepunch.Steamworks.Win64.dll + ..\..\ref\GamecraftPreview_Data\Managed\Facepunch.Steamworks.Win64.dll + + + ..\ref\GamecraftPreview_Data\Managed\JWT.dll + ..\..\ref\GamecraftPreview_Data\Managed\JWT.dll + + + ..\ref\GamecraftPreview_Data\Managed\mscorlib.dll + ..\..\ref\GamecraftPreview_Data\Managed\mscorlib.dll + + + ..\ref\GamecraftPreview_Data\Managed\netstandard.dll + ..\..\ref\GamecraftPreview_Data\Managed\netstandard.dll + + + ..\ref\GamecraftPreview_Data\Managed\Newtonsoft.Json.dll + ..\..\ref\GamecraftPreview_Data\Managed\Newtonsoft.Json.dll + + + ..\ref\GamecraftPreview_Data\Managed\Novell.Directory.Ldap.dll + ..\..\ref\GamecraftPreview_Data\Managed\Novell.Directory.Ldap.dll + + + ..\ref\GamecraftPreview_Data\Managed\Rewired_Core.dll + ..\..\ref\GamecraftPreview_Data\Managed\Rewired_Core.dll + + + ..\ref\GamecraftPreview_Data\Managed\Rewired_Windows.dll + ..\..\ref\GamecraftPreview_Data\Managed\Rewired_Windows.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Burst.Unsafe.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Burst.Unsafe.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.AccessibilityModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.AccessibilityModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.AIModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.AIModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.AndroidJNIModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.AndroidJNIModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.AnimationModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.AnimationModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.ARModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.ARModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.AssetBundleModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.AssetBundleModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.AudioModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.AudioModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.ClothModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.ClothModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.ClusterInputModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.ClusterInputModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.ClusterRendererModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.ClusterRendererModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.CoreModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.CoreModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.CrashReportingModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.CrashReportingModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.DirectorModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.DirectorModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.DSPGraphModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.DSPGraphModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.GameCenterModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.GameCenterModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.GridModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.GridModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.HotReloadModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.HotReloadModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.ImageConversionModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.ImageConversionModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.IMGUIModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.IMGUIModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.InputLegacyModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.InputLegacyModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.InputModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.InputModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.JSONSerializeModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.JSONSerializeModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.LocalizationModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.LocalizationModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.ParticleSystemModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.ParticleSystemModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.PerformanceReportingModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.PerformanceReportingModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.Physics2DModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.Physics2DModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.PhysicsModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.PhysicsModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.ProfilerModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.ProfilerModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.ScreenCaptureModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.ScreenCaptureModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.SharedInternalsModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.SharedInternalsModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.SpriteMaskModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.SpriteMaskModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.SpriteShapeModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.SpriteShapeModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.StreamingModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.StreamingModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.SubstanceModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.SubstanceModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.SubsystemsModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.SubsystemsModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.TerrainModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.TerrainModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.TerrainPhysicsModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.TerrainPhysicsModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.TextCoreModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.TextCoreModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.TextRenderingModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.TextRenderingModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.TilemapModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.TilemapModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.TLSModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.TLSModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UIElementsModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UIElementsModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UIModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UIModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UmbraModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UmbraModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UNETModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UNETModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityAnalyticsModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityAnalyticsModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityConnectModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityConnectModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityTestProtocolModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityTestProtocolModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityWebRequestModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityWebRequestModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.VehiclesModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.VehiclesModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.VFXModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.VFXModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.VideoModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.VideoModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.VRModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.VRModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.WindModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.WindModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.XRModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.XRModule.dll + + + ..\ref\GamecraftPreview_Data\Managed\IllusionInjector.dll + ..\..\ref\GamecraftPreview_Data\Managed\IllusionInjector.dll + + + ..\ref\GamecraftPreview_Data\Managed\IllusionPlugin.dll + ..\..\ref\GamecraftPreview_Data\Managed\IllusionPlugin.dll - + \ No newline at end of file diff --git a/GamecraftModdingAPI/Tests/TestRoot.cs b/GamecraftModdingAPI/Tests/TestRoot.cs index 4e9da73..3cb32f5 100644 --- a/GamecraftModdingAPI/Tests/TestRoot.cs +++ b/GamecraftModdingAPI/Tests/TestRoot.cs @@ -130,7 +130,7 @@ namespace GamecraftModdingAPI.Tests private static IEnumerator GoToGameTests() { - Client app = new Client(); + /*Client app = new Client(); int oldLength = 0; while (app.MyGames.Length == 0 || oldLength != app.MyGames.Length) { @@ -138,11 +138,10 @@ namespace GamecraftModdingAPI.Tests yield return new WaitForSecondsEnumerator(1).Continue(); } yield return Yield.It; - app.MyGames[0].EnterGame(); - // returning from a new game without saving will hard lock GC (it's an invalid state) - //Game newGame = Game.NewGame(); - //yield return new WaitForSecondsEnumerator(5).Continue(); // wait for sync - //newGame.EnterGame(); + app.MyGames[0].EnterGame();*/ + Game newGame = Game.NewGame(); + yield return new WaitForSecondsEnumerator(5).Continue(); // wait for sync + newGame.EnterGame(); } private static IEnumerator GameTests() From cc4ed3e17495080c90df8d58b5cd7116fa8c0c25 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 19 Jul 2020 01:13:39 +0200 Subject: [PATCH 05/32] Test fixes, block event Block property Fixed Assert.Equal() Changed tests to reflect changes Added Block property to the block event args Completely removed sync things --- GamecraftModdingAPI/Block.cs | 4 +- GamecraftModdingAPI/Blocks/BlockEngine.cs | 2 - .../Blocks/BlockEventsEngine.cs | 37 ++----------------- GamecraftModdingAPI/Blocks/BlockTests.cs | 6 +-- GamecraftModdingAPI/Blocks/PlacementEngine.cs | 1 - GamecraftModdingAPI/SimBody.cs | 2 +- GamecraftModdingAPI/Tests/Assert.cs | 24 +----------- .../Tests/GamecraftModdingAPIPluginTest.cs | 2 +- .../DeterministicStepCompositionRootPatch.cs | 25 ------------- 9 files changed, 12 insertions(+), 91 deletions(-) delete mode 100644 GamecraftModdingAPI/Utility/DeterministicStepCompositionRootPatch.cs diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index f334c30..ade9f9b 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -342,10 +342,10 @@ namespace GamecraftModdingAPI public bool Remove() => RemovalEngine.RemoveBlock(Id); /// - /// Returns the rigid body of the cluster of blocks this one belongs to during simulation. + /// Returns the rigid body of the chunk of blocks this one belongs to during simulation. /// Can be used to apply forces or move the block around while the simulation is running. /// - /// The SimBody of the cluster or null if the block doesn't exist. + /// The SimBody of the chunk or null if the block doesn't exist. public SimBody GetSimBody() { return BlockEngine.GetBlockInfo(this, diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index d6f4907..375620e 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -25,8 +25,6 @@ namespace GamecraftModdingAPI.Blocks public bool isRemovable => false; - internal bool Synced = true; - public void Dispose() { } diff --git a/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs b/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs index 0a205f0..1e5ce21 100644 --- a/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs @@ -13,14 +13,8 @@ namespace GamecraftModdingAPI.Blocks public event EventHandler Placed; public event EventHandler Removed; - public BlockEventsEngine() - { - //Console.WriteLine("Creating BlockEventsEngine\n" + Environment.StackTrace); - } - public void Ready() { - //Console.WriteLine("BlockEventsEngine registered"); } public EntitiesDB entitiesDB { get; set; } @@ -50,37 +44,12 @@ namespace GamecraftModdingAPI.Blocks } } - /*[HarmonyPatch] - public static class TestPatch - { - public static void Postfix(FasterDictionary, FasterList> engines, - ExclusiveGroupStruct? previousGroup, in PlatformProfiler profiler, EGID egid) - { - if (!engines.TryGetValue(new RefWrapper(TypeSafeDictionary._type), out result)) - return; - } - public static MethodBase TargetMethod() - { - return AccessTools.Method("Svelto.ECS.Internal.TypeSafeDictionary:AddEntityComponentToEngines"); - } - }*/ - - /*[HarmonyPatch] - public static class TestPatch - { - public static void Postfix(EGID basePartEGID) - { - Console.WriteLine("Patched Add method: " + basePartEGID); - } - public static MethodBase TargetMethod() - { - return AccessTools.Method("RobocraftX.CR.MachineEditing.BuildBlockAdditionalPartEngine:Add"); - } - }*/ - public struct BlockPlacedRemovedEventArgs { public EGID ID; public BlockIDs Type; + private Block block; + + public Block Block => block ?? (block = new Block(ID)); } } \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/BlockTests.cs b/GamecraftModdingAPI/Blocks/BlockTests.cs index 133db5e..3e430ea 100644 --- a/GamecraftModdingAPI/Blocks/BlockTests.cs +++ b/GamecraftModdingAPI/Blocks/BlockTests.cs @@ -20,11 +20,11 @@ namespace GamecraftModdingAPI.Blocks } [APITestCase(TestType.EditMode)] - public static void TestSync() + public static void TestInitProperty() { Block newBlock = Block.PlaceNew(BlockIDs.AluminiumCube, Unity.Mathematics.float3.zero + 2); if (!Assert.CloseTo(newBlock.Position, (Unity.Mathematics.float3.zero + 2), $"Newly placed block at {newBlock.Position} is expected at {Unity.Mathematics.float3.zero + 2}.", "Newly placed block position matches.")) return; - Assert.Equal(newBlock.Exists, true, "Newly placed block does not exist, possibly because Sync() skipped/missed/failed.", "Newly placed block exists, Sync() successful."); + //Assert.Equal(newBlock.Exists, true, "Newly placed block does not exist, possibly because Sync() skipped/missed/failed.", "Newly placed block exists, Sync() successful."); } [APITestCase(TestType.EditMode)] @@ -32,7 +32,7 @@ namespace GamecraftModdingAPI.Blocks { TextBlock textBlock = null; // Note: the assignment operation is a lambda, which slightly confuses the compiler Assert.Errorless(() => { textBlock = Block.PlaceNew(BlockIDs.TextBlock, Unity.Mathematics.float3.zero + 1); }, "Block.PlaceNew() raised an exception: ", "Block.PlaceNew() completed without issue."); - if (!Assert.NotNull(textBlock, "Block.Specialize() returned null, possibly because it failed silently.", "Specialized TextBlock is not null.")) return; + if (!Assert.NotNull(textBlock, "Block.PlaceNew() returned null, possibly because it failed silently.", "Specialized TextBlock is not null.")) return; if (!Assert.NotNull(textBlock.Text, "TextBlock.Text is null, possibly because it failed silently.", "TextBlock.Text is not null.")) return; if (!Assert.NotNull(textBlock.TextBlockId, "TextBlock.TextBlockId is null, possibly because it failed silently.", "TextBlock.TextBlockId is not null.")) return; } diff --git a/GamecraftModdingAPI/Blocks/PlacementEngine.cs b/GamecraftModdingAPI/Blocks/PlacementEngine.cs index 61834b0..e111598 100644 --- a/GamecraftModdingAPI/Blocks/PlacementEngine.cs +++ b/GamecraftModdingAPI/Blocks/PlacementEngine.cs @@ -107,7 +107,6 @@ namespace GamecraftModdingAPI.Blocks ref PickedBlockExtraDataStruct pickedBlock = ref entitiesDB.QueryEntity(playerEGID); pickedBlock.placedBlockEntityID = structInitializer.EGID; pickedBlock.placedBlockWasAPickedBlock = false; - Block.BlockEngine.Synced = false; // Block entities will need to be submitted before properties can be used return structInitializer; } diff --git a/GamecraftModdingAPI/SimBody.cs b/GamecraftModdingAPI/SimBody.cs index 420a655..19f4285 100644 --- a/GamecraftModdingAPI/SimBody.cs +++ b/GamecraftModdingAPI/SimBody.cs @@ -9,7 +9,7 @@ using RobocraftX.Physics; namespace GamecraftModdingAPI { /// - /// A rigid body (like a cluster of connected blocks) during simulation. + /// A rigid body (like a chunk of connected blocks) during simulation. /// public class SimBody : IEquatable, IEquatable { diff --git a/GamecraftModdingAPI/Tests/Assert.cs b/GamecraftModdingAPI/Tests/Assert.cs index eec9c5c..78f0597 100644 --- a/GamecraftModdingAPI/Tests/Assert.cs +++ b/GamecraftModdingAPI/Tests/Assert.cs @@ -83,32 +83,12 @@ namespace GamecraftModdingAPI.Tests { if (err == null) err = $"{nameof(T)} '{obj1}' is not equal to '{obj2}'."; if (success == null) success = $"{nameof(T)} '{obj1}' is equal to '{obj2}'."; - if (obj1 == null && obj2 == null) + if ((obj1 == null && obj2 == null) + || (obj1 != null && obj2 != null && obj1.Equals(obj2) && obj2.Equals(obj1))) { // pass Log(PASS + success); TestRoot.TestsPassed = true; - return true; - } - else if (!(obj1 == null && obj2 == null) && obj1.Equals(obj2) && obj2.Equals(obj1)) - { - // pass - Log(PASS + success); - TestRoot.TestsPassed = true; - return true; - } - else if (obj1 != null && (obj1 != null && !obj1.Equals(obj2))) - { - // pass - Log(PASS + success); - TestRoot.TestsPassed = true; - return true; - } - else if (obj2 != null && !obj2.Equals(obj1)) - { - // pass - Log(PASS + success); - TestRoot.TestsPassed = true; return true; } else diff --git a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs index d5cf714..d8b50fa 100644 --- a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs +++ b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs @@ -234,7 +234,7 @@ namespace GamecraftModdingAPI.Tests CommandBuilder.Builder() .Name("PlaceConsole") - .Description("Place a bunch of console block with a given text") + .Description("Place a bunch of console block with a given text - entering simulation with them crashes the game as the cmd doesn't exist") .Action((float x, float y, float z) => { Stopwatch sw = new Stopwatch(); diff --git a/GamecraftModdingAPI/Utility/DeterministicStepCompositionRootPatch.cs b/GamecraftModdingAPI/Utility/DeterministicStepCompositionRootPatch.cs deleted file mode 100644 index 9cabbe0..0000000 --- a/GamecraftModdingAPI/Utility/DeterministicStepCompositionRootPatch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; - -using RobocraftX.StateSync; -using Svelto.ECS; - -using HarmonyLib; - -namespace GamecraftModdingAPI.Utility -{ - [HarmonyPatch(typeof(DeterministicStepCompositionRoot), "ResetWorld")] - public static class DeterministicStepCompositionRootPatch - { - private static SimpleEntitiesSubmissionScheduler engineRootScheduler; - public static void Postfix(SimpleEntitiesSubmissionScheduler scheduler) - { - engineRootScheduler = scheduler; - } - - internal static void SubmitEntitiesNow() - { - if (engineRootScheduler != null) - engineRootScheduler.SubmitEntities(); - } - } -} From 16521ab7eb26ecca2f26cabc671adcd90228a2a0 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 19 Jul 2020 01:42:32 +0200 Subject: [PATCH 06/32] Remove initializer data once the block is placed --- GamecraftModdingAPI/Block.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index ade9f9b..dc3fe19 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -82,6 +82,7 @@ namespace GamecraftModdingAPI position, uscale, scale, player, rotation, out var initializer); var bl = New(egid.entityID, egid.groupID); bl.InitData.Group = BlockEngine.InitGroup(initializer); + Placed += bl.OnPlacedInit; return bl; } @@ -352,6 +353,13 @@ namespace GamecraftModdingAPI (GridConnectionsEntityStruct st) => new SimBody(st.machineRigidBodyId)); } + private void OnPlacedInit(object sender, BlockPlacedRemovedEventArgs e) + { //Member method instead of lambda to avoid constantly creating delegates + if (e.ID != Id) return; + 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 + } + public override string ToString() { return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Type)}: {Type}, {nameof(Color)}: {Color}, {nameof(Exists)}: {Exists}"; From 4a9ceecc292e5bfcab9e4b40b38291703bfe0abb Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Sun, 19 Jul 2020 12:43:06 -0400 Subject: [PATCH 07/32] Improve dev info in README --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1955de0..fd3bf5a 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,16 @@ This means your code won't break when the GamecraftModdingAPI or Gamecraft updat For more info, please check out the [official documentation](https://mod.exmods.org). -For more support, join the ExMods [Discord](https://discord.gg/xjnFxQV). +For more support, join the ExMods [Discord](https://discord.exmods.org). ## Installation -[Please follow the official mod installation guide](https://www.exmods.org/guides/install.html) +[Please follow the official mod installation guide](https://www.exmods.org/guides/install.html) or use GCMM. + +## Development +To get started, create a symbolic link called `ref` in the root of the project, or one folder higher, linking to the Gamecraft install folder. +This will allow your IDE to resolve references to Gamecraft files for building and IDE tools. + +GamecraftModdingAPI version numbers follow the [Semantic Versioning guidelines](https://semver.org/). ## External Libraries GamecraftModdingAPI includes [Harmony](https://github.com/pardeike/Harmony) to modify the behaviour of existing Gamecraft code. @@ -21,4 +27,5 @@ GamecraftModdingAPI includes [Harmony](https://github.com/pardeike/Harmony) to m # Disclaimer This API is an unofficial modification of Gamecraft software, and is not endorsed or supported by FreeJam or Gamecraft. The GamecraftModdingAPI developer(s) claim no rights on the Gamecraft code referenced within this project. +All code contained in this project is licensed under the [GNU Public License v3](https://git.exmods.org/modtainers/GamecraftModdingAPI/src/branch/master/LICENSE). From cda57afade2745eebd77cb664e98cbbf55d35824 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Sun, 19 Jul 2020 16:39:35 -0400 Subject: [PATCH 08/32] Add sfx block support --- GamecraftModdingAPI/Blocks/BlockTests.cs | 18 +++ GamecraftModdingAPI/Blocks/MusicBlock.cs | 157 +++++++++++++++++++++++ GamecraftModdingAPI/Tests/TestRoot.cs | 8 +- 3 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 GamecraftModdingAPI/Blocks/MusicBlock.cs diff --git a/GamecraftModdingAPI/Blocks/BlockTests.cs b/GamecraftModdingAPI/Blocks/BlockTests.cs index 418fa43..ed42024 100644 --- a/GamecraftModdingAPI/Blocks/BlockTests.cs +++ b/GamecraftModdingAPI/Blocks/BlockTests.cs @@ -1,5 +1,7 @@ using System; +using Gamecraft.Wires; + using GamecraftModdingAPI; using GamecraftModdingAPI.Tests; @@ -72,6 +74,22 @@ namespace GamecraftModdingAPI.Blocks if (!Assert.CloseTo(b.MinimumAngle, -180f, $"Servo.MinimumAngle {b.MinimumAngle} does not equal default value, possibly because it failed silently.", "Servo.MinimumAngle is close enough to default.")) return; if (!Assert.CloseTo(b.MaximumForce, 750f, $"Servo.MaximumForce {b.MaximumForce} does not equal default value, possibly because it failed silently.", "Servo.MaximumForce is close enough to default.")) return; } + + [APITestCase(TestType.EditMode)] + public static void TestMusicBlock() + { + Block newBlock = Block.PlaceNew(BlockIDs.MusicBlock, Unity.Mathematics.float3.zero + 2); + MusicBlock b = null; // Note: the assignment operation is a lambda, which slightly confuses the compiler + Assert.Errorless(() => { b = newBlock.Specialise(); }, "Block.Specialize() raised an exception: ", "Block.Specialize() completed without issue."); + if (!Assert.NotNull(b, "Block.Specialize() returned null, possibly because it failed silently.", "Specialized MusicBlock is not null.")) return; + if (!Assert.CloseTo(b.Volume, 100f, $"MusicBlock.Volume {b.Volume} does not equal default value, possibly because it failed silently.", "MusicBlock.Volume is close enough to default.")) return; + if (!Assert.Equal(b.TrackIndex, 0, $"MusicBlock.TrackIndex {b.TrackIndex} does not equal default value, possibly because it failed silently.", "MusicBlock.TrackIndex is equal to default.")) return; + b.IsPlaying = true; // play sfx + if (!Assert.Equal(b.IsPlaying, true, $"MusicBlock.IsPlaying {b.IsPlaying} does not equal default value, possibly because it failed silently.", "MusicBlock.IsPlaying is set properly.")) return; + if (!Assert.Equal(b.ChannelType, ChannelType.Character, $"MusicBlock.ChannelType {b.ChannelType} does not equal default value, possibly because it failed silently.", "MusicBlock.ChannelType is equal to default.")) return; + //Assert.Log(b.Track.ToString()); + if (!Assert.Equal(b.Track.ToString(), new Guid("3237ff8f-f5f2-4f84-8144-496ca280f8c0").ToString(), $"MusicBlock.Track {b.Track} does not equal default value, possibly because it failed silently.", "MusicBlock.Track is equal to default.")) return; + } } #endif } diff --git a/GamecraftModdingAPI/Blocks/MusicBlock.cs b/GamecraftModdingAPI/Blocks/MusicBlock.cs new file mode 100644 index 0000000..a7f862e --- /dev/null +++ b/GamecraftModdingAPI/Blocks/MusicBlock.cs @@ -0,0 +1,157 @@ +using System; + +using FMOD.Studio; +using FMODUnity; +using Gamecraft.Wires; +using RobocraftX.Blocks; +using Svelto.ECS; +using Unity.Mathematics; + +using GamecraftModdingAPI; +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + public class MusicBlock : Block + { + public static MusicBlock PlaceNew(float3 position, + float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, + int uscale = 1, float3 scale = default, Player player = null) + { + if (PlacementEngine.IsInGame && GameState.IsBuildMode()) + { + EGID id = PlacementEngine.PlaceBlock(BlockIDs.MusicBlock, color, darkness, + position, uscale, scale, player, rotation); + return new MusicBlock(id); + } + + return null; + } + + public MusicBlock(EGID id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + public MusicBlock(uint id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + public byte TrackIndex + { + get + { + return BlockEngine.GetBlockInfo(Id).trackIndx; + } + + set + { + ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); + msdes.trackIndx = value; + } + } + + public Guid Track + { + get + { + ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); + return msdes.fmod2DEventPaths.Get(msdes.trackIndx); + } + + set + { + ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); + for (byte i = 0; i < msdes.fmod2DEventPaths.Count(); i++) + { + Guid track = msdes.fmod2DEventPaths.Get(i); + if (track == value) + { + msdes.trackIndx = i; + break; + } + } + } + } + + public Guid[] Tracks + { + get + { + ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); + Guid[] tracks = new Guid[msdes.fmod2DEventPaths.Count()]; + for (byte i = 0; i < tracks.Length; i++) + { + tracks[i] = msdes.fmod2DEventPaths.Get(i); + } + return tracks; + } + } + + public float Volume + { + get + { + return BlockEngine.GetBlockInfo(Id).tweakableVolume; + } + + set + { + ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); + msdes.tweakableVolume = value; + } + } + + public ChannelType ChannelType + { + get + { + return (ChannelType)BlockEngine.GetBlockInfo(Id).channelType; + } + + set + { + ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); + msdes.channelType = (byte)value; + } + } + + public bool IsPlaying + { + get + { + return BlockEngine.GetBlockInfo(Id).isPlaying; + } + + set + { + ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); + if (msdes.isPlaying == value) return; + if (value) + { + // start playing + EventInstance inst = RuntimeManager.CreateInstance(msdes.fmod2DEventPaths.Get(msdes.trackIndx)); + inst.setVolume(msdes.tweakableVolume / 100f); + inst.start(); + msdes.eventHandle = inst.handle; + } + else + { + // stop playing + EventInstance inst = default(EventInstance); + inst.handle = msdes.eventHandle; + inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT); + inst.release(); + } + msdes.isPlaying = value; + } + } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Tests/TestRoot.cs b/GamecraftModdingAPI/Tests/TestRoot.cs index 3cb32f5..f39169e 100644 --- a/GamecraftModdingAPI/Tests/TestRoot.cs +++ b/GamecraftModdingAPI/Tests/TestRoot.cs @@ -130,7 +130,7 @@ namespace GamecraftModdingAPI.Tests private static IEnumerator GoToGameTests() { - /*Client app = new Client(); + Client app = new Client(); int oldLength = 0; while (app.MyGames.Length == 0 || oldLength != app.MyGames.Length) { @@ -138,10 +138,10 @@ namespace GamecraftModdingAPI.Tests yield return new WaitForSecondsEnumerator(1).Continue(); } yield return Yield.It; - app.MyGames[0].EnterGame();*/ - Game newGame = Game.NewGame(); + app.MyGames[0].EnterGame(); + /*Game newGame = Game.NewGame(); yield return new WaitForSecondsEnumerator(5).Continue(); // wait for sync - newGame.EnterGame(); + newGame.EnterGame();*/ } private static IEnumerator GameTests() From 9e47bbcd9ad578627a69d0b1f96582603091a4a2 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Sun, 19 Jul 2020 20:05:01 -0400 Subject: [PATCH 09/32] Add popup UI method to Client --- GamecraftModdingAPI/App/Client.cs | 77 ++++++++++++++++++++++ GamecraftModdingAPI/App/ClientAlertTest.cs | 59 +++++++++++++++++ GamecraftModdingAPI/App/UserPrompts.cs | 27 ++++++++ 3 files changed, 163 insertions(+) create mode 100644 GamecraftModdingAPI/App/ClientAlertTest.cs create mode 100644 GamecraftModdingAPI/App/UserPrompts.cs diff --git a/GamecraftModdingAPI/App/Client.cs b/GamecraftModdingAPI/App/Client.cs index fbe960e..ca5dcfa 100644 --- a/GamecraftModdingAPI/App/Client.cs +++ b/GamecraftModdingAPI/App/Client.cs @@ -1,8 +1,12 @@ using System; +using System.Reflection; +using HarmonyLib; +using RobocraftX.Services; using UnityEngine; using GamecraftModdingAPI.Utility; +using RobocraftX.Common; namespace GamecraftModdingAPI.App { @@ -14,6 +18,12 @@ namespace GamecraftModdingAPI.App // extensible engine protected static AppEngine appEngine = new AppEngine(); + protected static Func ErrorHandlerInstanceGetter; + + protected static Action EnqueueError; + + protected static Action HandleErrorClosed; + /// /// An event that fires whenever the main menu is loaded. /// @@ -74,9 +84,76 @@ namespace GamecraftModdingAPI.App get => appEngine.IsInMenu; } + /// + /// Open a popup which prompts the user to click a button. + /// This reuses Gamecraft's error dialog popup + /// + /// The popup to display. Use an instance of SingleChoicePrompt or DualChoicePrompt. + public void PromptUser(Error popup) + { + // if the stuff wasn't mostly set to internal, this would be written as: + // RobocraftX.Services.ErrorHandler.Instance.EqueueError(error); + object errorHandlerInstance = ErrorHandlerInstanceGetter(); + EnqueueError(errorHandlerInstance, popup); + } + + // TODO + /*public void CloseCurrentPrompt() + { + // RobocraftX.Services.ErrorHandler.Instance.HandlePopupClosed(); + // FIXME: this is a call that is also called when closing, not the actual closing action itself (so it doesn't work) + object errorHandlerInstance = ErrorHandlerInstanceGetter(); + HandleErrorClosed(errorHandlerInstance); + }*/ + internal static void Init() { + // this would have been so much simpler if this didn't involve a bunch of internal fields & classes + Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler"); + Type errorHandle = AccessTools.TypeByName("RobocraftX.Services.ErrorHandle"); + ErrorHandlerInstanceGetter = (Func) AccessTools.Method("GamecraftModdingAPI.App.Client:GenInstanceGetter") + .MakeGenericMethod(errorHandler) + .Invoke(null, new object[0]); + EnqueueError = (Action) AccessTools.Method("GamecraftModdingAPI.App.Client:GenEnqueueError") + .MakeGenericMethod(errorHandler, errorHandle) + .Invoke(null, new object[0]); + /*HandleErrorClosed = (Action) AccessTools.Method("GamecraftModdingAPI.App.Client:GenHandlePopupClosed") + .MakeGenericMethod(errorHandler) + .Invoke(null, new object[0]);*/ + // register engines MenuEngineManager.AddMenuEngine(appEngine); } + + // Creating delegates once is faster than reflection every time + // Admittedly, this way is more difficult to code and less readable + private static Func GenInstanceGetter() + { + Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler"); + MethodInfo instance = AccessTools.PropertyGetter(errorHandler, "Instance"); + Func getterSimple = (Func) Delegate.CreateDelegate(typeof(Func), null, instance); + Func getterCasted = () => (object) getterSimple(); + return getterCasted; + } + + private static Action GenEnqueueError() + { + Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler"); + MethodInfo enqueueError = AccessTools.Method(errorHandler, "EnqueueError"); + Func enqueueSimple = + (Func) Delegate.CreateDelegate(typeof(Func), enqueueError); + Action enqueueCasted = + (object instance, Error error) => { enqueueSimple((T) instance, error); }; + return enqueueCasted; + } + + private static Action GenHandlePopupClosed() + { + Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler"); + MethodInfo handlePopupClosed = AccessTools.Method(errorHandler, "HandlePopupClosed"); + Action handleSimple = + (Action) Delegate.CreateDelegate(typeof(Action), handlePopupClosed); + Action handleCasted = (object instance) => handleSimple((T) instance); + return handleCasted; + } } } diff --git a/GamecraftModdingAPI/App/ClientAlertTest.cs b/GamecraftModdingAPI/App/ClientAlertTest.cs new file mode 100644 index 0000000..23ced76 --- /dev/null +++ b/GamecraftModdingAPI/App/ClientAlertTest.cs @@ -0,0 +1,59 @@ +using System; +using HarmonyLib; + +using RobocraftX.Services; + +using GamecraftModdingAPI.Tests; + +namespace GamecraftModdingAPI.App +{ +#if TEST + /// + /// Client popups tests. + /// Only available in TEST builds. + /// + [APITestClass] + public static class ClientAlertTest + { + private static DualChoicePrompt popup2 = null; + + private static SingleChoicePrompt popup1 = null; + + [APITestStartUp] + public static void StartUp2() + { + popup2 = new DualChoicePrompt("This is a test double-button popup", + "The cake is a lie", + "lmao", + () => { }, + "kek", + () => { }); + } + + [APITestStartUp] + public static void StartUp1() + { + popup1 = new SingleChoicePrompt("The cake is a lie", + "This is a test single-button popup", + "qwertyuiop", + () => { }); + } + + [APITestCase(TestType.Menu)] + public static void TestPopUp2() + { + Client c = new Client(); + c.PromptUser(popup2); + //c.CloseCurrentPrompt(); + } + + [APITestCase(TestType.Menu)] + public static void TestPopUp1() + { + Client c = new Client(); + c.PromptUser(popup1); + //c.CloseCurrentPrompt(); + } + } +#endif +} \ No newline at end of file diff --git a/GamecraftModdingAPI/App/UserPrompts.cs b/GamecraftModdingAPI/App/UserPrompts.cs new file mode 100644 index 0000000..26a9395 --- /dev/null +++ b/GamecraftModdingAPI/App/UserPrompts.cs @@ -0,0 +1,27 @@ +using System; +using HarmonyLib; + +using RobocraftX.Services; + +namespace GamecraftModdingAPI.App +{ + public class DualChoicePrompt : MultiChoiceError + { + public DualChoicePrompt(string errorMessage, string title, string firstButtonText, Action firstButtonAction, string secondButtonText, Action secondButtonAction) : base(errorMessage, firstButtonText, firstButtonAction, secondButtonText, secondButtonAction) + { + // internal readonly field smh + new Traverse(this).Field("Title").Value = title; + } + } + + public class SingleChoicePrompt : SingleChoiceError + { + public SingleChoicePrompt(string errorMessage, string buttonText, Action buttonClickAction) : base(errorMessage, buttonText, buttonClickAction) + { + } + + public SingleChoicePrompt(string titleText, string errorMessage, string buttonText, Action buttonClickAction) : base(titleText, errorMessage, buttonText, buttonClickAction) + { + } + } +} \ No newline at end of file From 3f2139d5921993a5ee98e4146817220109f5ea6b Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 21 Jul 2020 00:19:30 +0200 Subject: [PATCH 10/32] Add some info and prev. value for setters --- GamecraftModdingAPI/Block.cs | 18 ++++++++++++++++-- GamecraftModdingAPI/Blocks/BlockEngine.cs | 5 +++-- GamecraftModdingAPI/Blocks/BlockEngineInit.cs | 6 ++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index dc3fe19..5f30a64 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -137,6 +137,16 @@ namespace GamecraftModdingAPI {typeof(Timer), new[] {CommonExclusiveGroups.BUILD_TIMER_BLOCK_GROUP}} }; + /// + /// Constructs a new instance of T with the given ID and group using dynamically created delegates. + /// It's equivalent to new T(EGID) with a minimal overhead thanks to caching the created delegates. + /// + /// The block ID + /// The block group + /// The block's type or Block itself + /// An instance of the provided type + /// The block group doesn't match or cannot be found + /// The block class doesn't have the needed constructor private static T New(uint id, ExclusiveGroupStruct? group = null) where T : Block { var type = typeof(T); @@ -175,8 +185,8 @@ namespace GamecraftModdingAPI il.DeclareLocal(type); il.Emit(OpCodes.Ldarg_0); //Load EGID and pass to constructor il.Emit(OpCodes.Newobj, ctor); //Call constructor - il.Emit(OpCodes.Stloc_0); - il.Emit(OpCodes.Ldloc_0); + //il.Emit(OpCodes.Stloc_0); - doesn't seem like we need these + //il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ret); func = (Func) dynamic.CreateDelegate(typeof(Func)); @@ -188,6 +198,9 @@ namespace GamecraftModdingAPI public Block(EGID id) { Id = id; + if (typeToGroup.TryGetValue(GetType(), out var groups) && groups.All(gr => gr != id.groupID)) + throw new BlockTypeException("The block has the wrong group! The type is " + GetType() + + " while the group is " + id.groupID); } /// @@ -328,6 +341,7 @@ namespace GamecraftModdingAPI /// /// 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. /// public bool Exists => BlockEngine.BlockExists(Id); diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index 375620e..f97e405 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -85,10 +85,11 @@ namespace GamecraftModdingAPI.Blocks { if (entitiesDB.Exists(block.Id)) setter(ref entitiesDB.QueryEntity(block.Id), value); - if (block.InitData.Group != null) + else if (block.InitData.Group != null) { var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group); - ref T structRef = ref (new T[1])[0]; //A reference for a default value for struct + T component = initializer.Has() ? initializer.Get() : default; + ref T structRef = ref component; setter(ref structRef, value); initializer.Init(structRef); } diff --git a/GamecraftModdingAPI/Blocks/BlockEngineInit.cs b/GamecraftModdingAPI/Blocks/BlockEngineInit.cs index 4be9a98..70f713a 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngineInit.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngineInit.cs @@ -9,6 +9,9 @@ namespace GamecraftModdingAPI.Blocks { public partial class BlockEngine { + /// + /// Holds information needed to construct a component initializer + /// internal struct BlockInitData { public FasterDictionary, ITypeSafeDictionary> Group; @@ -17,6 +20,9 @@ namespace GamecraftModdingAPI.Blocks internal delegate FasterDictionary, ITypeSafeDictionary> GetInitGroup( EntityComponentInitializer initializer); + /// + /// Accesses the group field of the initializer + /// internal GetInitGroup InitGroup = CreateAccessor("_group"); //https://stackoverflow.com/questions/55878525/unit-testing-ref-structs-with-private-fields-via-reflection From 47126d2d799fca78f13fff3cf250d0884a87befb Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 21 Jul 2020 02:36:11 +0200 Subject: [PATCH 11/32] Update music block and attempt to fix test --- GamecraftModdingAPI/Block.cs | 15 ++- GamecraftModdingAPI/Blocks/BlockTests.cs | 17 +++- GamecraftModdingAPI/Blocks/MusicBlock.cs | 123 +++++++++++------------ 3 files changed, 81 insertions(+), 74 deletions(-) diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 5f30a64..2f9a901 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -29,7 +29,7 @@ namespace GamecraftModdingAPI protected static readonly SignalEngine SignalEngine = new SignalEngine(); protected static readonly BlockEventsEngine BlockEventsEngine = new BlockEventsEngine(); protected static readonly ScalingEngine ScalingEngine = new ScalingEngine(); - + protected internal static readonly BlockEngine BlockEngine = new BlockEngine(); /// @@ -123,6 +123,7 @@ namespace GamecraftModdingAPI { {typeof(ConsoleBlock), new[] {CommonExclusiveGroups.BUILD_CONSOLE_BLOCK_GROUP}}, {typeof(Motor), new[] {CommonExclusiveGroups.BUILD_MOTOR_BLOCK_GROUP}}, + {typeof(MusicBlock), new[] {CommonExclusiveGroups.BUILD_MUSIC_BLOCK_GROUP}}, {typeof(Piston), new[] {CommonExclusiveGroups.BUILD_PISTON_BLOCK_GROUP}}, {typeof(Servo), new[] {CommonExclusiveGroups.BUILD_SERVO_BLOCK_GROUP}}, { @@ -198,9 +199,15 @@ namespace GamecraftModdingAPI public Block(EGID id) { Id = id; - if (typeToGroup.TryGetValue(GetType(), out var groups) && groups.All(gr => gr != id.groupID)) - throw new BlockTypeException("The block has the wrong group! The type is " + GetType() + - " while the group is " + id.groupID); + var type = GetType(); + if (typeToGroup.TryGetValue(type, out var groups)) + { + if (groups.All(gr => gr != id.groupID)) + throw new BlockTypeException("The block has the wrong group! The type is " + GetType() + + " while the group is " + id.groupID); + } + else if (type != typeof(Block)) + Logging.LogWarning($"Unknown block type! Add {type} to the dictionary."); } /// diff --git a/GamecraftModdingAPI/Blocks/BlockTests.cs b/GamecraftModdingAPI/Blocks/BlockTests.cs index 85328d2..6186a1d 100644 --- a/GamecraftModdingAPI/Blocks/BlockTests.cs +++ b/GamecraftModdingAPI/Blocks/BlockTests.cs @@ -74,8 +74,8 @@ namespace GamecraftModdingAPI.Blocks if (!Assert.CloseTo(b.MaximumForce, 750f, $"Servo.MaximumForce {b.MaximumForce} does not equal default value, possibly because it failed silently.", "Servo.MaximumForce is close enough to default.")) return; } - [APITestCase(TestType.EditMode)] - public static void TestMusicBlock() + [APITestCase(TestType.Game)] + public static void TestMusicBlock1() { Block newBlock = Block.PlaceNew(BlockIDs.MusicBlock, Unity.Mathematics.float3.zero + 2); MusicBlock b = null; // Note: the assignment operation is a lambda, which slightly confuses the compiler @@ -83,8 +83,19 @@ namespace GamecraftModdingAPI.Blocks if (!Assert.NotNull(b, "Block.Specialize() returned null, possibly because it failed silently.", "Specialized MusicBlock is not null.")) return; if (!Assert.CloseTo(b.Volume, 100f, $"MusicBlock.Volume {b.Volume} does not equal default value, possibly because it failed silently.", "MusicBlock.Volume is close enough to default.")) return; if (!Assert.Equal(b.TrackIndex, 0, $"MusicBlock.TrackIndex {b.TrackIndex} does not equal default value, possibly because it failed silently.", "MusicBlock.TrackIndex is equal to default.")) return; + _musicBlock = b; + } + + private static MusicBlock _musicBlock; + + [APITestCase(TestType.EditMode)] + public static void TestMusicBlock2() + { + //Block newBlock = Block.GetLastPlacedBlock(); + var b = _musicBlock; + if (!Assert.NotNull(b, "Block.Specialize() returned null, possibly because it failed silently.", "Specialized MusicBlock is not null.")) return; b.IsPlaying = true; // play sfx - if (!Assert.Equal(b.IsPlaying, true, $"MusicBlock.IsPlaying {b.IsPlaying} does not equal default value, possibly because it failed silently.", "MusicBlock.IsPlaying is set properly.")) return; + if (!Assert.Equal(b.IsPlaying, true, $"MusicBlock.IsPlaying {b.IsPlaying} does not equal true, possibly because it failed silently.", "MusicBlock.IsPlaying is set properly.")) return; if (!Assert.Equal(b.ChannelType, ChannelType.Character, $"MusicBlock.ChannelType {b.ChannelType} does not equal default value, possibly because it failed silently.", "MusicBlock.ChannelType is equal to default.")) return; //Assert.Log(b.Track.ToString()); if (!Assert.Equal(b.Track.ToString(), new Guid("3237ff8f-f5f2-4f84-8144-496ca280f8c0").ToString(), $"MusicBlock.Track {b.Track} does not equal default value, possibly because it failed silently.", "MusicBlock.Track is equal to default.")) return; diff --git a/GamecraftModdingAPI/Blocks/MusicBlock.cs b/GamecraftModdingAPI/Blocks/MusicBlock.cs index a7f862e..2128a45 100644 --- a/GamecraftModdingAPI/Blocks/MusicBlock.cs +++ b/GamecraftModdingAPI/Blocks/MusicBlock.cs @@ -3,58 +3,38 @@ using System; using FMOD.Studio; using FMODUnity; using Gamecraft.Wires; +using RobocraftX.Common; using RobocraftX.Blocks; using Svelto.ECS; using Unity.Mathematics; using GamecraftModdingAPI; +using GamecraftModdingAPI.Tests; using GamecraftModdingAPI.Utility; namespace GamecraftModdingAPI.Blocks { public class MusicBlock : Block { - public static MusicBlock PlaceNew(float3 position, - float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, - int uscale = 1, float3 scale = default, Player player = null) - { - if (PlacementEngine.IsInGame && GameState.IsBuildMode()) - { - EGID id = PlacementEngine.PlaceBlock(BlockIDs.MusicBlock, color, darkness, - position, uscale, scale, player, rotation); - return new MusicBlock(id); - } - - return null; - } - public MusicBlock(EGID id) : base(id) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } - public MusicBlock(uint id) : base(id) + public MusicBlock(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_MUSIC_BLOCK_GROUP)) { - if (!BlockEngine.GetBlockInfoExists(this.Id)) - { - throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); - } } public byte TrackIndex { get { - return BlockEngine.GetBlockInfo(Id).trackIndx; + return BlockEngine.GetBlockInfo(this, (MusicBlockDataEntityStruct st) => st.trackIndx); } set { - ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); - msdes.trackIndx = value; + BlockEngine.SetBlockInfo(this, + (ref MusicBlockDataEntityStruct msdes, byte val) => msdes.trackIndx = val, value); } } @@ -62,22 +42,24 @@ namespace GamecraftModdingAPI.Blocks { get { - ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); - return msdes.fmod2DEventPaths.Get(msdes.trackIndx); + return BlockEngine.GetBlockInfo(this, + (MusicBlockDataEntityStruct msdes) => msdes.fmod2DEventPaths.Get(msdes.trackIndx)); } set { - ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); - for (byte i = 0; i < msdes.fmod2DEventPaths.Count(); i++) + BlockEngine.SetBlockInfo(this, (ref MusicBlockDataEntityStruct msdes, Guid val) => { - Guid track = msdes.fmod2DEventPaths.Get(i); - if (track == value) + for (byte i = 0; i < msdes.fmod2DEventPaths.Count(); i++) { - msdes.trackIndx = i; - break; + Guid track = msdes.fmod2DEventPaths.Get(i); + if (track == val) + { + msdes.trackIndx = i; + break; + } } - } + }, value); } } @@ -85,13 +67,15 @@ namespace GamecraftModdingAPI.Blocks { get { - ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); - Guid[] tracks = new Guid[msdes.fmod2DEventPaths.Count()]; - for (byte i = 0; i < tracks.Length; i++) + return BlockEngine.GetBlockInfo(this, (MusicBlockDataEntityStruct msdes) => { - tracks[i] = msdes.fmod2DEventPaths.Get(i); - } - return tracks; + Guid[] tracks = new Guid[msdes.fmod2DEventPaths.Count()]; + for (byte i = 0; i < tracks.Length; i++) + { + tracks[i] = msdes.fmod2DEventPaths.Get(i); + } + return tracks; + }); } } @@ -99,13 +83,13 @@ namespace GamecraftModdingAPI.Blocks { get { - return BlockEngine.GetBlockInfo(Id).tweakableVolume; + return BlockEngine.GetBlockInfo(this, (MusicBlockDataEntityStruct msdes) => msdes.tweakableVolume); } set { - ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); - msdes.tweakableVolume = value; + BlockEngine.SetBlockInfo(this, + (ref MusicBlockDataEntityStruct msdes, float val) => msdes.tweakableVolume = val, value); } } @@ -113,13 +97,15 @@ namespace GamecraftModdingAPI.Blocks { get { - return (ChannelType)BlockEngine.GetBlockInfo(Id).channelType; + Assert.Log("Block exists: " + Exists); + return BlockEngine.GetBlockInfo(this, + (MusicBlockDataEntityStruct msdes) => (ChannelType) msdes.channelType); } - + set { - ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); - msdes.channelType = (byte)value; + BlockEngine.SetBlockInfo(this, + (ref MusicBlockDataEntityStruct msdes, ChannelType val) => msdes.channelType = (byte) val, value); } } @@ -127,30 +113,33 @@ namespace GamecraftModdingAPI.Blocks { get { - return BlockEngine.GetBlockInfo(Id).isPlaying; + return BlockEngine.GetBlockInfo(this, + (MusicBlockDataEntityStruct msdes) => msdes.isPlaying); } set { - ref MusicBlockDataEntityStruct msdes = ref BlockEngine.GetBlockInfo(Id); - if (msdes.isPlaying == value) return; - if (value) + BlockEngine.SetBlockInfo(this, (ref MusicBlockDataEntityStruct msdes, bool val) => { - // start playing - EventInstance inst = RuntimeManager.CreateInstance(msdes.fmod2DEventPaths.Get(msdes.trackIndx)); - inst.setVolume(msdes.tweakableVolume / 100f); - inst.start(); - msdes.eventHandle = inst.handle; - } - else - { - // stop playing - EventInstance inst = default(EventInstance); - inst.handle = msdes.eventHandle; - inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT); - inst.release(); - } - msdes.isPlaying = value; + if (msdes.isPlaying == val) return; + if (val) + { + // start playing + EventInstance inst = RuntimeManager.CreateInstance(msdes.fmod2DEventPaths.Get(msdes.trackIndx)); + inst.setVolume(msdes.tweakableVolume / 100f); + inst.start(); + msdes.eventHandle = inst.handle; + } + else + { + // stop playing + EventInstance inst = default(EventInstance); + inst.handle = msdes.eventHandle; + inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT); + inst.release(); + } + msdes.isPlaying = val; + }, value); } } } From 50ebf4f0a600430a1f33452ac1cad0eb8a054783 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Fri, 7 Aug 2020 13:55:00 -0400 Subject: [PATCH 12/32] Fix build issues for latest Gamecraft preview version --- GamecraftModdingAPI/App/GameMenuEngine.cs | 17 ++- GamecraftModdingAPI/Block.cs | 4 +- GamecraftModdingAPI/Blocks/BlockEngine.cs | 70 ++++++++++- GamecraftModdingAPI/Blocks/BlockTests.cs | 2 +- GamecraftModdingAPI/Blocks/SignalEngine.cs | 4 +- .../GamecraftModdingAPI.csproj | 113 +++++++++++++++--- GamecraftModdingAPI/Players/PlayerEngine.cs | 11 +- 7 files changed, 184 insertions(+), 37 deletions(-) diff --git a/GamecraftModdingAPI/App/GameMenuEngine.cs b/GamecraftModdingAPI/App/GameMenuEngine.cs index fc2c35f..74bc42a 100644 --- a/GamecraftModdingAPI/App/GameMenuEngine.cs +++ b/GamecraftModdingAPI/App/GameMenuEngine.cs @@ -10,6 +10,7 @@ using Svelto.ECS.Experimental; using GamecraftModdingAPI.Engines; using GamecraftModdingAPI.Utility; +using Svelto.DataStructures; namespace GamecraftModdingAPI.App { @@ -114,11 +115,21 @@ namespace GamecraftModdingAPI.App } public ref MyGamesSlotEntityViewStruct GetGameViewInfo(EGID id) - { - return ref GetComponent(new EGID(id.entityID, MyGamesScreenExclusiveGroups.GameSlotGuiEntities)); + { + EntityCollection entities = + entitiesDB.QueryEntities(MyGamesScreenExclusiveGroups.GameSlotGuiEntities); + for (int i = 0; i < entities.count; i++) + { + if (entities[i].ID.entityID == id.entityID) + { + return ref entities[i]; + } + } + MyGamesSlotEntityViewStruct[] defRef = new MyGamesSlotEntityViewStruct[1]; + return ref defRef[0]; } - public ref T GetComponent(EGID id) where T: struct, IEntityComponent + public ref T GetComponent(EGID id) where T: unmanaged, IEntityComponent { return ref entitiesDB.QueryEntity(id); } diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 0194bae..c7b5d0d 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -337,10 +337,10 @@ namespace GamecraftModdingAPI /// public string Label { - get => BlockEngine.GetBlockInfo(this, (TextLabelEntityViewStruct st) => st.textLabelComponent?.text); + get => BlockEngine.GetBlockInfoViewStruct(this, (TextLabelEntityViewStruct st) => st.textLabelComponent?.text); set { - BlockEngine.SetBlockInfo(this, (ref TextLabelEntityViewStruct text, string val) => + BlockEngine.SetBlockInfoViewStruct(this, (ref TextLabelEntityViewStruct text, string val) => { if (text.textLabelComponent != null) text.textLabelComponent.text = val; }, value); diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index f97e405..33c4002 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -59,16 +59,34 @@ namespace GamecraftModdingAPI.Blocks color.paletteColour = paletteEntry.Colour; } - public ref T GetBlockInfo(EGID blockID) where T : struct, IEntityComponent + public ref T GetBlockInfo(EGID blockID) where T : unmanaged, IEntityComponent { if (entitiesDB.Exists(blockID)) return ref entitiesDB.QueryEntity(blockID); T[] structHolder = new T[1]; //Create something that can be referenced return ref structHolder[0]; //Gets a default value automatically } + + public ref T GetBlockInfoViewStruct(EGID blockID) where T : struct, INeedEGID, IEntityComponent + { + if (entitiesDB.Exists(blockID)) + { + // TODO: optimize by using EntitiesDB internal calls instead of iterating over everything + EntityCollection entities = entitiesDB.QueryEntities(blockID.groupID); + for (int i = 0; i < entities.count; i++) + { + if (entities[i].ID == blockID) + { + return ref entities[i]; + } + } + } + T[] structHolder = new T[1]; //Create something that can be referenced + return ref structHolder[0]; //Gets a default value automatically + } public U GetBlockInfo(Block block, Func getter, - U def = default) where T : struct, IEntityComponent + U def = default) where T : unmanaged, IEntityComponent { if (entitiesDB.Exists(block.Id)) return getter(entitiesDB.QueryEntity(block.Id)); @@ -78,10 +96,56 @@ namespace GamecraftModdingAPI.Blocks return getter(initializer.Get()); return def; } + + public U GetBlockInfoViewStruct(Block block, Func getter, + U def = default) where T : struct, INeedEGID, IEntityComponent + { + if (entitiesDB.Exists(block.Id)) + { + // TODO: optimize by using EntitiesDB internal calls instead of iterating over everything + EntityCollection entities = entitiesDB.QueryEntities(block.Id.groupID); + for (int i = 0; i < entities.count; i++) + { + if (entities[i].ID == block.Id) + { + return getter(entities[i]); + } + } + } + if (block.InitData.Group == null) return def; + var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group); + if (initializer.Has()) + return getter(initializer.Get()); + return def; + } public delegate void Setter(ref T component, U value) where T : struct, IEntityComponent; - public void SetBlockInfo(Block block, Setter setter, U value) where T : struct, IEntityComponent + public void SetBlockInfoViewStruct(Block block, Setter setter, U value) where T : struct, INeedEGID, IEntityComponent + { + if (entitiesDB.Exists(block.Id)) + { + EntityCollection entities = entitiesDB.QueryEntities(block.Id.groupID); + for (int i = 0; i < entities.count; i++) + { + if (entities[i].ID == block.Id) + { + setter(ref entities[i], value); + return; + } + } + } + else if (block.InitData.Group != null) + { + var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group); + T component = initializer.Has() ? initializer.Get() : default; + ref T structRef = ref component; + setter(ref structRef, value); + initializer.Init(structRef); + } + } + + public void SetBlockInfo(Block block, Setter setter, U value) where T : unmanaged, IEntityComponent { if (entitiesDB.Exists(block.Id)) setter(ref entitiesDB.QueryEntity(block.Id), value); diff --git a/GamecraftModdingAPI/Blocks/BlockTests.cs b/GamecraftModdingAPI/Blocks/BlockTests.cs index 9013b3d..5447f6c 100644 --- a/GamecraftModdingAPI/Blocks/BlockTests.cs +++ b/GamecraftModdingAPI/Blocks/BlockTests.cs @@ -119,6 +119,6 @@ namespace GamecraftModdingAPI.Blocks if (!Assert.Errorless(() => { newWire = b.Connect(0, target, 0);})) return; if (!Assert.NotNull(newWire, "SignalingBlock.Connect(...) returned null, possible because it failed silently.", "SignalingBlock.Connect(...) returned a non-null value.")) return; } -} + } #endif } diff --git a/GamecraftModdingAPI/Blocks/SignalEngine.cs b/GamecraftModdingAPI/Blocks/SignalEngine.cs index e961423..763a1a1 100644 --- a/GamecraftModdingAPI/Blocks/SignalEngine.cs +++ b/GamecraftModdingAPI/Blocks/SignalEngine.cs @@ -96,7 +96,7 @@ namespace GamecraftModdingAPI.Blocks return ref GetPortByOffset(bps, portNumber, input); } - public ref T GetComponent(EGID egid) where T : struct, IEntityComponent + public ref T GetComponent(EGID egid) where T : unmanaged, IEntityComponent { return ref entitiesDB.QueryEntity(egid); } @@ -372,7 +372,7 @@ namespace GamecraftModdingAPI.Blocks return results.ToArray(); } - private ref T GetFromDbOrInitData(Block block, EGID id, out bool exists) where T : struct, IEntityComponent + private ref T GetFromDbOrInitData(Block block, EGID id, out bool exists) where T : unmanaged, IEntityComponent { T[] defRef = new T[1]; if (entitiesDB.Exists(id)) diff --git a/GamecraftModdingAPI/GamecraftModdingAPI.csproj b/GamecraftModdingAPI/GamecraftModdingAPI.csproj index 7337ebe..7a7fe1d 100644 --- a/GamecraftModdingAPI/GamecraftModdingAPI.csproj +++ b/GamecraftModdingAPI/GamecraftModdingAPI.csproj @@ -25,8 +25,17 @@ + + + ..\ref\GamecraftPreview_Data\Managed\IllusionInjector.dll + ..\..\ref\GamecraftPreview_Data\Managed\IllusionInjector.dll + + + ..\ref\GamecraftPreview_Data\Managed\IllusionPlugin.dll + ..\..\ref\GamecraftPreview_Data\Managed\IllusionPlugin.dll + ..\ref\GamecraftPreview_Data\Managed\Analytics.dll ..\..\ref\GamecraftPreview_Data\Managed\Analytics.dll @@ -43,10 +52,6 @@ ..\ref\GamecraftPreview_Data\Managed\Authentication.dll ..\..\ref\GamecraftPreview_Data\Managed\Authentication.dll - - ..\ref\GamecraftPreview_Data\Managed\BlockEntityFactory.dll - ..\..\ref\GamecraftPreview_Data\Managed\BlockEntityFactory.dll - ..\ref\GamecraftPreview_Data\Managed\Blocks.HUDFeedbackBlocks.dll ..\..\ref\GamecraftPreview_Data\Managed\Blocks.HUDFeedbackBlocks.dll @@ -55,6 +60,18 @@ ..\ref\GamecraftPreview_Data\Managed\CommandLine.dll ..\..\ref\GamecraftPreview_Data\Managed\CommandLine.dll + + ..\ref\GamecraftPreview_Data\Managed\CommandLineCompositionRoot.dll + ..\..\ref\GamecraftPreview_Data\Managed\CommandLineCompositionRoot.dll + + + ..\ref\GamecraftPreview_Data\Managed\ConsoleBlockComposotionRoot.dll + ..\..\ref\GamecraftPreview_Data\Managed\ConsoleBlockComposotionRoot.dll + + + ..\ref\GamecraftPreview_Data\Managed\ConsoleCommand.dll + ..\..\ref\GamecraftPreview_Data\Managed\ConsoleCommand.dll + ..\ref\GamecraftPreview_Data\Managed\DataLoader.dll ..\..\ref\GamecraftPreview_Data\Managed\DataLoader.dll @@ -75,6 +92,14 @@ ..\ref\GamecraftPreview_Data\Managed\Gamecraft.AudioBlocks.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.AudioBlocks.dll + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlockCompositionRoot.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlockCompositionRoot.dll + + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlockEntityFactory.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlockEntityFactory.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.ConsoleBlock.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.ConsoleBlock.dll @@ -83,6 +108,10 @@ ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.DamagingSurfaceBlock.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.DamagingSurfaceBlock.dll + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.DestructionBlocks.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.DestructionBlocks.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.GenericPhysicsBlocks.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.GenericPhysicsBlocks.dll @@ -95,10 +124,18 @@ ..\ref\GamecraftPreview_Data\Managed\GameCraft.Blocks.ProjectileBlock.dll ..\..\ref\GamecraftPreview_Data\Managed\GameCraft.Blocks.ProjectileBlock.dll + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.TextBlock.CompositionRoot.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.TextBlock.CompositionRoot.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.TimerBlock.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.TimerBlock.dll + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.CharacterVulnerability.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.CharacterVulnerability.dll @@ -107,10 +144,22 @@ ..\ref\GamecraftPreview_Data\Managed\Gamecraft.CharacterVulnerabilityGui.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.CharacterVulnerabilityGui.dll + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Damage.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Damage.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Effects.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Effects.dll + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.ExplosionFragments.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.ExplosionFragments.dll + + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GraphicsSettings.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GraphicsSettings.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.ConsoleBlock.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.ConsoleBlock.dll @@ -139,6 +188,14 @@ ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.InventoryTimeRunning.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.InventoryTimeRunning.dll + + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.JointBlocks.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.JointBlocks.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Music.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Music.dll @@ -147,6 +204,22 @@ ..\ref\GamecraftPreview_Data\Managed\Gamecraft.PerformanceWarnings.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.PerformanceWarnings.dll + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.PickupBlck.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.PickupBlck.dll + + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.PickupsCommon.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.PickupsCommon.dll + + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.PopupMessage.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.PopupMessage.dll + + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Projectiles.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Projectiles.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Tweaks.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Tweaks.dll @@ -155,6 +228,10 @@ ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Tweaks.Mockup.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Tweaks.Mockup.dll + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.VisualEffects.Decals.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.VisualEffects.Decals.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.VisualEffects.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.VisualEffects.dll @@ -163,10 +240,6 @@ ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.dll - - ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.Input.dll - ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.Input.dll - ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.Mockup.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Wires.Mockup.dll @@ -379,6 +452,14 @@ ..\ref\GamecraftPreview_Data\Managed\RobocratX.SimulationCompositionRoot.dll ..\..\ref\GamecraftPreview_Data\Managed\RobocratX.SimulationCompositionRoot.dll + + ..\ref\GamecraftPreview_Data\Managed\SpawningPointCompositionRoot.dll + ..\..\ref\GamecraftPreview_Data\Managed\SpawningPointCompositionRoot.dll + + + ..\ref\GamecraftPreview_Data\Managed\SpecializedDescriptors.dll + ..\..\ref\GamecraftPreview_Data\Managed\SpecializedDescriptors.dll + ..\ref\GamecraftPreview_Data\Managed\StringFormatter.dll ..\..\ref\GamecraftPreview_Data\Managed\StringFormatter.dll @@ -399,6 +480,10 @@ ..\ref\GamecraftPreview_Data\Managed\Svelto.Tasks.dll ..\..\ref\GamecraftPreview_Data\Managed\Svelto.Tasks.dll + + ..\ref\GamecraftPreview_Data\Managed\UltimateDecals.dll + ..\..\ref\GamecraftPreview_Data\Managed\UltimateDecals.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.Addressables.dll ..\..\ref\GamecraftPreview_Data\Managed\Unity.Addressables.dll @@ -563,6 +648,10 @@ ..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.Hybrid.dll ..\..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.Hybrid.dll + + ..\ref\GamecraftPreview_Data\Managed\Unity.VisualEffectGraph.Runtime.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.VisualEffectGraph.Runtime.dll + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UI.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UI.dll @@ -855,14 +944,6 @@ ..\ref\GamecraftPreview_Data\Managed\UnityEngine.XRModule.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.XRModule.dll - - ..\ref\GamecraftPreview_Data\Managed\IllusionInjector.dll - ..\..\ref\GamecraftPreview_Data\Managed\IllusionInjector.dll - - - ..\ref\GamecraftPreview_Data\Managed\IllusionPlugin.dll - ..\..\ref\GamecraftPreview_Data\Managed\IllusionPlugin.dll - \ No newline at end of file diff --git a/GamecraftModdingAPI/Players/PlayerEngine.cs b/GamecraftModdingAPI/Players/PlayerEngine.cs index 805ae21..ce0b63a 100644 --- a/GamecraftModdingAPI/Players/PlayerEngine.cs +++ b/GamecraftModdingAPI/Players/PlayerEngine.cs @@ -10,8 +10,6 @@ using RobocraftX.Physics; using RobocraftX.Blocks.Ghost; using RobocraftX.Character.Camera; using RobocraftX.Character.Factories; -using Gamecraft.CharacterVulnerability; -using Gamecraft.CharacterVulnerability.Entities; using Svelto.ECS; using Unity.Mathematics; using Unity.Physics; @@ -282,14 +280,7 @@ namespace GamecraftModdingAPI.Players public bool DamagePlayer(uint playerId, float amount) { if (entitiesDB == null) return false; - Factory.BuildEntity( - new EGID(CharacterVulnerabilityExclusiveGroups.NextDamageEntityId, CharacterVulnerabilityExclusiveGroups.CharacterDamageExclusiveGroup) - ).Init(new DamageEntityStruct - { - damage = amount, - targetPlayerEntityId = playerId, - }); - return true; + return SetCurrentHealth(playerId, GetCurrentHealth(playerId) - amount); } public bool GetDamageable(uint playerId) From 2172364d2674f65b3db843fdcdfe7d3fb573a0f9 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Thu, 13 Aug 2020 16:59:13 +0200 Subject: [PATCH 13/32] Fixes, block IDs, cluster & chunk health support --- GamecraftModdingAPI/Block.cs | 2 +- GamecraftModdingAPI/Blocks/BlockEngine.cs | 91 +++++++++++-------- GamecraftModdingAPI/Blocks/BlockIDs.cs | 5 + GamecraftModdingAPI/Cluster.cs | 41 +++++++++ GamecraftModdingAPI/SimBody.cs | 37 ++++++++ .../Tests/GamecraftModdingAPIPluginTest.cs | 10 ++ .../Utility/DebugInterfaceEngine.cs | 11 ++- 7 files changed, 154 insertions(+), 43 deletions(-) create mode 100644 GamecraftModdingAPI/Cluster.cs diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index c7b5d0d..b901f81 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -372,7 +372,7 @@ namespace GamecraftModdingAPI public SimBody GetSimBody() { return BlockEngine.GetBlockInfo(this, - (GridConnectionsEntityStruct st) => new SimBody(st.machineRigidBodyId)); + (GridConnectionsEntityStruct st) => new SimBody(st.machineRigidBodyId, st.clusterId)); } private void OnPlacedInit(object sender, BlockPlacedRemovedEventArgs e) diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index 33c4002..2622d41 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Gamecraft.Wires; using RobocraftX.Blocks; @@ -9,6 +10,7 @@ using RobocraftX.Physics; using RobocraftX.Scene.Simulation; using Svelto.DataStructures; using Svelto.ECS; +using Svelto.ECS.Hybrid; using GamecraftModdingAPI.Engines; @@ -90,28 +92,19 @@ namespace GamecraftModdingAPI.Blocks { if (entitiesDB.Exists(block.Id)) return getter(entitiesDB.QueryEntity(block.Id)); - if (block.InitData.Group == null) return def; - var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group); - if (initializer.Has()) - return getter(initializer.Get()); - return def; + return GetBlockInitInfo(block, getter, def); } public U GetBlockInfoViewStruct(Block block, Func getter, - U def = default) where T : struct, INeedEGID, IEntityComponent + U def = default) where T : struct, IEntityViewComponent { if (entitiesDB.Exists(block.Id)) - { - // TODO: optimize by using EntitiesDB internal calls instead of iterating over everything - EntityCollection entities = entitiesDB.QueryEntities(block.Id.groupID); - for (int i = 0; i < entities.count; i++) - { - if (entities[i].ID == block.Id) - { - return getter(entities[i]); - } - } - } + return getter(entitiesDB.QueryEntity(block.Id)); + return GetBlockInitInfo(block, getter, def); + } + + private U GetBlockInitInfo(Block block, Func getter, U def) where T : struct, IEntityComponent + { if (block.InitData.Group == null) return def; var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group); if (initializer.Has()) @@ -121,35 +114,26 @@ namespace GamecraftModdingAPI.Blocks public delegate void Setter(ref T component, U value) where T : struct, IEntityComponent; - public void SetBlockInfoViewStruct(Block block, Setter setter, U value) where T : struct, INeedEGID, IEntityComponent + public void SetBlockInfoViewStruct(Block block, Setter setter, U value) where T : struct, IEntityViewComponent { if (entitiesDB.Exists(block.Id)) - { - EntityCollection entities = entitiesDB.QueryEntities(block.Id.groupID); - for (int i = 0; i < entities.count; i++) - { - if (entities[i].ID == block.Id) - { - setter(ref entities[i], value); - return; - } - } - } - else if (block.InitData.Group != null) - { - var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group); - T component = initializer.Has() ? initializer.Get() : default; - ref T structRef = ref component; - setter(ref structRef, value); - initializer.Init(structRef); - } + setter(ref entitiesDB.QueryEntity(block.Id), value); + else + SetBlockInitInfo(block, setter, value); } public void SetBlockInfo(Block block, Setter setter, U value) where T : unmanaged, IEntityComponent { if (entitiesDB.Exists(block.Id)) setter(ref entitiesDB.QueryEntity(block.Id), value); - else if (block.InitData.Group != null) + else + SetBlockInitInfo(block, setter, value); + } + + private void SetBlockInitInfo(Block block, Setter setter, U value) + where T : struct, IEntityComponent + { + if (block.InitData.Group != null) { var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group); T component = initializer.Has() ? initializer.Get() : default; @@ -222,6 +206,22 @@ namespace GamecraftModdingAPI.Blocks return list.ToArray(); } + public SimBody[] GetClusterBodies(uint cid) + { + var groups = entitiesDB.QueryEntities(); + var bodies = new HashSet(); + foreach (var (coll, _) in groups) + { + foreach (var conn in coll) + { + if (conn.clusterId == cid) + bodies.Add(conn.machineRigidBodyId); + } + } + + return bodies.Select(id => new SimBody(id)).ToArray(); + } + public EGID? FindBlockEGID(uint id) { var groups = entitiesDB.FindGroups(); @@ -234,6 +234,21 @@ namespace GamecraftModdingAPI.Blocks return null; } + public Cluster GetCluster(uint sbid) + { + var groups = entitiesDB.QueryEntities(); + foreach (var (coll, _) in groups) + { + foreach (var conn in coll) + { + if (conn.machineRigidBodyId == sbid) + return new Cluster(conn.clusterId); + } + } + + return null; + } + #if DEBUG public EntitiesDB GetEntitiesDB() { diff --git a/GamecraftModdingAPI/Blocks/BlockIDs.cs b/GamecraftModdingAPI/Blocks/BlockIDs.cs index 596fb38..33f9522 100644 --- a/GamecraftModdingAPI/Blocks/BlockIDs.cs +++ b/GamecraftModdingAPI/Blocks/BlockIDs.cs @@ -192,6 +192,9 @@ namespace GamecraftModdingAPI.Blocks PlayerFilter, TeamFilter, Number2Text, //193 + DestructionManager = 260, + ChunkHealthModifier, + ClusterHealthModifier, //262 BeachTree1 = 200, BeachTree2, BeachTree3, @@ -243,6 +246,8 @@ namespace GamecraftModdingAPI.Blocks AdvancedRotator, MusicBlock, //256 PlasmaCannonBlock, + QuantumRiflePickup = 300, + QuantumRifleAmmoPickup, MagmaRockCube=777, MagmaRockCubeSliced, MagmaRockSlope, diff --git a/GamecraftModdingAPI/Cluster.cs b/GamecraftModdingAPI/Cluster.cs new file mode 100644 index 0000000..074c26c --- /dev/null +++ b/GamecraftModdingAPI/Cluster.cs @@ -0,0 +1,41 @@ +using Gamecraft.Damage; +using RobocraftX.Common; +using Svelto.ECS; + +namespace GamecraftModdingAPI +{ + /// + /// Represnts a cluster of blocks in time running mode, meaning blocks that are connected either directly or via joints. + /// + public class Cluster + { + public EGID Id { get; } + + public Cluster(EGID id) + { + Id = id; + } + + public Cluster(uint id) : this(new EGID(id, CommonExclusiveGroups.SIMULATION_CLUSTERS_GROUP)) + { + } + + public float InitialHealth + { + get => Block.BlockEngine.GetBlockInfo(Id).initialHealth; + set => Block.BlockEngine.GetBlockInfo(Id).initialHealth = value; + } + + public float CurrentHealth + { + get => Block.BlockEngine.GetBlockInfo(Id).currentHealth; + set => Block.BlockEngine.GetBlockInfo(Id).currentHealth = value; + } + + public float HealthMultiplier + { + get => Block.BlockEngine.GetBlockInfo(Id).healthMultiplier; + set => Block.BlockEngine.GetBlockInfo(Id).healthMultiplier = value; + } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/SimBody.cs b/GamecraftModdingAPI/SimBody.cs index 19f4285..a3f6d55 100644 --- a/GamecraftModdingAPI/SimBody.cs +++ b/GamecraftModdingAPI/SimBody.cs @@ -3,6 +3,7 @@ using Svelto.ECS; using Unity.Mathematics; using UnityEngine; +using Gamecraft.Damage; using RobocraftX.Common; using RobocraftX.Physics; @@ -15,6 +16,14 @@ namespace GamecraftModdingAPI { public EGID Id { get; } + /// + /// The cluster this chunk belongs to, or null if the chunk doesn't exist. Get the SimBody from a Block if possible for good performance here. + /// + public Cluster Cluster => cluster ?? (cluster = clusterId == uint.MaxValue ? Block.BlockEngine.GetCluster(Id.entityID) : new Cluster(clusterId)); + + private Cluster cluster; + private uint clusterId; + public SimBody(EGID id) { Id = id; @@ -24,6 +33,11 @@ namespace GamecraftModdingAPI { } + internal SimBody(uint id, uint clusterID) : this(id) + { + clusterId = clusterID; + } + /// /// The position of this body. When setting the position, update the position of the connected bodies as well, /// otherwise unexpected forces may arise. @@ -70,6 +84,29 @@ namespace GamecraftModdingAPI //set => GetStruct().physicsMass.CenterOfMass = value; } + public float Volume + { + get => GetStruct().volume; + } + + public float InitialHealth + { + get => Block.BlockEngine.GetBlockInfo(Id).initialHealth; + set => Block.BlockEngine.GetBlockInfo(Id).initialHealth = value; + } + + public float CurrentHealth + { + get => Block.BlockEngine.GetBlockInfo(Id).currentHealth; + set => Block.BlockEngine.GetBlockInfo(Id).currentHealth = value; + } + + public float HealthMultiplier + { + get => Block.BlockEngine.GetBlockInfo(Id).healthMultiplier; + set => Block.BlockEngine.GetBlockInfo(Id).healthMultiplier = value; + } + /// /// Whether the body can be moved or static. /// diff --git a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs index e7bed82..62e369b 100644 --- a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs +++ b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs @@ -268,6 +268,16 @@ namespace GamecraftModdingAPI.Tests }) .Build(); + CommandBuilder.Builder("TestChunkHealth", "Sets the chunk looked at to the given health.") + .Action((float val, float max) => + { + var body = new Player(PlayerType.Local).GetSimBodyLookedAt(); + if (body == null) return; + body.CurrentHealth = val; + body.InitialHealth = max; + Logging.CommandLog("Health set to: " + val); + }).Build(); + GameClient.SetDebugInfo("InstalledMods", InstalledMods); Block.Placed += (sender, args) => Logging.MetaDebugLog("Placed block " + args.Type + " with ID " + args.ID); diff --git a/GamecraftModdingAPI/Utility/DebugInterfaceEngine.cs b/GamecraftModdingAPI/Utility/DebugInterfaceEngine.cs index c604c34..0e4d023 100644 --- a/GamecraftModdingAPI/Utility/DebugInterfaceEngine.cs +++ b/GamecraftModdingAPI/Utility/DebugInterfaceEngine.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; +using System.Text; using System.Text.Formatting; using GamecraftModdingAPI.Blocks; using GamecraftModdingAPI.Engines; @@ -46,9 +47,9 @@ namespace GamecraftModdingAPI.Utility var array = new CodeInstruction[] { new CodeInstruction(OpCodes.Ldloc_0), //StringBuffer - new CodeInstruction(OpCodes.Call, ((Action)AddInfo).Method) + new CodeInstruction(OpCodes.Call, ((Action)AddInfo).Method) }; - list.InsertRange(index, array); + list.InsertRange(index - 1, array); //-1: ldloc.1 ("local") before ldfld } catch (Exception e) { @@ -58,13 +59,15 @@ namespace GamecraftModdingAPI.Utility return list; } - public static void AddInfo(StringBuffer sb) + public static void AddInfo(StringBuilder sb) { foreach (var info in _extraInfo) { try { - sb.Append(info.Value() + "\n"); + string text = info.Value().Trim(); + if (text.Length != 0) + sb.Append(text + "\n"); } catch (Exception e) { From 1e9d1c8f81d1c9f1e3348b2087126df1b528125c Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 18 Sep 2020 21:19:39 +0200 Subject: [PATCH 14/32] Fix TextBlock.Text=null, most new blocks and others --- GamecraftModdingAPI/Block.cs | 7 +++- GamecraftModdingAPI/Blocks/BlockIDs.cs | 48 +++++++++++++++++++++++++ GamecraftModdingAPI/Blocks/TextBlock.cs | 1 + 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index b901f81..2e4161a 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -439,7 +439,12 @@ namespace GamecraftModdingAPI //Lets improve that using delegates var block = New(Id.entityID, Id.groupID); - block.InitData = this.InitData; + if (this.InitData.Group != null) + { + block.InitData = this.InitData; + Placed += block.OnPlacedInit; //Reset InitData of new object + } + return block; } diff --git a/GamecraftModdingAPI/Blocks/BlockIDs.cs b/GamecraftModdingAPI/Blocks/BlockIDs.cs index 33f9522..06f7036 100644 --- a/GamecraftModdingAPI/Blocks/BlockIDs.cs +++ b/GamecraftModdingAPI/Blocks/BlockIDs.cs @@ -248,6 +248,54 @@ namespace GamecraftModdingAPI.Blocks PlasmaCannonBlock, QuantumRiflePickup = 300, QuantumRifleAmmoPickup, + AluminiumSlicedFraction, + AluminiumSlicedSlope, + AluminiumHalfPyramidLeft = 305, + AluminiumHalfPyramidRight, + AluminiumPyramidSliced, + AluminiumTubeCross, + AluminiumTubeT, + AluminiumPlateSquare, + AluminiumPlateCircle, + AluminiumPlateTriangle, //312 + OiledSlicedFraction = 314, + OiledSlicedSlope, + OiledHalfPyramidLeft, + OiledHalfPyramidRight, + OiledPyramidSliced, + GlassSlicedFraction, + GlassSlicedSlope, + GlassHalfPyramidLeft, + GlassHalfPyramidRight, + GlassPyramidSliced, + RubberSlicedFraction, + RubberSlicedSlope, + RubberHalfPyramidLeft, + RubberHalfPyramidRight, + RubberPyramidSliced, + WoodSlicedFraction, + WoodSlicedSlope, //330 + WoodHalfPyramidLeft, + WoodHalfPyramidRight, + WoodPyramidSliced, + OiledTubeCross = 339, + OiledTubeT, + GlassTubeT, + RubberTubeCross = 343, + RubberTubeT, + WoodTubeCross, + WoodTubeT, + OiledTubeCorner = 353, + GlassTubeCorner, + RubberTubeCorner, + WoodTubeCorner, + IronSlicedFraction = 366, + IronSlicedSlope, + IronHalfPyramidLeft, + IronHalfPyramidRight, + IronPyramidSliced, + IronTubeCross, + IronTubeT, MagmaRockCube=777, MagmaRockCubeSliced, MagmaRockSlope, diff --git a/GamecraftModdingAPI/Blocks/TextBlock.cs b/GamecraftModdingAPI/Blocks/TextBlock.cs index e4b4c73..ea5e089 100644 --- a/GamecraftModdingAPI/Blocks/TextBlock.cs +++ b/GamecraftModdingAPI/Blocks/TextBlock.cs @@ -33,6 +33,7 @@ namespace GamecraftModdingAPI.Blocks { BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) => { + if (val == null) val = ""; tbds.textCurrent.Set(val); tbds.textStored.Set(val); }, value); From d581ec598aed04cbdbb8b3bb42c338d9f8959206 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 19 Sep 2020 00:13:05 +0200 Subject: [PATCH 15/32] Add the rest of the blocks --- GamecraftModdingAPI/Blocks/BlockIDs.cs | 45 ++++++++++++++++++++------ 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/GamecraftModdingAPI/Blocks/BlockIDs.cs b/GamecraftModdingAPI/Blocks/BlockIDs.cs index 06f7036..a9a8d3a 100644 --- a/GamecraftModdingAPI/Blocks/BlockIDs.cs +++ b/GamecraftModdingAPI/Blocks/BlockIDs.cs @@ -228,7 +228,7 @@ namespace GamecraftModdingAPI.Blocks ObjectiveHUD, GameStatsHUD, //231 GameOverBlock, - SFXBlockGameplay=240, + SFXBlockGameplay = 240, SFXBlock8Bit, SFXBlockInstrument, SFXBlockSciFi, @@ -278,25 +278,52 @@ namespace GamecraftModdingAPI.Blocks WoodHalfPyramidLeft, WoodHalfPyramidRight, WoodPyramidSliced, - OiledTubeCross = 339, - OiledTubeT, + HexNetSlicedFraction, + HexNetSlicedSlope, + HexNetHalfPyramidLeft, + HexNetHalfPyramidRight, + HexNetPyramidSliced, + OiledTubeCross, + OiledTubeT, //340 + GlassTubeCross, GlassTubeT, - RubberTubeCross = 343, + RubberTubeCross, RubberTubeT, WoodTubeCross, WoodTubeT, - OiledTubeCorner = 353, + HexNetTubeCross, + HexNetTubeT, + BouncyCube, + BouncySlicedCube, //350 + BouncySlope, + BouncyCorner, + OiledTubeCorner, GlassTubeCorner, RubberTubeCorner, WoodTubeCorner, - IronSlicedFraction = 366, + Basketball, + BowlingBall, + SoccerBall, + GolfBall, //360 + HockeyPuck, + PoolBall, + BouncyBall, + TennisBall, + UnlitCube, + IronSlicedFraction, IronSlicedSlope, IronHalfPyramidLeft, IronHalfPyramidRight, - IronPyramidSliced, + IronPyramidSliced, //370 IronTubeCross, IronTubeT, - MagmaRockCube=777, + SFXBlockMob = 374, + PointLight, + SpotLight, + SunLight, + AmbientLight, + UnlitGlowCube = 381, + MagmaRockCube = 777, MagmaRockCubeSliced, MagmaRockSlope, MagmaRockCorner, @@ -315,7 +342,7 @@ namespace GamecraftModdingAPI.Blocks HexNetSlopeRounded, HexNetCornerRounded, //794 MagmaRockBulgedInner, - HexNetCylinder=797, + HexNetCylinder = 797, HexNetHemisphere, HexNetSphere, HexNetTubeCorner //800 From 9e6edc19bdae238a43c18d457bee9e744fcb472f Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Wed, 23 Sep 2020 15:31:54 -0400 Subject: [PATCH 16/32] Implement SFX block API and bump version --- GamecraftModdingAPI/Block.cs | 8 + GamecraftModdingAPI/Blocks/MusicBlock.cs | 2 +- GamecraftModdingAPI/Blocks/SfxBlock.cs | 209 ++++++++++++++++++ .../GamecraftModdingAPI.csproj | 2 +- 4 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 GamecraftModdingAPI/Blocks/SfxBlock.cs diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 2e4161a..97386a3 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -135,6 +135,14 @@ namespace GamecraftModdingAPI CommonExclusiveGroups.BUILD_BUILDINGSPAWN_BLOCK_GROUP } }, + { + typeof(SfxBlock), + new[] + { + CommonExclusiveGroups.BUILD_SIMPLESFX_BLOCK_GROUP, + CommonExclusiveGroups.BUILD_LOOPEDSFX_BLOCK_GROUP + } + }, {typeof(TextBlock), new[] {CommonExclusiveGroups.BUILD_TEXT_BLOCK_GROUP}}, {typeof(Timer), new[] {CommonExclusiveGroups.BUILD_TIMER_BLOCK_GROUP}} }; diff --git a/GamecraftModdingAPI/Blocks/MusicBlock.cs b/GamecraftModdingAPI/Blocks/MusicBlock.cs index 185913b..fc3c880 100644 --- a/GamecraftModdingAPI/Blocks/MusicBlock.cs +++ b/GamecraftModdingAPI/Blocks/MusicBlock.cs @@ -97,7 +97,7 @@ namespace GamecraftModdingAPI.Blocks { get { - Assert.Log("Block exists: " + Exists); + //Assert.Log("Block exists: " + Exists); return BlockEngine.GetBlockInfo(this, (MusicBlockDataEntityStruct msdes) => (ChannelType) msdes.channelType); } diff --git a/GamecraftModdingAPI/Blocks/SfxBlock.cs b/GamecraftModdingAPI/Blocks/SfxBlock.cs new file mode 100644 index 0000000..f7efe6d --- /dev/null +++ b/GamecraftModdingAPI/Blocks/SfxBlock.cs @@ -0,0 +1,209 @@ +using System; +using FMOD.Studio; +using FMODUnity; +using Gamecraft.Wires; +using RobocraftX.Blocks; +using RobocraftX.Common; +using Svelto.ECS; + +namespace GamecraftModdingAPI.Blocks +{ + public class SfxBlock : SignalingBlock + { + public SfxBlock(EGID id) : base(id) + { + } + + public SfxBlock(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_SIMPLESFX_BLOCK_GROUP /* This could also be BUILD_LOOPEDSFX_BLOCK_GROUP */)) + { + } + + public float Volume + { + get + { + return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => obj.tweakableVolume); + } + + set + { + BlockEngine.SetBlockInfo(this, + (ref SoundSfxBlockDataEntityStruct obj, float val) => obj.tweakableVolume = val, value); + } + } + + public float Pitch + { + get + { + return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => obj.tweakablePitch); + } + + set + { + BlockEngine.SetBlockInfo(this, + (ref SoundSfxBlockDataEntityStruct obj, float val) => obj.tweakablePitch = val, value); + } + } + + public bool Is3D + { + get + { + return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => obj.is3D); + } + + set + { + BlockEngine.SetBlockInfo(this, + (ref SoundSfxBlockDataEntityStruct obj, bool val) => obj.is3D = val, value); + } + } + + public ChannelType ChannelType + { + get + { + return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => (ChannelType)obj.channelType); + } + + set + { + BlockEngine.SetBlockInfo(this, + (ref SoundSfxBlockDataEntityStruct obj, ChannelType val) => obj.tweakableVolume = (byte) val, value); + } + } + + public byte TrackIndex + { + get + { + return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => obj.soundEffectIndex); + } + + set + { + BlockEngine.SetBlockInfo(this, + (ref SoundSfxBlockDataEntityStruct obj, byte val) => obj.soundEffectIndex = val, value); + } + } + + // track + public Guid Track + { + get + { + return BlockEngine.GetBlockInfo(this, + (SoundSfxBlockDataEntityStruct obj) => obj.is3D ? obj.fmod3DEventPaths.Get(obj.soundEffectIndex) : obj.fmod2DEventPaths.Get(obj.soundEffectIndex)); + } + + set + { + BlockEngine.SetBlockInfo(this, (ref SoundSfxBlockDataEntityStruct obj, Guid val) => + { + for (byte i = 0; i < obj.fmod2DEventPaths.Count(); i++) + { + Guid track = obj.fmod2DEventPaths.Get(i); + if (track == val) + { + obj.soundEffectIndex = i; + obj.is3D = false; + return; + } + } + for (byte i = 0; i < obj.fmod3DEventPaths.Count(); i++) + { + Guid track = obj.fmod3DEventPaths.Get(i); + if (track == val) + { + obj.soundEffectIndex = i; + obj.is3D = true; + return; + } + } + }, value); + } + } + + // all tracks + public Guid[] Tracks2D + { + get + { + return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => + { + Guid[] tracks = new Guid[obj.fmod2DEventPaths.Count()]; + for (byte i = 0; i < tracks.Length; i++) + { + tracks[i] = obj.fmod2DEventPaths.Get(i); + } + return tracks; + }); + } + } + + public Guid[] Tracks3D + { + get + { + return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => + { + Guid[] tracks = new Guid[obj.fmod3DEventPaths.Count()]; + for (byte i = 0; i < tracks.Length; i++) + { + tracks[i] = obj.fmod2DEventPaths.Get(i); + } + return tracks; + }); + } + } + + public bool IsLooped + { + get + { + return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => obj.isLoopedBlock); + } + + set + { + BlockEngine.SetBlockInfo(this, + (ref SoundSfxBlockDataEntityStruct obj, bool val) => obj.isLoopedBlock = val, value); + } + } + + public bool IsPlaying + { + get + { + return BlockEngine.GetBlockInfo(this, + (SoundSfxBlockDataEntityStruct obj) => obj.isPlaying); + } + + set + { + BlockEngine.SetBlockInfo(this, (ref SoundSfxBlockDataEntityStruct obj, bool val) => + { + if (obj.isPlaying == val) return; + if (val) + { + // start playing + EventInstance inst = RuntimeManager.CreateInstance(obj.is3D ? obj.fmod3DEventPaths.Get(obj.soundEffectIndex) : obj.fmod2DEventPaths.Get(obj.soundEffectIndex)); + inst.setVolume(obj.tweakableVolume / 100f); + inst.start(); + obj.eventHandle = inst.handle; + } + else + { + // stop playing + EventInstance inst = default(EventInstance); + inst.handle = obj.eventHandle; + inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT); + inst.release(); + } + obj.isPlaying = val; + }, value); + } + } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/GamecraftModdingAPI.csproj b/GamecraftModdingAPI/GamecraftModdingAPI.csproj index 7a7fe1d..193a14f 100644 --- a/GamecraftModdingAPI/GamecraftModdingAPI.csproj +++ b/GamecraftModdingAPI/GamecraftModdingAPI.csproj @@ -2,7 +2,7 @@ net472 true - 1.5.0-preview + 1.6.0-preview Exmods GNU General Public Licence 3+ https://git.exmods.org/modtainers/GamecraftModdingAPI From ee6a0e3af638efcf2c5df9b397e86fd17052a829 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 28 Sep 2020 03:10:59 +0200 Subject: [PATCH 17/32] Add support for getting the RGB of block colors Only works if the constructors are used --- GamecraftModdingAPI/Block.cs | 13 ++++--------- GamecraftModdingAPI/Blocks/BlockColor.cs | 16 +++++++++++++++- GamecraftModdingAPI/Blocks/BlockEngine.cs | 11 +++++------ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 97386a3..f827e09 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -36,16 +36,11 @@ namespace GamecraftModdingAPI /// Place a new block at the given position. If scaled, position means the center of the block. The default block size is 0.2 in terms of position. /// Place blocks next to each other to connect them. /// The placed block will be a complete block with a placement grid and collision which will be saved along with the game. - /// - /// When placing multiple blocks, do not access properties immediately after creation as this - /// triggers a sync each time which can affect performance and may cause issues with the game. - /// You may either use AsyncUtils.WaitForSubmission() after placing all of the blocks - /// or simply access the block properties which will trigger the synchronization the first time a property is used. /// /// The block's type /// The block's color /// The block color's darkness (0-9) - 0 is default color - /// The block's position in the grid - default block size is 0.2 + /// The block's position - default block size is 0.2 /// The block's rotation in degrees /// The block's uniform scale - default scale is 1 (with 0.2 width) /// The block's non-uniform scale - 0 means is used @@ -66,7 +61,7 @@ namespace GamecraftModdingAPI /// The block's type /// The block's color /// The block color's darkness (0-9) - 0 is default color - /// The block's position in the grid - default block size is 0.2 + /// The block's position - default block size is 0.2 /// The block's rotation in degrees /// The block's uniform scale - default scale is 1 (with 0.2 width) /// The block's non-uniform scale - 0 means is used @@ -192,7 +187,7 @@ namespace GamecraftModdingAPI type); ILGenerator il = dynamic.GetILGenerator(); - il.DeclareLocal(type); + //il.DeclareLocal(type); il.Emit(OpCodes.Ldarg_0); //Load EGID and pass to constructor il.Emit(OpCodes.Newobj, ctor); //Call constructor //il.Emit(OpCodes.Stloc_0); - doesn't seem like we need these @@ -317,7 +312,7 @@ namespace GamecraftModdingAPI color.indexInPalette = (byte) (val.Color + val.Darkness * 10); color.overridePaletteColour = false; color.needsUpdate = true; - BlockEngine.SetBlockColorFromPalette(ref color); + color.paletteColour = BlockEngine.ConvertBlockColor(color.indexInPalette); }, value); } } diff --git a/GamecraftModdingAPI/Blocks/BlockColor.cs b/GamecraftModdingAPI/Blocks/BlockColor.cs index d7ada0d..46a5dc4 100644 --- a/GamecraftModdingAPI/Blocks/BlockColor.cs +++ b/GamecraftModdingAPI/Blocks/BlockColor.cs @@ -1,9 +1,13 @@ -namespace GamecraftModdingAPI.Blocks +using System; +using Unity.Mathematics; + +namespace GamecraftModdingAPI.Blocks { public struct BlockColor { public BlockColors Color; public byte Darkness; + public byte Index; public BlockColor(byte index) { @@ -14,17 +18,27 @@ } else { + if (index > 99) + throw new ArgumentOutOfRangeException(nameof(index), "Invalid color index. Must be 0-90 or 255."); Color = (BlockColors) (index % 10); Darkness = (byte) (index / 10); } + + Index = index; } public BlockColor(BlockColors color, byte darkness) { + if (darkness > 9) + throw new ArgumentOutOfRangeException(nameof(darkness), "Darkness must be 0-9 where 0 is default."); Color = color; Darkness = darkness; + if (color == BlockColors.Default) Index = byte.MaxValue; + else Index = (byte) (darkness * 10 + color); } + public float4 RGBA => Block.BlockEngine.ConvertBlockColor(Index); + public override string ToString() { return $"{nameof(Color)}: {Color}, {nameof(Darkness)}: {Darkness}"; diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index 2622d41..3a979fe 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -13,6 +13,7 @@ using Svelto.ECS; using Svelto.ECS.Hybrid; using GamecraftModdingAPI.Engines; +using Unity.Mathematics; namespace GamecraftModdingAPI.Blocks { @@ -54,12 +55,10 @@ namespace GamecraftModdingAPI.Blocks return ret; } - public void SetBlockColorFromPalette(ref ColourParameterEntityStruct color) - { - ref var paletteEntry = ref entitiesDB.QueryEntity(color.indexInPalette, - CommonExclusiveGroups.COLOUR_PALETTE_GROUP); - color.paletteColour = paletteEntry.Colour; - } + public float4 ConvertBlockColor(byte index) => index == byte.MaxValue + ? new float4(-1f, -1f, -1f, -1f) + : entitiesDB.QueryEntity(index, + CommonExclusiveGroups.COLOUR_PALETTE_GROUP).Colour; public ref T GetBlockInfo(EGID blockID) where T : unmanaged, IEntityComponent { From 58cfba443eb2a4ba41582335cea06f0638b837cd Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 30 Sep 2020 23:52:17 +0200 Subject: [PATCH 18/32] Add hotfix blocks and Player.LocalPlayer --- GamecraftModdingAPI/Blocks/BlockIDs.cs | 4 ++++ GamecraftModdingAPI/Player.cs | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/GamecraftModdingAPI/Blocks/BlockIDs.cs b/GamecraftModdingAPI/Blocks/BlockIDs.cs index a9a8d3a..d867ce0 100644 --- a/GamecraftModdingAPI/Blocks/BlockIDs.cs +++ b/GamecraftModdingAPI/Blocks/BlockIDs.cs @@ -323,6 +323,10 @@ namespace GamecraftModdingAPI.Blocks SunLight, AmbientLight, UnlitGlowCube = 381, + PointLightInvisible, + SpotLightInvisible, + UnlitSlope, + UnlitGlowSlope, MagmaRockCube = 777, MagmaRockCubeSliced, MagmaRockSlope, diff --git a/GamecraftModdingAPI/Player.cs b/GamecraftModdingAPI/Player.cs index 40dd385..a4b7064 100644 --- a/GamecraftModdingAPI/Player.cs +++ b/GamecraftModdingAPI/Player.cs @@ -17,6 +17,7 @@ namespace GamecraftModdingAPI { // static functionality private static PlayerEngine playerEngine = new PlayerEngine(); + private static Player localPlayer; /// /// Checks if the specified player exists. @@ -54,6 +55,19 @@ namespace GamecraftModdingAPI return (uint) playerEngine.GetAllPlayerCount(); } + /// + /// Returns the current player belonging to this client. + /// + public static Player LocalPlayer + { + get + { + if (localPlayer == null || localPlayer.Id != playerEngine.GetLocalPlayer()) + localPlayer = new Player(PlayerType.Local); + return localPlayer; + } + } + /// /// Initializes a new instance of the class. /// From 92965404ce61e3d6bea7f4bcd05514c5656efbff Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 2 Oct 2020 01:54:59 +0200 Subject: [PATCH 19/32] Remove ScalingEngine.Setup() and add object ID to dict --- GamecraftModdingAPI/Block.cs | 5 +---- GamecraftModdingAPI/Blocks/ScalingEngine.cs | 9 +++------ GamecraftModdingAPI/Events/GameActivatedComposePatch.cs | 2 -- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index f827e09..f63e96c 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -120,6 +120,7 @@ namespace GamecraftModdingAPI {typeof(LogicGate), new [] {CommonExclusiveGroups.BUILD_LOGIC_BLOCK_GROUP}}, {typeof(Motor), new[] {CommonExclusiveGroups.BUILD_MOTOR_BLOCK_GROUP}}, {typeof(MusicBlock), new[] {CommonExclusiveGroups.BUILD_MUSIC_BLOCK_GROUP}}, + {typeof(ObjectIdentifier), new[]{CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP}}, {typeof(Piston), new[] {CommonExclusiveGroups.BUILD_PISTON_BLOCK_GROUP}}, {typeof(Servo), new[] {CommonExclusiveGroups.BUILD_SERVO_BLOCK_GROUP}}, { @@ -460,9 +461,5 @@ namespace GamecraftModdingAPI } } #endif - internal static void Setup(World physicsWorld) - { - ScalingEngine.Setup(physicsWorld.EntityManager); - } } } \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/ScalingEngine.cs b/GamecraftModdingAPI/Blocks/ScalingEngine.cs index a531865..fcbf900 100644 --- a/GamecraftModdingAPI/Blocks/ScalingEngine.cs +++ b/GamecraftModdingAPI/Blocks/ScalingEngine.cs @@ -27,10 +27,12 @@ namespace GamecraftModdingAPI.Blocks public string Name { get; } = "GamecraftModdingAPIScalingEngine"; public bool isRemovable { get; } = false; - private static EntityManager _entityManager; //Unity entity manager + private EntityManager _entityManager; //Unity entity manager public void UpdateCollision(EGID egid) { + if (_entityManager == default) + _entityManager = FullGameFields._physicsWorld.EntityManager; //Assuming the block exists var entity = entitiesDB.QueryEntity(egid).uecsEntity; var pes = new UECSPhysicsEntityCreationStruct(); @@ -38,11 +40,6 @@ namespace GamecraftModdingAPI.Blocks _entityManager.DestroyEntity(entity); } - internal void Setup(EntityManager entityManager) - { - _entityManager = entityManager; - } - [HarmonyPatch] public class PhysicsEnginePatch { diff --git a/GamecraftModdingAPI/Events/GameActivatedComposePatch.cs b/GamecraftModdingAPI/Events/GameActivatedComposePatch.cs index 4142fb3..c3a5fb5 100644 --- a/GamecraftModdingAPI/Events/GameActivatedComposePatch.cs +++ b/GamecraftModdingAPI/Events/GameActivatedComposePatch.cs @@ -31,8 +31,6 @@ namespace GamecraftModdingAPI.Events GameEngineManager.RegisterEngines(enginesRoot); // initialize AsyncUtils AsyncUtils.Setup(enginesRoot); - // initialize Block - Block.Setup(physicsWorld); // A new EnginesRoot is always created when ActivateGame is called // so all event emitters and handlers must be re-registered. EventManager.RegisterEngines(enginesRoot); From 0bd348bd47c2a94a5149d267a908f1750991aa5d Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Thu, 29 Oct 2020 00:37:47 +0100 Subject: [PATCH 20/32] Fix initial issues and add error on patch fail Fixed compilation and loading issues for 2020.10.27.17.13 --- Automation/gen_csproj.py | 0 GamecraftModdingAPI/Blocks/BlockColor.cs | 5 --- GamecraftModdingAPI/Blocks/BlockEngine.cs | 2 +- GamecraftModdingAPI/Blocks/PlacementEngine.cs | 4 +-- GamecraftModdingAPI/Blocks/RemovalEngine.cs | 5 ++- GamecraftModdingAPI/Input/FakeInput.cs | 4 +-- .../HotbarSlotSelectionHandlerEnginePatch.cs | 4 +-- GamecraftModdingAPI/Main.cs | 31 ++++++++++++++----- .../Tests/GamecraftModdingAPIPluginTest.cs | 5 --- 9 files changed, 33 insertions(+), 27 deletions(-) mode change 100644 => 100755 Automation/gen_csproj.py diff --git a/Automation/gen_csproj.py b/Automation/gen_csproj.py old mode 100644 new mode 100755 diff --git a/GamecraftModdingAPI/Blocks/BlockColor.cs b/GamecraftModdingAPI/Blocks/BlockColor.cs index 4461f91..bf22090 100644 --- a/GamecraftModdingAPI/Blocks/BlockColor.cs +++ b/GamecraftModdingAPI/Blocks/BlockColor.cs @@ -7,7 +7,6 @@ namespace GamecraftModdingAPI.Blocks { public BlockColors Color; public byte Darkness; - public byte Index; public byte Index => Color == BlockColors.Default ? byte.MaxValue @@ -27,8 +26,6 @@ namespace GamecraftModdingAPI.Blocks Color = (BlockColors) (index % 10); Darkness = (byte) (index / 10); } - - Index = index; } public BlockColor(BlockColors color, byte darkness) @@ -37,8 +34,6 @@ namespace GamecraftModdingAPI.Blocks throw new ArgumentOutOfRangeException(nameof(darkness), "Darkness must be 0-9 where 0 is default."); Color = color; Darkness = darkness; - if (color == BlockColors.Default) Index = byte.MaxValue; - else Index = (byte) (darkness * 10 + color); } public float4 RGBA => Block.BlockEngine.ConvertBlockColor(Index); diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index 929a65f..e39a3e8 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -2,10 +2,10 @@ using System; using System.Collections.Generic; using System.Linq; +using Gamecraft.ColourPalette; using Gamecraft.Wires; using RobocraftX.Blocks; using RobocraftX.Common; -using RobocraftX.GUI.Hotbar.Colours; using RobocraftX.Physics; using RobocraftX.Scene.Simulation; using Svelto.DataStructures; diff --git a/GamecraftModdingAPI/Blocks/PlacementEngine.cs b/GamecraftModdingAPI/Blocks/PlacementEngine.cs index e111598..cb1cdee 100644 --- a/GamecraftModdingAPI/Blocks/PlacementEngine.cs +++ b/GamecraftModdingAPI/Blocks/PlacementEngine.cs @@ -70,9 +70,7 @@ namespace GamecraftModdingAPI.Blocks DBEntityStruct dbEntity = new DBEntityStruct {DBID = dbid}; BlockPlacementScaleEntityStruct placementScale = new BlockPlacementScaleEntityStruct { - blockPlacementHeight = uscale, blockPlacementWidth = uscale, desiredScaleFactor = uscale, - snapGridScale = uscale, - unitSnapOffset = 0, isUsingUnitSize = true + blockPlacementHeight = uscale, blockPlacementWidth = uscale, desiredScaleFactor = uscale }; EquippedColourStruct colour = new EquippedColourStruct {indexInPalette = color}; diff --git a/GamecraftModdingAPI/Blocks/RemovalEngine.cs b/GamecraftModdingAPI/Blocks/RemovalEngine.cs index 629fd7e..c27c339 100644 --- a/GamecraftModdingAPI/Blocks/RemovalEngine.cs +++ b/GamecraftModdingAPI/Blocks/RemovalEngine.cs @@ -20,8 +20,11 @@ namespace GamecraftModdingAPI.Blocks if (!entitiesDB.Exists(target)) return false; var connections = entitiesDB.QueryEntity(target); + var groups = entitiesDB.FindGroups(); + var connStructMapper = + entitiesDB.QueryNativeMappedEntities(groups); for (int i = connections.connections.Count() - 1; i >= 0; i--) - _connectionFactory.RemoveConnection(connections, i, entitiesDB); + _connectionFactory.RemoveConnection(connections, i, connStructMapper); _entityFunctions.RemoveEntity(target); return true; } diff --git a/GamecraftModdingAPI/Input/FakeInput.cs b/GamecraftModdingAPI/Input/FakeInput.cs index df6c3ce..8cab6f5 100644 --- a/GamecraftModdingAPI/Input/FakeInput.cs +++ b/GamecraftModdingAPI/Input/FakeInput.cs @@ -76,7 +76,7 @@ namespace GamecraftModdingAPI.Input case 9: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_9; break; default: break; } - if (commandLine) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.ToggleCommandLine; + //if (commandLine) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.ToggleCommandLine; - TODO if (escape) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Escape; if (enter) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Return; if (debug) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.ToggleDebugDisplay; @@ -125,7 +125,7 @@ namespace GamecraftModdingAPI.Input if (tertiary) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.TertiaryAction; if (primaryHeld) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.PrimaryActionHeld; if (secondaryHeld) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.SecondaryActionHeld; - if (toggleUnitGrid) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleUnitGrid; + //if (toggleUnitGrid) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleUnitGrid; if (ctrl) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.CtrlAction; if (toggleColourMode) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleColourMode; if (scaleBlockUp) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ScaleBlockUp; diff --git a/GamecraftModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs b/GamecraftModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs index dd8a375..9a81f99 100644 --- a/GamecraftModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs +++ b/GamecraftModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs @@ -1,8 +1,6 @@ using System; using System.Reflection; -using RobocraftX.GUI; -using RobocraftX.GUI.Hotbar; using Svelto.ECS; using HarmonyLib; @@ -17,7 +15,7 @@ namespace GamecraftModdingAPI.Inventory public static BlockIDs EquippedPartID { get => (BlockIDs)selectedBlockInt; } - private static MethodInfo PatchedMethod { get; } = AccessTools.Method(AccessTools.TypeByName("RobocraftX.GUI.Hotbar.HotbarSlotSelectionHandlerEngine"), "ActivateSlotForCube", parameters: new Type[] { typeof(uint), typeof(int), typeof(ExclusiveGroupStruct) }); + private static MethodInfo PatchedMethod { get; } = AccessTools.Method("Gamecraft.GUI.Hotbar.Blocks.SyncHotbarSlotSelectedToEquipedPartEngine:ActivateSlotForCube", parameters: new Type[] { typeof(uint), typeof(int), typeof(ExclusiveGroupStruct) }); public static void Prefix(uint playerID, int selectedDBPartID, ExclusiveGroupStruct groupID) { diff --git a/GamecraftModdingAPI/Main.cs b/GamecraftModdingAPI/Main.cs index 4a8cf24..98fb6f6 100644 --- a/GamecraftModdingAPI/Main.cs +++ b/GamecraftModdingAPI/Main.cs @@ -1,17 +1,15 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Reflection; using GamecraftModdingAPI.Blocks; using HarmonyLib; +using RobocraftX; +using RobocraftX.Services; +using Svelto.Context; + using GamecraftModdingAPI.Utility; using GamecraftModdingAPI.Events; -using GamecraftModdingAPI.Players; using GamecraftModdingAPI.Tasks; -using uREPL; namespace GamecraftModdingAPI { @@ -46,7 +44,20 @@ namespace GamecraftModdingAPI Logging.MetaDebugLog($"Patching Gamecraft"); var currentAssembly = Assembly.GetExecutingAssembly(); harmony = new Harmony(currentAssembly.GetName().Name); - harmony.PatchAll(currentAssembly); + try + { + harmony.PatchAll(currentAssembly); + } + catch (Exception e) + { //Can't use ErrorBuilder or Logging.LogException (which eventually uses ErrorBuilder) yet + Logging.Log(e.ToString()); + Logging.LogWarning("Failed to patch Gamecraft. Attempting to patch to display error..."); + harmony.Patch(AccessTools.Method(typeof(FullGameCompositionRoot), "OnContextInitialized") + .MakeGenericMethod(typeof(UnityContext)), + new HarmonyMethod(((Action) OnPatchError).Method)); //Can't use lambdas here :( + return; + } + // init utility Logging.MetaDebugLog($"Initializing Utility"); #pragma warning disable 0612,0618 @@ -102,5 +113,11 @@ namespace GamecraftModdingAPI Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} shutdown"); } } + + private static void OnPatchError() + { + ErrorBuilder.DisplayMustQuitError("Failed to patch Gamecraft!\n" + + "Make sure you're using the latest version of GamecraftModdingAPI or disable mods if the API isn't released yet."); + } } } diff --git a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs index 0cba023..e3a9c50 100644 --- a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs +++ b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs @@ -173,11 +173,6 @@ namespace GamecraftModdingAPI.Tests Logging.CommandLog("Finished in " + sw.ElapsedMilliseconds + "ms"); }) .Build(); - //With Sync(): 1135ms - //Without Sync(): 134ms - //Async: 348 794ms, doesn't freeze game - //Without Sync() but wait for submission: 530ms - //With Sync() at the end: 380ms Block b = null; CommandBuilder.Builder("moveBlockInSim", "Run in build mode first while looking at a block, then in sim to move it up") From 1cb663b4d13b60565661f553221446ab2d026f95 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Mon, 9 Nov 2020 16:18:25 -0500 Subject: [PATCH 21/32] Fix build errors from beta hotfix 1 --- GamecraftModdingAPI/App/AppEngine.cs | 5 +- GamecraftModdingAPI/App/GameGameEngine.cs | 6 +- GamecraftModdingAPI/App/GameMenuEngine.cs | 10 +- GamecraftModdingAPI/Block.cs | 42 +- GamecraftModdingAPI/Blocks/BlockEngine.cs | 49 ++- GamecraftModdingAPI/Blocks/BlockEngineInit.cs | 4 +- GamecraftModdingAPI/Blocks/ConsoleBlock.cs | 2 +- GamecraftModdingAPI/Blocks/DampedSpring.cs | 2 +- GamecraftModdingAPI/Blocks/LogicGate.cs | 2 +- GamecraftModdingAPI/Blocks/Motor.cs | 2 +- GamecraftModdingAPI/Blocks/MusicBlock.cs | 2 +- .../Blocks/ObjectIdentifier.cs | 2 +- GamecraftModdingAPI/Blocks/Piston.cs | 2 +- GamecraftModdingAPI/Blocks/PlacementEngine.cs | 3 +- GamecraftModdingAPI/Blocks/Servo.cs | 2 +- GamecraftModdingAPI/Blocks/SfxBlock.cs | 2 +- GamecraftModdingAPI/Blocks/SignalEngine.cs | 44 +- GamecraftModdingAPI/Blocks/SpawnPoint.cs | 2 +- GamecraftModdingAPI/Blocks/TextBlock.cs | 2 +- GamecraftModdingAPI/Blocks/Timer.cs | 2 +- .../GamecraftModdingAPI.csproj | 413 +++++++++--------- GamecraftModdingAPI/Inventory/HotbarEngine.cs | 8 +- GamecraftModdingAPI/Players/PlayerEngine.cs | 8 +- GamecraftModdingAPI/Tests/TestRoot.cs | 2 +- 24 files changed, 330 insertions(+), 288 deletions(-) diff --git a/GamecraftModdingAPI/App/AppEngine.cs b/GamecraftModdingAPI/App/AppEngine.cs index 4f20b7e..9cc454d 100644 --- a/GamecraftModdingAPI/App/AppEngine.cs +++ b/GamecraftModdingAPI/App/AppEngine.cs @@ -46,11 +46,12 @@ namespace GamecraftModdingAPI.App public Game[] GetMyGames() { EntityCollection mgsevs = entitiesDB.QueryEntities(MyGamesScreenExclusiveGroups.MyGames); + var mgsevsB = mgsevs.ToBuffer().buffer; Game[] games = new Game[mgsevs.count]; for (int i = 0; i < mgsevs.count; i++) { - Utility.Logging.MetaDebugLog($"Found game named {mgsevs[i].GameName}"); - games[i] = new Game(mgsevs[i].ID); + Utility.Logging.MetaDebugLog($"Found game named {mgsevsB[i].GameName}"); + games[i] = new Game(mgsevsB[i].ID); } return games; } diff --git a/GamecraftModdingAPI/App/GameGameEngine.cs b/GamecraftModdingAPI/App/GameGameEngine.cs index a616df5..dea3821 100644 --- a/GamecraftModdingAPI/App/GameGameEngine.cs +++ b/GamecraftModdingAPI/App/GameGameEngine.cs @@ -52,7 +52,7 @@ namespace GamecraftModdingAPI.App { if (async) { - ExitCurrentGameAsync().RunOn(Lean.EveryFrameStepRunner_RUNS_IN_TIME_STOPPED_AND_RUNNING); + ExitCurrentGameAsync().RunOn(Lean.EveryFrameStepRunner_TimeRunningAndStopped); } else { @@ -102,14 +102,14 @@ namespace GamecraftModdingAPI.App if (filter == BlockIDs.Invalid) { foreach (var (blocks, _) in allBlocks) - foreach (var block in blocks) + foreach (var block in blocks.ToBuffer().buffer.ToManagedArray()) blockEGIDs.Add(block.ID); return blockEGIDs.ToArray(); } else { foreach (var (blocks, _) in allBlocks) - foreach (var block in blocks) + foreach (var block in blocks.ToBuffer().buffer.ToManagedArray()) if (block.DBID == (ulong) filter) blockEGIDs.Add(block.ID); return blockEGIDs.ToArray(); diff --git a/GamecraftModdingAPI/App/GameMenuEngine.cs b/GamecraftModdingAPI/App/GameMenuEngine.cs index 74bc42a..efcb73e 100644 --- a/GamecraftModdingAPI/App/GameMenuEngine.cs +++ b/GamecraftModdingAPI/App/GameMenuEngine.cs @@ -61,12 +61,13 @@ namespace GamecraftModdingAPI.App public uint HighestID() { EntityCollection games = entitiesDB.QueryEntities(MyGamesScreenExclusiveGroups.MyGames); + var gamesB = games.ToBuffer().buffer; uint max = 0; for (int i = 0; i < games.count; i++) { - if (games[i].ID.entityID > max) + if (gamesB[i].ID.entityID > max) { - max = games[i].ID.entityID; + max = gamesB[i].ID.entityID; } } return max; @@ -118,11 +119,12 @@ namespace GamecraftModdingAPI.App { EntityCollection entities = entitiesDB.QueryEntities(MyGamesScreenExclusiveGroups.GameSlotGuiEntities); + var entitiesB = entities.ToBuffer().buffer; for (int i = 0; i < entities.count; i++) { - if (entities[i].ID.entityID == id.entityID) + if (entitiesB[i].ID.entityID == id.entityID) { - return ref entities[i]; + return ref entitiesB[i]; } } MyGamesSlotEntityViewStruct[] defRef = new MyGamesSlotEntityViewStruct[1]; diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 408304d..81d6439 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -116,32 +116,32 @@ namespace GamecraftModdingAPI private static Dictionary typeToGroup = new Dictionary { - {typeof(ConsoleBlock), new[] {CommonExclusiveGroups.BUILD_CONSOLE_BLOCK_GROUP}}, - {typeof(LogicGate), new [] {CommonExclusiveGroups.BUILD_LOGIC_BLOCK_GROUP}}, - {typeof(Motor), new[] {CommonExclusiveGroups.BUILD_MOTOR_BLOCK_GROUP}}, - {typeof(MusicBlock), new[] {CommonExclusiveGroups.BUILD_MUSIC_BLOCK_GROUP}}, - {typeof(ObjectIdentifier), new[]{CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP}}, - {typeof(Piston), new[] {CommonExclusiveGroups.BUILD_PISTON_BLOCK_GROUP}}, - {typeof(Servo), new[] {CommonExclusiveGroups.BUILD_SERVO_BLOCK_GROUP}}, + {typeof(ConsoleBlock), new[] {CommonExclusiveGroups.CONSOLE_BLOCK_GROUP}}, + {typeof(LogicGate), new [] {CommonExclusiveGroups.LOGIC_BLOCK_GROUP}}, + {typeof(Motor), new[] {CommonExclusiveGroups.MOTOR_BLOCK_GROUP}}, + {typeof(MusicBlock), new[] {CommonExclusiveGroups.MUSIC_BLOCK_GROUP}}, + {typeof(ObjectIdentifier), new[]{CommonExclusiveGroups.OBJID_BLOCK_GROUP}}, + {typeof(Piston), new[] {CommonExclusiveGroups.PISTON_BLOCK_GROUP}}, + {typeof(Servo), new[] {CommonExclusiveGroups.SERVO_BLOCK_GROUP}}, { typeof(SpawnPoint), new[] { - CommonExclusiveGroups.BUILD_SPAWNPOINT_BLOCK_GROUP, - CommonExclusiveGroups.BUILD_BUILDINGSPAWN_BLOCK_GROUP + CommonExclusiveGroups.SPAWNPOINT_BLOCK_GROUP, + CommonExclusiveGroups.BUILDINGSPAWN_BLOCK_GROUP } }, { typeof(SfxBlock), new[] { - CommonExclusiveGroups.BUILD_SIMPLESFX_BLOCK_GROUP, - CommonExclusiveGroups.BUILD_LOOPEDSFX_BLOCK_GROUP + CommonExclusiveGroups.SIMPLESFX_BLOCK_GROUP, + CommonExclusiveGroups.LOOPEDSFX_BLOCK_GROUP } }, - {typeof(DampedSpring), new [] {CommonExclusiveGroups.BUILD_DAMPEDSPRING_BLOCK_GROUP}}, - {typeof(TextBlock), new[] {CommonExclusiveGroups.BUILD_TEXT_BLOCK_GROUP}}, - {typeof(Timer), new[] {CommonExclusiveGroups.BUILD_TIMER_BLOCK_GROUP}} + {typeof(DampedSpring), new [] {CommonExclusiveGroups.DAMPEDSPRING_BLOCK_GROUP}}, + {typeof(TextBlock), new[] {CommonExclusiveGroups.TEXT_BLOCK_GROUP}}, + {typeof(Timer), new[] {CommonExclusiveGroups.TIMER_BLOCK_GROUP}} }; /// @@ -312,8 +312,9 @@ namespace GamecraftModdingAPI BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, BlockColor val) => { color.indexInPalette = (byte) (val.Color + val.Darkness * 10); - color.overridePaletteColour = false; - color.needsUpdate = true; + //color.overridePaletteColour = false; + //color.needsUpdate = true; + color.hasNetworkChange = true; color.paletteColour = BlockEngine.ConvertBlockColor(color.indexInPalette); }, value); } @@ -324,14 +325,15 @@ namespace GamecraftModdingAPI /// public float4 CustomColor { - get => BlockEngine.GetBlockInfo(this, (ColourParameterEntityStruct st) => st.overriddenColour); + get => BlockEngine.GetBlockInfo(this, (ColourParameterEntityStruct st) => st.paletteColour); set { BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, float4 val) => { - color.overriddenColour = val; - color.overridePaletteColour = true; - color.needsUpdate = true; + color.paletteColour = val; + //color.overridePaletteColour = true; + //color.needsUpdate = true; + color.hasNetworkChange = true; }, value); } } diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index e39a3e8..5566525 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using Gamecraft.ColourPalette; +using Gamecraft.TimeRunning; using Gamecraft.Wires; using RobocraftX.Blocks; using RobocraftX.Common; @@ -43,8 +44,14 @@ namespace GamecraftModdingAPI.Blocks FasterList cubes = new FasterList(10); var coll = entitiesDB.QueryEntities(); foreach (var (ecoll, _) in coll) - foreach (ref var conn in ecoll) - conn.isProcessed = false; + { + var ecollB = ecoll.ToBuffer(); + for(int i = 0; i < ecoll.count; i++) + { + ref var conn = ref ecollB.buffer[i]; + conn.isProcessed = false; + } + } ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubeStack, cubes, (in GridConnectionsEntityStruct g) => { return false; }); @@ -68,17 +75,17 @@ namespace GamecraftModdingAPI.Blocks return ref structHolder[0]; //Gets a default value automatically } - public ref T GetBlockInfoViewStruct(EGID blockID) where T : struct, INeedEGID, IEntityComponent + public ref T GetBlockInfoViewStruct(EGID blockID) where T : struct, INeedEGID, IEntityViewComponent { if (entitiesDB.Exists(blockID)) { // TODO: optimize by using EntitiesDB internal calls instead of iterating over everything - EntityCollection entities = entitiesDB.QueryEntities(blockID.groupID); + BT> entities = entitiesDB.QueryEntities(blockID.groupID).ToBuffer(); for (int i = 0; i < entities.count; i++) { - if (entities[i].ID == blockID) + if (entities.buffer[i].ID == blockID) { - return ref entities[i]; + return ref entities.buffer[i]; } } } @@ -160,12 +167,13 @@ namespace GamecraftModdingAPI.Blocks public SimBody[] GetSimBodiesFromID(byte id) { var ret = new FasterList(4); - if (!entitiesDB.HasAny(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP)) + if (!entitiesDB.HasAny(CommonExclusiveGroups.OBJID_BLOCK_GROUP)) return new SimBody[0]; - var oids = entitiesDB.QueryEntities(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP); - var connections = entitiesDB.QueryMappedEntities(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP); - foreach (ref ObjectIdEntityStruct oid in oids) + var oids = entitiesDB.QueryEntities(CommonExclusiveGroups.OBJID_BLOCK_GROUP).ToBuffer(); + var connections = entitiesDB.QueryMappedEntities(CommonExclusiveGroups.OBJID_BLOCK_GROUP); + for (int i = 0; i < oids.count; i++) { + ref ObjectIdEntityStruct oid = ref oids.buffer[i]; if (oid.objectId != id) continue; var rid = connections.Entity(oid.ID.entityID).machineRigidBodyId; foreach (var rb in ret) @@ -182,21 +190,26 @@ namespace GamecraftModdingAPI.Blocks public ObjectIdentifier[] GetObjectIDsFromID(byte id, bool sim) { var ret = new FasterList(4); - if (!entitiesDB.HasAny(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP)) + if (!entitiesDB.HasAny(CommonExclusiveGroups.OBJID_BLOCK_GROUP)) return new ObjectIdentifier[0]; - var oids = entitiesDB.QueryEntities(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP); - foreach (ref ObjectIdEntityStruct oid in oids) + var oids = entitiesDB.QueryEntities(CommonExclusiveGroups.OBJID_BLOCK_GROUP).ToBuffer(); + for (int i = 0; i < oids.count; i++) + { + ref ObjectIdEntityStruct oid = ref oids.buffer[i]; if (sim ? oid.simObjectId == id : oid.objectId == id) ret.Add(new ObjectIdentifier(oid.ID)); + } + return ret.ToArray(); } public SimBody[] GetConnectedSimBodies(uint id) { - var joints = entitiesDB.QueryEntities(MachineSimulationGroups.JOINTS_GROUP); + var joints = entitiesDB.QueryEntities(MachineSimulationGroups.JOINTS_GROUP).ToBuffer(); var list = new FasterList(4); - foreach (var joint in joints) + for (int i = 0; i < joints.count; i++) { + ref var joint = ref joints.buffer[i]; if (joint.jointState == JointState.Broken) continue; if (joint.connectedEntityA == id) list.Add(new SimBody(joint.connectedEntityB)); else if (joint.connectedEntityB == id) list.Add(new SimBody(joint.connectedEntityA)); @@ -211,7 +224,7 @@ namespace GamecraftModdingAPI.Blocks var bodies = new HashSet(); foreach (var (coll, _) in groups) { - foreach (var conn in coll) + foreach (var conn in coll.ToBuffer().buffer.ToManagedArray()) { if (conn.clusterId == cid) bodies.Add(conn.machineRigidBodyId); @@ -238,7 +251,7 @@ namespace GamecraftModdingAPI.Blocks var groups = entitiesDB.QueryEntities(); foreach (var (coll, _) in groups) { - foreach (var conn in coll) + foreach (var conn in coll.ToBuffer().buffer.ToManagedArray()) { //Static blocks don't have a cluster ID but the cluster destruction manager should have one if (conn.machineRigidBodyId == sbid && conn.clusterId != uint.MaxValue) return new Cluster(conn.clusterId); @@ -254,7 +267,7 @@ namespace GamecraftModdingAPI.Blocks var set = new HashSet(); foreach (var (coll, _) in groups) { - foreach (var conn in coll) + foreach (var conn in coll.ToBuffer().buffer.ToManagedArray()) { if (conn.machineRigidBodyId == sbid) set.Add(new Block(conn.ID)); diff --git a/GamecraftModdingAPI/Blocks/BlockEngineInit.cs b/GamecraftModdingAPI/Blocks/BlockEngineInit.cs index 70f713a..1bf6c15 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngineInit.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngineInit.cs @@ -14,10 +14,10 @@ namespace GamecraftModdingAPI.Blocks /// internal struct BlockInitData { - public FasterDictionary, ITypeSafeDictionary> Group; + public FasterDictionary Group; } - internal delegate FasterDictionary, ITypeSafeDictionary> GetInitGroup( + internal delegate FasterDictionary GetInitGroup( EntityComponentInitializer initializer); /// diff --git a/GamecraftModdingAPI/Blocks/ConsoleBlock.cs b/GamecraftModdingAPI/Blocks/ConsoleBlock.cs index c8982e4..e696fca 100644 --- a/GamecraftModdingAPI/Blocks/ConsoleBlock.cs +++ b/GamecraftModdingAPI/Blocks/ConsoleBlock.cs @@ -16,7 +16,7 @@ namespace GamecraftModdingAPI.Blocks { } - public ConsoleBlock(uint id): base(new EGID(id, CommonExclusiveGroups.BUILD_CONSOLE_BLOCK_GROUP)) + public ConsoleBlock(uint id): base(new EGID(id, CommonExclusiveGroups.CONSOLE_BLOCK_GROUP)) { } diff --git a/GamecraftModdingAPI/Blocks/DampedSpring.cs b/GamecraftModdingAPI/Blocks/DampedSpring.cs index 96e628d..5a5a936 100644 --- a/GamecraftModdingAPI/Blocks/DampedSpring.cs +++ b/GamecraftModdingAPI/Blocks/DampedSpring.cs @@ -10,7 +10,7 @@ namespace GamecraftModdingAPI.Blocks { } - public DampedSpring(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_DAMPEDSPRING_BLOCK_GROUP)) + public DampedSpring(uint id) : base(new EGID(id, CommonExclusiveGroups.DAMPEDSPRING_BLOCK_GROUP)) { } diff --git a/GamecraftModdingAPI/Blocks/LogicGate.cs b/GamecraftModdingAPI/Blocks/LogicGate.cs index 124bc10..2ec4cef 100644 --- a/GamecraftModdingAPI/Blocks/LogicGate.cs +++ b/GamecraftModdingAPI/Blocks/LogicGate.cs @@ -9,7 +9,7 @@ namespace GamecraftModdingAPI.Blocks { } - public LogicGate(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_LOGIC_BLOCK_GROUP)) + public LogicGate(uint id) : base(new EGID(id, CommonExclusiveGroups.LOGIC_BLOCK_GROUP)) { } } diff --git a/GamecraftModdingAPI/Blocks/Motor.cs b/GamecraftModdingAPI/Blocks/Motor.cs index 3c38a52..0a69d27 100644 --- a/GamecraftModdingAPI/Blocks/Motor.cs +++ b/GamecraftModdingAPI/Blocks/Motor.cs @@ -15,7 +15,7 @@ namespace GamecraftModdingAPI.Blocks { } - public Motor(uint id): base(new EGID(id, CommonExclusiveGroups.BUILD_MOTOR_BLOCK_GROUP)) + public Motor(uint id): base(new EGID(id, CommonExclusiveGroups.MOTOR_BLOCK_GROUP)) { } diff --git a/GamecraftModdingAPI/Blocks/MusicBlock.cs b/GamecraftModdingAPI/Blocks/MusicBlock.cs index fc3c880..6b99b6f 100644 --- a/GamecraftModdingAPI/Blocks/MusicBlock.cs +++ b/GamecraftModdingAPI/Blocks/MusicBlock.cs @@ -20,7 +20,7 @@ namespace GamecraftModdingAPI.Blocks { } - public MusicBlock(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_MUSIC_BLOCK_GROUP)) + public MusicBlock(uint id) : base(new EGID(id, CommonExclusiveGroups.MUSIC_BLOCK_GROUP)) { } diff --git a/GamecraftModdingAPI/Blocks/ObjectIdentifier.cs b/GamecraftModdingAPI/Blocks/ObjectIdentifier.cs index 0dc835a..1233343 100644 --- a/GamecraftModdingAPI/Blocks/ObjectIdentifier.cs +++ b/GamecraftModdingAPI/Blocks/ObjectIdentifier.cs @@ -10,7 +10,7 @@ namespace GamecraftModdingAPI.Blocks { } - public ObjectIdentifier(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP)) + public ObjectIdentifier(uint id) : base(new EGID(id, CommonExclusiveGroups.OBJID_BLOCK_GROUP)) { } diff --git a/GamecraftModdingAPI/Blocks/Piston.cs b/GamecraftModdingAPI/Blocks/Piston.cs index c3f2497..04b3aeb 100644 --- a/GamecraftModdingAPI/Blocks/Piston.cs +++ b/GamecraftModdingAPI/Blocks/Piston.cs @@ -15,7 +15,7 @@ namespace GamecraftModdingAPI.Blocks { } - public Piston(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_PISTON_BLOCK_GROUP)) + public Piston(uint id) : base(new EGID(id, CommonExclusiveGroups.PISTON_BLOCK_GROUP)) { } diff --git a/GamecraftModdingAPI/Blocks/PlacementEngine.cs b/GamecraftModdingAPI/Blocks/PlacementEngine.cs index cb1cdee..cf9a80f 100644 --- a/GamecraftModdingAPI/Blocks/PlacementEngine.cs +++ b/GamecraftModdingAPI/Blocks/PlacementEngine.cs @@ -16,6 +16,7 @@ using UnityEngine; using GamecraftModdingAPI.Utility; using GamecraftModdingAPI.Engines; using GamecraftModdingAPI.Players; +using RobocraftX.Rendering.GPUI; namespace GamecraftModdingAPI.Blocks { @@ -81,7 +82,7 @@ namespace GamecraftModdingAPI.Blocks structInitializer.Init(new ColourParameterEntityStruct { indexInPalette = colour.indexInPalette, - needsUpdate = true + hasNetworkChange = true }); uint prefabId = PrefabsID.GetPrefabId(dbid, 0); structInitializer.Init(new GFXPrefabEntityStructGPUI(prefabId)); diff --git a/GamecraftModdingAPI/Blocks/Servo.cs b/GamecraftModdingAPI/Blocks/Servo.cs index 1177fb6..606a48a 100644 --- a/GamecraftModdingAPI/Blocks/Servo.cs +++ b/GamecraftModdingAPI/Blocks/Servo.cs @@ -15,7 +15,7 @@ namespace GamecraftModdingAPI.Blocks { } - public Servo(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_SERVO_BLOCK_GROUP)) + public Servo(uint id) : base(new EGID(id, CommonExclusiveGroups.SERVO_BLOCK_GROUP)) { } diff --git a/GamecraftModdingAPI/Blocks/SfxBlock.cs b/GamecraftModdingAPI/Blocks/SfxBlock.cs index f7efe6d..88d69d2 100644 --- a/GamecraftModdingAPI/Blocks/SfxBlock.cs +++ b/GamecraftModdingAPI/Blocks/SfxBlock.cs @@ -14,7 +14,7 @@ namespace GamecraftModdingAPI.Blocks { } - public SfxBlock(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_SIMPLESFX_BLOCK_GROUP /* This could also be BUILD_LOOPEDSFX_BLOCK_GROUP */)) + public SfxBlock(uint id) : base(new EGID(id, CommonExclusiveGroups.SIMPLESFX_BLOCK_GROUP /* This could also be BUILD_LOOPEDSFX_BLOCK_GROUP */)) { } diff --git a/GamecraftModdingAPI/Blocks/SignalEngine.cs b/GamecraftModdingAPI/Blocks/SignalEngine.cs index 763a1a1..0980d79 100644 --- a/GamecraftModdingAPI/Blocks/SignalEngine.cs +++ b/GamecraftModdingAPI/Blocks/SignalEngine.cs @@ -115,7 +115,8 @@ namespace GamecraftModdingAPI.Blocks public bool SetSignal(uint signalID, float signal, bool input = true) { var array = GetSignalStruct(signalID, out uint index, input); - if (array.count > 0) array[index].valueAsFloat = signal; + var arrayB = array.ToBuffer(); + if (array.count > 0) arrayB.buffer[index].valueAsFloat = signal; return false; } @@ -128,9 +129,10 @@ namespace GamecraftModdingAPI.Blocks public float AddSignal(uint signalID, float signal, bool clamp = true, bool input = true) { var array = GetSignalStruct(signalID, out uint index, input); + var arrayB = array.ToBuffer(); if (array.count > 0) { - ref var channelData = ref array[index]; + ref var channelData = ref arrayB.buffer[index]; channelData.valueAsFloat += signal; if (clamp) { @@ -159,7 +161,8 @@ namespace GamecraftModdingAPI.Blocks public float GetSignal(uint signalID, bool input = true) { var array = GetSignalStruct(signalID, out uint index, input); - return array.count > 0 ? array[index].valueAsFloat : 0f; + var arrayB = array.ToBuffer(); + return array.count > 0 ? arrayB.buffer[index].valueAsFloat : 0f; } public uint[] GetSignalIDs(EGID blockID, bool input = true) @@ -244,13 +247,14 @@ namespace GamecraftModdingAPI.Blocks { ref PortEntityStruct port = ref entitiesDB.QueryEntity(portID); var wires = entitiesDB.QueryEntities(NamedExclusiveGroup.Group); + var wiresB = wires.ToBuffer().buffer; for (uint i = 0; i < wires.count; i++) { - if ((wires[i].destinationPortUsage == port.usage && wires[i].destinationBlockEGID == blockID) - || (wires[i].sourcePortUsage == port.usage && wires[i].sourceBlockEGID == blockID)) + if ((wiresB[i].destinationPortUsage == port.usage && wiresB[i].destinationBlockEGID == blockID) + || (wiresB[i].sourcePortUsage == port.usage && wiresB[i].sourceBlockEGID == blockID)) { exists = true; - return ref wires[i]; + return ref wiresB[i]; } } exists = false; @@ -286,6 +290,7 @@ namespace GamecraftModdingAPI.Blocks } EntityCollection wires = entitiesDB.QueryEntities(NamedExclusiveGroup.Group); + var wiresB = wires.ToBuffer().buffer; for (int endIndex = 0; endIndex < endPorts.Length; endIndex++) { PortEntityStruct endPES = entitiesDB.QueryEntity(endPorts[endIndex]); @@ -294,11 +299,11 @@ namespace GamecraftModdingAPI.Blocks PortEntityStruct startPES = entitiesDB.QueryEntity(startPorts[startIndex]); for (int w = 0; w < wires.count; w++) { - if ((wires[w].destinationPortUsage == endPES.usage && wires[w].destinationBlockEGID == endBlock) - && (wires[w].sourcePortUsage == startPES.usage && wires[w].sourceBlockEGID == startBlock)) + if ((wiresB[w].destinationPortUsage == endPES.usage && wiresB[w].destinationBlockEGID == endBlock) + && (wiresB[w].sourcePortUsage == startPES.usage && wiresB[w].sourceBlockEGID == startBlock)) { exists = true; - return ref wires[w]; + return ref wiresB[w]; } } } @@ -313,10 +318,11 @@ namespace GamecraftModdingAPI.Blocks { ref PortEntityStruct port = ref entitiesDB.QueryEntity(portID); var channels = entitiesDB.QueryEntities(NamedExclusiveGroup.Group); + var channelsB = channels.ToBuffer(); if (port.firstChannelIndexCachedInSim < channels.count) { exists = true; - return ref channels[port.firstChannelIndexCachedInSim]; + return ref channelsB.buffer[port.firstChannelIndexCachedInSim]; } exists = false; ChannelDataStruct[] defRef = new ChannelDataStruct[1]; @@ -327,8 +333,15 @@ namespace GamecraftModdingAPI.Blocks { var res = new FasterList(); foreach (var (coll, _) in entitiesDB.QueryEntities()) - foreach (ref BlockPortsStruct s in coll) - res.Add(s.ID); + { + var collB = coll.ToBuffer(); + for (int i = 0; i < coll.count; i++) + { + ref BlockPortsStruct s = ref collB.buffer[i]; + res.Add(s.ID); + } + } + return res.ToArray(); } @@ -358,15 +371,16 @@ namespace GamecraftModdingAPI.Blocks return result; } - private T[] Search(ExclusiveGroup group, Func isMatch) where T : struct, IEntityComponent + private T[] Search(ExclusiveGroup group, Func isMatch) where T : unmanaged, IEntityComponent { FasterList results = new FasterList(); EntityCollection components = entitiesDB.QueryEntities(group); + var componentsB = components.ToBuffer(); for (uint i = 0; i < components.count; i++) { - if (isMatch(components[i])) + if (isMatch(componentsB.buffer[i])) { - results.Add(components[i]); + results.Add(componentsB.buffer[i]); } } return results.ToArray(); diff --git a/GamecraftModdingAPI/Blocks/SpawnPoint.cs b/GamecraftModdingAPI/Blocks/SpawnPoint.cs index 7616acb..17bffd9 100644 --- a/GamecraftModdingAPI/Blocks/SpawnPoint.cs +++ b/GamecraftModdingAPI/Blocks/SpawnPoint.cs @@ -17,7 +17,7 @@ namespace GamecraftModdingAPI.Blocks { } - public SpawnPoint(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_SPAWNPOINT_BLOCK_GROUP)) + public SpawnPoint(uint id) : base(new EGID(id, CommonExclusiveGroups.SPAWNPOINT_BLOCK_GROUP)) { } diff --git a/GamecraftModdingAPI/Blocks/TextBlock.cs b/GamecraftModdingAPI/Blocks/TextBlock.cs index e696dda..6fa5487 100644 --- a/GamecraftModdingAPI/Blocks/TextBlock.cs +++ b/GamecraftModdingAPI/Blocks/TextBlock.cs @@ -16,7 +16,7 @@ namespace GamecraftModdingAPI.Blocks { } - public TextBlock(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_TEXT_BLOCK_GROUP)) + public TextBlock(uint id) : base(new EGID(id, CommonExclusiveGroups.TEXT_BLOCK_GROUP)) { } diff --git a/GamecraftModdingAPI/Blocks/Timer.cs b/GamecraftModdingAPI/Blocks/Timer.cs index 1aeecd9..0bbd302 100644 --- a/GamecraftModdingAPI/Blocks/Timer.cs +++ b/GamecraftModdingAPI/Blocks/Timer.cs @@ -17,7 +17,7 @@ namespace GamecraftModdingAPI.Blocks { } - public Timer(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_TIMER_BLOCK_GROUP)) + public Timer(uint id) : base(new EGID(id, CommonExclusiveGroups.TIMER_BLOCK_GROUP)) { } diff --git a/GamecraftModdingAPI/GamecraftModdingAPI.csproj b/GamecraftModdingAPI/GamecraftModdingAPI.csproj index 59de2af..cdbb4d9 100644 --- a/GamecraftModdingAPI/GamecraftModdingAPI.csproj +++ b/GamecraftModdingAPI/GamecraftModdingAPI.csproj @@ -25,11 +25,16 @@ + - - ..\ref\GamecraftPreview_Data\Managed\Accessibility.dll - ..\..\ref\GamecraftPreview_Data\Managed\Accessibility.dll + + ..\ref\GamecraftPreview_Data\Managed\IllusionInjector.dll + ..\..\ref\GamecraftPreview_Data\Managed\IllusionInjector.dll + + + ..\ref\GamecraftPreview_Data\Managed\IllusionPlugin.dll + ..\..\ref\GamecraftPreview_Data\Managed\IllusionPlugin.dll ..\ref\GamecraftPreview_Data\Managed\Analytics.dll @@ -83,14 +88,14 @@ ..\ref\GamecraftPreview_Data\Managed\FMOD.dll ..\..\ref\GamecraftPreview_Data\Managed\FMOD.dll + + ..\ref\GamecraftPreview_Data\Managed\FullGame.dll + ..\..\ref\GamecraftPreview_Data\Managed\FullGame.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.AudioBlocks.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.AudioBlocks.dll - - ..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlockCompositionRoot.dll - ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlockCompositionRoot.dll - ..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlockEntityFactory.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlockEntityFactory.dll @@ -135,6 +140,10 @@ ..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.TimerBlock.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.Blocks.TimerBlock.dll + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.CharacterVulnerability.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.CharacterVulnerability.dll @@ -187,6 +196,10 @@ ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll + + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll + ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll + ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll @@ -243,66 +256,10 @@ ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll - - ..\ref\GamecraftPreview_Data\Managed\FullGame.dll - ..\..\ref\GamecraftPreview_Data\Managed\FullGame.dll - - - ..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll - ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll - - - ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - ..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUIs.Hotbar.BlueprintsHotbar.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.GUIs.Hotbar.BlueprintsHotbar.dll - - ..\ref\GamecraftPreview_Data\Managed\IllusionInjector.dll - ..\..\ref\GamecraftPreview_Data\Managed\IllusionInjector.dll - - - ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Common.dll - ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Common.dll - - - ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Input.dll - ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Input.dll - - - ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Rendering.dll - ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Rendering.dll - - - ..\ref\GamecraftPreview_Data\Managed\Svelto.ECS.dll - ..\..\ref\GamecraftPreview_Data\Managed\Svelto.ECS.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.DataFlowGraph.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.DataFlowGraph.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Properties.UI.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Properties.UI.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.Hybrid.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.Hybrid.dll - - - ..\ref\GamecraftPreview_Data\Managed\UnityEngine.dll - ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.dll - - - ..\ref\GamecraftPreview_Data\Managed\UnityEngine.PhysicsModule.dll - ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.PhysicsModule.dll - - - ..\ref\GamecraftPreview_Data\Managed\UnityEngine.TLSModule.dll - ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.TLSModule.dll - ..\ref\GamecraftPreview_Data\Managed\Gamecraft.InventoryTimeRunning.dll ..\..\ref\GamecraftPreview_Data\Managed\Gamecraft.InventoryTimeRunning.dll @@ -379,18 +336,6 @@ ..\ref\GamecraftPreview_Data\Managed\Havok.Physics.Hybrid.dll ..\..\ref\GamecraftPreview_Data\Managed\Havok.Physics.Hybrid.dll - - ..\ref\GamecraftPreview_Data\Managed\IL3DN_FOG.dll - ..\..\ref\GamecraftPreview_Data\Managed\IL3DN_FOG.dll - - - ..\ref\GamecraftPreview_Data\Managed\IllusionPlugin.dll - ..\..\ref\GamecraftPreview_Data\Managed\IllusionPlugin.dll - - - ..\ref\GamecraftPreview_Data\Managed\JWT.dll - ..\..\ref\GamecraftPreview_Data\Managed\JWT.dll - ..\ref\GamecraftPreview_Data\Managed\LZ4.dll ..\..\ref\GamecraftPreview_Data\Managed\LZ4.dll @@ -407,18 +352,6 @@ ..\ref\GamecraftPreview_Data\Managed\MultiplayerTest.dll ..\..\ref\GamecraftPreview_Data\Managed\MultiplayerTest.dll - - ..\ref\GamecraftPreview_Data\Managed\netstandard.dll - ..\..\ref\GamecraftPreview_Data\Managed\netstandard.dll - - - ..\ref\GamecraftPreview_Data\Managed\Newtonsoft.Json.dll - ..\..\ref\GamecraftPreview_Data\Managed\Newtonsoft.Json.dll - - - ..\ref\GamecraftPreview_Data\Managed\Novell.Directory.Ldap.dll - ..\..\ref\GamecraftPreview_Data\Managed\Novell.Directory.Ldap.dll - ..\ref\GamecraftPreview_Data\Managed\RCX.ScreenshotTaker.dll ..\..\ref\GamecraftPreview_Data\Managed\RCX.ScreenshotTaker.dll @@ -467,6 +400,10 @@ ..\ref\GamecraftPreview_Data\Managed\RobocraftX.ClusterToWireConversion.dll ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.ClusterToWireConversion.dll + + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Common.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Common.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.ControlsScreen.dll ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.ControlsScreen.dll @@ -523,6 +460,10 @@ ..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUIs.WorkshopPrefabs.dll ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.GUIs.WorkshopPrefabs.dll + + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Input.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Input.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.MachineEditor.dll ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.MachineEditor.dll @@ -579,6 +520,10 @@ ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Player.dll ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Player.dll + + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Rendering.dll + ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Rendering.dll + ..\ref\GamecraftPreview_Data\Managed\RobocraftX.Rendering.Mock.dll ..\..\ref\GamecraftPreview_Data\Managed\RobocraftX.Rendering.Mock.dll @@ -631,9 +576,13 @@ ..\ref\GamecraftPreview_Data\Managed\StringFormatter.dll ..\..\ref\GamecraftPreview_Data\Managed\StringFormatter.dll - - ..\ref\GamecraftPreview_Data\Managed\Svelto.Common_3.dll - ..\..\ref\GamecraftPreview_Data\Managed\Svelto.Common_3.dll + + ..\ref\GamecraftPreview_Data\Managed\Svelto.Common.dll + ..\..\ref\GamecraftPreview_Data\Managed\Svelto.Common.dll + + + ..\ref\GamecraftPreview_Data\Managed\Svelto.ECS.dll + ..\..\ref\GamecraftPreview_Data\Managed\Svelto.ECS.dll ..\ref\GamecraftPreview_Data\Managed\Svelto.Services.dll @@ -643,114 +592,6 @@ ..\ref\GamecraftPreview_Data\Managed\Svelto.Tasks.dll ..\..\ref\GamecraftPreview_Data\Managed\Svelto.Tasks.dll - - ..\ref\GamecraftPreview_Data\Managed\Unity.Deformations.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Deformations.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Entities.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Entities.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Entities.Hybrid.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Entities.Hybrid.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Jobs.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Jobs.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.MemoryProfiler.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.MemoryProfiler.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Physics.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Physics.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Physics.Hybrid.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Physics.Hybrid.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Platforms.Common.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Platforms.Common.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Postprocessing.Runtime.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Postprocessing.Runtime.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Properties.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Properties.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Properties.Reflection.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Properties.Reflection.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipeline.Universal.ShaderLibrary.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipeline.Universal.ShaderLibrary.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Runtime.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Runtime.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Shaders.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Shaders.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.ResourceManager.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.ResourceManager.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Scenes.Hybrid.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Scenes.Hybrid.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.ScriptableBuildPipeline.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.ScriptableBuildPipeline.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Serialization.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Serialization.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.TextMeshPro.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.TextMeshPro.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Timeline.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Timeline.dll - - - ..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.dll - ..\ref\GamecraftPreview_Data\Managed\UltimateDecals.dll ..\..\ref\GamecraftPreview_Data\Managed\UltimateDecals.dll @@ -795,14 +636,138 @@ ..\ref\GamecraftPreview_Data\Managed\Unity.Burst.dll ..\..\ref\GamecraftPreview_Data\Managed\Unity.Burst.dll - - ..\ref\GamecraftPreview_Data\Managed\Unity.Burst.Unsafe.dll - ..\..\ref\GamecraftPreview_Data\Managed\Unity.Burst.Unsafe.dll - ..\ref\GamecraftPreview_Data\Managed\Unity.Collections.dll ..\..\ref\GamecraftPreview_Data\Managed\Unity.Collections.dll + + ..\ref\GamecraftPreview_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.DataFlowGraph.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.DataFlowGraph.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Deformations.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Deformations.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Entities.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Entities.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Entities.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Entities.Hybrid.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.InternalAPIEngineBridge.002.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.InternalAPIEngineBridge.002.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Jobs.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Jobs.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.MemoryProfiler.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.MemoryProfiler.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Physics.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Physics.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Physics.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Physics.Hybrid.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Platforms.Common.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Platforms.Common.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Postprocessing.Runtime.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Postprocessing.Runtime.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Properties.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Properties.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Properties.Reflection.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Properties.Reflection.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Properties.UI.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Properties.UI.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipeline.Universal.ShaderLibrary.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipeline.Universal.ShaderLibrary.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Runtime.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Runtime.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Shaders.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.RenderPipelines.Universal.Shaders.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.ResourceManager.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.ResourceManager.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Scenes.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Scenes.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.ScriptableBuildPipeline.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.ScriptableBuildPipeline.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Serialization.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Serialization.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.TextMeshPro.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.TextMeshPro.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Timeline.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Timeline.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.Hybrid.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Transforms.Hybrid.dll + ..\ref\GamecraftPreview_Data\Managed\Unity.VisualEffectGraph.Runtime.dll ..\..\ref\GamecraftPreview_Data\Managed\Unity.VisualEffectGraph.Runtime.dll @@ -859,6 +824,10 @@ ..\ref\GamecraftPreview_Data\Managed\UnityEngine.DirectorModule.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.DirectorModule.dll + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.dll + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.DSPGraphModule.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.DSPGraphModule.dll @@ -911,6 +880,10 @@ ..\ref\GamecraftPreview_Data\Managed\UnityEngine.Physics2DModule.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.Physics2DModule.dll + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.PhysicsModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.PhysicsModule.dll + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.ProfilerModule.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.ProfilerModule.dll @@ -963,6 +936,10 @@ ..\ref\GamecraftPreview_Data\Managed\UnityEngine.TilemapModule.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.TilemapModule.dll + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.TLSModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.TLSModule.dll + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UI.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UI.dll @@ -971,6 +948,10 @@ ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UIElementsModule.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UIElementsModule.dll + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UIElementsNativeModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UIElementsNativeModule.dll + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.UIModule.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.UIModule.dll @@ -1027,6 +1008,10 @@ ..\ref\GamecraftPreview_Data\Managed\UnityEngine.VideoModule.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.VideoModule.dll + + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.VirtualTexturingModule.dll + ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.VirtualTexturingModule.dll + ..\ref\GamecraftPreview_Data\Managed\UnityEngine.VRModule.dll ..\..\ref\GamecraftPreview_Data\Managed\UnityEngine.VRModule.dll @@ -1047,6 +1032,30 @@ ..\ref\GamecraftPreview_Data\Managed\VisualProfiler.dll ..\..\ref\GamecraftPreview_Data\Managed\VisualProfiler.dll + + ..\ref\GamecraftPreview_Data\Managed\Accessibility.dll + ..\..\ref\GamecraftPreview_Data\Managed\Accessibility.dll + + + ..\ref\GamecraftPreview_Data\Managed\JWT.dll + ..\..\ref\GamecraftPreview_Data\Managed\JWT.dll + + + ..\ref\GamecraftPreview_Data\Managed\netstandard.dll + ..\..\ref\GamecraftPreview_Data\Managed\netstandard.dll + + + ..\ref\GamecraftPreview_Data\Managed\Newtonsoft.Json.dll + ..\..\ref\GamecraftPreview_Data\Managed\Newtonsoft.Json.dll + + + ..\ref\GamecraftPreview_Data\Managed\Novell.Directory.Ldap.dll + ..\..\ref\GamecraftPreview_Data\Managed\Novell.Directory.Ldap.dll + + + ..\ref\GamecraftPreview_Data\Managed\Unity.Burst.Unsafe.dll + ..\..\ref\GamecraftPreview_Data\Managed\Unity.Burst.Unsafe.dll + \ No newline at end of file diff --git a/GamecraftModdingAPI/Inventory/HotbarEngine.cs b/GamecraftModdingAPI/Inventory/HotbarEngine.cs index d5eb2d8..34cdf12 100644 --- a/GamecraftModdingAPI/Inventory/HotbarEngine.cs +++ b/GamecraftModdingAPI/Inventory/HotbarEngine.cs @@ -36,13 +36,13 @@ namespace GamecraftModdingAPI.Inventory public bool SelectBlock(int block, uint playerID, bool cubeSelectedByPick = false) { - var inputs = entitiesDB.QueryEntities(InputExclusiveGroups.LocalPlayers); + var inputs = entitiesDB.QueryEntities(InputExclusiveGroups.LocalPlayers).ToBuffer(); if (inputs.count == 0) return false; for (int i = 0; i < inputs.count; i++) { - if (inputs[i].ID.entityID == playerID) { - inputs[i].cubeSelectedByPick = cubeSelectedByPick; - inputs[i].selectedCube = block; + if (inputs.buffer[i].ID.entityID == playerID) { + inputs.buffer[i].cubeSelectedByPick = cubeSelectedByPick; + inputs.buffer[i].selectedCube = block; return true; } } diff --git a/GamecraftModdingAPI/Players/PlayerEngine.cs b/GamecraftModdingAPI/Players/PlayerEngine.cs index 6d461f2..e253eac 100644 --- a/GamecraftModdingAPI/Players/PlayerEngine.cs +++ b/GamecraftModdingAPI/Players/PlayerEngine.cs @@ -50,10 +50,10 @@ namespace GamecraftModdingAPI.Players public uint GetLocalPlayer() { if (!isReady) return uint.MaxValue; - var localPlayers = entitiesDB.QueryEntities(PlayersExclusiveGroups.LocalPlayers); + var localPlayers = entitiesDB.QueryEntities(PlayersExclusiveGroups.LocalPlayers).ToBuffer(); if (localPlayers.count > 0) { - return localPlayers[0].ID.entityID; + return localPlayers.buffer[0].ID.entityID; } return uint.MaxValue; } @@ -61,10 +61,10 @@ namespace GamecraftModdingAPI.Players public uint GetRemotePlayer() { if (!isReady) return uint.MaxValue; - var localPlayers = entitiesDB.QueryEntities(PlayersExclusiveGroups.RemotePlayers); + var localPlayers = entitiesDB.QueryEntities(PlayersExclusiveGroups.RemotePlayers).ToBuffer(); if (localPlayers.count > 0) { - return localPlayers[0].ID.entityID; + return localPlayers.buffer[0].ID.entityID; } return uint.MaxValue; } diff --git a/GamecraftModdingAPI/Tests/TestRoot.cs b/GamecraftModdingAPI/Tests/TestRoot.cs index 6acb51c..22f3035 100644 --- a/GamecraftModdingAPI/Tests/TestRoot.cs +++ b/GamecraftModdingAPI/Tests/TestRoot.cs @@ -65,7 +65,7 @@ namespace GamecraftModdingAPI.Tests _testsCountPassed = 0; _testsCountFailed = 0; // flow control - Game.Enter += (sender, args) => { GameTests().RunOn(RobocraftX.Schedulers.Lean.EveryFrameStepRunner_RUNS_IN_TIME_STOPPED_AND_RUNNING); }; + Game.Enter += (sender, args) => { GameTests().RunOn(RobocraftX.Schedulers.Lean.EveryFrameStepRunner_TimeRunningAndStopped); }; Game.Exit += (s, a) => state = "ReturningFromGame"; Client.EnterMenu += (sender, args) => { From d891f12701eb45344fc8742a8285a7ba890ce6b2 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Mon, 9 Nov 2020 16:33:12 -0500 Subject: [PATCH 22/32] Fix harmony patch error due to fixed name --- .../Inventory/HotbarSlotSelectionHandlerEnginePatch.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GamecraftModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs b/GamecraftModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs index 9a81f99..a0ad5c1 100644 --- a/GamecraftModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs +++ b/GamecraftModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs @@ -15,7 +15,7 @@ namespace GamecraftModdingAPI.Inventory public static BlockIDs EquippedPartID { get => (BlockIDs)selectedBlockInt; } - private static MethodInfo PatchedMethod { get; } = AccessTools.Method("Gamecraft.GUI.Hotbar.Blocks.SyncHotbarSlotSelectedToEquipedPartEngine:ActivateSlotForCube", parameters: new Type[] { typeof(uint), typeof(int), typeof(ExclusiveGroupStruct) }); + private static MethodInfo PatchedMethod { get; } = AccessTools.Method("Gamecraft.GUI.Hotbar.Blocks.SyncHotbarSlotSelectedToEquippedPartEngine:ActivateSlotForCube", parameters: new Type[] { typeof(uint), typeof(int), typeof(ExclusiveGroupStruct) }); public static void Prefix(uint playerID, int selectedDBPartID, ExclusiveGroupStruct groupID) { From 1a986056a12cca0d07ca4be7516922a3fe65208b Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 10 Nov 2020 16:37:20 +0100 Subject: [PATCH 23/32] 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(); From 2179ba6386f96fe0a6f27491b7d668a3f0c2ed35 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 10 Nov 2020 19:28:36 +0100 Subject: [PATCH 24/32] Add support for setting and placing blueprints --- GamecraftModdingAPI/Blocks/BlueprintEngine.cs | 145 +++++++++++++++++- GamecraftModdingAPI/Blueprint.cs | 48 +++++- GamecraftModdingAPI/Utility/FullGameFields.cs | 9 ++ 3 files changed, 199 insertions(+), 3 deletions(-) diff --git a/GamecraftModdingAPI/Blocks/BlueprintEngine.cs b/GamecraftModdingAPI/Blocks/BlueprintEngine.cs index 7f0a616..f2f0bef 100644 --- a/GamecraftModdingAPI/Blocks/BlueprintEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlueprintEngine.cs @@ -1,13 +1,22 @@ -using System.Reflection; +using System; +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; namespace GamecraftModdingAPI.Blocks { @@ -18,8 +27,20 @@ namespace GamecraftModdingAPI.Blocks private readonly NativeDynamicArray selectedBlocksInGroup = new NativeDynamicArray(); private readonly NativeHashSet removedConnections = new NativeHashSet(); + 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 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 globalBlockMap; public void Ready() { @@ -55,6 +76,109 @@ namespace GamecraftModdingAPI.Blocks }); } + 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(entitiesDb, (uint) local1.currentBlockGroup, BlockGroupExclusiveGroups.BlockGroupEntityGroup); + //ref ColliderAabb collider = ref EntityNativeDBExtensions.QueryEntity(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) 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(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) 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); + } + public string Name { get; } = "GamecraftModdingAPIBlueprintGameEngine"; public bool isRemovable { get; } @@ -66,6 +190,7 @@ namespace GamecraftModdingAPI.Blocks { nativeRemove = entityFunctions.ToNativeRemove("GCAPI" + nameof(BlueprintEngine)); connectionFactory = machineGraphConnectionEntityFactory; + BlueprintEngine.entityFunctions = entityFunctions; } public static MethodBase TargetMethod() @@ -73,5 +198,23 @@ namespace GamecraftModdingAPI.Blocks return AccessTools.Constructor(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.RemoveBlockEngine")); } } + + [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")); + } + } } } \ No newline at end of file diff --git a/GamecraftModdingAPI/Blueprint.cs b/GamecraftModdingAPI/Blueprint.cs index de6d65e..26876f6 100644 --- a/GamecraftModdingAPI/Blueprint.cs +++ b/GamecraftModdingAPI/Blueprint.cs @@ -1,13 +1,20 @@ -using Gamecraft.GUI.Blueprints; +using System; +using Unity.Mathematics; namespace GamecraftModdingAPI { /// /// Represents a blueprint in the inventory. When placed it becomes a block group. /// - public class Blueprint + public class Blueprint : IDisposable { public uint Id { get; } + + internal Blueprint(uint id) + { + Id = id; + BlockGroup._engine.InitBlueprint(id); + } /*public static void SelectBlueprint(Blueprint blueprint) { @@ -16,5 +23,42 @@ namespace GamecraftModdingAPI blueprintResourceId = blueprint.Id }); }*/ + + /// + /// Creates a new, empty blueprint. It will be deleted on disposal unless the game holds a reference to it. + /// + /// A blueprint that doesn't have any blocks + public static Blueprint Create() + { + return new Blueprint(BlockGroup._engine.CreateBlueprint()); + } + + /// + /// Set the blocks that the blueprint contains. + /// + /// The array of blocks to use + /// The anchor position of the blueprint + /// The rotation of the blueprint + public void SetStoredBlocks(Block[] blocks, float3 position = default, float3 rotation = default) + { + BlockGroup._engine.ReplaceBlueprint(Player.LocalPlayer.Id, Id, blocks, position, + quaternion.Euler(rotation)); + } + + /// + /// Places the blocks the blueprint contains at the specified position and rotation. + /// + /// The position of the blueprint + /// The rotation of the blueprint + /// An array of the placed blocks + public Block[] PlaceBlocks(float3 position, float3 rotation) + { + return BlockGroup._engine.PlaceBlueprintBlocks(Id, Player.LocalPlayer.Id, position, rotation); + } + + public void Dispose() + { + BlockGroup._engine.DisposeBlueprint(Id); + } } } \ No newline at end of file diff --git a/GamecraftModdingAPI/Utility/FullGameFields.cs b/GamecraftModdingAPI/Utility/FullGameFields.cs index 8fd8895..432103d 100644 --- a/GamecraftModdingAPI/Utility/FullGameFields.cs +++ b/GamecraftModdingAPI/Utility/FullGameFields.cs @@ -12,6 +12,7 @@ using RobocraftX.GUI; using RobocraftX.Multiplayer; using RobocraftX.Rendering; using Svelto.Context; +using Svelto.DataStructures; using Svelto.ECS; using Svelto.ECS.Schedulers.Unity; using UnityEngine; @@ -159,6 +160,14 @@ namespace GamecraftModdingAPI.Utility } } + public static FasterList _deserialisedBlockMap + { + get + { + return (FasterList) fgcr?.Field("_deserialisedBlockMap").GetValue(); + } + } + private static Traverse fgcr; public static void Init(FullGameCompositionRoot instance) From f1376f5df6a4d01183f610391458df400826f973 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 10 Nov 2020 23:08:27 +0100 Subject: [PATCH 25/32] Replace ToManagedArray() and fix getting blocks from group --- GamecraftModdingAPI/App/GameGameEngine.cs | 21 ++++++++++--- GamecraftModdingAPI/BlockGroup.cs | 24 +++++++++++--- GamecraftModdingAPI/Blocks/BlockEngine.cs | 17 +++++++--- GamecraftModdingAPI/Blocks/BlueprintEngine.cs | 31 ++++++++++++------- 4 files changed, 68 insertions(+), 25 deletions(-) diff --git a/GamecraftModdingAPI/App/GameGameEngine.cs b/GamecraftModdingAPI/App/GameGameEngine.cs index dea3821..85fb672 100644 --- a/GamecraftModdingAPI/App/GameGameEngine.cs +++ b/GamecraftModdingAPI/App/GameGameEngine.cs @@ -102,16 +102,27 @@ namespace GamecraftModdingAPI.App if (filter == BlockIDs.Invalid) { foreach (var (blocks, _) in allBlocks) - foreach (var block in blocks.ToBuffer().buffer.ToManagedArray()) - blockEGIDs.Add(block.ID); + { + var buffer = blocks.ToBuffer().buffer; + for (int i = 0; i < buffer.capacity; i++) + blockEGIDs.Add(buffer[i].ID); + } + return blockEGIDs.ToArray(); } else { foreach (var (blocks, _) in allBlocks) - foreach (var block in blocks.ToBuffer().buffer.ToManagedArray()) - if (block.DBID == (ulong) filter) - blockEGIDs.Add(block.ID); + { + var array = blocks.ToBuffer().buffer; + for (var index = 0; index < array.capacity; index++) + { + var block = array[index]; + if (block.DBID == (ulong) filter) + blockEGIDs.Add(block.ID); + } + } + return blockEGIDs.ToArray(); } } diff --git a/GamecraftModdingAPI/BlockGroup.cs b/GamecraftModdingAPI/BlockGroup.cs index 2cd0f42..8d9e761 100644 --- a/GamecraftModdingAPI/BlockGroup.cs +++ b/GamecraftModdingAPI/BlockGroup.cs @@ -1,4 +1,7 @@ using Gamecraft.Blocks.BlockGroups; +using Unity.Mathematics; +using UnityEngine; + using GamecraftModdingAPI.Blocks; using GamecraftModdingAPI.Utility; @@ -11,23 +14,36 @@ namespace GamecraftModdingAPI { internal static BlueprintEngine _engine = new BlueprintEngine(); public int Id { get; } - private Block _sourceBlock; + private readonly 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; + sourceBlock = block; } + + /// + /// The position of the block group. Calculated when GetBlocks() is used. + /// + public float3 Position { get; private set; } + + /// + /// The rotation of the block group. Calculated when GetBlocks() is used. + /// + public float3 Rotation { get; private set; } /// - /// Collects each block that is a part of this group. + /// Collects each block that is a part of this group. Also sets the position and rotation. /// /// An array of blocks public Block[] GetBlocks() { - return _engine.GetBlocksFromGroup(_sourceBlock.Id); + var ret = _engine.GetBlocksFromGroup(sourceBlock.Id, out var pos, out var rot); + Position = pos; + Rotation = ((Quaternion) rot).eulerAngles; + return ret; } /// diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index 5566525..9ce6d62 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -12,9 +12,9 @@ using RobocraftX.Scene.Simulation; using Svelto.DataStructures; using Svelto.ECS; using Svelto.ECS.Hybrid; +using Unity.Mathematics; using GamecraftModdingAPI.Engines; -using Unity.Mathematics; namespace GamecraftModdingAPI.Blocks { @@ -224,8 +224,10 @@ namespace GamecraftModdingAPI.Blocks var bodies = new HashSet(); foreach (var (coll, _) in groups) { - foreach (var conn in coll.ToBuffer().buffer.ToManagedArray()) + var array = coll.ToBuffer().buffer; + for (var index = 0; index < array.capacity; index++) { + var conn = array[index]; if (conn.clusterId == cid) bodies.Add(conn.machineRigidBodyId); } @@ -251,8 +253,11 @@ namespace GamecraftModdingAPI.Blocks var groups = entitiesDB.QueryEntities(); foreach (var (coll, _) in groups) { - foreach (var conn in coll.ToBuffer().buffer.ToManagedArray()) - { //Static blocks don't have a cluster ID but the cluster destruction manager should have one + var array = coll.ToBuffer().buffer; + for (var index = 0; index < array.capacity; index++) + { + var conn = array[index]; + //Static blocks don't have a cluster ID but the cluster destruction manager should have one if (conn.machineRigidBodyId == sbid && conn.clusterId != uint.MaxValue) return new Cluster(conn.clusterId); } @@ -267,8 +272,10 @@ namespace GamecraftModdingAPI.Blocks var set = new HashSet(); foreach (var (coll, _) in groups) { - foreach (var conn in coll.ToBuffer().buffer.ToManagedArray()) + var array = coll.ToBuffer().buffer; + for (var index = 0; index < array.capacity; index++) { + var conn = array[index]; if (conn.machineRigidBodyId == sbid) set.Add(new Block(conn.ID)); } diff --git a/GamecraftModdingAPI/Blocks/BlueprintEngine.cs b/GamecraftModdingAPI/Blocks/BlueprintEngine.cs index f2f0bef..4104ae6 100644 --- a/GamecraftModdingAPI/Blocks/BlueprintEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlueprintEngine.cs @@ -17,6 +17,7 @@ using Svelto.ECS.Serialization; using Unity.Collections; using Unity.Mathematics; using UnityEngine; +using Allocator = Svelto.Common.Allocator; namespace GamecraftModdingAPI.Blocks { @@ -24,8 +25,9 @@ namespace GamecraftModdingAPI.Blocks { private readonly MethodInfo getBlocksFromGroup = AccessTools.Method("RobocraftX.CR.MachineEditing.PlaceBlockUtility:GetBlocksSharingBlockgroup"); - private readonly NativeDynamicArray selectedBlocksInGroup = new NativeDynamicArray(); - private readonly NativeHashSet removedConnections = new NativeHashSet(); + + private NativeDynamicArray selectedBlocksInGroup; + private NativeHashSet removedConnections = new NativeHashSet(); private static readonly Type PlaceBlueprintUtilityType = AccessTools.TypeByName("RobocraftX.CR.MachineEditing.PlaceBlueprintUtility"); @@ -44,22 +46,29 @@ namespace GamecraftModdingAPI.Blocks public void Ready() { + selectedBlocksInGroup = NativeDynamicArray.Alloc(Allocator.Persistent); } public EntitiesDB entitiesDB { get; set; } public void Dispose() { + selectedBlocksInGroup.Dispose(); } - public Block[] GetBlocksFromGroup(EGID blockID) + public Block[] GetBlocksFromGroup(EGID blockID, out float3 pos, out quaternion rot) { - 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))); + 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(); + var ret = new Block[count]; + for (uint i = 0; i < count; i++) + ret[i] = new Block(selectedBlocksInGroup.Get(i)); selectedBlocksInGroup.FastClear(); - return list.ToArray(); + return ret; } public void RemoveBlockGroup(int id) @@ -195,7 +204,7 @@ namespace GamecraftModdingAPI.Blocks public static MethodBase TargetMethod() { - return AccessTools.Constructor(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.RemoveBlockEngine")); + return AccessTools.GetDeclaredConstructors(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.RemoveBlockEngine"))[0]; } } @@ -213,7 +222,7 @@ namespace GamecraftModdingAPI.Blocks public static MethodBase TargetMethod() { - return AccessTools.Constructor(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.SelectBlockEngine")); + return AccessTools.GetDeclaredConstructors(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.SelectBlockEngine"))[0]; } } } From 4580ae3b66564dae86e66e6fe905eac683a37f0d Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Thu, 12 Nov 2020 02:39:58 +0100 Subject: [PATCH 26/32] Add ability to create & move block groups & other stuff Added a way to store block groups as blueprints Blocks can be added/removed from block groups, although it doesn't work well atm Added some patches to the test class in an attempt to debug an unrelated issue Added a command to test placing a block group Added a SelectedBlueprint property to the Player class --- GamecraftModdingAPI/Block.cs | 28 +++- GamecraftModdingAPI/BlockGroup.cs | 153 ++++++++++++++++-- .../Blocks/BlockEventsEngine.cs | 11 +- GamecraftModdingAPI/Blocks/BlueprintEngine.cs | 49 ++++-- GamecraftModdingAPI/Blocks/PlacementEngine.cs | 8 +- GamecraftModdingAPI/Blueprint.cs | 16 +- GamecraftModdingAPI/Player.cs | 13 +- .../Tests/GamecraftModdingAPIPluginTest.cs | 101 ++++++++++++ 8 files changed, 332 insertions(+), 47 deletions(-) diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 862db3f..33a1623 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -240,6 +240,8 @@ namespace GamecraftModdingAPI set { MovementEngine.MoveBlock(Id, InitData, value); + if (blockGroup != null) + blockGroup.PosAndRotCalculated = false; } } @@ -252,6 +254,8 @@ namespace GamecraftModdingAPI set { RotationEngine.RotateBlock(Id, InitData, value); + if (blockGroup != null) + blockGroup.PosAndRotCalculated = false; } } @@ -354,15 +358,31 @@ namespace GamecraftModdingAPI } } + private BlockGroup blockGroup; /// /// 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. + /// 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. ///
public BlockGroup BlockGroup { - get => BlockEngine.GetBlockInfo(this, - (BlockGroupEntityComponent bgec) => - bgec.currentBlockGroup == -1 ? null : new BlockGroup(bgec.currentBlockGroup, this)); + get + { + if (blockGroup != null) return blockGroup; + return blockGroup = BlockEngine.GetBlockInfo(this, + (BlockGroupEntityComponent bgec) => + bgec.currentBlockGroup == -1 ? null : new BlockGroup(bgec.currentBlockGroup, this)); + } + set + { + blockGroup?.RemoveInternal(this); + BlockEngine.SetBlockInfo(this, + (ref BlockGroupEntityComponent bgec, BlockGroup val) => bgec.currentBlockGroup = val?.Id ?? -1, + value); + value?.AddInternal(this); + blockGroup = value; + } } /// diff --git a/GamecraftModdingAPI/BlockGroup.cs b/GamecraftModdingAPI/BlockGroup.cs index 8d9e761..d660236 100644 --- a/GamecraftModdingAPI/BlockGroup.cs +++ b/GamecraftModdingAPI/BlockGroup.cs @@ -1,4 +1,8 @@ -using Gamecraft.Blocks.BlockGroups; +using System; +using System.Collections; +using System.Collections.Generic; + +using Gamecraft.Blocks.BlockGroups; using Unity.Mathematics; using UnityEngine; @@ -10,11 +14,14 @@ namespace GamecraftModdingAPI /// /// A group of blocks that can be selected together. The placed version of blueprints. /// - public class BlockGroup + public class BlockGroup : ICollection { internal static BlueprintEngine _engine = new BlueprintEngine(); public int Id { get; } private readonly Block sourceBlock; + private readonly List blocks; + private float3 position, rotation; + internal bool PosAndRotCalculated; internal BlockGroup(int id, Block block) { @@ -22,41 +29,155 @@ namespace GamecraftModdingAPI throw new BlockException("Cannot create a block group for blocks without a group!"); Id = id; sourceBlock = block; + blocks = new List(GetBlocks()); } /// - /// The position of the block group. Calculated when GetBlocks() is used. + /// The position of the block group (center). Recalculated if blocks have been added/removed since the last query. /// - public float3 Position { get; private set; } - + public float3 Position + { + get + { + if (!PosAndRotCalculated) + Refresh(); + return position; + } + set + { + var diff = value - position; + foreach (var block in blocks) + block.Position += diff; + if (!PosAndRotCalculated) //The condition can only be true if a block has been added/removed manually + Refresh(); //So the blocks array is up to date + else + position += diff; + } + } + /// - /// The rotation of the block group. Calculated when GetBlocks() is used. + /// The rotation of the block group. Recalculated if blocks have been added/removed since the last query. /// - public float3 Rotation { get; private set; } + public float3 Rotation + { + get + { + if (!PosAndRotCalculated) + Refresh(); + return rotation; + } + set + { + var diff = value - rotation; + var qdiff = Quaternion.Euler(diff); + foreach (var block in blocks) + { + block.Rotation += diff; + block.Position = qdiff * block.Position; + } + if (!PosAndRotCalculated) + Refresh(); + else + rotation += diff; + } + } + + /*/// + /// Removes all of the blocks in this group from the world. + /// + public void RemoveBlocks() + { + _engine.RemoveBlockGroup(Id); - TODO: Causes a hard crash + }*/ + + /// + /// Creates a new block group consisting of a single block. + /// You can add more blocks using the Add() method or by setting the BlockGroup property of the blocks.
+ /// Note that only newly placed blocks should be added to groups. + ///
+ /// The block to add + /// A new block group containing the given block + public static BlockGroup Create(Block block) + { + return new BlockGroup(_engine.CreateBlockGroup(default, default), block); + } /// /// Collects each block that is a part of this group. Also sets the position and rotation. /// /// An array of blocks - public Block[] GetBlocks() + private Block[] GetBlocks() { + if (!sourceBlock.Exists) return new[] {sourceBlock}; //The block must exist to get the others var ret = _engine.GetBlocksFromGroup(sourceBlock.Id, out var pos, out var rot); - Position = pos; - Rotation = ((Quaternion) rot).eulerAngles; + position = pos; + rotation = ((Quaternion) rot).eulerAngles; + PosAndRotCalculated = true; return ret; } - /// - /// Removes all of the blocks in this group from the world. - /// - public void Remove() + private void Refresh() { - _engine.RemoveBlockGroup(Id); + blocks.Clear(); + blocks.AddRange(GetBlocks()); } - public static void Init() + internal static void Init() { GameEngineManager.AddGameEngine(_engine); } + + public IEnumerator GetEnumerator() => blocks.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => blocks.GetEnumerator(); + + /// + /// Adds a block to the group. You should only add newly placed blocks + /// so that the game initializes the group membership properly. + /// + /// + /// + public void Add(Block item) + { + if (item == null) throw new NullReferenceException("Cannot add null to a block group"); + item.BlockGroup = this; //Calls AddInternal + } + + internal void AddInternal(Block item) => blocks.Add(item); + + /// + /// Removes all blocks from this group. + /// You should not remove blocks that have been initialized, only those that you placed recently. + /// + public void Clear() + { + while (blocks.Count > 0) + Remove(blocks[blocks.Count - 1]); + } + + public bool Contains(Block item) => blocks.Contains(item); + public void CopyTo(Block[] array, int arrayIndex) => blocks.CopyTo(array, arrayIndex); + + /// + /// Removes a block from this group. + /// You should not remove blocks that have been initialized, only those that you placed recently. + /// + /// + /// + /// + public bool Remove(Block item) + { + if (item == null) throw new NullReferenceException("Cannot remove null from a block group"); + bool ret = item.BlockGroup == this; + if (ret) + item.BlockGroup = null; //Calls RemoveInternal + return ret; + } + + internal void RemoveInternal(Block item) => blocks.Remove(item); + + public int Count => blocks.Count; + public bool IsReadOnly { get; } = false; + + public Block this[int index] => blocks[index]; //Setting is not supported, since the order doesn't matter } } \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs b/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs index 1e5ce21..d1c2639 100644 --- a/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEventsEngine.cs @@ -5,10 +5,11 @@ using Svelto.ECS; using GamecraftModdingAPI.Engines; using GamecraftModdingAPI.Utility; +using RobocraftX.Blocks; namespace GamecraftModdingAPI.Blocks { - public class BlockEventsEngine : IReactionaryEngine + public class BlockEventsEngine : IReactionaryEngine { public event EventHandler Placed; public event EventHandler Removed; @@ -27,20 +28,20 @@ namespace GamecraftModdingAPI.Blocks public bool isRemovable { get; } = false; private bool shouldAddRemove; - public void Add(ref DBEntityStruct entityComponent, EGID egid) + public void Add(ref BlockTagEntityStruct entityComponent, EGID egid) { if (!(shouldAddRemove = !shouldAddRemove)) return; ExceptionUtil.InvokeEvent(Placed, this, - new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID}); + new BlockPlacedRemovedEventArgs {ID = egid}); } - public void Remove(ref DBEntityStruct entityComponent, EGID egid) + public void Remove(ref BlockTagEntityStruct entityComponent, EGID egid) { if (!(shouldAddRemove = !shouldAddRemove)) return; ExceptionUtil.InvokeEvent(Removed, this, - new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID}); + new BlockPlacedRemovedEventArgs {ID = egid}); } } diff --git a/GamecraftModdingAPI/Blocks/BlueprintEngine.cs b/GamecraftModdingAPI/Blocks/BlueprintEngine.cs index 4104ae6..e46ad50 100644 --- a/GamecraftModdingAPI/Blocks/BlueprintEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlueprintEngine.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Reflection; using Gamecraft.Blocks.BlockGroups; using Gamecraft.GUI.Blueprints; @@ -21,7 +22,7 @@ using Allocator = Svelto.Common.Allocator; namespace GamecraftModdingAPI.Blocks { - public class BlueprintEngine : IApiEngine + public class BlueprintEngine : IFactoryEngine { private readonly MethodInfo getBlocksFromGroup = AccessTools.Method("RobocraftX.CR.MachineEditing.PlaceBlockUtility:GetBlocksSharingBlockgroup"); @@ -77,12 +78,29 @@ namespace GamecraftModdingAPI.Blocks connectionFactory, default).Complete(); } + public int CreateBlockGroup(float3 position, quaternion rotation) + { + int nextFilterId = BlockGroupUtility.NextFilterId; + Factory.BuildEntity((uint) nextFilterId, + BlockGroupExclusiveGroups.BlockGroupEntityGroup).Init(new BlockGroupTransformEntityComponent + { + blockGroupGridRotation = rotation, + blockGroupGridPosition = position + }); + return nextFilterId; + } + public void SelectBlueprint(uint resourceID) { - BlueprintUtil.SelectBlueprint(null, new BlueprintInventoryItemEntityStruct + if (resourceID == uint.MaxValue) + BlueprintUtil.UnselectBlueprint(entitiesDB); + else { - blueprintResourceId = resourceID, - }); + BlueprintUtil.SelectBlueprint(entitiesDB, new BlueprintInventoryItemEntityStruct + { + blueprintResourceId = resourceID, + }); + } } public uint CreateBlueprint() @@ -91,28 +109,27 @@ namespace GamecraftModdingAPI.Blocks return index; } - public void ReplaceBlueprint(uint playerID, uint blueprintID, Block[] selected, float3 pos, quaternion rot) + public void ReplaceBlueprint(uint playerID, uint blueprintID, ICollection selected, float3 pos, quaternion rot) { - var blockIDs = new EGID[selected.Length]; - for (var i = 0; i < selected.Length; i++) + var blockIDs = new EGID[selected.Count]; + using (var enumerator = selected.GetEnumerator()) { - var block = selected[i]; - blockIDs[i] = block.Id; + 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); - if (selected.Length == 0) + if (selected.Count == 0) return; //ref BlockGroupTransformEntityComponent groupTransform = ref EntityNativeDBExtensions.QueryEntity(entitiesDb, (uint) local1.currentBlockGroup, BlockGroupExclusiveGroups.BlockGroupEntityGroup); //ref ColliderAabb collider = ref EntityNativeDBExtensions.QueryEntity(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, @@ -189,7 +206,7 @@ namespace GamecraftModdingAPI.Blocks } public string Name { get; } = "GamecraftModdingAPIBlueprintGameEngine"; - public bool isRemovable { get; } + public bool isRemovable { get; } = false; [HarmonyPatch] private static class RemoveEnginePatch @@ -225,5 +242,7 @@ namespace GamecraftModdingAPI.Blocks return AccessTools.GetDeclaredConstructors(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.SelectBlockEngine"))[0]; } } + + public IEntityFactory Factory { get; set; } } } \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/PlacementEngine.cs b/GamecraftModdingAPI/Blocks/PlacementEngine.cs index cf9a80f..5357e7f 100644 --- a/GamecraftModdingAPI/Blocks/PlacementEngine.cs +++ b/GamecraftModdingAPI/Blocks/PlacementEngine.cs @@ -53,15 +53,15 @@ namespace GamecraftModdingAPI.Blocks private EntityComponentInitializer BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot, uint playerId) { if (_blockEntityFactory == null) - throw new Exception("The factory is null."); + throw new BlockException("The factory is null."); if (uscale < 1) - throw new Exception("Scale needs to be at least 1"); + throw new BlockException("Scale needs to be at least 1"); if (scale.x < 4e-5) scale.x = uscale; if (scale.y < 4e-5) scale.y = uscale; if (scale.z < 4e-5) scale.z = uscale; uint dbid = block; - if (!PrefabsID.DBIDMAP.ContainsKey(dbid)) - throw new Exception("Block with ID " + dbid + " not found!"); + if (!PrefabsID.HasPrefabRegistered(dbid, 0)) + throw new BlockException("Block with ID " + dbid + " not found!"); //RobocraftX.CR.MachineEditing.PlaceBlockEngine ScalingEntityStruct scaling = new ScalingEntityStruct {scale = scale}; Quaternion rotQ = Quaternion.Euler(rot); diff --git a/GamecraftModdingAPI/Blueprint.cs b/GamecraftModdingAPI/Blueprint.cs index 26876f6..458c56c 100644 --- a/GamecraftModdingAPI/Blueprint.cs +++ b/GamecraftModdingAPI/Blueprint.cs @@ -1,5 +1,6 @@ using System; using Unity.Mathematics; +using UnityEngine; namespace GamecraftModdingAPI { @@ -35,16 +36,27 @@ namespace GamecraftModdingAPI /// /// Set the blocks that the blueprint contains. + /// Use the BlockGroup overload for automatically calculated position and rotation. /// /// The array of blocks to use /// The anchor position of the blueprint - /// The rotation of the blueprint - public void SetStoredBlocks(Block[] blocks, float3 position = default, float3 rotation = default) + /// The base rotation of the blueprint + public void StoreBlocks(Block[] blocks, float3 position, float3 rotation) { BlockGroup._engine.ReplaceBlueprint(Player.LocalPlayer.Id, Id, blocks, position, quaternion.Euler(rotation)); } + /// + /// Store the blocks from the given group in the blueprint with correct position and rotation for the blueprint. + /// + /// The block group to store + public void StoreBlocks(BlockGroup group) + { + BlockGroup._engine.ReplaceBlueprint(Player.LocalPlayer.Id, Id, group, group.Position, + Quaternion.Euler(group.Rotation)); + } + /// /// Places the blocks the blueprint contains at the specified position and rotation. /// diff --git a/GamecraftModdingAPI/Player.cs b/GamecraftModdingAPI/Player.cs index a4b7064..14892a3 100644 --- a/GamecraftModdingAPI/Player.cs +++ b/GamecraftModdingAPI/Player.cs @@ -1,5 +1,5 @@ using System; - +using Gamecraft.GUI.Blueprints; using Unity.Mathematics; using RobocraftX.Common; using RobocraftX.Common.Players; @@ -343,6 +343,17 @@ namespace GamecraftModdingAPI } } + /// + /// The player's selected blueprint in their hand. Set to null to clear. Dispose after usage. + /// + public Blueprint SelectedBlueprint + { + get => playerEngine.GetPlayerStruct(Id, out BlueprintInventoryItemEntityStruct biies) + ? new Blueprint(biies.blueprintResourceId) + : null; + set => BlockGroup._engine.SelectBlueprint(value?.Id ?? uint.MaxValue); + } + // object methods /// diff --git a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs index e3a9c50..c904ef7 100644 --- a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs +++ b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs @@ -1,24 +1,29 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Reflection.Emit; using System.Text; using HarmonyLib; using IllusionInjector; // test +using GPUInstancer; using Svelto.ECS; using RobocraftX.Blocks; using RobocraftX.Common; using RobocraftX.SimulationModeState; using RobocraftX.FrontEnd; using Unity.Mathematics; +using UnityEngine; using GamecraftModdingAPI.Commands; using GamecraftModdingAPI.Events; using GamecraftModdingAPI.Utility; using GamecraftModdingAPI.Blocks; using GamecraftModdingAPI.Players; +using EventType = GamecraftModdingAPI.Events.EventType; namespace GamecraftModdingAPI.Tests { @@ -269,6 +274,20 @@ namespace GamecraftModdingAPI.Tests Logging.CommandLog("Health set to: " + val); }).Build(); + CommandBuilder.Builder("placeBlockGroup", "Places some blocks in a group") + .Action((float x, float y, float z) => + { + var pos = new float3(x, y, z); + var group = BlockGroup.Create(Block.PlaceNew(BlockIDs.AluminiumCube, pos, + color: BlockColors.Aqua)); + Block.PlaceNew(BlockIDs.AluminiumCube, pos += new float3(1, 0, 0), color: BlockColors.Blue) + .BlockGroup = group; + Block.PlaceNew(BlockIDs.AluminiumCube, pos += new float3(1, 0, 0), color: BlockColors.Green) + .BlockGroup = group; + Block.PlaceNew(BlockIDs.AluminiumCube, pos += new float3(1, 0, 0), color: BlockColors.Lime) + .BlockGroup = group; + }).Build(); + GameClient.SetDebugInfo("InstalledMods", InstalledMods); Block.Placed += (sender, args) => Logging.MetaDebugLog("Placed block " + args.Type + " with ID " + args.ID); @@ -391,6 +410,88 @@ namespace GamecraftModdingAPI.Tests return ((Action) MinimumSpecsCheck.CheckRequirementsMet).Method; } } + + [HarmonyPatch] + public class BugHuntPatch + { + public static MethodInfo method = + SymbolExtensions.GetMethodInfo(str => Console.WriteLine(str)); + + public static IEnumerable Transpiler(IEnumerable instructions) + { + int i = 0; + foreach (var instruction in instructions) + { + i++; + yield return instruction; //Return the instruction first + //stloc, dup, callvirt + if (instruction.opcode.Name.ToLower().StartsWith("stloc") + || instruction.opcode == OpCodes.Dup + || instruction.opcode == OpCodes.Callvirt) + { + yield return new CodeInstruction(OpCodes.Ldstr, + "Just ran the " + i + ". instruction ending with " + instruction.opcode.Name); + yield return new CodeInstruction(OpCodes.Call, method); + } + } + } + + public static MethodInfo TargetMethod() + { + return AccessTools.Method("RobocraftX.CR.MachineEditing.BoxSelect.CopySelectionEngine:GenerateThumbnail"); + } + } + + [HarmonyPatch] + public class BugHuntPatch2 + { + public static void Prefix(int width, float fieldOfView, Vector3 cameraDirection, Vector3 lightDirection) + { + Console.WriteLine("TakeThumbnail invoked with parameters: " + width + ", " + fieldOfView + ", " + + cameraDirection + ", " + lightDirection); + + GPUInstancerManager manager = GPUInstancerAPI.GetActiveManagers().Find(m => m is GPUInstancerPrefabManager); + Bounds instancesBounds = manager.ComputeInstancesBounds(2); + Console.WriteLine("Bounds: " + instancesBounds); + Console.WriteLine("Size: " + instancesBounds.size); + Console.WriteLine("Size.x < 0: " + (instancesBounds.size.x < 0)); + } + + public static void Postfix(Texture2D __result) + { + Console.WriteLine("TakeThumbnail returned: " + (__result == null ? null : __result.name)); + } + + private delegate Texture2D TakeThumbnailDel(int width, float fieldOfView, Vector3 cameraDirection, + Vector3 lightDirection); + + public static MethodInfo TargetMethod() + { + return ((TakeThumbnailDel) ThumbnailUtility.TakeThumbnail).Method; + } + } + + [HarmonyPatch] + public class BugHuntPatch3 + { + public static void Prefix(int width, int filterLayerMask, GPUInstancerManager manager, + Vector3 cameraPosition, Quaternion cameraRotation, float cameraFov, Vector3 lightDirection, + int cullingLayer) + { + Console.WriteLine("Inner TakeThumbnail invoked with parameters: " + width + ", " + filterLayerMask + + ", " + (manager != null ? manager.name : null) + ", " + cameraPosition + ", " + + cameraRotation + ", " + cameraFov + ", " + lightDirection + ", " + cullingLayer); + } + + private delegate Texture2D TakeThumbnailDel(int width, int filterLayerMask, GPUInstancerManager manager, + Vector3 cameraPosition, Quaternion cameraRotation, float cameraFov, Vector3 lightDirection, + int cullingLayer); + + public static MethodInfo TargetMethod() + { + return ((TakeThumbnailDel) ThumbnailUtility.TakeThumbnail).Method; + } + } } #endif } From 2a1782cd82ba73a394563c3c86ecb77dd650a9b9 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 15 Dec 2021 03:46:38 +0100 Subject: [PATCH 27/32] Start updating to 2021.12.14.17.00 A bunch of errors still --- Automation/gen_csproj.py | 2 +- TechbloxModdingAPI/App/CurrentGameMode.cs | 14 +- TechbloxModdingAPI/App/Game.cs | 6 +- TechbloxModdingAPI/App/GameGameEngine.cs | 2 +- TechbloxModdingAPI/App/GameMenuEngine.cs | 7 +- TechbloxModdingAPI/Block.cs | 9 +- .../Blocks/Engines/BlockCloneEngine.cs | 2 +- .../Blocks/Engines/MovementEngine.cs | 1 - .../Blocks/Engines/PlacementEngine.cs | 3 +- .../Blocks/Engines/SignalEngine.cs | 34 +- TechbloxModdingAPI/Input/FakeInput.cs | 2 +- .../Persistence/SaveGameEnginePatch.cs | 12 +- .../Persistence/SimpleEntitySerializer.cs | 2 +- TechbloxModdingAPI/Player.cs | 2 +- TechbloxModdingAPI/Tasks/Scheduler.cs | 4 +- TechbloxModdingAPI/TechbloxModdingAPI.csproj | 1344 +++++++++-------- TechbloxModdingAPI/Tests/TestRoot.cs | 2 +- TechbloxModdingAPI/Utility/FullGameFields.cs | 8 - 18 files changed, 779 insertions(+), 677 deletions(-) diff --git a/Automation/gen_csproj.py b/Automation/gen_csproj.py index 9d5dfbc..bcfd712 100755 --- a/Automation/gen_csproj.py +++ b/Automation/gen_csproj.py @@ -39,7 +39,7 @@ if __name__ == "__main__": args = parser.parse_args() print("Building Assembly references") - asmXml = buildReferencesXml("../ref/TechbloxPreview_Data/Managed") + asmXml = buildReferencesXml("../ref_preview/TechbloxPreview_Data/Managed") # print(asmXml) with open("../TechbloxModdingAPI/TechbloxModdingAPI.csproj", "r") as xmlFile: diff --git a/TechbloxModdingAPI/App/CurrentGameMode.cs b/TechbloxModdingAPI/App/CurrentGameMode.cs index 85b3e09..211b552 100644 --- a/TechbloxModdingAPI/App/CurrentGameMode.cs +++ b/TechbloxModdingAPI/App/CurrentGameMode.cs @@ -1,23 +1,27 @@ -namespace TechbloxModdingAPI.App +using System; + +namespace TechbloxModdingAPI.App { public enum CurrentGameMode { None, /// - /// Building a game + /// Building a world /// Build, /// - /// Playing a game + /// Playing on a map /// Play, /// - /// Viewing a prefab + /// Viewing a prefab (doesn't exist anymore) /// + [Obsolete] View, /// - /// Viewing a tutorial + /// Viewing a tutorial (doesn't exist anymore) /// + [Obsolete] Tutorial } } \ No newline at end of file diff --git a/TechbloxModdingAPI/App/Game.cs b/TechbloxModdingAPI/App/Game.cs index 7f52965..aac7cb5 100644 --- a/TechbloxModdingAPI/App/Game.cs +++ b/TechbloxModdingAPI/App/Game.cs @@ -2,12 +2,10 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; -using RobocraftX.Common; using RobocraftX.GUI.MyGamesScreen; -using RobocraftX.StateSync; using Svelto.ECS; +using Techblox.GameSelection; -using TechbloxModdingAPI; using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Tasks; using TechbloxModdingAPI.Utility; @@ -318,7 +316,7 @@ namespace TechbloxModdingAPI.App get { if (menuMode || !VerifyMode()) return CurrentGameMode.None; - return (CurrentGameMode) GameMode.CurrentMode; + return gameEngine.GetGameData().gameMode == GameMode.CreateWorld ? CurrentGameMode.Build : CurrentGameMode.Play; } } diff --git a/TechbloxModdingAPI/App/GameGameEngine.cs b/TechbloxModdingAPI/App/GameGameEngine.cs index 2bed201..147606e 100644 --- a/TechbloxModdingAPI/App/GameGameEngine.cs +++ b/TechbloxModdingAPI/App/GameGameEngine.cs @@ -54,7 +54,7 @@ namespace TechbloxModdingAPI.App { if (async) { - ExitCurrentGameAsync().RunOn(Lean.EveryFrameStepRunner_TimeRunningAndStopped); + ExitCurrentGameAsync().RunOn(ClientLean.EveryFrameStepRunner_TimeRunningAndStopped); } else { diff --git a/TechbloxModdingAPI/App/GameMenuEngine.cs b/TechbloxModdingAPI/App/GameMenuEngine.cs index ac24e3a..f356a0d 100644 --- a/TechbloxModdingAPI/App/GameMenuEngine.cs +++ b/TechbloxModdingAPI/App/GameMenuEngine.cs @@ -3,16 +3,14 @@ using System.Reflection; using HarmonyLib; using RobocraftX; -using RobocraftX.Common; -using RobocraftX.FrontEnd; using RobocraftX.GUI; using RobocraftX.GUI.MyGamesScreen; using Svelto.ECS; using Svelto.ECS.Experimental; using Techblox.GameSelection; + using TechbloxModdingAPI.Engines; using TechbloxModdingAPI.Utility; -using GameMode = RobocraftX.Common.GameMode; namespace TechbloxModdingAPI.App { @@ -107,11 +105,10 @@ namespace TechbloxModdingAPI.App public bool EnterGame(string gameName, string fileId, bool autoEnterSim = false) { - GameMode.CurrentMode = autoEnterSim ? RCXMode.Play : RCXMode.Build; var data = new GameSelectionData { gameMode = Techblox.GameSelection.GameMode.PlayGame, - gameType = GameType.MachineEditor, + isOnline = false, saveName = gameName, saveType = SaveType.ExistingSave, gameID = "GAMEID_Road_Track", //TODO: Expose to the API diff --git a/TechbloxModdingAPI/Block.cs b/TechbloxModdingAPI/Block.cs index ec1147a..ccc02ab 100644 --- a/TechbloxModdingAPI/Block.cs +++ b/TechbloxModdingAPI/Block.cs @@ -8,9 +8,10 @@ using Svelto.ECS.EntityStructs; using RobocraftX.Common; using RobocraftX.Blocks; using Unity.Mathematics; -using Gamecraft.Blocks.GUI; using HarmonyLib; using RobocraftX.PilotSeat; +using RobocraftX.Rendering; +using Techblox.BlockLabels; using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Blocks.Engines; @@ -342,11 +343,9 @@ namespace TechbloxModdingAPI [TestValue(null)] public string Label { - get => BlockEngine.GetBlockInfoViewComponent(this).textLabelComponent?.text; + get => BlockEngine.GetBlockInfo(this).ToString(); //TODO: Block labels set - { - var comp = BlockEngine.GetBlockInfoViewComponent(this).textLabelComponent; - if (comp != null) comp.text = value; + { //TODO } } diff --git a/TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs b/TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs index 01f2d05..a8cd39e 100644 --- a/TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs @@ -60,7 +60,7 @@ namespace TechbloxModdingAPI.Blocks.Engines copyToBlock.Invoke(Patch.copyEngine, new object[] {pickedBlock.ID, pickedBlock}); - ExclusiveGroupStruct group = WiresExclusiveGroups.WIRES_COPY_GROUP + playerID; + ExclusiveGroupStruct group = BuildModeWiresGroups.WIRES_COPY_GROUP + playerID; copyWireToBlock.Invoke(Patch.createWireEngine, new object[] {group, pickedBlock.ID}); pickedBlock.placedBlockTweaksMustCopy = false; diff --git a/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs b/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs index 9351623..07bfbe6 100644 --- a/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs @@ -1,5 +1,4 @@ using RobocraftX.Common; -using RobocraftX.UECS; using Svelto.ECS; using Svelto.ECS.EntityStructs; using Unity.Mathematics; diff --git a/TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs b/TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs index 9ce7d84..f4ea4c0 100644 --- a/TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs @@ -54,7 +54,8 @@ namespace TechbloxModdingAPI.Blocks.Engines //RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine DBEntityStruct dbEntity = new DBEntityStruct {DBID = block}; - EntityInitializer structInitializer = _blockEntityFactory.Build(CommonExclusiveGroups.nextBlockEntityID, block); //The ghost block index is only used for triggers + //TODO: Test + EntityInitializer structInitializer = _blockEntityFactory.Build(CommonExclusiveGroups.blockIDGeneratorClient.Next(), block); //The ghost block index is only used for triggers uint prefabAssetID = structInitializer.Has() ? structInitializer.Get().prefabAssetID : throw new BlockException("Prefab asset ID not found!"); //Set by the game diff --git a/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs b/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs index 3c2e1cb..a612ea2 100644 --- a/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs @@ -43,7 +43,7 @@ namespace TechbloxModdingAPI.Blocks.Engines public WireEntityStruct CreateNewWire(EGID startBlock, byte startPort, EGID endBlock, byte endPort) { - EGID wireEGID = new EGID(WiresExclusiveGroups.NewWireEntityId, NamedExclusiveGroup.Group); + EGID wireEGID = new EGID(BuildModeWiresGroups.NewWireEntityId, BuildModeWiresGroups.WiresGroup.Group); EntityInitializer wireInitializer = Factory.BuildEntity(wireEGID); wireInitializer.Init(new WireEntityStruct { @@ -77,8 +77,8 @@ namespace TechbloxModdingAPI.Blocks.Engines public ref PortEntityStruct GetPortByOffset(BlockPortsStruct bps, byte portNumber, bool input) { ExclusiveGroup group = input - ? NamedExclusiveGroup.Group - : NamedExclusiveGroup.Group; + ? NamedExclusiveGroup.Group + : NamedExclusiveGroup.Group; uint id = (input ? bps.firstInputID : bps.firstOutputID) + portNumber; EGID egid = new EGID(id, group); if (!entitiesDB.Exists(egid)) @@ -193,7 +193,7 @@ namespace TechbloxModdingAPI.Blocks.Engines EGID[] inputs = new EGID[ports.inputCount]; for (uint i = 0; i < ports.inputCount; i++) { - inputs[i] = new EGID(i + ports.firstInputID, NamedExclusiveGroup.Group); + inputs[i] = new EGID(i + ports.firstInputID, NamedExclusiveGroup.Group); } return inputs; } @@ -204,7 +204,7 @@ namespace TechbloxModdingAPI.Blocks.Engines EGID[] outputs = new EGID[ports.outputCount]; for (uint i = 0; i < ports.outputCount; i++) { - outputs[i] = new EGID(i + ports.firstOutputID, NamedExclusiveGroup.Group); + outputs[i] = new EGID(i + ports.firstOutputID, NamedExclusiveGroup.Group); } return outputs; } @@ -219,8 +219,8 @@ namespace TechbloxModdingAPI.Blocks.Engines if (!entitiesDB.Exists(block)) return default; var group = output - ? NamedExclusiveGroup.Group - : NamedExclusiveGroup.Group; + ? NamedExclusiveGroup.Group + : NamedExclusiveGroup.Group; BlockPortsStruct ports = entitiesDB.QueryEntity(block); if (!entitiesDB.TryQueryMappedEntities(group, out var mapper)) return default; @@ -237,7 +237,7 @@ namespace TechbloxModdingAPI.Blocks.Engines public ref WireEntityStruct MatchPortToWire(PortEntityStruct port, EGID blockID, out bool exists) { - var wires = entitiesDB.QueryEntities(NamedExclusiveGroup.Group); + var wires = entitiesDB.QueryEntities(NamedExclusiveGroup.Group); var wiresB = wires.ToBuffer().buffer; for (uint i = 0; i < wires.count; i++) { @@ -264,7 +264,7 @@ namespace TechbloxModdingAPI.Blocks.Engines else { BlockPortsStruct ports = entitiesDB.QueryEntity(startBlock); - startPorts = new EGID[] {new EGID(ports.firstOutputID + startPort, NamedExclusiveGroup.Group) }; + startPorts = new EGID[] {new EGID(ports.firstOutputID + startPort, NamedExclusiveGroup.Group) }; } EGID[] endPorts; @@ -276,10 +276,10 @@ namespace TechbloxModdingAPI.Blocks.Engines else { BlockPortsStruct ports = entitiesDB.QueryEntity(endBlock); - endPorts = new EGID[] {new EGID(ports.firstInputID + endPort, NamedExclusiveGroup.Group) }; + endPorts = new EGID[] {new EGID(ports.firstInputID + endPort, NamedExclusiveGroup.Group) }; } - EntityCollection wires = entitiesDB.QueryEntities(NamedExclusiveGroup.Group); + EntityCollection wires = entitiesDB.QueryEntities(NamedExclusiveGroup.Group); var wiresB = wires.ToBuffer().buffer; for (int endIndex = 0; endIndex < endPorts.Length; endIndex++) { @@ -304,7 +304,7 @@ namespace TechbloxModdingAPI.Blocks.Engines public OptionalRef GetChannelDataStruct(EGID portID) { var port = GetPort(portID); - var channels = entitiesDB.QueryEntities(NamedExclusiveGroup.Group); + var channels = entitiesDB.QueryEntities(NamedExclusiveGroup.Group); var channelsB = channels.ToBuffer(); return port.firstChannelIndexCachedInSim < channels.count ? new OptionalRef(channelsB.buffer, port.firstChannelIndexCachedInSim) @@ -329,7 +329,7 @@ namespace TechbloxModdingAPI.Blocks.Engines public EGID[] WiredToInput(EGID block, byte port) { - WireEntityStruct[] wireEntityStructs = Search(NamedExclusiveGroup.Group, + WireEntityStruct[] wireEntityStructs = Search(NamedExclusiveGroup.Group, (WireEntityStruct wes) => wes.destinationPortUsage == port && wes.destinationBlockEGID == block); EGID[] result = new EGID[wireEntityStructs.Length]; for (uint i = 0; i < wireEntityStructs.Length; i++) @@ -342,7 +342,7 @@ namespace TechbloxModdingAPI.Blocks.Engines public EGID[] WiredToOutput(EGID block, byte port) { - WireEntityStruct[] wireEntityStructs = Search(NamedExclusiveGroup.Group, + WireEntityStruct[] wireEntityStructs = Search(NamedExclusiveGroup.Group, (WireEntityStruct wes) => wes.sourcePortUsage == port && wes.sourceBlockEGID == block); EGID[] result = new EGID[wireEntityStructs.Length]; for (uint i = 0; i < wireEntityStructs.Length; i++) @@ -371,13 +371,13 @@ namespace TechbloxModdingAPI.Blocks.Engines private EntityCollection GetSignalStruct(uint signalID, out uint index, bool input = true) { ExclusiveGroup group = input - ? NamedExclusiveGroup.Group - : NamedExclusiveGroup.Group; + ? NamedExclusiveGroup.Group + : NamedExclusiveGroup.Group; if (entitiesDB.Exists(signalID, group)) { index = entitiesDB.QueryEntity(signalID, group).anyChannelIndex; var channelData = - entitiesDB.QueryEntities(NamedExclusiveGroup.Group); + entitiesDB.QueryEntities(NamedExclusiveGroup.Group); return channelData; } diff --git a/TechbloxModdingAPI/Input/FakeInput.cs b/TechbloxModdingAPI/Input/FakeInput.cs index a3d068a..6beb63f 100644 --- a/TechbloxModdingAPI/Input/FakeInput.cs +++ b/TechbloxModdingAPI/Input/FakeInput.cs @@ -111,7 +111,7 @@ namespace TechbloxModdingAPI.Input ref LocalPlayerInputEntityStruct currentInput = ref inputEngine.GetPlayerInputRef(playerID); //Utility.Logging.CommandLog($"Current sim frame {currentInput.frame}"); // set inputs - if (toggleMode) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleTimeRunningMode; + if (toggleMode) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleTimeRunningModeTest; //TODO: Test, play if (forward) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Forward; if (backward) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Backward; if (up) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Up; diff --git a/TechbloxModdingAPI/Persistence/SaveGameEnginePatch.cs b/TechbloxModdingAPI/Persistence/SaveGameEnginePatch.cs index 4386d3a..06f4a1a 100644 --- a/TechbloxModdingAPI/Persistence/SaveGameEnginePatch.cs +++ b/TechbloxModdingAPI/Persistence/SaveGameEnginePatch.cs @@ -25,7 +25,7 @@ namespace TechbloxModdingAPI.Persistence Logging.MetaDebugLog("Skipping component serialization: no serializers registered!"); return; } - serializationData.data.ExpandBy((uint)frameStart.Length); + serializationData.data.IncreaseCapacityBy((uint)frameStart.Length); BinaryBufferWriter bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out int buffLen), serializationData.dataPos); uint originalPos = serializationData.dataPos; Logging.MetaDebugLog($"dataPos: {originalPos}"); @@ -35,14 +35,14 @@ namespace TechbloxModdingAPI.Persistence bbw.Write(frameStart[i]); } Logging.MetaDebugLog($"dataPos (after frame start): {bbw.Position}"); - serializationData.data.ExpandBy(4u); + serializationData.data.IncreaseCapacityBy(4u); bbw.Write((uint)SerializerManager.GetSerializersCount()); string[] serializerKeys = SerializerManager.GetSerializerNames(); for (uint c = 0; c < serializerKeys.Length; c++) { Logging.MetaDebugLog($"dataPos (loop start): {bbw.Position}"); // write component info - serializationData.data.ExpandBy(4u + (uint)serializerKeys[c].Length); + serializationData.data.IncreaseCapacityBy(4u + (uint)serializerKeys[c].Length); bbw.Write((uint)serializerKeys[c].Length); Logging.MetaDebugLog($"dataPos (now): {bbw.Position}"); byte[] nameBytes = Encoding.UTF8.GetBytes(serializerKeys[c]); @@ -51,7 +51,7 @@ namespace TechbloxModdingAPI.Persistence bbw.Write(nameBytes[i]); } Logging.MetaDebugLog($"dataPos (now): {bbw.Position}"); - serializationData.data.ExpandBy(4u); + serializationData.data.IncreaseCapacityBy(4u); serializationData.dataPos = bbw.Position + 4u; Logging.MetaDebugLog($"dataPos (now): {bbw.Position}"); Logging.MetaDebugLog($"dataPos (appears to be): {serializationData.dataPos}"); @@ -73,8 +73,8 @@ namespace TechbloxModdingAPI.Persistence } public static MethodBase TargetMethod() - { - return typeof(SaveGameEngine).GetMethod("SerializeGameToBuffer"); + { + return AccessTools.TypeByName("RobocraftX.SaveAndLoad.SaveGameEngine").GetMethod("SerializeGameToBuffer"); } } } diff --git a/TechbloxModdingAPI/Persistence/SimpleEntitySerializer.cs b/TechbloxModdingAPI/Persistence/SimpleEntitySerializer.cs index 10e7ce1..57f787a 100644 --- a/TechbloxModdingAPI/Persistence/SimpleEntitySerializer.cs +++ b/TechbloxModdingAPI/Persistence/SimpleEntitySerializer.cs @@ -46,7 +46,7 @@ namespace TechbloxModdingAPI.Persistence public bool Serialize(ref ISerializationData serializationData, EntitiesDB entitiesDB, IEntitySerialization entitySerializer) { - serializationData.data.ExpandBy(4u); + serializationData.data.IncreaseCapacityBy(4u); BinaryBufferWriter bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out int count), serializationData.dataPos); EGID[] toSerialize = getEntitiesToSerialize(entitiesDB); bbw.Write((uint)toSerialize.Length); diff --git a/TechbloxModdingAPI/Player.cs b/TechbloxModdingAPI/Player.cs index 2ce88f1..f4386db 100644 --- a/TechbloxModdingAPI/Player.cs +++ b/TechbloxModdingAPI/Player.cs @@ -481,7 +481,7 @@ namespace TechbloxModdingAPI { var egid = playerEngine.GetThingLookedAt(Id, maxDistance); return egid != default && egid.groupID == WiresGUIExclusiveGroups.WireGroup - ? EcsObjectBase.GetInstance(new EGID(egid.entityID, NamedExclusiveGroup.Group), + ? EcsObjectBase.GetInstance(new EGID(egid.entityID, BuildModeWiresGroups.WiresGroup.Group), e => new Wire(e)) : null; } diff --git a/TechbloxModdingAPI/Tasks/Scheduler.cs b/TechbloxModdingAPI/Tasks/Scheduler.cs index 764e9b7..5ad842e 100644 --- a/TechbloxModdingAPI/Tasks/Scheduler.cs +++ b/TechbloxModdingAPI/Tasks/Scheduler.cs @@ -20,7 +20,7 @@ namespace TechbloxModdingAPI.Tasks { get { - return RobocraftX.Schedulers.Lean.UIScheduler; + return RobocraftX.Schedulers.ClientLean.UIScheduler; } } @@ -28,7 +28,7 @@ namespace TechbloxModdingAPI.Tasks { get { - return RobocraftX.Schedulers.ExtraLean.UIScheduler; + return RobocraftX.Schedulers.ClientExtraLean.UIScheduler; } } diff --git a/TechbloxModdingAPI/TechbloxModdingAPI.csproj b/TechbloxModdingAPI/TechbloxModdingAPI.csproj index 95927f8..7d5cab8 100644 --- a/TechbloxModdingAPI/TechbloxModdingAPI.csproj +++ b/TechbloxModdingAPI/TechbloxModdingAPI.csproj @@ -37,1205 +37,1317 @@ ..\..\ref\TechbloxPreview_Data\Managed\IllusionPlugin.dll - ..\ref\TechbloxPreview_Data\Managed\Analytics.dll - ..\..\ref\TechbloxPreview_Data\Managed\Analytics.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Analytics.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Analytics.dll - ..\ref\TechbloxPreview_Data\Managed\Assembly-CSharp-firstpass.dll - ..\..\ref\TechbloxPreview_Data\Managed\Assembly-CSharp-firstpass.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Assembly-CSharp-firstpass.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Assembly-CSharp-firstpass.dll - ..\ref\TechbloxPreview_Data\Managed\Assembly-CSharp.dll - ..\..\ref\TechbloxPreview_Data\Managed\Assembly-CSharp.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Assembly-CSharp.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Assembly-CSharp.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\AWSSDK.Core.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\AWSSDK.Core.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\AWSSDK.GameLift.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\AWSSDK.GameLift.dll - ..\ref\TechbloxPreview_Data\Managed\BevelEffect.dll - ..\..\ref\TechbloxPreview_Data\Managed\BevelEffect.dll + ..\ref_preview\TechbloxPreview_Data\Managed\BevelEffect.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\BevelEffect.dll - ..\ref\TechbloxPreview_Data\Managed\Blocks.HUDFeedbackBlocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Blocks.HUDFeedbackBlocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Blocks.HUDFeedbackBlocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Blocks.HUDFeedbackBlocks.dll - ..\ref\TechbloxPreview_Data\Managed\Boxophobic.TheVehetationEngine.Runtime.dll - ..\..\ref\TechbloxPreview_Data\Managed\Boxophobic.TheVehetationEngine.Runtime.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Boxophobic.TheVehetationEngine.Runtime.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Boxophobic.TheVehetationEngine.Runtime.dll - ..\ref\TechbloxPreview_Data\Managed\Boxophobic.Utils.Scripts.dll - ..\..\ref\TechbloxPreview_Data\Managed\Boxophobic.Utils.Scripts.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Boxophobic.Utils.Scripts.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Boxophobic.Utils.Scripts.dll - ..\ref\TechbloxPreview_Data\Managed\DataLoader.dll - ..\..\ref\TechbloxPreview_Data\Managed\DataLoader.dll + ..\ref_preview\TechbloxPreview_Data\Managed\DataLoader.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\DataLoader.dll - ..\ref\TechbloxPreview_Data\Managed\DDNA.dll - ..\..\ref\TechbloxPreview_Data\Managed\DDNA.dll + ..\ref_preview\TechbloxPreview_Data\Managed\DDNA.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\DDNA.dll - ..\ref\TechbloxPreview_Data\Managed\EasyButtons.dll - ..\..\ref\TechbloxPreview_Data\Managed\EasyButtons.dll + ..\ref_preview\TechbloxPreview_Data\Managed\EasyButtons.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\EasyButtons.dll - ..\ref\TechbloxPreview_Data\Managed\EOSSDK.dll - ..\..\ref\TechbloxPreview_Data\Managed\EOSSDK.dll + ..\ref_preview\TechbloxPreview_Data\Managed\EOSSDK.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\EOSSDK.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Facepunch.Steamworks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Facepunch.Steamworks.dll - ..\ref\TechbloxPreview_Data\Managed\FMODUnity.dll - ..\..\ref\TechbloxPreview_Data\Managed\FMODUnity.dll + ..\ref_preview\TechbloxPreview_Data\Managed\FMODUnity.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\FMODUnity.dll - ..\ref\TechbloxPreview_Data\Managed\FMODUnityResonance.dll - ..\..\ref\TechbloxPreview_Data\Managed\FMODUnityResonance.dll + ..\ref_preview\TechbloxPreview_Data\Managed\FMODUnityResonance.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\FMODUnityResonance.dll - ..\ref\TechbloxPreview_Data\Managed\FullGame.dll - ..\..\ref\TechbloxPreview_Data\Managed\FullGame.dll + ..\ref_preview\TechbloxPreview_Data\Managed\FullGame.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\FullGame.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.AudioBlocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.AudioBlocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.AudioBlocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.AudioBlocks.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.BlockEntityFactory.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.BlockEntityFactory.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.BlockEntityFactory.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.BlockEntityFactory.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.BlockGroups.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.BlockGroups.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.BlockGroups.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.BlockGroups.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.DamagingSurfaceBlock.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.DamagingSurfaceBlock.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Blocks.DamagingSurfaceBlock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Blocks.DamagingSurfaceBlock.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.DestructionBlocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.DestructionBlocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Blocks.DestructionBlocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Blocks.DestructionBlocks.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.GenericPhysicsBlocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.GenericPhysicsBlocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Blocks.GenericPhysicsBlocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Blocks.GenericPhysicsBlocks.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.LogicBlock.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.LogicBlock.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Blocks.LogicBlock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Blocks.LogicBlock.dll - ..\ref\TechbloxPreview_Data\Managed\GameCraft.Blocks.ProjectileBlock.dll - ..\..\ref\TechbloxPreview_Data\Managed\GameCraft.Blocks.ProjectileBlock.dll - - - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.TextBlock.CompositionRoot.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.TextBlock.CompositionRoot.dll - - - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.TimerBlock.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Blocks.TimerBlock.dll + ..\ref_preview\TechbloxPreview_Data\Managed\GameCraft.Blocks.ProjectileBlock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\GameCraft.Blocks.ProjectileBlock.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.CharacterVulnerability.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.CharacterVulnerability.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.CharacterVulnerability.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.CharacterVulnerability.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.CharacterVulnerabilityGui.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.CharacterVulnerabilityGui.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.CharacterVulnerabilityGui.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.CharacterVulnerabilityGui.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.ColourPalette.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.ColourPalette.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.ColourPalette.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.ColourPalette.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Damage.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Damage.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Damage.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Damage.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Effects.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Effects.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Effects.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Effects.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.ExplosionFragments.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.ExplosionFragments.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.ExplosionFragments.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.ExplosionFragments.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GraphicsSettings.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GraphicsSettings.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GraphicsSettings.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GraphicsSettings.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintInventory.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintInventory.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintInventory.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintInventory.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintInventoryMock.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintInventoryMock.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintInventoryMock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintInventoryMock.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Blueprints.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Blueprints.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Blueprints.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Blueprints.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintSets.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintSets.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintSets.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.BlueprintSets.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.BlueprintsHotbar.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.BlueprintsHotbar.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.BlueprintsHotbar.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.BlueprintsHotbar.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.Colours.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.Colours.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.Colours.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Hotbar.Colours.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.HUDFeedbackBlocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.HUDFeedbackBlocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.HUDFeedbackBlocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.HUDFeedbackBlocks.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.ModeBar.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.ModeBar.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.ModeBar.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.ModeBar.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.OptionsScreen.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.OptionsScreen.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.OptionsScreen.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.OptionsScreen.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Blocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Blocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Blocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Blocks.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Blueprints.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Blueprints.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Blueprints.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Blueprints.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Colours.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Colours.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Colours.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Colours.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Common.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Common.dll - - - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.TimeModeClock.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.TimeModeClock.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Common.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.TabsBar.Common.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Tweaks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Tweaks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Tweaks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Tweaks.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Wires.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Wires.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Wires.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Wires.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Wires.Mockup.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.Wires.Mockup.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Wires.Mockup.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.Wires.Mockup.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.InventoryTimeRunning.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.InventoryTimeRunning.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.InventoryTimeRunning.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.InventoryTimeRunning.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.JointBlocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.JointBlocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.JointBlocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.JointBlocks.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Music.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Music.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Music.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Music.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.NetStrings.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.NetStrings.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.NetStrings.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.NetStrings.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.PerformanceWarnings.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.PerformanceWarnings.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.PerformanceWarnings.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.PerformanceWarnings.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.PickupBlck.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.PickupBlck.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.PickupBlck.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.PickupBlck.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.PickupsCommon.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.PickupsCommon.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.PickupsCommon.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.PickupsCommon.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.PopupMessage.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.PopupMessage.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.PopupMessage.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.PopupMessage.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Projectiles.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Projectiles.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Projectiles.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Projectiles.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Serialization.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Serialization.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Serialization.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Serialization.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Tweaks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Tweaks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Tweaks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Tweaks.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Tweaks.Mockup.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Tweaks.Mockup.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Tweaks.Mockup.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Tweaks.Mockup.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.VisualEffects.Decals.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.VisualEffects.Decals.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.VisualEffects.Decals.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.VisualEffects.Decals.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.VisualEffects.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.VisualEffects.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.VisualEffects.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.VisualEffects.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Wires.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Wires.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Wires.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Wires.dll - ..\ref\TechbloxPreview_Data\Managed\Gamecraft.Wires.Mockup.dll - ..\..\ref\TechbloxPreview_Data\Managed\Gamecraft.Wires.Mockup.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Wires.Mockup.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Gamecraft.Wires.Mockup.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\GameLiftServerSDKNet45.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\GameLiftServerSDKNet45.dll - ..\ref\TechbloxPreview_Data\Managed\GameState.dll - ..\..\ref\TechbloxPreview_Data\Managed\GameState.dll + ..\ref_preview\TechbloxPreview_Data\Managed\GameState.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\GameState.dll - ..\ref\TechbloxPreview_Data\Managed\GhostShark.Outline.dll - ..\..\ref\TechbloxPreview_Data\Managed\GhostShark.Outline.dll + ..\ref_preview\TechbloxPreview_Data\Managed\GhostShark.Outline.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\GhostShark.Outline.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Google.Protobuf.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Google.Protobuf.dll - ..\ref\TechbloxPreview_Data\Managed\GPUInstancer.CrowdAnimations.dll - ..\..\ref\TechbloxPreview_Data\Managed\GPUInstancer.CrowdAnimations.dll + ..\ref_preview\TechbloxPreview_Data\Managed\GPUInstancer.CrowdAnimations.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\GPUInstancer.CrowdAnimations.dll - ..\ref\TechbloxPreview_Data\Managed\GPUInstancer.dll - ..\..\ref\TechbloxPreview_Data\Managed\GPUInstancer.dll + ..\ref_preview\TechbloxPreview_Data\Managed\GPUInstancer.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\GPUInstancer.dll - ..\ref\TechbloxPreview_Data\Managed\Havok.Physics.dll - ..\..\ref\TechbloxPreview_Data\Managed\Havok.Physics.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Havok.Physics.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Havok.Physics.dll - ..\ref\TechbloxPreview_Data\Managed\Havok.Physics.Hybrid.dll - ..\..\ref\TechbloxPreview_Data\Managed\Havok.Physics.Hybrid.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Havok.Physics.Hybrid.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Havok.Physics.Hybrid.dll - ..\ref\TechbloxPreview_Data\Managed\JWT.dll - ..\..\ref\TechbloxPreview_Data\Managed\JWT.dll + ..\ref_preview\TechbloxPreview_Data\Managed\JWT.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\JWT.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\log4net.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\log4net.dll - ..\ref\TechbloxPreview_Data\Managed\LZ4.dll - ..\..\ref\TechbloxPreview_Data\Managed\LZ4.dll + ..\ref_preview\TechbloxPreview_Data\Managed\LZ4.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\LZ4.dll - ..\ref\TechbloxPreview_Data\Managed\mscorlib.dll - ..\..\ref\TechbloxPreview_Data\Managed\mscorlib.dll + ..\ref_preview\TechbloxPreview_Data\Managed\mscorlib.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\mscorlib.dll - ..\ref\TechbloxPreview_Data\Managed\MultiplayerNetworking.dll - ..\..\ref\TechbloxPreview_Data\Managed\MultiplayerNetworking.dll - - - ..\ref\TechbloxPreview_Data\Managed\MultiplayerTest.dll - ..\..\ref\TechbloxPreview_Data\Managed\MultiplayerTest.dll + ..\ref_preview\TechbloxPreview_Data\Managed\MultiplayerNetworking.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\MultiplayerNetworking.dll - ..\ref\TechbloxPreview_Data\Managed\netstandard.dll - ..\..\ref\TechbloxPreview_Data\Managed\netstandard.dll + ..\ref_preview\TechbloxPreview_Data\Managed\netstandard.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\netstandard.dll - ..\ref\TechbloxPreview_Data\Managed\Newtonsoft.Json.dll - ..\..\ref\TechbloxPreview_Data\Managed\Newtonsoft.Json.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Newtonsoft.Json.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Newtonsoft.Json.dll - ..\ref\TechbloxPreview_Data\Managed\RCX.ScreenshotTaker.dll - ..\..\ref\TechbloxPreview_Data\Managed\RCX.ScreenshotTaker.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RCX.ScreenshotTaker.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RCX.ScreenshotTaker.dll - ..\ref\TechbloxPreview_Data\Managed\Rewired_Core.dll - ..\..\ref\TechbloxPreview_Data\Managed\Rewired_Core.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Rewired_Core.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Rewired_Core.dll - ..\ref\TechbloxPreview_Data\Managed\Rewired_Windows.dll - ..\..\ref\TechbloxPreview_Data\Managed\Rewired_Windows.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Rewired_Windows.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Rewired_Windows.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftECS.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftECS.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftECS.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftECS.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.AccountPreferences.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.AccountPreferences.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.AccountPreferences.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.AccountPreferences.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Blocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Blocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Blocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Blocks.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Blocks.Ghost.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Blocks.Ghost.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Blocks.Ghost.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Blocks.Ghost.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Blocks.Triggers.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Blocks.Triggers.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Blocks.Triggers.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Blocks.Triggers.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Building.BoxSelect.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Building.BoxSelect.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Building.BoxSelect.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Building.BoxSelect.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Building.Jobs.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Building.Jobs.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Building.Jobs.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Building.Jobs.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Character.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Character.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Character.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Character.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Character.Weapons.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Character.Weapons.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Common.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Common.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Common.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Common.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.ControlsScreen.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.ControlsScreen.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.ControlsScreen.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.ControlsScreen.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Crosshair.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Crosshair.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Crosshair.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Crosshair.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.FrontEnd.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.FrontEnd.dll - - - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.BlockLabel.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.BlockLabel.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.FrontEnd.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.FrontEnd.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.DebugDisplay.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.DebugDisplay.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.DebugDisplay.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.DebugDisplay.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Hotbar.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Hotbar.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.Hotbar.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.Hotbar.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.BlocksInventory.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.BlocksInventory.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.BlocksInventory.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.BlocksInventory.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.ColourInventory.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.ColourInventory.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.ColourInventory.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.ColourInventory.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.PauseMenu.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.PauseMenu.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.PauseMenu.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.PauseMenu.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.ScaleGhost.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.ScaleGhost.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.ScaleGhost.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.ScaleGhost.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.TabsBar.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.TabsBar.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.TabsBar.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.GUI.TabsBar.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Input.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Input.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Input.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Input.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.MachineEditor.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.MachineEditor.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MachineEditor.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MachineEditor.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MachineEditorMock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MachineEditorMock.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.MainGame.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.MainGame.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MainGame.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MainGame.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.MainGameMock.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.MainGameMock.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MainGameMock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MainGameMock.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.MainSimulation.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.MainSimulation.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MainSimulation.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MainSimulation.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.MockCharacter.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.MockCharacter.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MockCharacter.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MockCharacter.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.dll - - - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.GUI.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.GUI.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.Serializers.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.Serializers.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.Serializers.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Multiplayer.Serializers.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.MultiplayerInput.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.MultiplayerInput.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MultiplayerInput.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.MultiplayerInput.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.ObjectIdBlocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.ObjectIdBlocks.dll - - - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Party.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Party.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.ObjectIdBlocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.ObjectIdBlocks.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Physics.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Physics.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Physics.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Physics.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.PilotSeat.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.PilotSeat.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.PilotSeat.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.PilotSeat.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Player.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Player.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Player.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Player.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Rendering.Mock.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Rendering.Mock.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Rendering.Mock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Rendering.Mock.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.SaveAndLoad.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.SaveAndLoad.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.SaveAndLoad.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.SaveAndLoad.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.SaveGameDialog.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.SaveGameDialog.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.SaveGameDialog.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.SaveGameDialog.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.Services.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.Services.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Services.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.Services.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.SignalHandling.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.SignalHandling.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.SignalHandling.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.SignalHandling.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.SpawnPoints.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.SpawnPoints.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.SpawnPoints.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.SpawnPoints.dll - ..\ref\TechbloxPreview_Data\Managed\RobocraftX.StateSync.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.StateSync.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.StateSync.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.StateSync.dll - - ..\ref\TechbloxPreview_Data\Managed\RobocraftX_TextBlock.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocraftX_TextBlock.dll + + ..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.StateSync.Mock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocraftX.StateSync.Mock.dll - ..\ref\TechbloxPreview_Data\Managed\RobocratX.SimulationMockCompositionRoot.dll - ..\..\ref\TechbloxPreview_Data\Managed\RobocratX.SimulationMockCompositionRoot.dll + ..\ref_preview\TechbloxPreview_Data\Managed\RobocratX.SimulationMockCompositionRoot.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\RobocratX.SimulationMockCompositionRoot.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\ShaderVariantsGenerationTool.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\ShaderVariantsGenerationTool.dll - ..\ref\TechbloxPreview_Data\Managed\SpecializedDescriptors.dll - ..\..\ref\TechbloxPreview_Data\Managed\SpecializedDescriptors.dll + ..\ref_preview\TechbloxPreview_Data\Managed\SpecializedDescriptors.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\SpecializedDescriptors.dll - ..\ref\TechbloxPreview_Data\Managed\StringFormatter.dll - ..\..\ref\TechbloxPreview_Data\Managed\StringFormatter.dll + ..\ref_preview\TechbloxPreview_Data\Managed\StringFormatter.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\StringFormatter.dll - ..\ref\TechbloxPreview_Data\Managed\Svelto.Common.dll - ..\..\ref\TechbloxPreview_Data\Managed\Svelto.Common.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Svelto.Common.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Svelto.Common.dll - ..\ref\TechbloxPreview_Data\Managed\Svelto.ECS.dll - ..\..\ref\TechbloxPreview_Data\Managed\Svelto.ECS.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Svelto.ECS.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Svelto.ECS.dll - ..\ref\TechbloxPreview_Data\Managed\Svelto.ECS.GUI.dll - ..\..\ref\TechbloxPreview_Data\Managed\Svelto.ECS.GUI.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Svelto.ECS.GUI.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Svelto.ECS.GUI.dll - ..\ref\TechbloxPreview_Data\Managed\Svelto.Services.dll - ..\..\ref\TechbloxPreview_Data\Managed\Svelto.Services.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Svelto.Services.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Svelto.Services.dll - ..\ref\TechbloxPreview_Data\Managed\Svelto.Tasks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Svelto.Tasks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Svelto.Tasks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Svelto.Tasks.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.AdditionalParts.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.AdditionalParts.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Anticheat.Client.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Anticheat.Client.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Anticheat.Common.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Anticheat.Common.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Anticheat.Server.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Anticheat.Server.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.AtmosphereBlock.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.AtmosphereBlock.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.AtmosphereBlock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.AtmosphereBlock.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.AutoForward.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.AutoForward.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.AutoForward.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.AutoForward.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Backend.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Backend.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Backend.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Backend.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.BitBlock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.BitBlock.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.BlockColours.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.BlockColours.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.BlockLabels.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.BlockLabels.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Blocks.LightBlock.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Blocks.LightBlock.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Blocks.LightBlock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Blocks.LightBlock.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Building.Rules.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Building.Rules.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Building.Rules.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Building.Rules.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.BuildingDrone.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.BuildingDrone.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.BuildingDrone.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.BuildingDrone.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Camera.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Camera.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Camera.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Camera.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.ContextSensitiveTextHint.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.ContextSensitiveTextHint.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.ContextSensitiveTextHint.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.ContextSensitiveTextHint.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.ECSResourceManagers.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.ECSResourceManagers.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.EngineBlock.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.EngineBlock.dll - - - ..\ref\TechbloxPreview_Data\Managed\Techblox.Environment.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Environment.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.EngineBlock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.EngineBlock.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.BuildingEnvironment.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.BuildingEnvironment.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.BuildingEnvironment.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.BuildingEnvironment.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.SimulationWorldEnvironment.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.SimulationWorldEnvironment.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.SimulationWorldEnvironment.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.EnvironmentBlocks.SimulationWorldEnvironment.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GameSelection.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GameSelection.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GameSelection.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GameSelection.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Building.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Building.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Building.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Building.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.BuildRules.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.BuildRules.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.BuildRules.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.BuildRules.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.BuildRules.MockUps.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.BuildRules.MockUps.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.BuildRules.MockUps.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.BuildRules.MockUps.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Commands.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Commands.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Controls.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Controls.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.GamePortal.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.GamePortal.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.GamePortal.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.GamePortal.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.GamePortal.MockUps.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.GamePortal.MockUps.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.GamePortal.MockUps.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.GamePortal.MockUps.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Hotbar.Landscapes.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Hotbar.Landscapes.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Hotbar.Landscapes.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Hotbar.Landscapes.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Hotbar.Materials.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Hotbar.Materials.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Hotbar.Materials.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Hotbar.Materials.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Common.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Common.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Common.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Common.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Landscapes.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Landscapes.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Landscapes.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Landscapes.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Materials.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Materials.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Materials.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Inventory.Materials.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.LoadingBar.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.LoadingBar.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Login.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Login.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Login.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Login.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Mocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Mocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Mocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Mocks.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Mocks.DynamicListBuild.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Mocks.DynamicListBuild.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Mocks.DynamicListBuild.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Mocks.DynamicListBuild.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.MyGamesScreen.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.MyGamesScreen.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.MyGamesScreen.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.MyGamesScreen.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Notifications.MockUps.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.Notifications.MockUps.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Notifications.MockUps.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Notifications.MockUps.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.TabsBar.Landscapes.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.TabsBar.Landscapes.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.TabsBar.Landscapes.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.TabsBar.Landscapes.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.TabsBar.Materials.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.GUI.TabsBar.Materials.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.TabsBar.Materials.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.TabsBar.Materials.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Toggle.MockUps.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.Toggle.MockUps.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.UsernameDisplay.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.GUI.UsernameDisplay.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.InputCapture.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.InputCapture.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.InputCapture.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.InputCapture.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.MachineSimulationPreprocessing.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.MachineSimulationPreprocessing.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.MachineSpawning.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.MachineSpawning.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Matchmaking.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Matchmaking.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Multiplayer.UsernameMessages.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Multiplayer.UsernameMessages.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.PlayUX.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.PlayUX.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Pointer.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Pointer.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Pointer.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Pointer.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.ProceduralReflectionProbes.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.ProceduralReflectionProbes.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.ProceduralReflectionProbes.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.ProceduralReflectionProbes.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Rendering.Common.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Rendering.Common.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Rendering.Common.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Rendering.Common.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Rendering.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Rendering.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Rendering.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Rendering.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Rendering.DOTS.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Rendering.DOTS.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Rendering.DOTS.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Rendering.DOTS.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Rendering.GPUI.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Rendering.GPUI.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Rendering.GPUI.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Rendering.GPUI.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Rendering.Unity.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Rendering.Unity.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Rendering.Unity.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Rendering.Unity.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.SaveGamesConversion.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.SaveGamesConversion.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.SaveGamesConversion.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.SaveGamesConversion.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Server.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Server.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Anticheat.Client.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Anticheat.Client.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Anticheat.Server.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Anticheat.Server.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Eos.Common.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Eos.Common.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Services.Eos.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Services.Eos.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Eos.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Eos.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Eos.Server.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Eos.Server.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Services.GameDetails.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Services.GameDetails.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.GameDetails.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.GameDetails.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Matchmaking.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Matchmaking.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.Services.Storage.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.Services.Storage.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Storage.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.Services.Storage.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.SwitchAnimation.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.SwitchAnimation.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.SwitchAnimation.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.SwitchAnimation.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.TextBlock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.TextBlock.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.TimerBlock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.TimerBlock.dll - ..\ref\TechbloxPreview_Data\Managed\Techblox.WheelRigBlock.dll - ..\..\ref\TechbloxPreview_Data\Managed\Techblox.WheelRigBlock.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Techblox.WheelRigBlock.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Techblox.WheelRigBlock.dll - ..\ref\TechbloxPreview_Data\Managed\UniTask.Addressables.dll - ..\..\ref\TechbloxPreview_Data\Managed\UniTask.Addressables.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UniTask.Addressables.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UniTask.Addressables.dll - ..\ref\TechbloxPreview_Data\Managed\UniTask.dll - ..\..\ref\TechbloxPreview_Data\Managed\UniTask.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UniTask.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UniTask.dll - ..\ref\TechbloxPreview_Data\Managed\UniTask.DOTween.dll - ..\..\ref\TechbloxPreview_Data\Managed\UniTask.DOTween.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UniTask.DOTween.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UniTask.DOTween.dll - ..\ref\TechbloxPreview_Data\Managed\UniTask.Linq.dll - ..\..\ref\TechbloxPreview_Data\Managed\UniTask.Linq.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UniTask.Linq.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UniTask.Linq.dll - ..\ref\TechbloxPreview_Data\Managed\UniTask.TextMeshPro.dll - ..\..\ref\TechbloxPreview_Data\Managed\UniTask.TextMeshPro.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UniTask.TextMeshPro.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UniTask.TextMeshPro.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Addressables.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Addressables.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Addressables.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Addressables.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Mdb.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Mdb.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Mdb.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Mdb.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Pdb.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Pdb.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Pdb.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Pdb.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Rocks.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Rocks.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Rocks.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.Cecil.Rocks.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Burst.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Burst.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Burst.Unsafe.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Burst.Unsafe.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.Unsafe.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Burst.Unsafe.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Collections.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Collections.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Collections.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Collections.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Deformations.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Deformations.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Deformations.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Deformations.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Entities.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Entities.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Entities.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Entities.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Entities.Hybrid.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Entities.Hybrid.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Entities.Hybrid.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Entities.Hybrid.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.InternalAPIEngineBridge.012.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.InternalAPIEngineBridge.012.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.InternalAPIEngineBridge.012.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.InternalAPIEngineBridge.012.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Jobs.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Jobs.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Jobs.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Jobs.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Mathematics.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Mathematics.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Mathematics.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Mathematics.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Mathematics.Extensions.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Mathematics.Extensions.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Mathematics.Extensions.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Mathematics.Extensions.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.MemoryProfiler.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.MemoryProfiler.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.MemoryProfiler.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.MemoryProfiler.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Physics.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Physics.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Physics.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Physics.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Physics.Hybrid.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Physics.Hybrid.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Physics.Hybrid.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Physics.Hybrid.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Platforms.Common.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Platforms.Common.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Platforms.Common.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Platforms.Common.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Properties.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Properties.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Properties.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Properties.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Properties.Reflection.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Properties.Reflection.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Properties.Reflection.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Properties.Reflection.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Properties.UI.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Properties.UI.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Properties.UI.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Properties.UI.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Recorder.Base.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Recorder.Base.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Recorder.Base.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Recorder.Base.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Recorder.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Recorder.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Recorder.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Recorder.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Rendering.Hybrid.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Rendering.Hybrid.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Rendering.Hybrid.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Rendering.Hybrid.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.RenderPipelines.HighDefinition.Config.Runtime.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.RenderPipelines.HighDefinition.Config.Runtime.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.RenderPipelines.HighDefinition.Config.Runtime.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.RenderPipelines.HighDefinition.Config.Runtime.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.RenderPipelines.HighDefinition.Runtime.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.RenderPipelines.HighDefinition.Runtime.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.RenderPipelines.HighDefinition.Runtime.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.RenderPipelines.HighDefinition.Runtime.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.ResourceManager.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.ResourceManager.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.ResourceManager.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.ResourceManager.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Scenes.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Scenes.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Scenes.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Scenes.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.ScriptableBuildPipeline.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.ScriptableBuildPipeline.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.ScriptableBuildPipeline.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.ScriptableBuildPipeline.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Serialization.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Serialization.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Serialization.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Serialization.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.TextMeshPro.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.TextMeshPro.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.TextMeshPro.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.TextMeshPro.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Timeline.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Timeline.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Timeline.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Timeline.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Transforms.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Transforms.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Transforms.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Transforms.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.Transforms.Hybrid.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.Transforms.Hybrid.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.Transforms.Hybrid.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.Transforms.Hybrid.dll - ..\ref\TechbloxPreview_Data\Managed\Unity.VisualEffectGraph.Runtime.dll - ..\..\ref\TechbloxPreview_Data\Managed\Unity.VisualEffectGraph.Runtime.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Unity.VisualEffectGraph.Runtime.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Unity.VisualEffectGraph.Runtime.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.AccessibilityModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.AccessibilityModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AccessibilityModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AccessibilityModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.AIModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.AIModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AIModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AIModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.AndroidJNIModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.AndroidJNIModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AndroidJNIModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AndroidJNIModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.AnimationModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.AnimationModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AnimationModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AnimationModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.ARModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.ARModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ARModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ARModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.AssetBundleModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.AssetBundleModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AssetBundleModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AssetBundleModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.AudioModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.AudioModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AudioModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.AudioModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.ClothModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.ClothModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ClothModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ClothModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.ClusterInputModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.ClusterInputModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ClusterInputModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ClusterInputModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.ClusterRendererModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.ClusterRendererModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ClusterRendererModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ClusterRendererModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.CoreModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.CoreModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.CoreModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.CoreModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.CrashReportingModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.CrashReportingModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.CrashReportingModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.CrashReportingModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.DirectorModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.DirectorModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.DirectorModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.DirectorModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.DSPGraphModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.DSPGraphModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.DSPGraphModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.DSPGraphModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.GameCenterModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.GameCenterModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.GameCenterModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.GameCenterModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.GIModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.GIModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.GIModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.GIModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.GridModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.GridModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.GridModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.GridModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.HotReloadModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.HotReloadModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.HotReloadModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.HotReloadModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.ImageConversionModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.ImageConversionModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ImageConversionModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ImageConversionModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.IMGUIModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.IMGUIModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.IMGUIModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.IMGUIModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.InputLegacyModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.InputLegacyModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.InputLegacyModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.InputLegacyModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.InputModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.InputModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.InputModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.InputModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.JSONSerializeModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.JSONSerializeModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.JSONSerializeModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.JSONSerializeModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.LocalizationModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.LocalizationModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.LocalizationModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.LocalizationModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.ParticleSystemModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.ParticleSystemModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ParticleSystemModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ParticleSystemModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.PerformanceReportingModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.PerformanceReportingModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.PerformanceReportingModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.PerformanceReportingModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.Physics2DModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.Physics2DModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.Physics2DModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.Physics2DModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.PhysicsModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.PhysicsModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.PhysicsModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.PhysicsModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.ProfilerModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.ProfilerModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ProfilerModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ProfilerModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.ScreenCaptureModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.ScreenCaptureModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ScreenCaptureModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.ScreenCaptureModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.SharedInternalsModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.SharedInternalsModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.SharedInternalsModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.SharedInternalsModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.SpriteMaskModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.SpriteMaskModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.SpriteMaskModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.SpriteMaskModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.SpriteShapeModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.SpriteShapeModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.SpriteShapeModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.SpriteShapeModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.StreamingModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.StreamingModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.StreamingModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.StreamingModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.SubstanceModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.SubstanceModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.SubstanceModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.SubstanceModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.SubsystemsModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.SubsystemsModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.SubsystemsModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.SubsystemsModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.TerrainModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.TerrainModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TerrainModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TerrainModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.TerrainPhysicsModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TerrainPhysicsModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.TextCoreModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.TextCoreModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TextCoreModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TextCoreModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.TextRenderingModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.TextRenderingModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TextRenderingModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TextRenderingModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.TilemapModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.TilemapModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TilemapModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TilemapModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.TLSModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.TLSModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TLSModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.TLSModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UI.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UI.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UI.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UI.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UIElementsModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UIElementsModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UIElementsModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UIElementsModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UIElementsNativeModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UIElementsNativeModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UIElementsNativeModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UIElementsNativeModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UIModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UIModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UIModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UIModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UmbraModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UmbraModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UmbraModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UmbraModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UNETModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UNETModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UNETModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UNETModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityAnalyticsModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityAnalyticsModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityConnectModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityConnectModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityConnectModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityConnectModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityCurlModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityCurlModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityCurlModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityCurlModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityTestProtocolModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityTestProtocolModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.VehiclesModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.VehiclesModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.VehiclesModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.VehiclesModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.VFXModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.VFXModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.VFXModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.VFXModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.VideoModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.VideoModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.VideoModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.VideoModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.VirtualTexturingModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.VirtualTexturingModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.VirtualTexturingModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.VirtualTexturingModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.VRModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.VRModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.VRModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.VRModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.WindModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.WindModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.WindModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.WindModule.dll - ..\ref\TechbloxPreview_Data\Managed\UnityEngine.XRModule.dll - ..\..\ref\TechbloxPreview_Data\Managed\UnityEngine.XRModule.dll + ..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.XRModule.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\UnityEngine.XRModule.dll - ..\ref\TechbloxPreview_Data\Managed\VisualProfiler.dll - ..\..\ref\TechbloxPreview_Data\Managed\VisualProfiler.dll + ..\ref_preview\TechbloxPreview_Data\Managed\VisualProfiler.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\VisualProfiler.dll + + + ..\ref_preview\TechbloxPreview_Data\Managed\websocket-sharp.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\websocket-sharp.dll - ..\ref\TechbloxPreview_Data\Managed\Whinarn.UnityMeshSimplifier.Runtime.dll - ..\..\ref\TechbloxPreview_Data\Managed\Whinarn.UnityMeshSimplifier.Runtime.dll + ..\ref_preview\TechbloxPreview_Data\Managed\Whinarn.UnityMeshSimplifier.Runtime.dll + ..\..\ref_preview\TechbloxPreview_Data\Managed\Whinarn.UnityMeshSimplifier.Runtime.dll - + \ No newline at end of file diff --git a/TechbloxModdingAPI/Tests/TestRoot.cs b/TechbloxModdingAPI/Tests/TestRoot.cs index 7177818..bd5dc01 100644 --- a/TechbloxModdingAPI/Tests/TestRoot.cs +++ b/TechbloxModdingAPI/Tests/TestRoot.cs @@ -64,7 +64,7 @@ namespace TechbloxModdingAPI.Tests _testsCountPassed = 0; _testsCountFailed = 0; // flow control - Game.Enter += (sender, args) => { GameTests().RunOn(RobocraftX.Schedulers.Lean.EveryFrameStepRunner_TimeRunningAndStopped); }; + Game.Enter += (sender, args) => { GameTests().RunOn(RobocraftX.Schedulers.ClientLean.EveryFrameStepRunner_TimeRunningAndStopped); }; Game.Exit += (s, a) => state = "ReturningFromGame"; Client.EnterMenu += (sender, args) => { diff --git a/TechbloxModdingAPI/Utility/FullGameFields.cs b/TechbloxModdingAPI/Utility/FullGameFields.cs index 0a4dd1d..7ab1978 100644 --- a/TechbloxModdingAPI/Utility/FullGameFields.cs +++ b/TechbloxModdingAPI/Utility/FullGameFields.cs @@ -104,14 +104,6 @@ namespace TechbloxModdingAPI.Utility } } - public static PhysicsUtility _physicsUtility - { - get - { - return (PhysicsUtility)fgcr?.Field("_physicsUtility").GetValue(); - } - } - /*public static UnityEntitySubmissionScheduler _frontEndSubmissionScheduler { get From f817becc6e6660f178dedecabf78a442b3b97c4b Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Thu, 16 Dec 2021 21:13:45 +0100 Subject: [PATCH 28/32] Resolve all compile-time and patching errors, remove anticheat in singleplayer --- TechbloxModdingAPI/App/GameMenuEngine.cs | 2 +- TechbloxModdingAPI/Blocks/Engine.cs | 5 +- .../Blocks/Engines/BlueprintEngine.cs | 6 ++- .../Blocks/Engines/MovementEngine.cs | 5 +- .../Blocks/Engines/RotationEngine.cs | 6 +-- .../Blocks/Engines/ScalingEngine.cs | 14 +++--- TechbloxModdingAPI/Commands/CommandPatch.cs | 34 -------------- TechbloxModdingAPI/Engines/EnginePatches.cs | 24 +++++++++- TechbloxModdingAPI/Main.cs | 46 +++++++++++++++++-- TechbloxModdingAPI/Player.cs | 9 +--- TechbloxModdingAPI/Players/PlayerEngine.cs | 8 ++++ .../Tests/TechbloxModdingAPIPluginTest.cs | 9 ---- TechbloxModdingAPI/Utility/FullGameFields.cs | 16 ++----- 13 files changed, 99 insertions(+), 85 deletions(-) delete mode 100644 TechbloxModdingAPI/Commands/CommandPatch.cs diff --git a/TechbloxModdingAPI/App/GameMenuEngine.cs b/TechbloxModdingAPI/App/GameMenuEngine.cs index f356a0d..276bda8 100644 --- a/TechbloxModdingAPI/App/GameMenuEngine.cs +++ b/TechbloxModdingAPI/App/GameMenuEngine.cs @@ -175,7 +175,7 @@ namespace TechbloxModdingAPI.App public static MethodBase TargetMethod() { - return AccessTools.Method(typeof(FullGameCompositionRoot), "GoToMenu"); + return AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToMenu"); } } diff --git a/TechbloxModdingAPI/Blocks/Engine.cs b/TechbloxModdingAPI/Blocks/Engine.cs index 6140b11..9684108 100644 --- a/TechbloxModdingAPI/Blocks/Engine.cs +++ b/TechbloxModdingAPI/Blocks/Engine.cs @@ -22,7 +22,7 @@ namespace TechbloxModdingAPI.Blocks base(new EGID(id, CommonExclusiveGroups.ENGINE_BLOCK_BUILD_GROUP)) { } - + /* /// /// Gets or sets the Engine's On property. May not be saved. /// @@ -34,6 +34,7 @@ namespace TechbloxModdingAPI.Blocks } set { + Techblox.BlockColours.BlockColoursCompositionRoot BlockEngine.GetBlockInfo(this).engineOn = value; } } @@ -377,6 +378,6 @@ namespace TechbloxModdingAPI.Blocks { BlockEngine.GetBlockInfo(this).manualToAutoGearCoolOffTime = value; } - } + }*/ } } diff --git a/TechbloxModdingAPI/Blocks/Engines/BlueprintEngine.cs b/TechbloxModdingAPI/Blocks/Engines/BlueprintEngine.cs index 2ba15ce..789076e 100644 --- a/TechbloxModdingAPI/Blocks/Engines/BlueprintEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/BlueprintEngine.cs @@ -173,7 +173,8 @@ namespace TechbloxModdingAPI.Blocks.Engines foreach (var block in blocks) { GhostChildUtility.BuildGhostChild(in playerID, block.Id, in pos, in rot, entitiesDB, - BuildGhostBlueprintFactory, false, bssesopt.Get().buildingDroneReference); + BuildGhostBlueprintFactory, false, bssesopt.Get().buildingDroneReference, + FullGameFields._managers.blockLabelResourceManager); } } @@ -272,7 +273,8 @@ namespace TechbloxModdingAPI.Blocks.Engines uint ghostChildBlockId = CommonExclusiveGroups.GetNewGhostChildBlockID(); var ghostEntityReference = GhostBlockUtils.GetGhostEntityReference(sourceId.entityID, entitiesDB); var entityInitializer = BuildGhostBlueprintFactory.Build( - new EGID(ghostChildBlockId, BoxSelectExclusiveGroups.GhostChildEntitiesExclusiveGroup), /*dbStruct.DBID*/ (uint)BlockIDs.Cube); + new EGID(ghostChildBlockId, BoxSelectExclusiveGroups.GhostChildEntitiesExclusiveGroup), /*dbStruct.DBID*/ (uint)BlockIDs.Cube, + FullGameFields._managers.blockLabelResourceManager); entityInitializer.Init(dbStruct); entityInitializer.Init(new GFXPrefabEntityStructGPUI( PrefabsID.GetOrCreatePrefabID((ushort)entityInitializer.Get().prefabAssetID, diff --git a/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs b/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs index 07bfbe6..f9d65d8 100644 --- a/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs @@ -1,4 +1,5 @@ using RobocraftX.Common; +using RobocraftX.DOTS; using Svelto.ECS; using Svelto.ECS.EntityStructs; using Unity.Mathematics; @@ -39,7 +40,7 @@ namespace TechbloxModdingAPI.Blocks.Engines ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntityOrDefault(block); ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntityOrDefault(block); ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntityOrDefault(block); - ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntityOrDefault(block); + ref DOTSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntityOrDefault(block); // main (persistent) position posStruct.position = vector; // placement grid position @@ -49,7 +50,7 @@ namespace TechbloxModdingAPI.Blocks.Engines // collision position if (phyStruct.ID != default) { //It exists - FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation + FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.dotsEntity, new Translation { Value = posStruct.position }); diff --git a/TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs b/TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs index b2be508..4186bfd 100644 --- a/TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs @@ -1,5 +1,5 @@ using RobocraftX.Common; -using RobocraftX.UECS; +using RobocraftX.DOTS; using Svelto.ECS; using Svelto.ECS.EntityStructs; using Unity.Mathematics; @@ -40,7 +40,7 @@ namespace TechbloxModdingAPI.Blocks.Engines ref RotationEntityStruct rotStruct = ref this.entitiesDB.QueryEntityOrDefault(block); ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntityOrDefault(block); ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntityOrDefault(block); - ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntityOrDefault(block); + ref DOTSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntityOrDefault(block); // main (persistent) rotation Quaternion newRotation = rotStruct.rotation; newRotation.eulerAngles = vector; @@ -52,7 +52,7 @@ namespace TechbloxModdingAPI.Blocks.Engines // collision rotation if (phyStruct.ID != default) { //It exists - FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, + FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.dotsEntity, new Unity.Transforms.Rotation { Value = rotStruct.rotation diff --git a/TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs b/TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs index 9ca77f0..ef5cfe4 100644 --- a/TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs @@ -2,7 +2,7 @@ using HarmonyLib; using RobocraftX.Common; -using RobocraftX.UECS; +using RobocraftX.DOTS; using Svelto.ECS; using Unity.Entities; @@ -13,7 +13,7 @@ namespace TechbloxModdingAPI.Blocks.Engines { public class ScalingEngine : IApiEngine { - private static IReactOnAddAndRemove physicsEngine; + private static IReactOnAddAndRemove physicsEngine; public void Ready() { @@ -34,16 +34,16 @@ namespace TechbloxModdingAPI.Blocks.Engines if (_entityManager == default) _entityManager = FullGameFields._physicsWorld.EntityManager; //Assuming the block exists - var entity = entitiesDB.QueryEntity(egid).uecsEntity; - var pes = new UECSPhysicsEntityCreationStruct(); - physicsEngine.Add(ref pes, egid); //Create new UECS entity + var entity = entitiesDB.QueryEntity(egid).dotsEntity; + var pes = new DOTSPhysicsEntityCreationStruct(); + physicsEngine.Add(ref pes, egid); //Create new DOTS entity _entityManager.DestroyEntity(entity); } [HarmonyPatch] class PhysicsEnginePatch { - static void Postfix(IReactOnAddAndRemove __instance) + static void Postfix(IReactOnAddAndRemove __instance) { physicsEngine = __instance; Logging.MetaDebugLog("Physics engine injected."); @@ -51,7 +51,7 @@ namespace TechbloxModdingAPI.Blocks.Engines static MethodBase TargetMethod(Harmony instance) { - return AccessTools.Method("RobocraftX.StateSync.HandleUECSPhysicEntitiesWithPrefabCreationEngine" + + return AccessTools.Method("RobocraftX.StateSync.HandleDOTSPhysicEntitiesWithPrefabCreationEngine" + ":Ready"); } } diff --git a/TechbloxModdingAPI/Commands/CommandPatch.cs b/TechbloxModdingAPI/Commands/CommandPatch.cs deleted file mode 100644 index b928c1d..0000000 --- a/TechbloxModdingAPI/Commands/CommandPatch.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Reflection; - -using HarmonyLib; -using Svelto.ECS; -using RobocraftX.CR.MainGame; -using RobocraftX.Multiplayer; -using RobocraftX.StateSync; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Commands -{ - /// - /// Patch of RobocraftX.CR.MainGame.MainGameCompositionRoot.DeterministicCompose() - /// Initializes custom commands - /// - [HarmonyPatch] - static class CommandPatch - { - public static void Postfix(StateSyncRegistrationHelper stateSyncReg) - { - /*CommandLineCompositionRoot.Compose(contextHolder, stateSyncReg.enginesRoot, reloadGame, multiplayerParameters, - stateSyncReg); - uREPL C# compilation not supported anymore */ - var enginesRoot = stateSyncReg.enginesRoot; - CommandManager.RegisterEngines(enginesRoot); - } - - public static MethodInfo TargetMethod() - { - return AccessTools.Method(typeof(MainGameCompositionRoot), "DeterministicCompose") - .MakeGenericMethod(typeof(object)); - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Engines/EnginePatches.cs b/TechbloxModdingAPI/Engines/EnginePatches.cs index 8b6e6a5..7c9524b 100644 --- a/TechbloxModdingAPI/Engines/EnginePatches.cs +++ b/TechbloxModdingAPI/Engines/EnginePatches.cs @@ -6,12 +6,13 @@ using RobocraftX.FrontEnd; using RobocraftX.StateSync; using Svelto.ECS; using Svelto.ECS.Schedulers; +using TechbloxModdingAPI.Commands; using TechbloxModdingAPI.Utility; namespace TechbloxModdingAPI.Engines { [HarmonyPatch] - class GameLoadedEnginePatch + static class GameLoadedTimeStoppedEnginePatch { public static EntitiesSubmissionScheduler Scheduler { get; private set; } public static void Postfix(StateSyncRegistrationHelper stateSyncReg) @@ -19,11 +20,30 @@ namespace TechbloxModdingAPI.Engines // register all game engines, including deterministic GameEngineManager.RegisterEngines(stateSyncReg); Scheduler = stateSyncReg.enginesRoot.scheduler; + // register command engines + /*CommandLineCompositionRoot.Compose(contextHolder, stateSyncReg.enginesRoot, reloadGame, multiplayerParameters, + stateSyncReg); - uREPL C# compilation not supported anymore */ + CommandManager.RegisterEngines(stateSyncReg.enginesRoot); } public static MethodBase TargetMethod() { - return AccessTools.Method(typeof(MainGameCompositionRoot), "DeterministicCompose").MakeGenericMethod(typeof(object)); + return AccessTools.Method(typeof(MainGameCompositionRoot), "DeterministicTimeStoppedCompose").MakeGenericMethod(typeof(object)); + } + } + + [HarmonyPatch] + static class GameLoadedTimeRunningEnginePatch + { + public static EntitiesSubmissionScheduler Scheduler { get; private set; } + public static void Postfix(StateSyncRegistrationHelper stateSyncReg) + { + GameLoadedTimeStoppedEnginePatch.Postfix(stateSyncReg); + } + + public static MethodBase TargetMethod() + { + return AccessTools.Method(typeof(MainGameCompositionRoot), "DeterministicTimeRunningCompose").MakeGenericMethod(typeof(object)); } } diff --git a/TechbloxModdingAPI/Main.cs b/TechbloxModdingAPI/Main.cs index 610aa8e..0961576 100644 --- a/TechbloxModdingAPI/Main.cs +++ b/TechbloxModdingAPI/Main.cs @@ -1,15 +1,15 @@ using System; +using System.Collections.Generic; using System.Reflection; using HarmonyLib; using RobocraftX; -using RobocraftX.Schedulers; using RobocraftX.Services; using Svelto.Context; -using Svelto.Tasks.ExtraLean; +using Svelto.Tasks; + using TechbloxModdingAPI.App; using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Events; using TechbloxModdingAPI.Tasks; using TechbloxModdingAPI.Utility; @@ -78,9 +78,20 @@ namespace TechbloxModdingAPI // init UI Interface.IMGUI.Constants.Init(); Interface.IMGUI.IMGUIManager.Init(); + Logging.MetaDebugLog("Initializing anti-anticheat"); + var type = AccessTools.TypeByName("Techblox.Services.Eos.Anticheat.Client.Services.AnticheatClientService"); + harmony.Patch(type.GetConstructors()[0], new HarmonyMethod(((Func) AntiAntiCheat).Method)); + harmony.Patch(AccessTools.Method(type, "Shutdown"), new HarmonyMethod(((Func) AntiAntiCheat).Method)); + harmony.Patch(AccessTools.Method(type, "StartProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegate) AntiAntiCheat).Method)); + harmony.Patch(AccessTools.Method(type, "StopProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegateBool) AntiAntiCheat).Method)); + harmony.Patch(AccessTools.Method("Techblox.Services.Eos.Anticheat.Client.EosGetPendingMessagesToSendServiceRequest:Execute"), new HarmonyMethod(((AntiAnticheatDelegateTask)AntiAntiCheatTask).Method)); Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized"); } + public delegate bool AntiAnticheatDelegate(ref object __result); + public delegate bool AntiAnticheatDelegateBool(ref bool __result); + public delegate bool AntiAnticheatDelegateTask(ref IEnumerator __result); + /// /// Shuts down & cleans up the TechbloxModdingAPI. /// Call this as late as possible before Techblox quits. @@ -109,5 +120,34 @@ namespace TechbloxModdingAPI ErrorBuilder.DisplayMustQuitError("Failed to patch Techblox!\n" + "Make sure you're using the latest version of TechbloxModdingAPI or disable mods if the API isn't released yet."); } + + private static bool AntiAntiCheat() => false; + + private static bool AntiAntiCheat(ref object __result) + { + var targetType = + AccessTools.TypeByName("Techblox.Services.Eos.Anticheat.Client.Services.StartProtectedSessionResult"); + var target = Activator.CreateInstance(targetType); + targetType.GetField("Success").SetValue(target, true); + __result = target; + return false; + } + + private static bool AntiAntiCheat(ref bool __result) + { + __result = true; + return false; + } + + private static bool AntiAntiCheatTask(ref IEnumerator __result) + { + IEnumerator Func() + { + yield return Yield.It; + } + + __result = Func(); + return false; + } } } diff --git a/TechbloxModdingAPI/Player.cs b/TechbloxModdingAPI/Player.cs index f4386db..125f2e0 100644 --- a/TechbloxModdingAPI/Player.cs +++ b/TechbloxModdingAPI/Player.cs @@ -187,8 +187,6 @@ namespace TechbloxModdingAPI public float Mass => 1f / playerEngine.GetCharacterStruct(Id).Get().physicsMass.InverseMass; - private float _ping = -1f; - /// /// The player's latest network ping time. /// @@ -197,12 +195,7 @@ namespace TechbloxModdingAPI { get { - var opt = playerEngine.GetPlayerStruct(Id, Type); - if (opt) - { - _ping = opt.Get().lastPingTimeSinceLevelLoad ?? _ping; - } - return _ping; + return playerEngine.GetPing() / 1000f; } } diff --git a/TechbloxModdingAPI/Players/PlayerEngine.cs b/TechbloxModdingAPI/Players/PlayerEngine.cs index 0dc2298..2722258 100644 --- a/TechbloxModdingAPI/Players/PlayerEngine.cs +++ b/TechbloxModdingAPI/Players/PlayerEngine.cs @@ -10,6 +10,7 @@ using RobocraftX.Physics; using RobocraftX.Blocks.Ghost; using Gamecraft.GUI.HUDFeedbackBlocks; using RobocraftX.Blocks; +using RobocraftX.Multiplayer; using RobocraftX.PilotSeat; using Svelto.ECS; using Techblox.Camera; @@ -227,5 +228,12 @@ namespace TechbloxModdingAPI.Players opt.Get().instantExit = true; entitiesDB.PublishEntityChange(egid); } + + public uint GetPing() + { + return entitiesDB + .QueryUniqueEntity(MultiplayerExclusiveGroups.MultiplayerStateGroup) + .networkStats.PingMs; + } } } diff --git a/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs b/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs index 75d0cc4..1cdfe9e 100644 --- a/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs +++ b/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs @@ -360,15 +360,6 @@ namespace TechbloxModdingAPI.Tests return modsString = sb.ToString(); } - public override void OnUpdate() - { - if (UnityEngine.Input.GetKeyDown(KeyCode.End)) - { - Console.WriteLine("Pressed button to toggle console"); - FakeInput.CustomInput(new LocalCosmeticInputEntityComponent {commandLineToggleInput = true}); - } - } - [HarmonyPatch] public class MinimumSpecsPatch { diff --git a/TechbloxModdingAPI/Utility/FullGameFields.cs b/TechbloxModdingAPI/Utility/FullGameFields.cs index 7ab1978..0aec467 100644 --- a/TechbloxModdingAPI/Utility/FullGameFields.cs +++ b/TechbloxModdingAPI/Utility/FullGameFields.cs @@ -1,20 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using DataLoader; +using DataLoader; using HarmonyLib; using RobocraftX; -using RobocraftX.Common.Utilities; +using RobocraftX.CR.MainGame; using RobocraftX.GUI; using RobocraftX.Multiplayer; -using RobocraftX.Rendering; using Svelto.Context; using Svelto.DataStructures; using Svelto.ECS; -using Svelto.ECS.Schedulers; using UnityEngine; using Unity.Entities; using Unity.Physics.Systems; @@ -128,11 +120,11 @@ namespace TechbloxModdingAPI.Utility } } - public static ECSGameObjectResourceManager _eCsGameObjectResourceManager + public static ECSResourceManagers _managers { get { - return (ECSGameObjectResourceManager)fgcr?.Field("_eCsGameObjectResourceManager").GetValue(); + return (ECSResourceManagers)fgcr?.Field("_managers").GetValue(); } } From 4ac8d53a2d0dab5472060aa89353853d6783172e Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 26 Dec 2021 23:37:02 +0100 Subject: [PATCH 29/32] Organize anti-anticheat, add block IDs, fix crash when adding event handlers multiple times --- TechbloxModdingAPI/App/AntiAntiCheatPatch.cs | 55 +++++++++++++++++++ TechbloxModdingAPI/Blocks/BlockIDs.cs | 8 ++- TechbloxModdingAPI/Main.cs | 45 ++------------- .../Players/PlayerEventsEngine.cs | 4 +- .../Tests/TechbloxModdingAPIPluginTest.cs | 2 - TechbloxModdingAPI/Utility/WrappedHandler.cs | 6 ++ 6 files changed, 75 insertions(+), 45 deletions(-) create mode 100644 TechbloxModdingAPI/App/AntiAntiCheatPatch.cs diff --git a/TechbloxModdingAPI/App/AntiAntiCheatPatch.cs b/TechbloxModdingAPI/App/AntiAntiCheatPatch.cs new file mode 100644 index 0000000..f07921d --- /dev/null +++ b/TechbloxModdingAPI/App/AntiAntiCheatPatch.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using HarmonyLib; +using Svelto.Tasks; + +namespace TechbloxModdingAPI.App +{ + public static class AntiAntiCheatPatch + { + private delegate bool AntiAnticheatDelegate(ref object __result); + + private delegate bool AntiAnticheatDelegateBool(ref bool __result); + + private delegate bool AntiAnticheatDelegateTask(ref IEnumerator __result); + + public static void Init(Harmony harmony) + { + var type = AccessTools.TypeByName("Techblox.Services.Eos.Anticheat.Client.Services.AnticheatClientService"); + harmony.Patch(type.GetConstructors()[0], new HarmonyMethod(((Func) AntiAntiCheat).Method)); + harmony.Patch(AccessTools.Method(type, "Shutdown"), new HarmonyMethod(((Func) AntiAntiCheat).Method)); + harmony.Patch(AccessTools.Method(type, "StartProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegate) AntiAntiCheat).Method)); + harmony.Patch(AccessTools.Method(type, "StopProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegateBool) AntiAntiCheat).Method)); + harmony.Patch(AccessTools.Method("Techblox.Services.Eos.Anticheat.Client.EosGetPendingMessagesToSendServiceRequest:Execute"), new HarmonyMethod(((AntiAnticheatDelegateTask)AntiAntiCheatTask).Method)); + } + + private static bool AntiAntiCheat() => false; + + private static bool AntiAntiCheat(ref object __result) + { + var targetType = + AccessTools.TypeByName("Techblox.Services.Eos.Anticheat.Client.Services.StartProtectedSessionResult"); + var target = Activator.CreateInstance(targetType); + targetType.GetField("Success").SetValue(target, true); + __result = target; + return false; + } + + private static bool AntiAntiCheat(ref bool __result) + { + __result = true; + return false; + } + + private static bool AntiAntiCheatTask(ref IEnumerator __result) + { + IEnumerator Func() + { + yield return Yield.It; + } + + __result = Func(); + return false; + } + } +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/BlockIDs.cs b/TechbloxModdingAPI/Blocks/BlockIDs.cs index e454c40..2e3618f 100644 --- a/TechbloxModdingAPI/Blocks/BlockIDs.cs +++ b/TechbloxModdingAPI/Blocks/BlockIDs.cs @@ -273,6 +273,12 @@ namespace TechbloxModdingAPI.Blocks /// /// The grid block used by the world editor, named Small Grid like the other one /// - SmallGridInWorldEditor + SmallGridInWorldEditor, + SegoeUITextblock = 376, + GravtracTextblock, + HauserTextblock, + TechnopollasTextblock, + BitBlock = 385, + Timer } } \ No newline at end of file diff --git a/TechbloxModdingAPI/Main.cs b/TechbloxModdingAPI/Main.cs index 0961576..f11059b 100644 --- a/TechbloxModdingAPI/Main.cs +++ b/TechbloxModdingAPI/Main.cs @@ -1,12 +1,10 @@ using System; -using System.Collections.Generic; using System.Reflection; using HarmonyLib; using RobocraftX; using RobocraftX.Services; using Svelto.Context; -using Svelto.Tasks; using TechbloxModdingAPI.App; using TechbloxModdingAPI.Blocks; @@ -72,26 +70,20 @@ namespace TechbloxModdingAPI Block.Init(); BlockGroup.Init(); Wire.Init(); + // init client Logging.MetaDebugLog($"Initializing Client"); Client.Init(); Game.Init(); // init UI + Logging.MetaDebugLog($"Initializing UI"); Interface.IMGUI.Constants.Init(); Interface.IMGUI.IMGUIManager.Init(); + // init anti-anticheat Logging.MetaDebugLog("Initializing anti-anticheat"); - var type = AccessTools.TypeByName("Techblox.Services.Eos.Anticheat.Client.Services.AnticheatClientService"); - harmony.Patch(type.GetConstructors()[0], new HarmonyMethod(((Func) AntiAntiCheat).Method)); - harmony.Patch(AccessTools.Method(type, "Shutdown"), new HarmonyMethod(((Func) AntiAntiCheat).Method)); - harmony.Patch(AccessTools.Method(type, "StartProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegate) AntiAntiCheat).Method)); - harmony.Patch(AccessTools.Method(type, "StopProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegateBool) AntiAntiCheat).Method)); - harmony.Patch(AccessTools.Method("Techblox.Services.Eos.Anticheat.Client.EosGetPendingMessagesToSendServiceRequest:Execute"), new HarmonyMethod(((AntiAnticheatDelegateTask)AntiAntiCheatTask).Method)); + AntiAntiCheatPatch.Init(harmony); Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized"); } - public delegate bool AntiAnticheatDelegate(ref object __result); - public delegate bool AntiAnticheatDelegateBool(ref bool __result); - public delegate bool AntiAnticheatDelegateTask(ref IEnumerator __result); - /// /// Shuts down & cleans up the TechbloxModdingAPI. /// Call this as late as possible before Techblox quits. @@ -120,34 +112,5 @@ namespace TechbloxModdingAPI ErrorBuilder.DisplayMustQuitError("Failed to patch Techblox!\n" + "Make sure you're using the latest version of TechbloxModdingAPI or disable mods if the API isn't released yet."); } - - private static bool AntiAntiCheat() => false; - - private static bool AntiAntiCheat(ref object __result) - { - var targetType = - AccessTools.TypeByName("Techblox.Services.Eos.Anticheat.Client.Services.StartProtectedSessionResult"); - var target = Activator.CreateInstance(targetType); - targetType.GetField("Success").SetValue(target, true); - __result = target; - return false; - } - - private static bool AntiAntiCheat(ref bool __result) - { - __result = true; - return false; - } - - private static bool AntiAntiCheatTask(ref IEnumerator __result) - { - IEnumerator Func() - { - yield return Yield.It; - } - - __result = Func(); - return false; - } } } diff --git a/TechbloxModdingAPI/Players/PlayerEventsEngine.cs b/TechbloxModdingAPI/Players/PlayerEventsEngine.cs index 2c80f24..af7d095 100644 --- a/TechbloxModdingAPI/Players/PlayerEventsEngine.cs +++ b/TechbloxModdingAPI/Players/PlayerEventsEngine.cs @@ -1,7 +1,9 @@ using RobocraftX.Character; using RobocraftX.Character.Movement; using Svelto.ECS; + using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Utility; namespace TechbloxModdingAPI.Players { @@ -21,7 +23,7 @@ namespace TechbloxModdingAPI.Players public void MovedTo(ref CharacterPilotSeatEntityStruct entityComponent, ExclusiveGroupStruct previousGroup, EGID egid) { - var seatId = entityComponent.pilotSeatEntity.ToEGID(entitiesDB); + entitiesDB.TryGetEGID(entityComponent.pilotSeatEntity, out var seatId); //TODO: Can't get EGID var player = EcsObjectBase.GetInstance(new EGID(egid.entityID, CharacterExclusiveGroups.OnFootGroup), e => new Player(e.entityID)); if (previousGroup == CharacterExclusiveGroups.InPilotSeatGroup) diff --git a/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs b/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs index 1cdfe9e..f528f83 100644 --- a/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs +++ b/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs @@ -10,12 +10,10 @@ using IllusionInjector; using RobocraftX.FrontEnd; using Unity.Mathematics; using UnityEngine; -using RobocraftX.Common.Input; using Svelto.Tasks; using Svelto.Tasks.Lean; using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Commands; -using TechbloxModdingAPI.Input; using TechbloxModdingAPI.Players; using TechbloxModdingAPI.Tasks; using TechbloxModdingAPI.Utility; diff --git a/TechbloxModdingAPI/Utility/WrappedHandler.cs b/TechbloxModdingAPI/Utility/WrappedHandler.cs index 57ff3ba..41e2fc7 100644 --- a/TechbloxModdingAPI/Utility/WrappedHandler.cs +++ b/TechbloxModdingAPI/Utility/WrappedHandler.cs @@ -34,6 +34,12 @@ namespace TechbloxModdingAPI.Utility Logging.LogWarning(wrappedException.ToString()); } }; + if (wrappers.ContainsKey(added)) + { + original.eventHandler -= wrapped; + wrappers.Remove(added); + } + wrappers.Add(added, wrapped); return new WrappedHandler { eventHandler = original.eventHandler + wrapped }; } From 93a0b2287a81afd4d8a7e18b4ee5e4d2796aa49d Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 27 Dec 2021 02:28:09 +0100 Subject: [PATCH 30/32] Added player join/leave events and fix errors - Fixed anticheat status error spam - Fixed IMGUI not actually running on OnGUI because that runner was changed in Svelto - Added player join and leave events - Made Game.Enter only trigger when both the game has finished loading *and* the local player has joined --- TechbloxModdingAPI/App/AntiAntiCheatPatch.cs | 1 + TechbloxModdingAPI/App/GameGameEngine.cs | 31 +++++++++++++++++-- .../Interface/IMGUI/IMGUIManager.cs | 8 +---- TechbloxModdingAPI/Player.Events.cs | 22 +++++++++++++ TechbloxModdingAPI/Player.cs | 10 ++++-- .../Players/PlayerEventsEngine.cs | 17 +++++++--- TechbloxModdingAPI/Tasks/OnGuiRunner.cs | 16 ++++++++++ 7 files changed, 90 insertions(+), 15 deletions(-) create mode 100644 TechbloxModdingAPI/Tasks/OnGuiRunner.cs diff --git a/TechbloxModdingAPI/App/AntiAntiCheatPatch.cs b/TechbloxModdingAPI/App/AntiAntiCheatPatch.cs index f07921d..ed249bf 100644 --- a/TechbloxModdingAPI/App/AntiAntiCheatPatch.cs +++ b/TechbloxModdingAPI/App/AntiAntiCheatPatch.cs @@ -21,6 +21,7 @@ namespace TechbloxModdingAPI.App harmony.Patch(AccessTools.Method(type, "StartProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegate) AntiAntiCheat).Method)); harmony.Patch(AccessTools.Method(type, "StopProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegateBool) AntiAntiCheat).Method)); harmony.Patch(AccessTools.Method("Techblox.Services.Eos.Anticheat.Client.EosGetPendingMessagesToSendServiceRequest:Execute"), new HarmonyMethod(((AntiAnticheatDelegateTask)AntiAntiCheatTask).Method)); + harmony.Patch(AccessTools.Method("Techblox.Anticheat.Client.Engines.ShowFeedbackDialogEngine:PollAnticheatStatus"), new HarmonyMethod(((AntiAnticheatDelegateTask)AntiAntiCheatTask).Method)); } private static bool AntiAntiCheat() => false; diff --git a/TechbloxModdingAPI/App/GameGameEngine.cs b/TechbloxModdingAPI/App/GameGameEngine.cs index 147606e..46167a4 100644 --- a/TechbloxModdingAPI/App/GameGameEngine.cs +++ b/TechbloxModdingAPI/App/GameGameEngine.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using RobocraftX.Common; using RobocraftX.Schedulers; @@ -13,6 +14,7 @@ using Techblox.Environment.Transition; using Techblox.GameSelection; using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Players; using TechbloxModdingAPI.Utility; namespace TechbloxModdingAPI.App @@ -30,16 +32,32 @@ namespace TechbloxModdingAPI.App public EntitiesDB entitiesDB { set; private get; } private bool enteredGame; + private bool loadingFinished; + private bool playerJoined; public void Dispose() { ExitGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID }); IsInGame = false; + loadingFinished = false; + playerJoined = false; + enteredGame = false; } public void Ready() { enteredGame = true; + Player.Joined += OnPlayerJoined; + } + + private void OnPlayerJoined(object sender, PlayerEventArgs args) + { + Console.WriteLine("Player joined: " + args.PlayerId + " asd"); + if (args.Player.Type != PlayerType.Local) return; + Console.WriteLine("Player joined is local asd"); + playerJoined = true; + Player.Joined -= OnPlayerJoined; + CheckJoinEvent(); } // game functionality @@ -142,9 +160,18 @@ namespace TechbloxModdingAPI.App public void Remove(ref LoadingActionEntityStruct entityComponent, EGID egid) { // Finished loading if (!enteredGame) return; + enteredGame = false; + loadingFinished = true; + Console.WriteLine("Loading finished - asd"); + CheckJoinEvent(); + } + + private void CheckJoinEvent() + { + Console.WriteLine($"Check: {loadingFinished} {playerJoined}"); + if (!loadingFinished || !playerJoined) return; EnterGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID }); IsInGame = true; - enteredGame = false; } } } diff --git a/TechbloxModdingAPI/Interface/IMGUI/IMGUIManager.cs b/TechbloxModdingAPI/Interface/IMGUI/IMGUIManager.cs index 8b3c865..c27c484 100644 --- a/TechbloxModdingAPI/Interface/IMGUI/IMGUIManager.cs +++ b/TechbloxModdingAPI/Interface/IMGUI/IMGUIManager.cs @@ -1,13 +1,7 @@ -using System; -using System.Collections; using System.Collections.Generic; -using TechbloxModdingAPI.App; -using TechbloxModdingAPI.Utility; -using Rewired.Internal; -using Svelto.DataStructures; using Svelto.Tasks; using Svelto.Tasks.ExtraLean; -using Svelto.Tasks.ExtraLean.Unity; +using TechbloxModdingAPI.Tasks; using UnityEngine; namespace TechbloxModdingAPI.Interface.IMGUI diff --git a/TechbloxModdingAPI/Player.Events.cs b/TechbloxModdingAPI/Player.Events.cs index 1a07c36..8d8cd10 100644 --- a/TechbloxModdingAPI/Player.Events.cs +++ b/TechbloxModdingAPI/Player.Events.cs @@ -20,6 +20,22 @@ namespace TechbloxModdingAPI add => seatExited += value; remove => seatExited -= value; } + + internal static WrappedHandler joined; + + public static event EventHandler Joined + { + add => joined += value; + remove => joined -= value; + } + + internal static WrappedHandler left; + + public static event EventHandler Left + { + add => left += value; + remove => left -= value; + } } public struct PlayerSeatEventArgs @@ -27,4 +43,10 @@ namespace TechbloxModdingAPI public EGID SeatId; public Seat Seat => (Seat)Block.New(SeatId); } + + public struct PlayerEventArgs + { + public EGID PlayerId; + public Player Player => Player.GetInstance(PlayerId.entityID); + } } \ No newline at end of file diff --git a/TechbloxModdingAPI/Player.cs b/TechbloxModdingAPI/Player.cs index 125f2e0..462e44b 100644 --- a/TechbloxModdingAPI/Player.cs +++ b/TechbloxModdingAPI/Player.cs @@ -23,8 +23,8 @@ namespace TechbloxModdingAPI public partial class Player : EcsObjectBase, IEquatable, IEquatable { // static functionality - private static PlayerEngine playerEngine = new PlayerEngine(); - private static PlayerEventsEngine playerEventsEngine = new PlayerEventsEngine(); + private static readonly PlayerEngine playerEngine = new PlayerEngine(); + private static readonly PlayerEventsEngine playerEventsEngine = new PlayerEventsEngine(); private static Player localPlayer; /// @@ -76,6 +76,12 @@ namespace TechbloxModdingAPI } } + internal static Player GetInstance(uint id) + { + return EcsObjectBase.GetInstance(new EGID(id, CharacterExclusiveGroups.OnFootGroup), + e => new Player(e.entityID)); + } + /// /// Initializes a new instance of the class. /// diff --git a/TechbloxModdingAPI/Players/PlayerEventsEngine.cs b/TechbloxModdingAPI/Players/PlayerEventsEngine.cs index af7d095..4461b71 100644 --- a/TechbloxModdingAPI/Players/PlayerEventsEngine.cs +++ b/TechbloxModdingAPI/Players/PlayerEventsEngine.cs @@ -1,13 +1,13 @@ using RobocraftX.Character; using RobocraftX.Character.Movement; +using RobocraftX.Common.Input; using Svelto.ECS; using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; namespace TechbloxModdingAPI.Players { - public class PlayerEventsEngine : IApiEngine, IReactOnSwap + public class PlayerEventsEngine : IApiEngine, IReactOnSwap, IReactOnAddAndRemove { public void Ready() { @@ -24,12 +24,21 @@ namespace TechbloxModdingAPI.Players public void MovedTo(ref CharacterPilotSeatEntityStruct entityComponent, ExclusiveGroupStruct previousGroup, EGID egid) { entitiesDB.TryGetEGID(entityComponent.pilotSeatEntity, out var seatId); //TODO: Can't get EGID - var player = EcsObjectBase.GetInstance(new EGID(egid.entityID, CharacterExclusiveGroups.OnFootGroup), - e => new Player(e.entityID)); + var player = Player.GetInstance(egid.entityID); if (previousGroup == CharacterExclusiveGroups.InPilotSeatGroup) player.seatExited.Invoke(this, new PlayerSeatEventArgs { SeatId = seatId}); else if (egid.groupID == CharacterExclusiveGroups.InPilotSeatGroup) player.seatEntered.Invoke(this, new PlayerSeatEventArgs { SeatId = seatId }); } + + public void Add(ref PlayerIDStruct entityComponent, EGID egid) + { + Player.joined.Invoke(this, new PlayerEventArgs { PlayerId = egid }); + } + + public void Remove(ref PlayerIDStruct entityComponent, EGID egid) + { + Player.left.Invoke(this, new PlayerEventArgs { PlayerId = egid }); + } } } \ No newline at end of file diff --git a/TechbloxModdingAPI/Tasks/OnGuiRunner.cs b/TechbloxModdingAPI/Tasks/OnGuiRunner.cs new file mode 100644 index 0000000..b3c4000 --- /dev/null +++ b/TechbloxModdingAPI/Tasks/OnGuiRunner.cs @@ -0,0 +1,16 @@ +using System.Collections; +using Svelto.Tasks; +using Svelto.Tasks.ExtraLean; +using Svelto.Tasks.Unity.Internal; + +namespace TechbloxModdingAPI.Tasks +{ + public class OnGuiRunner : BaseRunner> + { + public OnGuiRunner(string name, uint runningOrder = 0) + : base(name) + { + UnityCoroutineRunner.StartOnGuiCoroutine(this._processEnumerator, runningOrder); + } + } +} \ No newline at end of file From 5602ef9268f023bf761006aae22548eeaaf04408 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 28 Dec 2021 15:09:01 +0100 Subject: [PATCH 31/32] All kinds of fixes of issues during automatic tests - Fixed toggling time running mode - Fixed closing popups - Added support for pressing the buttons on a popup - Added error handling to Main.Init() - Automatically closing the beta message in the test plugin - Fixed Game.EnterGame() causing a crash in the game --- TechbloxModdingAPI/App/AppEngine.cs | 44 ---------- TechbloxModdingAPI/App/Client.cs | 59 +++++++++---- TechbloxModdingAPI/App/ClientAlertTest.cs | 20 +++-- .../App/GameBuildSimEventEngine.cs | 2 + TechbloxModdingAPI/App/GameGameEngine.cs | 33 +++++--- TechbloxModdingAPI/App/GameMenuEngine.cs | 32 ++++--- TechbloxModdingAPI/Input/FakeInput.cs | 2 +- TechbloxModdingAPI/Main.cs | 84 ++++++++++++------- .../Tests/TechbloxModdingAPIPluginTest.cs | 5 ++ TechbloxModdingAPI/Tests/TestRoot.cs | 12 ++- TechbloxModdingAPI/Utility/FullGameFields.cs | 18 ++++ 11 files changed, 188 insertions(+), 123 deletions(-) delete mode 100644 TechbloxModdingAPI/App/AppEngine.cs diff --git a/TechbloxModdingAPI/App/AppEngine.cs b/TechbloxModdingAPI/App/AppEngine.cs deleted file mode 100644 index e4f5dcb..0000000 --- a/TechbloxModdingAPI/App/AppEngine.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; - -using RobocraftX.GUI.MyGamesScreen; -using Svelto.ECS; -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.App -{ - public class AppEngine : IFactoryEngine - { - public WrappedHandler EnterMenu; - - public WrappedHandler ExitMenu; - - public IEntityFactory Factory { set; private get; } - - public string Name => "TechbloxModdingAPIAppEngine"; - - public bool isRemovable => false; - - public EntitiesDB entitiesDB { set; private get; } - - public void Dispose() - { - IsInMenu = false; - ExitMenu.Invoke(this, new MenuEventArgs { }); - } - - public void Ready() - { - IsInMenu = true; - EnterMenu.Invoke(this, new MenuEventArgs { }); - } - - // app functionality - - public bool IsInMenu - { - get; - private set; - } = false; - } -} diff --git a/TechbloxModdingAPI/App/Client.cs b/TechbloxModdingAPI/App/Client.cs index 6fe4b4e..89f486f 100644 --- a/TechbloxModdingAPI/App/Client.cs +++ b/TechbloxModdingAPI/App/Client.cs @@ -14,12 +14,12 @@ namespace TechbloxModdingAPI.App /// public class Client { + public static Client Instance { get; } = new Client(); + protected static Func ErrorHandlerInstanceGetter; protected static Action EnqueueError; - protected static Action HandleErrorClosed; - /// /// An event that fires whenever the main menu is loaded. /// @@ -93,14 +93,31 @@ namespace TechbloxModdingAPI.App EnqueueError(errorHandlerInstance, popup); } - // TODO - /*public void CloseCurrentPrompt() + public void CloseCurrentPrompt() { - // RobocraftX.Services.ErrorHandler.Instance.HandlePopupClosed(); - // FIXME: this is a call that is also called when closing, not the actual closing action itself (so it doesn't work) object errorHandlerInstance = ErrorHandlerInstanceGetter(); - HandleErrorClosed(errorHandlerInstance); - }*/ + var popup = GetPopupCloseMethods(errorHandlerInstance); + popup.Close(); + } + + public void SelectFirstPromptButton() + { + object errorHandlerInstance = ErrorHandlerInstanceGetter(); + var popup = GetPopupCloseMethods(errorHandlerInstance); + popup.FirstButton(); + } + + public void SelectSecondPromptButton() + { + object errorHandlerInstance = ErrorHandlerInstanceGetter(); + var popup = GetPopupCloseMethods(errorHandlerInstance); + popup.SecondButton(); + } + + internal void CloseBetaPopup() + { + Game.menuEngine.CloseBetaPopup(); + } internal static void Init() { @@ -113,9 +130,6 @@ namespace TechbloxModdingAPI.App EnqueueError = (Action) AccessTools.Method("TechbloxModdingAPI.App.Client:GenEnqueueError") .MakeGenericMethod(errorHandler, errorHandle) .Invoke(null, new object[0]); - /*HandleErrorClosed = (Action) AccessTools.Method("TechbloxModdingAPI.App.Client:GenHandlePopupClosed") - .MakeGenericMethod(errorHandler) - .Invoke(null, new object[0]);*/ } // Creating delegates once is faster than reflection every time @@ -140,14 +154,23 @@ namespace TechbloxModdingAPI.App return enqueueCasted; } - private static Action GenHandlePopupClosed() + private static (Action Close, Action FirstButton, Action SecondButton) _errorPopup; + + private static (Action Close, Action FirstButton, Action SecondButton) GetPopupCloseMethods(object handler) { - Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler"); - MethodInfo handlePopupClosed = AccessTools.Method(errorHandler, "HandlePopupClosed"); - Action handleSimple = - (Action) Delegate.CreateDelegate(typeof(Action), handlePopupClosed); - Action handleCasted = (object instance) => handleSimple((T) instance); - return handleCasted; + if (_errorPopup.Close != null) + return _errorPopup; + Type errorHandler = handler.GetType(); + FieldInfo field = AccessTools.Field(errorHandler, "errorPopup"); + var errorPopup = (ErrorPopup)field.GetValue(handler); + MethodInfo info = AccessTools.Method(errorPopup.GetType(), "ClosePopup"); + var close = (Action)Delegate.CreateDelegate(typeof(Action), errorPopup, info); + info = AccessTools.Method(errorPopup.GetType(), "HandleFirstOption"); + var first = (Action)Delegate.CreateDelegate(typeof(Action), errorPopup, info); + info = AccessTools.Method(errorPopup.GetType(), "HandleSecondOption"); + var second = (Action)Delegate.CreateDelegate(typeof(Action), errorPopup, info); + _errorPopup = (close, first, second); + return _errorPopup; } } } diff --git a/TechbloxModdingAPI/App/ClientAlertTest.cs b/TechbloxModdingAPI/App/ClientAlertTest.cs index 20d8201..278a826 100644 --- a/TechbloxModdingAPI/App/ClientAlertTest.cs +++ b/TechbloxModdingAPI/App/ClientAlertTest.cs @@ -42,17 +42,25 @@ namespace TechbloxModdingAPI.App [APITestCase(TestType.Menu)] public static void TestPopUp2() { - Client c = new Client(); - c.PromptUser(popup2); - //c.CloseCurrentPrompt(); + Client.Instance.PromptUser(popup2); } [APITestCase(TestType.Menu)] public static void TestPopUp1() { - Client c = new Client(); - c.PromptUser(popup1); - //c.CloseCurrentPrompt(); + Client.Instance.PromptUser(popup1); + } + + [APITestCase(TestType.Menu)] + public static void TestPopUpClose1() + { + Client.Instance.CloseCurrentPrompt(); + } + + [APITestCase(TestType.Menu)] + public static void TestPopUpClose2() + { + Client.Instance.CloseCurrentPrompt(); } } #endif diff --git a/TechbloxModdingAPI/App/GameBuildSimEventEngine.cs b/TechbloxModdingAPI/App/GameBuildSimEventEngine.cs index 67e6769..1846dd2 100644 --- a/TechbloxModdingAPI/App/GameBuildSimEventEngine.cs +++ b/TechbloxModdingAPI/App/GameBuildSimEventEngine.cs @@ -27,12 +27,14 @@ namespace TechbloxModdingAPI.App public JobHandle OnInitializeTimeRunningMode(JobHandle inputDeps) { + Console.WriteLine("Init time running mode"); SimulationMode.Invoke(this, new GameEventArgs { GameName = "", GamePath = "" }); // TODO return inputDeps; } public JobHandle OnInitializeTimeStoppedMode(JobHandle inputDeps) { + Console.WriteLine("Init time stopped mode"); BuildMode.Invoke(this, new GameEventArgs { GameName = "", GamePath = "" }); return inputDeps; } diff --git a/TechbloxModdingAPI/App/GameGameEngine.cs b/TechbloxModdingAPI/App/GameGameEngine.cs index 46167a4..279b170 100644 --- a/TechbloxModdingAPI/App/GameGameEngine.cs +++ b/TechbloxModdingAPI/App/GameGameEngine.cs @@ -1,6 +1,7 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; +using HarmonyLib; +using RobocraftX; using RobocraftX.Common; using RobocraftX.Schedulers; using RobocraftX.SimulationModeState; @@ -9,11 +10,14 @@ using Svelto.Tasks; using Svelto.Tasks.Lean; using RobocraftX.Blocks; using RobocraftX.Common.Loading; +using RobocraftX.Multiplayer; using RobocraftX.ScreenshotTaker; using Techblox.Environment.Transition; using Techblox.GameSelection; + using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Input; using TechbloxModdingAPI.Players; using TechbloxModdingAPI.Utility; @@ -52,9 +56,7 @@ namespace TechbloxModdingAPI.App private void OnPlayerJoined(object sender, PlayerEventArgs args) { - Console.WriteLine("Player joined: " + args.PlayerId + " asd"); if (args.Player.Type != PlayerType.Local) return; - Console.WriteLine("Player joined is local asd"); playerJoined = true; Player.Joined -= OnPlayerJoined; CheckJoinEvent(); @@ -112,10 +114,23 @@ namespace TechbloxModdingAPI.App public void ToggleTimeMode() { - if (!entitiesDB.FoundInGroups()) - throw new AppStateException("At least one block must exist in the world to enter simulation"); - SwitchAnimationUtil.Start(entitiesDB); - } + if (TimeRunningModeUtil.IsTimeStoppedMode(entitiesDB)) + FakeInput.ActionInput(toggleMode: true); + else + { + IEnumerator ReloadBuildModeTask() + { + SwitchAnimationUtil.Start(entitiesDB); + while (SwitchAnimationUtil.IsFadeOutActive(entitiesDB)) + yield return (TaskContract)Yield.It; + FullGameFields._multiplayerParams.MultiplayerMode = MultiplayerMode.SinglePlayer; + AccessTools.Method(typeof(FullGameCompositionRoot), "ReloadGame") + .Invoke(FullGameFields.Instance, new object[] { }); + } + + ReloadBuildModeTask().RunOn(ClientLean.UIScheduler); + } + } public EGID[] GetAllBlocksInGame(BlockIDs filter = BlockIDs.Invalid) { @@ -162,13 +177,11 @@ namespace TechbloxModdingAPI.App if (!enteredGame) return; enteredGame = false; loadingFinished = true; - Console.WriteLine("Loading finished - asd"); CheckJoinEvent(); } private void CheckJoinEvent() { - Console.WriteLine($"Check: {loadingFinished} {playerJoined}"); if (!loadingFinished || !playerJoined) return; EnterGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID }); IsInGame = true; diff --git a/TechbloxModdingAPI/App/GameMenuEngine.cs b/TechbloxModdingAPI/App/GameMenuEngine.cs index 276bda8..533b112 100644 --- a/TechbloxModdingAPI/App/GameMenuEngine.cs +++ b/TechbloxModdingAPI/App/GameMenuEngine.cs @@ -5,6 +5,7 @@ using HarmonyLib; using RobocraftX; using RobocraftX.GUI; using RobocraftX.GUI.MyGamesScreen; +using RobocraftX.Multiplayer; using Svelto.ECS; using Svelto.ECS.Experimental; using Techblox.GameSelection; @@ -103,19 +104,16 @@ namespace TechbloxModdingAPI.App return EnterGame(mgdes.GameName, mgdes.FileId); } - public bool EnterGame(string gameName, string fileId, bool autoEnterSim = false) + public bool EnterGame(ECSString gameName, string fileId, bool autoEnterSim = false) { - var data = new GameSelectionData - { - gameMode = Techblox.GameSelection.GameMode.PlayGame, - isOnline = false, - saveName = gameName, - saveType = SaveType.ExistingSave, - gameID = "GAMEID_Road_Track", //TODO: Expose to the API - userContentID = fileId - }; - // the private FullGameCompositionRoot.SwitchToGame() method gets passed to menu items for this reason - AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToGame").Invoke(FullGameFields.Instance, new object[]{data}); + FullGameFields._multiplayerParams.MultiplayerMode = MultiplayerMode.SinglePlayer; + ref var selection = ref entitiesDB.QueryEntity(GameSelectionConstants.GameSelectionEGID); + selection.userContentID.Set(fileId); + selection.triggerStart = true; + selection.saveType = SaveType.ExistingSave; + selection.saveName = gameName; + selection.gameMode = GameMode.PlayGame; + selection.gameID.Set("GAMEID_Road_Track"); //TODO: Expose to the API return true; } @@ -158,6 +156,16 @@ namespace TechbloxModdingAPI.App { return ref entitiesDB.QueryEntity(id); } + + internal void CloseBetaPopup() + { + var (buffer, count) = entitiesDB.QueryEntities(ExclusiveGroup.Search("BetaPopup")); + for (int index = 0; index < count; ++index) + { + entitiesDB.QueryEntity(buffer[index].TogglePanelButtonComponent.targetPanel) + .guiRoot.enabled = false; + } + } } internal class MyGameDataEntityDescriptor_DamnItFJWhyDidYouMakeThisInternal : GenericEntityDescriptor { } diff --git a/TechbloxModdingAPI/Input/FakeInput.cs b/TechbloxModdingAPI/Input/FakeInput.cs index 6beb63f..bcf8367 100644 --- a/TechbloxModdingAPI/Input/FakeInput.cs +++ b/TechbloxModdingAPI/Input/FakeInput.cs @@ -111,7 +111,7 @@ namespace TechbloxModdingAPI.Input ref LocalPlayerInputEntityStruct currentInput = ref inputEngine.GetPlayerInputRef(playerID); //Utility.Logging.CommandLog($"Current sim frame {currentInput.frame}"); // set inputs - if (toggleMode) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleTimeRunningModeTest; //TODO: Test, play + if (toggleMode) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleTimeRunningModePlay; //TODO: Test, play if (forward) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Forward; if (backward) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Backward; if (up) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Up; diff --git a/TechbloxModdingAPI/Main.cs b/TechbloxModdingAPI/Main.cs index f11059b..554debe 100644 --- a/TechbloxModdingAPI/Main.cs +++ b/TechbloxModdingAPI/Main.cs @@ -49,39 +49,42 @@ namespace TechbloxModdingAPI harmony.PatchAll(currentAssembly); } catch (Exception e) - { //Can't use ErrorBuilder or Logging.LogException (which eventually uses ErrorBuilder) yet - Logging.Log(e.ToString()); - Logging.LogWarning("Failed to patch Techblox. Attempting to patch to display error..."); - harmony.Patch(AccessTools.Method(typeof(FullGameCompositionRoot), "OnContextInitialized") - .MakeGenericMethod(typeof(UnityContext)), - new HarmonyMethod(((Action) OnPatchError).Method)); //Can't use lambdas here :( + { + HandleError(e, "Failed to patch Techblox. Attempting to patch to display error...", OnPatchError); return; } - // init utility - Logging.MetaDebugLog($"Initializing Utility"); - Utility.GameState.Init(); - // init block implementors - Logging.MetaDebugLog($"Initializing Blocks"); - // init input - Input.FakeInput.Init(); - // init object-oriented classes - Player.Init(); - Block.Init(); - BlockGroup.Init(); - Wire.Init(); - // init client - Logging.MetaDebugLog($"Initializing Client"); - Client.Init(); - Game.Init(); - // init UI - Logging.MetaDebugLog($"Initializing UI"); - Interface.IMGUI.Constants.Init(); - Interface.IMGUI.IMGUIManager.Init(); - // init anti-anticheat - Logging.MetaDebugLog("Initializing anti-anticheat"); - AntiAntiCheatPatch.Init(harmony); - Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized"); + try + { + // init utility + Logging.MetaDebugLog($"Initializing Utility"); + Utility.GameState.Init(); + // init block implementors + Logging.MetaDebugLog($"Initializing Blocks"); + // init input + Input.FakeInput.Init(); + // init object-oriented classes + Player.Init(); + Block.Init(); + BlockGroup.Init(); + Wire.Init(); + // init client + Logging.MetaDebugLog($"Initializing Client"); + Client.Init(); + Game.Init(); + // init UI + Logging.MetaDebugLog($"Initializing UI"); + Interface.IMGUI.Constants.Init(); + Interface.IMGUI.IMGUIManager.Init(); + // init anti-anticheat + Logging.MetaDebugLog("Initializing anti-anticheat"); + AntiAntiCheatPatch.Init(harmony); + Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized"); + } + catch (Exception e) + { + HandleError(e, "Failed to initialize the API! Attempting to patch to display error...", OnInitError); + } } /// @@ -112,5 +115,26 @@ namespace TechbloxModdingAPI ErrorBuilder.DisplayMustQuitError("Failed to patch Techblox!\n" + "Make sure you're using the latest version of TechbloxModdingAPI or disable mods if the API isn't released yet."); } + + private static void OnInitError() + { + ErrorBuilder.DisplayMustQuitError("Failed to initialize the modding API!\n" + + "Make sure you're using the latest version. If you are, please report the error."); + } + + /// + /// Handles an init error. Logs the exception, a log message, and allows displaying an error in-game. + /// + /// The exception + /// The log message + /// The action to run when the game is ready to display error messages + private static void HandleError(Exception e, string logMsg, Action onInit) + { //Can't use ErrorBuilder or Logging.LogException (which eventually uses ErrorBuilder) yet + Logging.Log(e.ToString()); + Logging.LogWarning(logMsg); + harmony.Patch(AccessTools.Method(typeof(FullGameCompositionRoot), "OnContextInitialized") + .MakeGenericMethod(typeof(UnityContext)), + new HarmonyMethod(onInit.Method)); //Can't use lambdas here :( + } } } diff --git a/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs b/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs index f528f83..124d159 100644 --- a/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs +++ b/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs @@ -343,6 +343,11 @@ namespace TechbloxModdingAPI.Tests Logging.CommandLog(asset); } }).Build(); + Client.EnterMenu += (sender, args) => Scheduler.Schedule(new Once(() => Client.Instance.CloseBetaPopup())); + + Game.Enter += (sender, args) => + Console.WriteLine( + $"Current game selection data: {FullGameFields._gameSelectionData.gameMode} - {FullGameFields._gameSelectionData.saveType}"); #if TEST TestRoot.RunTests(); #endif diff --git a/TechbloxModdingAPI/Tests/TestRoot.cs b/TechbloxModdingAPI/Tests/TestRoot.cs index bd5dc01..16b85d0 100644 --- a/TechbloxModdingAPI/Tests/TestRoot.cs +++ b/TechbloxModdingAPI/Tests/TestRoot.cs @@ -129,7 +129,7 @@ namespace TechbloxModdingAPI.Tests private static IEnumerator GoToGameTests() { - Client app = new Client(); + Client app = Client.Instance; int oldLength = 0; while (app.MyGames.Length == 0 || oldLength != app.MyGames.Length) { @@ -137,7 +137,15 @@ namespace TechbloxModdingAPI.Tests yield return new WaitForSecondsEnumerator(1).Continue(); } yield return Yield.It; - app.MyGames[0].EnterGame(); + try + { + app.MyGames[0].EnterGame(); + } + catch (Exception e) + { + Console.WriteLine("Failed to go to game tests"); + Console.WriteLine(e); + } /*Game newGame = Game.NewGame(); yield return new WaitForSecondsEnumerator(5).Continue(); // wait for sync newGame.EnterGame();*/ diff --git a/TechbloxModdingAPI/Utility/FullGameFields.cs b/TechbloxModdingAPI/Utility/FullGameFields.cs index 0aec467..de9f487 100644 --- a/TechbloxModdingAPI/Utility/FullGameFields.cs +++ b/TechbloxModdingAPI/Utility/FullGameFields.cs @@ -7,6 +7,8 @@ using RobocraftX.Multiplayer; using Svelto.Context; using Svelto.DataStructures; using Svelto.ECS; +using Svelto.ECS.GUI; +using Techblox.GameSelection; using UnityEngine; using Unity.Entities; using Unity.Physics.Systems; @@ -144,6 +146,22 @@ namespace TechbloxModdingAPI.Utility } } + public static SveltoGUI _frontEndGUI + { + get + { + return (SveltoGUI)fgcr?.Field("_frontEndGUI").GetValue(); + } + } + + public static GameSelectionData _gameSelectionData + { + get + { + return (GameSelectionData)fgcr?.Field("_gameSelectionData").GetValue(); + } + } + private static Traverse fgcr; public static void Init(FullGameCompositionRoot instance) From 966fdd4c3a936aa782ebbeac0e86ab6c2a7740f8 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 7 Jan 2022 02:14:58 +0100 Subject: [PATCH 32/32] Fix even more issues uncovered by tests - Fixed the time mode toggle not working during testing (changed the runner) - Made the testing thing wait until the time toggle finishes - Fixed the Game.Enter/Exit event being triggered on time mode change - Added a way to spawn and despawn the player's machine (which doesn't work yet) - Fixed the Player.Id property always being 0 - Attempted to fix the fake action inputs not working in simulation --- TechbloxModdingAPI/App/GameGameEngine.cs | 4 ++ TechbloxModdingAPI/EcsObjectBase.cs | 1 + TechbloxModdingAPI/Engines/EnginePatches.cs | 28 ++++++-- TechbloxModdingAPI/Input/FakeInput.cs | 70 +++++++++---------- TechbloxModdingAPI/Input/FakeInputEngine.cs | 10 +++ TechbloxModdingAPI/Input/FakeInputPatch.cs | 19 +++++ TechbloxModdingAPI/Player.cs | 24 +++++++ TechbloxModdingAPI/Players/PlayerEngine.cs | 32 +++++++++ TechbloxModdingAPI/Players/PlayerTests.cs | 17 ++++- TechbloxModdingAPI/Tests/TestRoot.cs | 14 +++- .../Utility/GameEngineManager.cs | 5 +- 11 files changed, 178 insertions(+), 46 deletions(-) create mode 100644 TechbloxModdingAPI/Input/FakeInputPatch.cs diff --git a/TechbloxModdingAPI/App/GameGameEngine.cs b/TechbloxModdingAPI/App/GameGameEngine.cs index 279b170..9856da8 100644 --- a/TechbloxModdingAPI/App/GameGameEngine.cs +++ b/TechbloxModdingAPI/App/GameGameEngine.cs @@ -41,6 +41,8 @@ namespace TechbloxModdingAPI.App public void Dispose() { + if (GameReloadedPatch.IsReload) + return; // Toggling time mode ExitGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID }); IsInGame = false; loadingFinished = false; @@ -50,6 +52,8 @@ namespace TechbloxModdingAPI.App public void Ready() { + if (GameReloadedPatch.IsReload) + return; // Toggling time mode enteredGame = true; Player.Joined += OnPlayerJoined; } diff --git a/TechbloxModdingAPI/EcsObjectBase.cs b/TechbloxModdingAPI/EcsObjectBase.cs index 9698eaa..ba42dc8 100644 --- a/TechbloxModdingAPI/EcsObjectBase.cs +++ b/TechbloxModdingAPI/EcsObjectBase.cs @@ -62,6 +62,7 @@ namespace TechbloxModdingAPI var id = initializer(this); if (!dict.ContainsKey(id)) // Multiple instances may be created dict.Add(id, this); + Id = id; } #region ECS initializer stuff diff --git a/TechbloxModdingAPI/Engines/EnginePatches.cs b/TechbloxModdingAPI/Engines/EnginePatches.cs index 7c9524b..d6b61a9 100644 --- a/TechbloxModdingAPI/Engines/EnginePatches.cs +++ b/TechbloxModdingAPI/Engines/EnginePatches.cs @@ -14,12 +14,10 @@ namespace TechbloxModdingAPI.Engines [HarmonyPatch] static class GameLoadedTimeStoppedEnginePatch { - public static EntitiesSubmissionScheduler Scheduler { get; private set; } public static void Postfix(StateSyncRegistrationHelper stateSyncReg) { // register all game engines, including deterministic GameEngineManager.RegisterEngines(stateSyncReg); - Scheduler = stateSyncReg.enginesRoot.scheduler; // register command engines /*CommandLineCompositionRoot.Compose(contextHolder, stateSyncReg.enginesRoot, reloadGame, multiplayerParameters, stateSyncReg); - uREPL C# compilation not supported anymore */ @@ -35,10 +33,10 @@ namespace TechbloxModdingAPI.Engines [HarmonyPatch] static class GameLoadedTimeRunningEnginePatch { - public static EntitiesSubmissionScheduler Scheduler { get; private set; } public static void Postfix(StateSyncRegistrationHelper stateSyncReg) { - GameLoadedTimeStoppedEnginePatch.Postfix(stateSyncReg); + GameEngineManager.RegisterEngines(stateSyncReg); + CommandManager.RegisterEngines(stateSyncReg.enginesRoot); } public static MethodBase TargetMethod() @@ -46,6 +44,28 @@ namespace TechbloxModdingAPI.Engines return AccessTools.Method(typeof(MainGameCompositionRoot), "DeterministicTimeRunningCompose").MakeGenericMethod(typeof(object)); } } + + [HarmonyPatch] + static class GameReloadedPatch + { + internal static bool IsReload; + public static void Prefix() => IsReload = true; + public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "ReloadGame"); + } + + [HarmonyPatch] + static class GameSwitchedToPatch + { + public static void Prefix() => GameReloadedPatch.IsReload = false; + public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToGame"); + } + + [HarmonyPatch] + static class MenuSwitchedToPatch + { + public static void Prefix() => GameReloadedPatch.IsReload = false; + public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToMenu"); + } [HarmonyPatch] class MenuLoadedEnginePatch diff --git a/TechbloxModdingAPI/Input/FakeInput.cs b/TechbloxModdingAPI/Input/FakeInput.cs index bcf8367..0b0a7f9 100644 --- a/TechbloxModdingAPI/Input/FakeInput.cs +++ b/TechbloxModdingAPI/Input/FakeInput.cs @@ -1,15 +1,13 @@ -using System; +using RobocraftX.Common.Input; -using RobocraftX.Common; -using RobocraftX.Common.Input; -using Svelto.ECS; +using TechbloxModdingAPI.App; using TechbloxModdingAPI.Utility; namespace TechbloxModdingAPI.Input { public static class FakeInput { - private static readonly FakeInputEngine inputEngine = new FakeInputEngine(); + internal static readonly FakeInputEngine inputEngine = new FakeInputEngine(); /// /// Customize the local input. @@ -103,39 +101,39 @@ namespace TechbloxModdingAPI.Input } public static void ActionInput(uint playerID = uint.MaxValue, bool toggleMode = false, bool forward = false, bool backward = false, bool up = false, bool down = false, bool left = false, bool right = false, bool sprint = false, bool toggleFly = false, bool alt = false, bool primary = false, bool secondary = false, bool tertiary = false, bool primaryHeld = false, bool secondaryHeld = false, bool toggleUnitGrid = false, bool ctrl = false, bool toggleColourMode = false, bool scaleBlockUp = false, bool scaleBlockDown = false, bool rotateBlockClockwise = false, bool rotateBlockCounterclockwise = false, bool cutSelection = false, bool copySelection = false, bool deleteSelection = false) - { - if (playerID == uint.MaxValue) - { - playerID = inputEngine.GetLocalPlayerID(); - } - ref LocalPlayerInputEntityStruct currentInput = ref inputEngine.GetPlayerInputRef(playerID); + { // TODO: We can only alter our own inputs clientside + ref var currentInput = ref inputEngine._localInputCache; + //Utility.Logging.CommandLog($"Current sim frame {currentInput.frame}"); // set inputs - if (toggleMode) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleTimeRunningModePlay; //TODO: Test, play - if (forward) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Forward; - if (backward) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Backward; - if (up) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Up; - if (down) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Down; - if (left) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Left; - if (right) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Right; - if (sprint) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Sprint; - //if (toggleFly) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.SwitchFlyMode; - //if (alt) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.AltAction; - if (primary) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.PrimaryAction; - if (secondary) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.SecondaryAction; - if (tertiary) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.TertiaryAction; - if (primaryHeld) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.PrimaryActionHeld; - if (secondaryHeld) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.SecondaryActionHeld; - //if (toggleUnitGrid) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleUnitGrid; - if (ctrl) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.CtrlAction; - if (toggleColourMode) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleColourMode; - if (scaleBlockUp) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ScaleBlockUp; - if (scaleBlockDown) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ScaleBlockDown; - if (rotateBlockClockwise) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.RotateBlockClockwise; - if (rotateBlockCounterclockwise) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.RotateBlockAnticlockwise; - if (cutSelection) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.CutSelection; - if (copySelection) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.CopySelection; - if (deleteSelection) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.DeleteSelection; + if (toggleMode) currentInput |= RobocraftX.Common.Input.ActionInput.ToggleTimeRunningModePlay; //TODO: Test, play + if (forward) currentInput |= RobocraftX.Common.Input.ActionInput.Forward; + if (backward) currentInput |= RobocraftX.Common.Input.ActionInput.Backward; + if (up) currentInput |= RobocraftX.Common.Input.ActionInput.Up; + if (down) currentInput |= RobocraftX.Common.Input.ActionInput.Down; + if (left) currentInput |= RobocraftX.Common.Input.ActionInput.Left; + if (right) currentInput |= RobocraftX.Common.Input.ActionInput.Right; + if (sprint) currentInput |= RobocraftX.Common.Input.ActionInput.Sprint; + //if (toggleFly) currentInput |= RobocraftX.Common.Input.ActionInput.SwitchFlyMode; + //if (alt) currentInput |= RobocraftX.Common.Input.ActionInput.AltAction; + if (primary) currentInput |= RobocraftX.Common.Input.ActionInput.PrimaryActionClick; + if (secondary) currentInput |= RobocraftX.Common.Input.ActionInput.SecondaryActionClick; + if (tertiary) currentInput |= RobocraftX.Common.Input.ActionInput.TertiaryAction; + if (primaryHeld) currentInput |= RobocraftX.Common.Input.ActionInput.PrimaryActionHeld; + if (secondaryHeld) currentInput |= RobocraftX.Common.Input.ActionInput.SecondaryActionHeld; + //if (toggleUnitGrid) currentInput |= RobocraftX.Common.Input.ActionInput.ToggleUnitGrid; + if (ctrl) currentInput |= RobocraftX.Common.Input.ActionInput.CtrlAction; + if (toggleColourMode) currentInput |= RobocraftX.Common.Input.ActionInput.ToggleColourMode; + if (scaleBlockUp) currentInput |= RobocraftX.Common.Input.ActionInput.ScaleBlockUp; + if (scaleBlockDown) currentInput |= RobocraftX.Common.Input.ActionInput.ScaleBlockDown; + if (rotateBlockClockwise) currentInput |= RobocraftX.Common.Input.ActionInput.RotateBlockClockwise; + if (rotateBlockCounterclockwise) currentInput |= RobocraftX.Common.Input.ActionInput.RotateBlockAnticlockwise; + if (cutSelection) currentInput |= RobocraftX.Common.Input.ActionInput.CutSelection; + if (copySelection) currentInput |= RobocraftX.Common.Input.ActionInput.CopySelection; + if (deleteSelection) currentInput |= RobocraftX.Common.Input.ActionInput.DeleteSelection; + + if(Game.CurrentGame().IsTimeStopped) + inputEngine.HandleCustomInput(); // Only gets called when online, so calling it here as well } public static void Init() diff --git a/TechbloxModdingAPI/Input/FakeInputEngine.cs b/TechbloxModdingAPI/Input/FakeInputEngine.cs index 7b4528c..cc6a6c2 100644 --- a/TechbloxModdingAPI/Input/FakeInputEngine.cs +++ b/TechbloxModdingAPI/Input/FakeInputEngine.cs @@ -20,6 +20,8 @@ namespace TechbloxModdingAPI.Input public bool IsReady = false; + internal ActionInput _localInputCache; + public void Dispose() { IsReady = false; @@ -86,6 +88,14 @@ namespace TechbloxModdingAPI.Input return ref entitiesDB.QueryEntity(egid); } + internal void HandleCustomInput() + { + if (!LocalPlayerIDUtility.DoesLocalPlayerExist(entitiesDB)) + return; + GetPlayerInputRef(GetLocalPlayerID()).actionMask |= _localInputCache; + _localInputCache = default; + } + public uint GetLocalPlayerID() { return LocalPlayerIDUtility.GetLocalPlayerID(entitiesDB); diff --git a/TechbloxModdingAPI/Input/FakeInputPatch.cs b/TechbloxModdingAPI/Input/FakeInputPatch.cs new file mode 100644 index 0000000..f1a3281 --- /dev/null +++ b/TechbloxModdingAPI/Input/FakeInputPatch.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using HarmonyLib; + +namespace TechbloxModdingAPI.Input +{ + [HarmonyPatch] + public static class FakeInputPatch + { + public static void Prefix() + { + FakeInput.inputEngine.HandleCustomInput(); // This gets called right before the input is sent to the server + } + + public static MethodBase TargetMethod() + { + return AccessTools.Method("RobocraftX.Multiplayer.Input.NetworkInputRecorderEngine:RecordDeterministicInput"); + } + } +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Player.cs b/TechbloxModdingAPI/Player.cs index 462e44b..63d13e0 100644 --- a/TechbloxModdingAPI/Player.cs +++ b/TechbloxModdingAPI/Player.cs @@ -125,6 +125,7 @@ namespace TechbloxModdingAPI }) { this.Type = player; + Id = base.Id.entityID; } // object fields & properties @@ -434,15 +435,38 @@ namespace TechbloxModdingAPI playerEngine.SetLocation(Id, location, exitSeat: exitSeat); } + /// + /// Enter the given seat. + /// + /// The seat to enter. public void EnterSeat(Seat seat) { playerEngine.EnterSeat(Id, seat.Id); } + /// + /// Exit the seat the player is currently in. + /// public void ExitSeat() { playerEngine.ExitSeat(Id); } + + /// + /// Spawn the machine the player is holding in time running mode. + /// + public bool SpawnMachine() + { + return playerEngine.SpawnMachine(Id); + } + + /// + /// Despawn the player's machine in time running mode and place it in their hand. + /// + public bool DespawnMachine() + { + return playerEngine.DespawnMachine(Id); + } /// /// Returns the block the player is currently looking at in build mode. diff --git a/TechbloxModdingAPI/Players/PlayerEngine.cs b/TechbloxModdingAPI/Players/PlayerEngine.cs index 2722258..bf9c548 100644 --- a/TechbloxModdingAPI/Players/PlayerEngine.cs +++ b/TechbloxModdingAPI/Players/PlayerEngine.cs @@ -12,6 +12,7 @@ using Gamecraft.GUI.HUDFeedbackBlocks; using RobocraftX.Blocks; using RobocraftX.Multiplayer; using RobocraftX.PilotSeat; +using RobocraftX.SimulationModeState; using Svelto.ECS; using Techblox.Camera; using Unity.Mathematics; @@ -20,6 +21,7 @@ using Svelto.ECS.EntityStructs; using Techblox.BuildingDrone; using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Input; using TechbloxModdingAPI.Utility; namespace TechbloxModdingAPI.Players @@ -205,6 +207,8 @@ namespace TechbloxModdingAPI.Players public void EnterSeat(uint playerId, EGID seatId) { + if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB)) + return; PilotSeatGroupUtils.SwapTagTo(Functions, seatId); var opt = GetCharacterStruct(playerId, out var group); if (!opt) return; @@ -222,6 +226,8 @@ namespace TechbloxModdingAPI.Players public void ExitSeat(uint playerId) { + if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB)) + return; EGID egid = new EGID(playerId, CharacterExclusiveGroups.InPilotSeatGroup); var opt = entitiesDB.QueryEntityOptional(egid); if (!opt) return; @@ -229,6 +235,32 @@ namespace TechbloxModdingAPI.Players entitiesDB.PublishEntityChange(egid); } + public bool SpawnMachine(uint playerId) + { + if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB)) + return false; + EGID egid = new EGID(playerId, CharacterExclusiveGroups.MachineSpawningGroup); + if (!entitiesDB.Exists(egid)) + return false; + //Functions.SwapEntityGroup(egid, CharacterExclusiveGroups.OnFootGroup); + FakeInput.ActionInput(playerId, primary: true); + return true; + } + + public bool DespawnMachine(uint playerId) + { + if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB)) + return false; + GetCharacterStruct(playerId, out var group); + if (group.isInvalid) + return false; + EGID egid = new EGID(playerId, group); + if (!entitiesDB.Exists(egid)) + return false; + Functions.SwapEntityGroup(egid, CharacterExclusiveGroups.MachineSpawningGroup); + return true; + } + public uint GetPing() { return entitiesDB diff --git a/TechbloxModdingAPI/Players/PlayerTests.cs b/TechbloxModdingAPI/Players/PlayerTests.cs index c974518..1fc4f49 100644 --- a/TechbloxModdingAPI/Players/PlayerTests.cs +++ b/TechbloxModdingAPI/Players/PlayerTests.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Svelto.Tasks; using Svelto.Tasks.Enumerators; @@ -7,6 +8,7 @@ using Unity.Mathematics; using TechbloxModdingAPI.App; using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Tests; +using TechbloxModdingAPI.Utility; namespace TechbloxModdingAPI.Players { @@ -45,7 +47,20 @@ namespace TechbloxModdingAPI.Players [APITestCase(TestType.SimulationMode)] public static IEnumerator SeatEventTestSim() { + yield return new WaitForSecondsEnumerator(1).Continue(); + Assert.Equal(Player.LocalPlayer.SpawnMachine(), true, "Failed to spawn the player's machine.", "Successfully spawned the player's machine."); + yield return new WaitForSecondsEnumerator(1).Continue(); var seats = Game.CurrentGame().GetBlocksInGame(BlockIDs.DriverSeat); + int c = 0; + while (seats.Length == 0 && c < 10) + { + Logging.MetaLog("Waiting for a seat to be spawned..."); + yield return new WaitForSecondsEnumerator(1).Continue(); + Console.WriteLine("Spawn machine: " + Player.LocalPlayer.SpawnMachine()); + seats = Game.CurrentGame().GetBlocksInGame(BlockIDs.DriverSeat); + c++; + } + if (seats.Length == 0) { Assert.Fail("No driver seat found!"); diff --git a/TechbloxModdingAPI/Tests/TestRoot.cs b/TechbloxModdingAPI/Tests/TestRoot.cs index 16b85d0..bffae51 100644 --- a/TechbloxModdingAPI/Tests/TestRoot.cs +++ b/TechbloxModdingAPI/Tests/TestRoot.cs @@ -7,7 +7,9 @@ using System.Linq; // welcome to the dark side using Svelto.Tasks; using Svelto.Tasks.Lean; using Svelto.Tasks.Enumerators; +using Svelto.Tasks.Lean.Unity; using UnityEngine; + using TechbloxModdingAPI.App; using TechbloxModdingAPI.Tasks; using TechbloxModdingAPI.Utility; @@ -64,7 +66,7 @@ namespace TechbloxModdingAPI.Tests _testsCountPassed = 0; _testsCountFailed = 0; // flow control - Game.Enter += (sender, args) => { GameTests().RunOn(RobocraftX.Schedulers.ClientLean.EveryFrameStepRunner_TimeRunningAndStopped); }; + Game.Enter += (sender, args) => { GameTests().RunOn(new UpdateMonoRunner("TechbloxModdingAPITestRunner")); }; Game.Exit += (s, a) => state = "ReturningFromGame"; Client.EnterMenu += (sender, args) => { @@ -165,6 +167,7 @@ namespace TechbloxModdingAPI.Tests }; for (var index = 0; index < testTypesToRun.Length; index++) { + Logging.MetaLog($"Running test type {testTypesToRun[index]}"); foreach (Type t in testTypes) { foreach (MethodBase m in t.GetMethods()) @@ -206,7 +209,16 @@ namespace TechbloxModdingAPI.Tests } if (index + 1 < testTypesToRun.Length) //Don't toggle on the last test + { + bool running = currentGame.IsTimeRunning; currentGame.ToggleTimeMode(); + while (running ? !currentGame.IsTimeStopped : !currentGame.IsTimeRunning) + { + Logging.MetaLog($"Waiting for time to {(running?"stop":"start")}..."); + yield return new WaitForSecondsEnumerator(1).Continue(); + } + } + yield return new WaitForSecondsEnumerator(5).Continue(); } // exit game diff --git a/TechbloxModdingAPI/Utility/GameEngineManager.cs b/TechbloxModdingAPI/Utility/GameEngineManager.cs index 16bf4e2..04b0da7 100644 --- a/TechbloxModdingAPI/Utility/GameEngineManager.cs +++ b/TechbloxModdingAPI/Utility/GameEngineManager.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using RobocraftX.StateSync; using Svelto.ECS;