From 8a5209526384b048b085bec321489b60d6a6e541 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 7 Oct 2023 22:51:02 +0200 Subject: [PATCH] Added machine and environment data and new engine manager --- TechbloxModdingAPI/App/Client.cs | 171 ------------------ TechbloxModdingAPI/App/Game.cs | 10 +- .../App/GameBuildSimEventEngine.cs | 7 +- TechbloxModdingAPI/App/GameGameEngine.cs | 3 +- TechbloxModdingAPI/App/GameMenuEngine.cs | 3 +- TechbloxModdingAPI/Block.cs | 46 ++--- TechbloxModdingAPI/BlockGroup.cs | 4 +- .../Blocks/Engines/BlockCloneEngine.cs | 1 + .../Blocks/Engines/BlockEngine.cs | 1 + .../Blocks/Engines/BlueprintEngine.cs | 3 +- .../Blocks/Engines/MovementEngine.cs | 3 +- .../Blocks/Engines/PlacementEngine.cs | 3 +- .../Blocks/Engines/RemovalEngine.cs | 1 + .../Blocks/Engines/RotationEngine.cs | 1 + .../Blocks/Engines/ScalingEngine.cs | 1 + .../Blocks/Engines/SignalEngine.cs | 7 +- TechbloxModdingAPI/Blocks/Wire.cs | 65 +------ TechbloxModdingAPI/Client/App/Client.cs | 127 ------------- TechbloxModdingAPI/Client/App/ClientEngine.cs | 46 +++++ TechbloxModdingAPI/Client/App/GameClient.cs | 79 ++++++++ TechbloxModdingAPI/Client/App/Popup.cs | 88 +++++++++ .../Client/Game/ClientEnvironment.cs | 5 + .../Client/Game/ClientMachine.cs | 15 ++ TechbloxModdingAPI/Client/Game/ClientWorld.cs | 10 + TechbloxModdingAPI/Commands/CommandManager.cs | 2 +- TechbloxModdingAPI/Commands/CustomCommands.cs | 5 +- .../Commands/ICustomCommandEngine.cs | 13 +- .../Common/Engines/ApiEngineType.cs | 21 +++ .../Common/Engines/EngineManager.cs | 52 ++++++ .../{ => Common}/Engines/EnginePatches.cs | 31 +++- .../Common/Engines/IFactoryEngine.cs | 15 ++ .../Common/Engines/IFunEngine.cs | 11 ++ .../Common/Engines/IReactionaryEngine.cs | 12 ++ TechbloxModdingAPI/Common/IApiEngine.cs | 11 ++ TechbloxModdingAPI/Common/INamedApiEngine.cs | 9 + TechbloxModdingAPI/Engines/IApiEngine.cs | 26 --- TechbloxModdingAPI/Engines/IFactoryEngine.cs | 24 --- TechbloxModdingAPI/Engines/IFunEngine.cs | 9 - .../Engines/IReactionaryEngine.cs | 20 -- TechbloxModdingAPI/Input/FakeInput.cs | 2 +- TechbloxModdingAPI/Input/FakeInputEngine.cs | 8 +- TechbloxModdingAPI/Interface/IMGUI/Group.cs | 2 +- TechbloxModdingAPI/Main.cs | 1 - .../Persistence/SerializerManager.cs | 4 +- TechbloxModdingAPI/Player.cs | 40 +--- TechbloxModdingAPI/Players/PlayerEngine.cs | 20 +- .../Players/PlayerEventsEngine.cs | 4 +- TechbloxModdingAPI/Players/PlayerTests.cs | 3 +- TechbloxModdingAPI/SimBody.cs | 2 +- TechbloxModdingAPI/Tasks/Scheduler.cs | 4 +- TechbloxModdingAPI/Tests/Assert.cs | 2 +- TechbloxModdingAPI/Tests/TestRoot.cs | 46 +++-- .../Utility/DebugInterfaceEngine.cs | 14 +- .../Utility/GameEngineManager.cs | 5 +- TechbloxModdingAPI/Utility/GameState.cs | 2 +- TechbloxModdingAPI/Utility/GameStateEngine.cs | 8 +- .../Utility/MenuEngineManager.cs | 11 +- TechbloxModdingAPI/Utility/WrappedHandler.cs | 3 +- 58 files changed, 516 insertions(+), 626 deletions(-) delete mode 100644 TechbloxModdingAPI/App/Client.cs delete mode 100644 TechbloxModdingAPI/Client/App/Client.cs create mode 100644 TechbloxModdingAPI/Client/App/ClientEngine.cs create mode 100644 TechbloxModdingAPI/Client/App/GameClient.cs create mode 100644 TechbloxModdingAPI/Client/App/Popup.cs create mode 100644 TechbloxModdingAPI/Client/Game/ClientMachine.cs create mode 100644 TechbloxModdingAPI/Client/Game/ClientWorld.cs create mode 100644 TechbloxModdingAPI/Common/Engines/ApiEngineType.cs create mode 100644 TechbloxModdingAPI/Common/Engines/EngineManager.cs rename TechbloxModdingAPI/{ => Common}/Engines/EnginePatches.cs (74%) create mode 100644 TechbloxModdingAPI/Common/Engines/IFactoryEngine.cs create mode 100644 TechbloxModdingAPI/Common/Engines/IFunEngine.cs create mode 100644 TechbloxModdingAPI/Common/Engines/IReactionaryEngine.cs create mode 100644 TechbloxModdingAPI/Common/IApiEngine.cs create mode 100644 TechbloxModdingAPI/Common/INamedApiEngine.cs delete mode 100644 TechbloxModdingAPI/Engines/IApiEngine.cs delete mode 100644 TechbloxModdingAPI/Engines/IFactoryEngine.cs delete mode 100644 TechbloxModdingAPI/Engines/IFunEngine.cs delete mode 100644 TechbloxModdingAPI/Engines/IReactionaryEngine.cs diff --git a/TechbloxModdingAPI/App/Client.cs b/TechbloxModdingAPI/App/Client.cs deleted file mode 100644 index 249d7a3..0000000 --- a/TechbloxModdingAPI/App/Client.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; -using System.Reflection; -using HarmonyLib; - -using RobocraftX.Services; -using UnityEngine; -using RobocraftX.Common; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.App -{ - /// - /// The Techblox application that is running this code right now. - /// - public class Client - { - public static Client Instance { get; } = new Client(); - - protected static Func ErrorHandlerInstanceGetter; - - protected static Action EnqueueError; - - /// - /// An event that fires whenever the main menu is loaded. - /// - public static event EventHandler EnterMenu - { - add => Game.menuEngine.EnterMenu += value; - remove => Game.menuEngine.EnterMenu -= value; - } - - /// - /// An event that fire whenever the main menu is exited. - /// - public static event EventHandler ExitMenu - { - add => Game.menuEngine.ExitMenu += value; - remove => Game.menuEngine.ExitMenu -= value; - } - - /// - /// Techblox build version string. - /// Usually this is in the form YYYY.mm.DD.HH.MM.SS - /// - /// The version. - public string Version - { - get => Application.version; - } - - /// - /// Unity version string. - /// - /// The unity version. - public string UnityVersion - { - get => Application.unityVersion; - } - - /// - /// Game saves currently visible in the menu. - /// These take a second to completely populate after the EnterMenu event fires. - /// - /// My games. - public Game[] MyGames - { - get - { - if (!Game.menuEngine.IsInMenu) return Array.Empty(); - return Game.menuEngine.GetMyGames(); - } - } - - /// - /// Whether Techblox is in the Main Menu - /// - /// true if in menu; false when loading or in a game. - public bool InMenu - { - get => Game.menuEngine.IsInMenu; - } - - /// - /// Open a popup which prompts the user to click a button. - /// This reuses Techblox'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); - } - - public void CloseCurrentPrompt() - { - object errorHandlerInstance = ErrorHandlerInstanceGetter(); - 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 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("TechbloxModdingAPI.App.Client:GenInstanceGetter") - .MakeGenericMethod(errorHandler) - .Invoke(null, new object[0]); - EnqueueError = (Action) AccessTools.Method("TechbloxModdingAPI.App.Client:GenEnqueueError") - .MakeGenericMethod(errorHandler, errorHandle) - .Invoke(null, new object[0]); - } - - // 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 = () => 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 Close, Action FirstButton, Action SecondButton) _errorPopup; - - private static (Action Close, Action FirstButton, Action SecondButton) GetPopupCloseMethods(object handler) - { - 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/Game.cs b/TechbloxModdingAPI/App/Game.cs index aac7cb5..977586d 100644 --- a/TechbloxModdingAPI/App/Game.cs +++ b/TechbloxModdingAPI/App/Game.cs @@ -20,12 +20,12 @@ namespace TechbloxModdingAPI.App public class Game { // extensible engines - protected static GameGameEngine gameEngine = new GameGameEngine(); - protected internal static GameMenuEngine menuEngine = new GameMenuEngine(); - protected static DebugInterfaceEngine debugOverlayEngine = new DebugInterfaceEngine(); - protected static GameBuildSimEventEngine buildSimEventEngine = new GameBuildSimEventEngine(); + protected static GameGameEngine gameEngine = new(); + protected internal static GameMenuEngine menuEngine = new(); + protected static DebugInterfaceEngine debugOverlayEngine = new(); + protected static GameBuildSimEventEngine buildSimEventEngine = new(); - private List debugIds = new List(); + private List debugIds = new(); private bool menuMode = true; private bool hasId = false; diff --git a/TechbloxModdingAPI/App/GameBuildSimEventEngine.cs b/TechbloxModdingAPI/App/GameBuildSimEventEngine.cs index 67e6769..86deed2 100644 --- a/TechbloxModdingAPI/App/GameBuildSimEventEngine.cs +++ b/TechbloxModdingAPI/App/GameBuildSimEventEngine.cs @@ -1,10 +1,7 @@ -using System; - -using RobocraftX.Common; -using RobocraftX.StateSync; +using RobocraftX.StateSync; using Svelto.ECS; +using TechbloxModdingAPI.Common; using Unity.Jobs; -using TechbloxModdingAPI.Engines; using TechbloxModdingAPI.Utility; namespace TechbloxModdingAPI.App diff --git a/TechbloxModdingAPI/App/GameGameEngine.cs b/TechbloxModdingAPI/App/GameGameEngine.cs index 8eab6fd..be088bd 100644 --- a/TechbloxModdingAPI/App/GameGameEngine.cs +++ b/TechbloxModdingAPI/App/GameGameEngine.cs @@ -16,7 +16,8 @@ using Techblox.Environment.Transition; using Techblox.GameSelection; using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Common; +using TechbloxModdingAPI.Common.Engines; using TechbloxModdingAPI.Input; using TechbloxModdingAPI.Players; using TechbloxModdingAPI.Utility; diff --git a/TechbloxModdingAPI/App/GameMenuEngine.cs b/TechbloxModdingAPI/App/GameMenuEngine.cs index 8da4742..3291006 100644 --- a/TechbloxModdingAPI/App/GameMenuEngine.cs +++ b/TechbloxModdingAPI/App/GameMenuEngine.cs @@ -9,8 +9,7 @@ using RobocraftX.Multiplayer; using Svelto.ECS; using Svelto.ECS.Experimental; using Techblox.GameSelection; - -using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Common.Engines; using TechbloxModdingAPI.Utility; namespace TechbloxModdingAPI.App diff --git a/TechbloxModdingAPI/Block.cs b/TechbloxModdingAPI/Block.cs index 5c3c897..f135247 100644 --- a/TechbloxModdingAPI/Block.cs +++ b/TechbloxModdingAPI/Block.cs @@ -25,16 +25,16 @@ namespace TechbloxModdingAPI /// public class Block : EcsObjectBase, IEquatable, IEquatable { - protected static readonly PlacementEngine PlacementEngine = new PlacementEngine(); - protected static readonly MovementEngine MovementEngine = new MovementEngine(); - protected static readonly RotationEngine RotationEngine = new RotationEngine(); - protected static readonly RemovalEngine RemovalEngine = new RemovalEngine(); - protected static readonly SignalEngine SignalEngine = new SignalEngine(); - protected static readonly BlockEventsEngine BlockEventsEngine = new BlockEventsEngine(); - protected static readonly ScalingEngine ScalingEngine = new ScalingEngine(); - protected static readonly BlockCloneEngine BlockCloneEngine = new BlockCloneEngine(); + protected static readonly PlacementEngine PlacementEngine = new(); + protected static readonly MovementEngine MovementEngine = new(); + protected static readonly RotationEngine RotationEngine = new(); + protected static readonly RemovalEngine RemovalEngine = new(); + protected static readonly SignalEngine SignalEngine = new(); + protected static readonly BlockEventsEngine BlockEventsEngine = new(); + protected static readonly ScalingEngine ScalingEngine = new(); + protected static readonly BlockCloneEngine BlockCloneEngine = new(); - protected internal static readonly BlockEngine BlockEngine = new BlockEngine(); + protected internal static readonly BlockEngine BlockEngine = new(); /// /// 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. @@ -96,7 +96,7 @@ namespace TechbloxModdingAPI } private static readonly Dictionary Constructor, Type Type)> GroupToConstructor = - new Dictionary, Type)> + new() { {CommonExclusiveGroups.DAMPEDSPRING_BLOCK_GROUP, (id => new DampedSpring(id), typeof(DampedSpring))}, {CommonExclusiveGroups.ENGINE_BLOCK_BUILD_GROUP, (id => new Engine(id), typeof(Engine))}, @@ -122,9 +122,9 @@ namespace TechbloxModdingAPI internal static Block New(EGID egid, bool signaling = false) { if (egid == default) return null; - if (GroupToConstructor.ContainsKey(egid.groupID)) + if (GroupToConstructor.TryGetValue(egid.groupID, out var value)) { - var (constructor, type) = GroupToConstructor[egid.groupID]; + var (constructor, type) = value; return GetInstance(egid, constructor, type); } @@ -133,7 +133,7 @@ namespace TechbloxModdingAPI : GetInstance(egid, e => new Block(e)); } - public Block(EGID id) : base(id) + public Block(EGID id) : base(id, typeof(BlockEntityDescriptor)) { Type expectedType; if (GroupToConstructor.ContainsKey(id.groupID) && @@ -153,26 +153,6 @@ namespace TechbloxModdingAPI { } - /// - /// Places a new block in the world. - /// - /// The block's type - /// The block's position (a block is 0.2 wide in terms of position) - /// Whether the block should be auto-wired (if functional) - /// The player who placed the block - public Block(BlockIDs type, float3 position, bool autoWire = false, Player player = null) - : base(block => - { - if (!PlacementEngine.IsInGame || !GameState.IsBuildMode()) - throw new BlockException("Blocks can only be placed in build mode."); - var initializer = PlacementEngine.PlaceBlock(type, position, player, autoWire); - block.InitData = initializer; - Placed += ((Block)block).OnPlacedInit; - return initializer.EGID; - }) - { - } - private EGID copiedFrom; /// diff --git a/TechbloxModdingAPI/BlockGroup.cs b/TechbloxModdingAPI/BlockGroup.cs index 82f0be0..cbb4a58 100644 --- a/TechbloxModdingAPI/BlockGroup.cs +++ b/TechbloxModdingAPI/BlockGroup.cs @@ -18,14 +18,14 @@ namespace TechbloxModdingAPI /// public class BlockGroup : EcsObjectBase, ICollection, IDisposable { - internal static BlueprintEngine _engine = new BlueprintEngine(); + internal static BlueprintEngine _engine = new(); private readonly Block sourceBlock; private readonly List blocks; private float3 position, rotation; internal bool PosAndRotCalculated; internal BlockGroup(int id, Block block) : base(new EGID((uint)id, - BlockGroupExclusiveGroups.BlockGroupEntityGroup)) + BlockGroupExclusiveGroups.BlockGroupEntityGroup), typeof(BlockGroupEntityDescriptor)) { if (id == BlockGroupUtility.GROUP_UNASSIGNED) throw new BlockException("Cannot create a block group for blocks without a group!"); diff --git a/TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs b/TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs index 3d64280..35acd2a 100644 --- a/TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs @@ -8,6 +8,7 @@ using RobocraftX.Character; using RobocraftX.Common; using Svelto.DataStructures; using Svelto.ECS; +using TechbloxModdingAPI.Common; using TechbloxModdingAPI.Engines; namespace TechbloxModdingAPI.Blocks.Engines diff --git a/TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs b/TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs index fd16d2f..c98e69c 100644 --- a/TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs @@ -17,6 +17,7 @@ using Svelto.ECS.Experimental; using Svelto.ECS.Hybrid; using Techblox.BuildingDrone; using Techblox.ObjectIDBlockServer; +using TechbloxModdingAPI.Common; using Unity.Mathematics; using TechbloxModdingAPI.Engines; diff --git a/TechbloxModdingAPI/Blocks/Engines/BlueprintEngine.cs b/TechbloxModdingAPI/Blocks/Engines/BlueprintEngine.cs index f04b3a3..c2c7fe4 100644 --- a/TechbloxModdingAPI/Blocks/Engines/BlueprintEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/BlueprintEngine.cs @@ -19,6 +19,7 @@ using Svelto.ECS.EntityStructs; using Svelto.ECS.Native; using Svelto.ECS.Serialization; using Techblox.Blocks.Connections; +using TechbloxModdingAPI.Common.Engines; using TechbloxModdingAPI.Engines; using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility.ECS; @@ -35,7 +36,7 @@ namespace TechbloxModdingAPI.Blocks.Engines AccessTools.Method("RobocraftX.CR.MachineEditing.PlaceBlockUtility:GetBlocksSharingBlockgroup"); private NativeDynamicArray selectedBlocksInGroup; - private NativeHashSet removedConnections = new NativeHashSet(); + private NativeHashSet removedConnections = new(); private int addingToBlockGroup = -1; private static readonly Type PlaceBlueprintUtilityType = diff --git a/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs b/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs index 7f8acfd..c60b2d5 100644 --- a/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs @@ -2,10 +2,9 @@ using RobocraftX.DOTS; using Svelto.ECS; using Svelto.ECS.EntityStructs; +using TechbloxModdingAPI.Common; using Unity.Mathematics; using Unity.Transforms; - -using TechbloxModdingAPI.Engines; using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility.ECS; diff --git a/TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs b/TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs index d32f7f1..6dbcdbb 100644 --- a/TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs @@ -12,9 +12,8 @@ using RobocraftX.Rendering; using RobocraftX.Rendering.GPUI; using Svelto.ECS; using Svelto.ECS.EntityStructs; +using TechbloxModdingAPI.Common; using Unity.Mathematics; - -using TechbloxModdingAPI.Engines; using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility.ECS; diff --git a/TechbloxModdingAPI/Blocks/Engines/RemovalEngine.cs b/TechbloxModdingAPI/Blocks/Engines/RemovalEngine.cs index e4e899b..bdb705b 100644 --- a/TechbloxModdingAPI/Blocks/Engines/RemovalEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/RemovalEngine.cs @@ -9,6 +9,7 @@ using RobocraftX.StateSync; using Svelto.ECS; using Svelto.ECS.Native; using Techblox.Blocks.Connections; +using TechbloxModdingAPI.Common; using Unity.Collections; using Unity.Jobs; using Allocator = Unity.Collections.Allocator; diff --git a/TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs b/TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs index ccfc13e..c079394 100644 --- a/TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs @@ -2,6 +2,7 @@ using RobocraftX.DOTS; using Svelto.ECS; using Svelto.ECS.EntityStructs; +using TechbloxModdingAPI.Common; using Unity.Mathematics; using UnityEngine; diff --git a/TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs b/TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs index ef5cfe4..45e5f62 100644 --- a/TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs @@ -4,6 +4,7 @@ using HarmonyLib; using RobocraftX.Common; using RobocraftX.DOTS; using Svelto.ECS; +using TechbloxModdingAPI.Common; using Unity.Entities; using TechbloxModdingAPI.Engines; diff --git a/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs b/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs index 45d6e75..50bbbf7 100644 --- a/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs @@ -3,7 +3,8 @@ using Gamecraft.Wires; using Svelto.DataStructures; using Svelto.ECS; - +using TechbloxModdingAPI.Common; +using TechbloxModdingAPI.Common.Engines; using TechbloxModdingAPI.Engines; using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility.ECS; @@ -260,7 +261,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(ports.firstOutputID + startPort, NamedExclusiveGroup.Group) }; } EGID[] endPorts; @@ -272,7 +273,7 @@ namespace TechbloxModdingAPI.Blocks.Engines else { BlockPortsStruct ports = entitiesDB.QueryEntity(endBlock); - endPorts = new EGID[] {new EGID(ports.firstInputID + endPort, NamedExclusiveGroup.Group) }; + endPorts = new EGID[] {new(ports.firstInputID + endPort, NamedExclusiveGroup.Group) }; } for (int endIndex = 0; endIndex < endPorts.Length; endIndex++) diff --git a/TechbloxModdingAPI/Blocks/Wire.cs b/TechbloxModdingAPI/Blocks/Wire.cs index 1a949dd..9be1cc7 100644 --- a/TechbloxModdingAPI/Blocks/Wire.cs +++ b/TechbloxModdingAPI/Blocks/Wire.cs @@ -69,45 +69,6 @@ namespace TechbloxModdingAPI.Blocks : null; } - /// - /// Construct a wire object froam n existing connection. - /// - /// Starting block ID. - /// Ending block ID. - /// Starting port number, or guess if omitted. - /// Ending port number, or guess if omitted. - /// Guessing failed or wire does not exist. - public Wire(Block start, Block end, byte startPort = Byte.MaxValue, byte endPort = Byte.MaxValue) : base(ecs => - { - var th = (Wire)ecs; - th.startBlockEGID = start.Id; - th.endBlockEGID = end.Id; - bool flipped = false; - // find block ports - EGID wire = signalEngine.MatchBlocksToWire(start.Id, end.Id, startPort, endPort); - if (wire == default) - { - // flip I/O around and try again - wire = signalEngine.MatchBlocksToWire(end.Id, start.Id, endPort, startPort); - flipped = true; - // NB: start and end are handled exactly as they're received as params. - // This makes wire traversal easier, but makes logic in this class a bit more complex - } - - if (wire != default) - { - th.Construct(start.Id, end.Id, startPort, endPort, wire, flipped); - } - else - { - throw new WireInvalidException("Wire not found"); - } - - return th.wireEGID; - }) - { - } - /// /// Construct a wire object from an existing wire connection. /// @@ -120,9 +81,9 @@ namespace TechbloxModdingAPI.Blocks public Wire(Block start, Block end, byte startPort, byte endPort, EGID wire, bool inputToOutput) : this(start.Id, end.Id, startPort, endPort, wire, inputToOutput) { - } + } // TODO: Convert all constructors (including the removed one) to static methods - private Wire(EGID startBlock, EGID endBlock, byte startPort, byte endPort, EGID wire, bool inputToOutput) : base(wire) + private Wire(EGID startBlock, EGID endBlock, byte startPort, byte endPort, EGID wire, bool inputToOutput) : base(wire, typeof(WireEntityDescriptor)) { Construct(startBlock, endBlock, startPort, endPort, wire, inputToOutput); } @@ -145,7 +106,7 @@ namespace TechbloxModdingAPI.Blocks /// Construct a wire object from an existing wire connection. /// /// The wire ID. - public Wire(EGID wireEgid) : base(wireEgid) + public Wire(EGID wireEgid) : base(wireEgid, typeof(WireEntityDescriptor)) { WireEntityStruct wire = signalEngine.GetWire(wireEGID); Construct(wire.sourceBlockEGID, wire.destinationBlockEGID, wire.sourcePortUsage, wire.destinationPortUsage, @@ -188,22 +149,6 @@ namespace TechbloxModdingAPI.Blocks signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsEcsString.Set(value); } } - - /// - /// The wire's raw string signal. - /// - public ECSString ECSString - { - get - { - return signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsEcsString; - } - - set - { - signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsEcsString = value; - } - } /// /// The wire's signal id. @@ -292,9 +237,7 @@ namespace TechbloxModdingAPI.Blocks inputToOutput = false; // swap inputs and outputs (endBlockEGID, startBlockEGID) = (startBlockEGID, endBlockEGID); - var tempPort = endPortEGID; - endPortEGID = startPortEGID; - startPortEGID = tempPort; + (endPortEGID, startPortEGID) = (startPortEGID, endPortEGID); (endPort, startPort) = (startPort, endPort); } } diff --git a/TechbloxModdingAPI/Client/App/Client.cs b/TechbloxModdingAPI/Client/App/Client.cs deleted file mode 100644 index 4b24e82..0000000 --- a/TechbloxModdingAPI/Client/App/Client.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.Reflection; -using HarmonyLib; -using RobocraftX.Services; -using TechbloxModdingAPI.App; -using TechbloxModdingAPI.Client.Game; -using TechbloxModdingAPI.Common.Utils; -using UnityEngine; - -namespace TechbloxModdingAPI.Client.App; - -/// -/// Contains information about the game client's current state. -/// -public static class Client -{ // TODO - public static GameState CurrentState { get; } - - private static Func ErrorHandlerInstanceGetter; - - private static Action EnqueueError; - - /// - /// An event that fires whenever the game's state changes - /// - public static event EventHandler StateChanged - { - add => Game.menuEngine.EnterMenu += value; - remove => Game.menuEngine.EnterMenu -= value; - } - - /// - /// Techblox build version string. - /// Usually this is in the form YYYY.mm.DD.HH.MM.SS - /// - /// The version. - public static string Version => Application.version; - - /// - /// Unity version string. - /// - /// The unity version. - public static string UnityVersion => Application.unityVersion; - - /// - /// Environments (maps) currently visible in the menu. - /// These take a second to completely populate after the EnterMenu event fires. - /// - /// Available environments. - public static ClientEnvironment[] Environments - { - get; - } - - /// - /// Open a popup which prompts the user to click a button. - /// This reuses Techblox's error dialog popup - /// - /// The popup to display. Use an instance of SingleChoicePrompt or DualChoicePrompt. - public static 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); - } - - public static void CloseCurrentPrompt() - { - object errorHandlerInstance = ErrorHandlerInstanceGetter(); - var popup = GetPopupCloseMethods(errorHandlerInstance); - popup.Close(); - } - - public static void SelectFirstPromptButton() - { - object errorHandlerInstance = ErrorHandlerInstanceGetter(); - var popup = GetPopupCloseMethods(errorHandlerInstance); - popup.FirstButton(); - } - - public static void SelectSecondPromptButton() - { - object errorHandlerInstance = ErrorHandlerInstanceGetter(); - var popup = GetPopupCloseMethods(errorHandlerInstance); - popup.SecondButton(); - } - - internal static void Init() - { - var errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler"); - ErrorHandlerInstanceGetter = GenInstanceGetter(errorHandler); - EnqueueError = GenEnqueueError(errorHandler); - } - - // 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 handler) - { - return Reflections.CreateAccessor>("Instance", handler); - } - - private static Action GenEnqueueError(Type handler) - { - var enqueueError = AccessTools.Method(handler, "EnqueueError"); - return Reflections.CreateMethodCall>(enqueueError, handler); - } - - private static (Action Close, Action FirstButton, Action SecondButton) _errorPopup; - - private static (Action Close, Action FirstButton, Action SecondButton) GetPopupCloseMethods(object handler) - { - 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; - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Client/App/ClientEngine.cs b/TechbloxModdingAPI/Client/App/ClientEngine.cs new file mode 100644 index 0000000..68989f7 --- /dev/null +++ b/TechbloxModdingAPI/Client/App/ClientEngine.cs @@ -0,0 +1,46 @@ +using RobocraftX.GUI.MyGamesScreen; +using RobocraftX.Multiplayer; +using Svelto.ECS; +using Techblox.GameSelection; +using TechbloxModdingAPI.Client.Game; +using TechbloxModdingAPI.Common; +using TechbloxModdingAPI.Utility; + +namespace TechbloxModdingAPI.Client.App; + +internal class ClientEngine : IApiEngine +{ + public void Ready() + { + } + + public EntitiesDB entitiesDB { get; set; } + + public void Dispose() + { + } + + public ClientMachine[] GetMachines() + { + var (mgsevs, count) = entitiesDB.QueryEntities(MyGamesScreenExclusiveGroups.MyGames); + var games = new ClientMachine[count]; + for (int i = 0; i < count; i++) + { + Logging.MetaDebugLog($"Found game named {mgsevs[i].GameName}"); + games[i] = new ClientMachine(mgsevs[i].ID); + } + return games; + } + + public void EnterBuildMode(ClientEnvironment environment, ClientMachine machine) + { // TODO: Move to using a single engine per 'type' (see AddEngine()) + FullGameFields._multiplayerParams.MultiplayerMode = MultiplayerMode.SinglePlayer; + ref var selection = ref entitiesDB.QueryEntity(GameSelectionConstants.GameSelectionEGID); + selection.userContentID.Set(machine.ContentID); + selection.triggerStart = true; + selection.saveType = SaveType.ExistingSave; + selection.saveName.Set(machine.Name); + selection.gameMode = machine is ClientWorld ? GameMode.CreateWorld : GameMode.PlayGame; + selection.gameID.Set(environment.Id); //TODO: Expose to the API + } +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Client/App/GameClient.cs b/TechbloxModdingAPI/Client/App/GameClient.cs new file mode 100644 index 0000000..85d3dc9 --- /dev/null +++ b/TechbloxModdingAPI/Client/App/GameClient.cs @@ -0,0 +1,79 @@ +using System; +using TechbloxModdingAPI.Client.Game; +using TechbloxModdingAPI.Common.Engines; +using TechbloxModdingAPI.Utility; +using UnityEngine; + +namespace TechbloxModdingAPI.Client.App; + +/// +/// Contains information about the game client's current state. +/// +public static class GameClient +{ + private static readonly ClientEngine _engine = new(); + + public static GameState CurrentState + { + get => _currentState; + internal set + { + _currentState = value; + var old = _currentState; + _stateChanged.Invoke(null, new GameStateChangedArgs { OldState = old, NewState = value }); + } + } + + private static GameState _currentState; + + + /// + /// An event that fires whenever the game's state changes + /// + public static event EventHandler StateChanged + { + add => _stateChanged += value; + remove => _stateChanged -= value; + } + + private static WrappedHandler _stateChanged; + + /// + /// Techblox build version string. + /// Usually this is in the form YYYY.mm.DD.HH.MM.SS + /// + /// The version. + public static string Version => Application.version; + + /// + /// Unity version string. + /// + /// The unity version. + public static string UnityVersion => Application.unityVersion; + + /// + /// Environments (maps) currently visible in the menu. + /// These take a second to completely populate after the EnterMenu event fires. + /// + /// Available environments. + public static ClientEnvironment[] Environments { get; } + + public static ClientMachine[] Machines { get; } + + public static void EnterBuildMode(ClientEnvironment environment, ClientMachine machine) + { + var env = new ClientEnvironment("GAMEID_Road_Track"); // TODO: The options are hardcoded + _engine.EnterBuildMode(env, machine); + } + + public static void Init() + { + EngineManager.AddEngine(_engine, ApiEngineType.Menu); + } + + public struct GameStateChangedArgs + { + public GameState OldState { get; set; } + public GameState NewState { get; set; } + } +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Client/App/Popup.cs b/TechbloxModdingAPI/Client/App/Popup.cs new file mode 100644 index 0000000..c23097c --- /dev/null +++ b/TechbloxModdingAPI/Client/App/Popup.cs @@ -0,0 +1,88 @@ +using System; +using System.Reflection; +using HarmonyLib; +using RobocraftX.Services; +using TechbloxModdingAPI.Common.Utils; + +namespace TechbloxModdingAPI.Client.App; + +public static class Popup +{ + private static Func ErrorHandlerInstanceGetter; + + private static Action EnqueueError; + + /// + /// Open a popup which prompts the user to click a button. + /// This reuses Techblox's error dialog popup + /// + /// The popup to display. Use an instance of SingleChoicePrompt or DualChoicePrompt. + public static void PromptUser(Error popup) + { + // if the stuff wasn't mostly set to internal, this would be written as: + // RobocraftX.Services.ErrorHandler.Instance.EnqueueError(error); + object errorHandlerInstance = ErrorHandlerInstanceGetter(); + EnqueueError(errorHandlerInstance, popup); + } + + public static void CloseCurrentPrompt() + { + object errorHandlerInstance = ErrorHandlerInstanceGetter(); + var popup = GetPopupCloseMethods(errorHandlerInstance); + popup.Close(); + } + + public static void SelectFirstPromptButton() + { + object errorHandlerInstance = ErrorHandlerInstanceGetter(); + var popup = GetPopupCloseMethods(errorHandlerInstance); + popup.FirstButton(); + } + + public static void SelectSecondPromptButton() + { + object errorHandlerInstance = ErrorHandlerInstanceGetter(); + var popup = GetPopupCloseMethods(errorHandlerInstance); + popup.SecondButton(); + } + + internal static void Init() + { + var errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler"); + ErrorHandlerInstanceGetter = GenInstanceGetter(errorHandler); + EnqueueError = GenEnqueueError(errorHandler); + } + + // 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 handler) + { + return Reflections.CreateAccessor>("Instance", handler); + } + + private static Action GenEnqueueError(Type handler) + { + var enqueueError = AccessTools.Method(handler, "EnqueueError"); + return Reflections.CreateMethodCall>(enqueueError, handler); + } + + private static (Action Close, Action FirstButton, Action SecondButton) _errorPopup; + + private static (Action Close, Action FirstButton, Action SecondButton) GetPopupCloseMethods(object handler) + { + 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; + } +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Client/Game/ClientEnvironment.cs b/TechbloxModdingAPI/Client/Game/ClientEnvironment.cs index 29054bb..48033e5 100644 --- a/TechbloxModdingAPI/Client/Game/ClientEnvironment.cs +++ b/TechbloxModdingAPI/Client/Game/ClientEnvironment.cs @@ -5,5 +5,10 @@ namespace TechbloxModdingAPI.Client.Game; /// public class ClientEnvironment { + public string Id { get; } + public ClientEnvironment(string id) + { + Id = id; + } } \ No newline at end of file diff --git a/TechbloxModdingAPI/Client/Game/ClientMachine.cs b/TechbloxModdingAPI/Client/Game/ClientMachine.cs new file mode 100644 index 0000000..a546dce --- /dev/null +++ b/TechbloxModdingAPI/Client/Game/ClientMachine.cs @@ -0,0 +1,15 @@ +using System; +using RobocraftX.GUI.MyGamesScreen; +using Svelto.ECS; + +namespace TechbloxModdingAPI.Client.Game; + +public class ClientMachine : EcsObjectBase +{ + public ClientMachine(EGID id) : base(id, typeof(MyGameDataEntityDescriptor)) + { + } + + public string ContentID { get; set; } // TODO + public string Name { get; set; } +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Client/Game/ClientWorld.cs b/TechbloxModdingAPI/Client/Game/ClientWorld.cs new file mode 100644 index 0000000..91972ca --- /dev/null +++ b/TechbloxModdingAPI/Client/Game/ClientWorld.cs @@ -0,0 +1,10 @@ +using Svelto.ECS; + +namespace TechbloxModdingAPI.Client.Game; + +public class ClientWorld : ClientMachine +{ + public ClientWorld(EGID id) : base(id) + { + } +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Commands/CommandManager.cs b/TechbloxModdingAPI/Commands/CommandManager.cs index e275ace..54116e6 100644 --- a/TechbloxModdingAPI/Commands/CommandManager.cs +++ b/TechbloxModdingAPI/Commands/CommandManager.cs @@ -15,7 +15,7 @@ namespace TechbloxModdingAPI.Commands /// public static class CommandManager { - private static Dictionary _customCommands = new Dictionary(); + private static Dictionary _customCommands = new(); private static EnginesRoot _lastEngineRoot; diff --git a/TechbloxModdingAPI/Commands/CustomCommands.cs b/TechbloxModdingAPI/Commands/CustomCommands.cs index 0cacff8..5b13faa 100644 --- a/TechbloxModdingAPI/Commands/CustomCommands.cs +++ b/TechbloxModdingAPI/Commands/CustomCommands.cs @@ -14,7 +14,7 @@ namespace TechbloxModdingAPI.Commands public Delegate Action; } - private static Dictionary _commands = new Dictionary(); + private static Dictionary _commands = new(); public static void Register(string name, Delegate action, string desc) { _commands.Add(name, new CommandData @@ -51,7 +51,6 @@ namespace TechbloxModdingAPI.Commands public static bool Exists(string name) => _commands.ContainsKey(name); - public static ReadOnlyDictionary GetAllCommandData() => - new ReadOnlyDictionary(_commands); + public static ReadOnlyDictionary GetAllCommandData() => new(_commands); } } \ No newline at end of file diff --git a/TechbloxModdingAPI/Commands/ICustomCommandEngine.cs b/TechbloxModdingAPI/Commands/ICustomCommandEngine.cs index afb0237..4f71923 100644 --- a/TechbloxModdingAPI/Commands/ICustomCommandEngine.cs +++ b/TechbloxModdingAPI/Commands/ICustomCommandEngine.cs @@ -1,13 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Svelto.ECS; - -using TechbloxModdingAPI.Utility; -using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Common; namespace TechbloxModdingAPI.Commands { @@ -16,7 +7,7 @@ namespace TechbloxModdingAPI.Commands /// If you are using implementing this yourself, you must manually register the command. /// See SimpleCustomCommandEngine's Ready() and Dispose() methods for an example of command registration. /// - public interface ICustomCommandEngine : IApiEngine + public interface ICustomCommandEngine : INamedApiEngine { /// /// The command's description, shown in command help messages diff --git a/TechbloxModdingAPI/Common/Engines/ApiEngineType.cs b/TechbloxModdingAPI/Common/Engines/ApiEngineType.cs new file mode 100644 index 0000000..d84f00b --- /dev/null +++ b/TechbloxModdingAPI/Common/Engines/ApiEngineType.cs @@ -0,0 +1,21 @@ +namespace TechbloxModdingAPI.Common.Engines; + +public enum ApiEngineType +{ + /// + /// Gets created and registered when loading the game and stays loaded until it's quit. Intended for menu changes. + /// + Menu, + /// + /// Gets created and registered when entering build mode. + /// + Build, + /// + /// Gets created and registered on the client's side when starting simulation (test or not). + /// + PlayClient, + /// + /// Gets created and registered on the server's side when starting simulation (test or not). + /// + PlayServer +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Common/Engines/EngineManager.cs b/TechbloxModdingAPI/Common/Engines/EngineManager.cs new file mode 100644 index 0000000..8248896 --- /dev/null +++ b/TechbloxModdingAPI/Common/Engines/EngineManager.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using RobocraftX.StateSync; +using Svelto.ECS; +using TechbloxModdingAPI.Utility; + +namespace TechbloxModdingAPI.Common.Engines; + +public class EngineManager +{ + private static Dictionary> _engines = new(); + + /// + /// Register an engine to a given game state and type. Or multiple. + /// + /// The engine + /// The types to register to + public static void AddEngine(IApiEngine engine, params ApiEngineType[] types) + { + foreach (var type in types) + { + if (!_engines.ContainsKey(type)) + _engines.Add(type, new List()); + _engines[type].Add(engine); + } + } + + public static void RegisterEngines(StateSyncRegistrationHelper helper, EnginesRoot enginesRoot, ApiEngineType type) + { + IEntityFactory factory = enginesRoot.GenerateEntityFactory(); + IEntityFunctions functions = enginesRoot.GenerateEntityFunctions(); + foreach (var engine in _engines[type]) + { + string name = engine is INamedApiEngine namedEngine ? namedEngine.Name : engine.ToString(); + Logging.MetaDebugLog($"Registering {type} IApiEngine {name}"); + if (engine is IDeterministicEngine detEngine) + if (helper is not null) helper.AddDeterministicEngine(detEngine); + else throw new InvalidOperationException($"Attempting to add deterministic engine to non-deterministic state {type}"); + else + enginesRoot.AddEngine(engine); + switch (engine) + { + case IFactoryEngine factEngine: + factEngine.Factory = factory; + break; + case IFunEngine funEngine: + funEngine.Functions = functions; + break; + } + } + } +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Engines/EnginePatches.cs b/TechbloxModdingAPI/Common/Engines/EnginePatches.cs similarity index 74% rename from TechbloxModdingAPI/Engines/EnginePatches.cs rename to TechbloxModdingAPI/Common/Engines/EnginePatches.cs index d6b61a9..3358672 100644 --- a/TechbloxModdingAPI/Engines/EnginePatches.cs +++ b/TechbloxModdingAPI/Common/Engines/EnginePatches.cs @@ -5,22 +5,21 @@ using RobocraftX.CR.MainGame; using RobocraftX.FrontEnd; using RobocraftX.StateSync; using Svelto.ECS; -using Svelto.ECS.Schedulers; using TechbloxModdingAPI.Commands; using TechbloxModdingAPI.Utility; +using GameState = TechbloxModdingAPI.Client.App.GameState; -namespace TechbloxModdingAPI.Engines +namespace TechbloxModdingAPI.Common.Engines { [HarmonyPatch] static class GameLoadedTimeStoppedEnginePatch { public static void Postfix(StateSyncRegistrationHelper stateSyncReg) { + Client.App.GameClient.CurrentState = GameState.InMachineEditor; // TODO: World editor // register all game engines, including deterministic GameEngineManager.RegisterEngines(stateSyncReg); // register command engines - /*CommandLineCompositionRoot.Compose(contextHolder, stateSyncReg.enginesRoot, reloadGame, multiplayerParameters, - stateSyncReg); - uREPL C# compilation not supported anymore */ CommandManager.RegisterEngines(stateSyncReg.enginesRoot); } @@ -35,6 +34,7 @@ namespace TechbloxModdingAPI.Engines { public static void Postfix(StateSyncRegistrationHelper stateSyncReg) { + Client.App.GameClient.CurrentState = GameState.InTestMode; // TODO: Client/server GameEngineManager.RegisterEngines(stateSyncReg); CommandManager.RegisterEngines(stateSyncReg.enginesRoot); } @@ -49,21 +49,36 @@ namespace TechbloxModdingAPI.Engines static class GameReloadedPatch { internal static bool IsReload; - public static void Prefix() => IsReload = true; + public static void Prefix() + { + IsReload = true; + Client.App.GameClient.CurrentState = GameState.Loading; + } + public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "ReloadGame"); } [HarmonyPatch] static class GameSwitchedToPatch { - public static void Prefix() => GameReloadedPatch.IsReload = false; + public static void Prefix() + { + GameReloadedPatch.IsReload = false; + Client.App.GameClient.CurrentState = GameState.Loading; + } + public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToGame"); } [HarmonyPatch] static class MenuSwitchedToPatch { - public static void Prefix() => GameReloadedPatch.IsReload = false; + public static void Prefix() + { + GameReloadedPatch.IsReload = false; + Client.App.GameClient.CurrentState = GameState.Loading; + } + public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToMenu"); } @@ -72,6 +87,7 @@ namespace TechbloxModdingAPI.Engines { public static void Postfix(EnginesRoot enginesRoot) { + Client.App.GameClient.CurrentState = GameState.InMenu; // TODO: Loaded states // register menu engines MenuEngineManager.RegisterEngines(enginesRoot); } @@ -87,6 +103,7 @@ namespace TechbloxModdingAPI.Engines { public static void Postfix(FullGameCompositionRoot __instance) { + Client.App.GameClient.CurrentState = GameState.Loading; FullGameFields.Init(__instance); } diff --git a/TechbloxModdingAPI/Common/Engines/IFactoryEngine.cs b/TechbloxModdingAPI/Common/Engines/IFactoryEngine.cs new file mode 100644 index 0000000..7381094 --- /dev/null +++ b/TechbloxModdingAPI/Common/Engines/IFactoryEngine.cs @@ -0,0 +1,15 @@ +using Svelto.ECS; + +namespace TechbloxModdingAPI.Common.Engines; + +/// +/// Engine interface to create entities using the given Factory. +/// +public interface IFactoryEngine : IApiEngine +{ + /// + /// The EntityFactory for the entitiesDB. + /// Use this to create entities in ECS. + /// + IEntityFactory Factory { set; } +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Common/Engines/IFunEngine.cs b/TechbloxModdingAPI/Common/Engines/IFunEngine.cs new file mode 100644 index 0000000..afd85a7 --- /dev/null +++ b/TechbloxModdingAPI/Common/Engines/IFunEngine.cs @@ -0,0 +1,11 @@ +using Svelto.ECS; + +namespace TechbloxModdingAPI.Common.Engines; + +/// +/// Engine interface to use entity functions to remove entities or swap their groups. +/// +public interface IFunEngine : IApiEngine +{ + public IEntityFunctions Functions { set; } +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Common/Engines/IReactionaryEngine.cs b/TechbloxModdingAPI/Common/Engines/IReactionaryEngine.cs new file mode 100644 index 0000000..9221b61 --- /dev/null +++ b/TechbloxModdingAPI/Common/Engines/IReactionaryEngine.cs @@ -0,0 +1,12 @@ +using Svelto.ECS; +using TechbloxModdingAPI.Common; + +namespace TechbloxModdingAPI.Engines +{ + /// + /// Engine interface to react on an entity component being added or removed. + /// + public interface IReactionaryEngine : IApiEngine, IReactOnAddAndRemove where T : unmanaged, IEntityComponent + { + } +} diff --git a/TechbloxModdingAPI/Common/IApiEngine.cs b/TechbloxModdingAPI/Common/IApiEngine.cs new file mode 100644 index 0000000..2901ea6 --- /dev/null +++ b/TechbloxModdingAPI/Common/IApiEngine.cs @@ -0,0 +1,11 @@ +using System; +using Svelto.ECS; + +namespace TechbloxModdingAPI.Common; + +/// +/// Base engine interface used by all TechbloxModdingAPI engines +/// +public interface IApiEngine : IQueryingEntitiesEngine, IDisposable +{ +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Common/INamedApiEngine.cs b/TechbloxModdingAPI/Common/INamedApiEngine.cs new file mode 100644 index 0000000..82a5b1c --- /dev/null +++ b/TechbloxModdingAPI/Common/INamedApiEngine.cs @@ -0,0 +1,9 @@ +namespace TechbloxModdingAPI.Common; + +public interface INamedApiEngine : IApiEngine +{ + /// + /// The name of the engine + /// + string Name { get; } +} \ No newline at end of file diff --git a/TechbloxModdingAPI/Engines/IApiEngine.cs b/TechbloxModdingAPI/Engines/IApiEngine.cs deleted file mode 100644 index 6a8519a..0000000 --- a/TechbloxModdingAPI/Engines/IApiEngine.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Svelto.ECS; - -namespace TechbloxModdingAPI.Engines -{ - /// - /// Base engine interface used by all TechbloxModdingAPI engines - /// - public interface IApiEngine : IEngine, IQueryingEntitiesEngine, IDisposable - { - /// - /// The name of the engine - /// - string Name { get; } - - /// - /// Whether the emitter can be removed with Manager.RemoveEventEmitter(name) - /// - bool isRemovable { get; } - } -} diff --git a/TechbloxModdingAPI/Engines/IFactoryEngine.cs b/TechbloxModdingAPI/Engines/IFactoryEngine.cs deleted file mode 100644 index d03b4e3..0000000 --- a/TechbloxModdingAPI/Engines/IFactoryEngine.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Svelto.ECS; - -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Engines -{ - /// - /// Engine interface to create a ModEventEntityStruct in entitiesDB when Emit() is called. - /// - public interface IFactoryEngine : IApiEngine - { - /// - /// The EntityFactory for the entitiesDB. - /// Use this to create a ModEventEntityStruct when Emit() is called. - /// - IEntityFactory Factory { set; } - } -} diff --git a/TechbloxModdingAPI/Engines/IFunEngine.cs b/TechbloxModdingAPI/Engines/IFunEngine.cs deleted file mode 100644 index d9ee7fe..0000000 --- a/TechbloxModdingAPI/Engines/IFunEngine.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Svelto.ECS; - -namespace TechbloxModdingAPI.Engines -{ - public interface IFunEngine : IApiEngine - { - public IEntityFunctions Functions { set; } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Engines/IReactionaryEngine.cs b/TechbloxModdingAPI/Engines/IReactionaryEngine.cs deleted file mode 100644 index 739d626..0000000 --- a/TechbloxModdingAPI/Engines/IReactionaryEngine.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Svelto.ECS; -using Svelto.ECS.Internal; - -using TechbloxModdingAPI.Events; - -namespace TechbloxModdingAPI.Engines -{ - /// - /// Engine interface to handle ModEventEntityStruct events emitted by IEventEmitterEngines. - /// - public interface IReactionaryEngine : IApiEngine, IReactOnAddAndRemove where T : unmanaged, IEntityComponent - { - } -} diff --git a/TechbloxModdingAPI/Input/FakeInput.cs b/TechbloxModdingAPI/Input/FakeInput.cs index 0b0a7f9..9409f77 100644 --- a/TechbloxModdingAPI/Input/FakeInput.cs +++ b/TechbloxModdingAPI/Input/FakeInput.cs @@ -7,7 +7,7 @@ namespace TechbloxModdingAPI.Input { public static class FakeInput { - internal static readonly FakeInputEngine inputEngine = new FakeInputEngine(); + internal static readonly FakeInputEngine inputEngine = new(); /// /// Customize the local input. diff --git a/TechbloxModdingAPI/Input/FakeInputEngine.cs b/TechbloxModdingAPI/Input/FakeInputEngine.cs index cc6a6c2..b406b2a 100644 --- a/TechbloxModdingAPI/Input/FakeInputEngine.cs +++ b/TechbloxModdingAPI/Input/FakeInputEngine.cs @@ -1,12 +1,8 @@ -using System; - -using RobocraftX.Common; +using RobocraftX.Common; using RobocraftX.Common.Input; using RobocraftX.Players; using Svelto.ECS; - -using TechbloxModdingAPI.Utility; -using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Common; namespace TechbloxModdingAPI.Input { diff --git a/TechbloxModdingAPI/Interface/IMGUI/Group.cs b/TechbloxModdingAPI/Interface/IMGUI/Group.cs index 88a36c2..db4299e 100644 --- a/TechbloxModdingAPI/Interface/IMGUI/Group.cs +++ b/TechbloxModdingAPI/Interface/IMGUI/Group.cs @@ -13,7 +13,7 @@ namespace TechbloxModdingAPI.Interface.IMGUI { private bool automaticLayout; - private FasterList elements = new FasterList(); + private FasterList elements = new(); /// /// The rectangular area in the window that the UI group can use diff --git a/TechbloxModdingAPI/Main.cs b/TechbloxModdingAPI/Main.cs index de38cc6..0ef6c03 100644 --- a/TechbloxModdingAPI/Main.cs +++ b/TechbloxModdingAPI/Main.cs @@ -70,7 +70,6 @@ namespace TechbloxModdingAPI Wire.Init(); // init client Logging.MetaDebugLog($"Initializing Client"); - Client.Init(); Game.Init(); // init UI Logging.MetaDebugLog($"Initializing UI"); diff --git a/TechbloxModdingAPI/Persistence/SerializerManager.cs b/TechbloxModdingAPI/Persistence/SerializerManager.cs index fe11320..972a21b 100644 --- a/TechbloxModdingAPI/Persistence/SerializerManager.cs +++ b/TechbloxModdingAPI/Persistence/SerializerManager.cs @@ -15,9 +15,9 @@ namespace TechbloxModdingAPI.Persistence /// public static class SerializerManager { - private static Dictionary _serializers = new Dictionary(); + private static Dictionary _serializers = new(); - private static Dictionary> _registrations = new Dictionary>(); + private static Dictionary> _registrations = new(); private static EnginesRoot _lastEnginesRoot; diff --git a/TechbloxModdingAPI/Player.cs b/TechbloxModdingAPI/Player.cs index 24799f3..b653133 100644 --- a/TechbloxModdingAPI/Player.cs +++ b/TechbloxModdingAPI/Player.cs @@ -24,8 +24,8 @@ namespace TechbloxModdingAPI public partial class Player : EcsObjectBase, IEquatable, IEquatable { // static functionality - private static readonly PlayerEngine playerEngine = new PlayerEngine(); - private static readonly PlayerEventsEngine playerEventsEngine = new PlayerEventsEngine(); + private static readonly PlayerEngine playerEngine = new(); + private static readonly PlayerEventsEngine playerEventsEngine = new(); private static Player localPlayer; /// @@ -38,7 +38,7 @@ namespace TechbloxModdingAPI switch (player) { case PlayerType.Remote: - return playerEngine.GetRemotePlayer() != uint.MaxValue; + return playerEngine.GetRemotePlayers().Length > 0; case PlayerType.Local: return playerEngine.GetLocalPlayer() != uint.MaxValue; } @@ -90,7 +90,7 @@ namespace TechbloxModdingAPI /// Initializes a new instance of the class. /// /// The player's unique identifier. - public Player(uint id) : base(new EGID(id, CharacterExclusiveGroups.OnFootGroup)) + public Player(uint id) : base(new EGID(id, CharacterExclusiveGroups.OnFootGroup), typeof(CharacterEntityDescriptor)) { this.Id = id; if (!Exists(id)) @@ -100,38 +100,6 @@ namespace TechbloxModdingAPI this.Type = playerEngine.GetLocalPlayer() == id ? PlayerType.Local : PlayerType.Remote; } - /// - /// Initializes a new instance of the class. - /// - /// The player type. Chooses the first available player matching the criteria. - public Player(PlayerType player) : base(ecs => - { - uint id; - switch (player) - { - case PlayerType.Local: - id = playerEngine.GetLocalPlayer(); - break; - case PlayerType.Remote: - id = playerEngine.GetRemotePlayer(); - break; - default: - id = uint.MaxValue; - break; - } - - if (id == uint.MaxValue) - { - throw new PlayerNotFoundException($"No player of {player} type exists"); - } - - return new EGID(id, CharacterExclusiveGroups.OnFootGroup); - }) - { - this.Type = player; - Id = base.Id.entityID; - } - // object fields & properties /// diff --git a/TechbloxModdingAPI/Players/PlayerEngine.cs b/TechbloxModdingAPI/Players/PlayerEngine.cs index a1965fd..615916a 100644 --- a/TechbloxModdingAPI/Players/PlayerEngine.cs +++ b/TechbloxModdingAPI/Players/PlayerEngine.cs @@ -14,11 +14,9 @@ using RobocraftX.SimulationModeState; using Svelto.ECS; using Techblox.Camera; using Unity.Mathematics; -using Svelto.ECS.DataStructures; using Techblox.BuildingDrone; using Techblox.Character; - -using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Common.Engines; using TechbloxModdingAPI.Input; using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility.ECS; @@ -58,15 +56,17 @@ namespace TechbloxModdingAPI.Players return uint.MaxValue; } - public uint GetRemotePlayer() + public uint[] GetRemotePlayers() { - if (!isReady) return uint.MaxValue; + if (!isReady) return Array.Empty(); var (localPlayers, count) = entitiesDB.QueryEntities(PlayersExclusiveGroups.RemotePlayers); - if (count > 0) - { - return localPlayers[0].ID.entityID; - } - return uint.MaxValue; + var players = new uint[count]; + for (int i = 0; i < count; i++) + { + players[i] = localPlayers[i].ID.entityID; + } + + return players; } public long GetAllPlayerCount() diff --git a/TechbloxModdingAPI/Players/PlayerEventsEngine.cs b/TechbloxModdingAPI/Players/PlayerEventsEngine.cs index cf90c40..797d7c0 100644 --- a/TechbloxModdingAPI/Players/PlayerEventsEngine.cs +++ b/TechbloxModdingAPI/Players/PlayerEventsEngine.cs @@ -1,10 +1,8 @@ -using System; using RobocraftX.Character; using RobocraftX.Character.Movement; using RobocraftX.Common.Input; using Svelto.ECS; - -using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Common; namespace TechbloxModdingAPI.Players { diff --git a/TechbloxModdingAPI/Players/PlayerTests.cs b/TechbloxModdingAPI/Players/PlayerTests.cs index 32e9c14..27190e5 100644 --- a/TechbloxModdingAPI/Players/PlayerTests.cs +++ b/TechbloxModdingAPI/Players/PlayerTests.cs @@ -7,6 +7,7 @@ using Unity.Mathematics; using TechbloxModdingAPI.App; using TechbloxModdingAPI.Blocks; +using TechbloxModdingAPI.Client.App; using TechbloxModdingAPI.Tests; using TechbloxModdingAPI.Utility; @@ -73,7 +74,7 @@ namespace TechbloxModdingAPI.Players while (Player.LocalPlayer.State != PlayerState.InSeat) { bool cont = false; - Client.Instance.PromptUser(new SingleChoicePrompt("Testing", $"Enter the seat at {seat.Position} pls", "OK", () => cont = true)); + Popup.PromptUser(new SingleChoicePrompt("Testing", $"Enter the seat at {seat.Position} pls", "OK", () => cont = true)); while (!cont) yield return Yield.It; yield return new WaitForSecondsEnumerator(5f).Continue(); diff --git a/TechbloxModdingAPI/SimBody.cs b/TechbloxModdingAPI/SimBody.cs index 1120103..396d470 100644 --- a/TechbloxModdingAPI/SimBody.cs +++ b/TechbloxModdingAPI/SimBody.cs @@ -27,7 +27,7 @@ namespace TechbloxModdingAPI private Cluster cluster; private readonly uint clusterId = uint.MaxValue; - public SimBody(EGID id) : base(id) + public SimBody(EGID id) : base(id, typeof(ClusterEntityDescriptor)) { } diff --git a/TechbloxModdingAPI/Tasks/Scheduler.cs b/TechbloxModdingAPI/Tasks/Scheduler.cs index 5ad842e..34c1015 100644 --- a/TechbloxModdingAPI/Tasks/Scheduler.cs +++ b/TechbloxModdingAPI/Tasks/Scheduler.cs @@ -32,9 +32,9 @@ namespace TechbloxModdingAPI.Tasks } } - public static readonly Svelto.Tasks.ExtraLean.Unity.UpdateMonoRunner extraLeanRunner = new Svelto.Tasks.ExtraLean.Unity.UpdateMonoRunner("TechbloxModdingAPIExtraLean"); + public static readonly Svelto.Tasks.ExtraLean.Unity.UpdateMonoRunner extraLeanRunner = new("TechbloxModdingAPIExtraLean"); - public static readonly Svelto.Tasks.Lean.Unity.UpdateMonoRunner leanRunner = new Svelto.Tasks.Lean.Unity.UpdateMonoRunner("TechbloxModdingAPILean"); + public static readonly Svelto.Tasks.Lean.Unity.UpdateMonoRunner leanRunner = new("TechbloxModdingAPILean"); /// /// Schedule a task to run asynchronously. diff --git a/TechbloxModdingAPI/Tests/Assert.cs b/TechbloxModdingAPI/Tests/Assert.cs index f71b132..8c02aea 100644 --- a/TechbloxModdingAPI/Tests/Assert.cs +++ b/TechbloxModdingAPI/Tests/Assert.cs @@ -14,7 +14,7 @@ namespace TechbloxModdingAPI.Tests { private static StreamWriter logFile = null; - private static ConcurrentDictionary callbacks = new ConcurrentDictionary(); + private static ConcurrentDictionary callbacks = new(); private const string PASS = "SUCCESS: "; diff --git a/TechbloxModdingAPI/Tests/TestRoot.cs b/TechbloxModdingAPI/Tests/TestRoot.cs index 5306adc..4b3c4dd 100644 --- a/TechbloxModdingAPI/Tests/TestRoot.cs +++ b/TechbloxModdingAPI/Tests/TestRoot.cs @@ -8,11 +8,12 @@ using Svelto.Tasks; using Svelto.Tasks.Lean; using Svelto.Tasks.Enumerators; using Svelto.Tasks.Lean.Unity; +using TechbloxModdingAPI.Client.App; using UnityEngine; -using TechbloxModdingAPI.App; using TechbloxModdingAPI.Tasks; using TechbloxModdingAPI.Utility; +using GameState = TechbloxModdingAPI.Client.App.GameState; namespace TechbloxModdingAPI.Tests { @@ -66,19 +67,33 @@ namespace TechbloxModdingAPI.Tests _testsCountPassed = 0; _testsCountFailed = 0; // flow control - Game.Enter += (sender, args) => { GameTests().RunOn(new UpdateMonoRunner("TechbloxModdingAPITestRunner")); }; - Game.Exit += (s, a) => state = "ReturningFromGame"; - Client.EnterMenu += (sender, args) => + Client.App.GameClient.StateChanged += (sender, args) => { - if (state == "EnteringMenu") + switch (args.NewState) { - MenuTests().RunOn(Scheduler.leanRunner); - state = "EnteringGame"; - } - if (state == "ReturningFromGame") - { - TearDown().RunOn(Scheduler.leanRunner); - state = "ShuttingDown"; + case GameState.InMenu: + { + if (state == "EnteringMenu") + { + MenuTests().RunOn(Scheduler.leanRunner); + state = "EnteringGame"; + } + + if (state == "ReturningFromGame") + { + TearDown().RunOn(Scheduler.leanRunner); + state = "ShuttingDown"; + } + + break; + } + case GameState.InMachineEditor: + GameTests().RunOn(new UpdateMonoRunner("TechbloxModdingAPITestRunner")); + break; + case GameState.Loading: + if (args.OldState == GameState.InTestMode) + state = "ReturningFromGame"; + break; } }; // init tests here @@ -131,17 +146,16 @@ namespace TechbloxModdingAPI.Tests private static IEnumerator GoToGameTests() { - Client app = Client.Instance; int oldLength = 0; - while (app.MyGames.Length == 0 || oldLength != app.MyGames.Length) + while (GameClient.Machines.Length == 0 || oldLength != GameClient.Machines.Length) { - oldLength = app.MyGames.Length; + oldLength = GameClient.Machines.Length; yield return new WaitForSecondsEnumerator(1).Continue(); } yield return Yield.It; try { - app.MyGames[0].EnterGame(); + GameClient.Machines[0].EnterGame(); } catch (Exception e) { diff --git a/TechbloxModdingAPI/Utility/DebugInterfaceEngine.cs b/TechbloxModdingAPI/Utility/DebugInterfaceEngine.cs index 7f9d97c..5633bc0 100644 --- a/TechbloxModdingAPI/Utility/DebugInterfaceEngine.cs +++ b/TechbloxModdingAPI/Utility/DebugInterfaceEngine.cs @@ -1,23 +1,17 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Text; -using System.Text.Formatting; -using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Players; using HarmonyLib; -using RobocraftX.GUI.Debug; using Svelto.ECS; -using Svelto.ECS.Experimental; -using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Common; namespace TechbloxModdingAPI.Utility { public class DebugInterfaceEngine : IApiEngine { - private static Dictionary> _extraInfo=new Dictionary>(); + private static Dictionary> _extraInfo=new(); public void Ready() { } @@ -46,8 +40,8 @@ namespace TechbloxModdingAPI.Utility int index = list.FindLastIndex(inst => inst.opcode == OpCodes.Ldfld); var array = new CodeInstruction[] { - new CodeInstruction(OpCodes.Ldloc_0), //StringBuffer - new CodeInstruction(OpCodes.Call, ((Action)AddInfo).Method) + new(OpCodes.Ldloc_0), //StringBuffer + new(OpCodes.Call, ((Action)AddInfo).Method) }; list.InsertRange(index - 1, array); //-1: ldloc.1 ("local") before ldfld } diff --git a/TechbloxModdingAPI/Utility/GameEngineManager.cs b/TechbloxModdingAPI/Utility/GameEngineManager.cs index 04b0da7..428a2c5 100644 --- a/TechbloxModdingAPI/Utility/GameEngineManager.cs +++ b/TechbloxModdingAPI/Utility/GameEngineManager.cs @@ -3,7 +3,8 @@ using System.Linq; using RobocraftX.StateSync; using Svelto.ECS; -using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Common; +using TechbloxModdingAPI.Common.Engines; namespace TechbloxModdingAPI.Utility { @@ -12,7 +13,7 @@ namespace TechbloxModdingAPI.Utility /// public static class GameEngineManager { - private static Dictionary _gameEngines = new Dictionary(); + private static Dictionary _gameEngines = new(); private static EnginesRoot _lastEngineRoot; diff --git a/TechbloxModdingAPI/Utility/GameState.cs b/TechbloxModdingAPI/Utility/GameState.cs index 79a72fe..cd0a8ca 100644 --- a/TechbloxModdingAPI/Utility/GameState.cs +++ b/TechbloxModdingAPI/Utility/GameState.cs @@ -11,7 +11,7 @@ namespace TechbloxModdingAPI.Utility /// public static class GameState { - private static GameStateEngine gameEngine = new GameStateEngine(); + private static GameStateEngine gameEngine = new(); /// /// Is the game in edit mode? diff --git a/TechbloxModdingAPI/Utility/GameStateEngine.cs b/TechbloxModdingAPI/Utility/GameStateEngine.cs index 936a8ef..0f2e385 100644 --- a/TechbloxModdingAPI/Utility/GameStateEngine.cs +++ b/TechbloxModdingAPI/Utility/GameStateEngine.cs @@ -1,12 +1,6 @@ using Svelto.ECS; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - using RobocraftX.SimulationModeState; -using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Common; namespace TechbloxModdingAPI.Utility { diff --git a/TechbloxModdingAPI/Utility/MenuEngineManager.cs b/TechbloxModdingAPI/Utility/MenuEngineManager.cs index 4358ca8..9887e79 100644 --- a/TechbloxModdingAPI/Utility/MenuEngineManager.cs +++ b/TechbloxModdingAPI/Utility/MenuEngineManager.cs @@ -1,11 +1,8 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; - using Svelto.ECS; -using TechbloxModdingAPI.Engines; +using TechbloxModdingAPI.Common; +using TechbloxModdingAPI.Common.Engines; namespace TechbloxModdingAPI.Utility { @@ -14,7 +11,7 @@ namespace TechbloxModdingAPI.Utility /// public static class MenuEngineManager { - private static Dictionary _menuEngines = new Dictionary(); + private static Dictionary _menuEngines = new(); private static EnginesRoot _lastEngineRoot; diff --git a/TechbloxModdingAPI/Utility/WrappedHandler.cs b/TechbloxModdingAPI/Utility/WrappedHandler.cs index 41e2fc7..983b3a4 100644 --- a/TechbloxModdingAPI/Utility/WrappedHandler.cs +++ b/TechbloxModdingAPI/Utility/WrappedHandler.cs @@ -15,8 +15,7 @@ namespace TechbloxModdingAPI.Utility /// /// Store wrappers so we can unregister them properly /// - private static Dictionary, EventHandler> wrappers = - new Dictionary, EventHandler>(); + private static Dictionary, EventHandler> wrappers = new(); public static WrappedHandler operator +(WrappedHandler original, EventHandler added) {