@@ -20,8 +20,8 @@ namespace TechbloxModdingAPI.App | |||
Game.Exit += Assert.CallsBack<GameEventArgs>("GameExit"); | |||
Game.Simulate += Assert.CallsBack<GameEventArgs>("GameSimulate"); | |||
Game.Edit += Assert.CallsBack<GameEventArgs>("GameEdit"); | |||
Client.EnterMenu += Assert.CallsBack<MenuEventArgs>("MenuEnter"); | |||
Client.ExitMenu += Assert.CallsBack<MenuEventArgs>("MenuExit"); | |||
/*Client.EnterMenu += Assert.CallsBack<MenuEventArgs>("MenuEnter"); | |||
Client.ExitMenu += Assert.CallsBack<MenuEventArgs>("MenuExit");*/ | |||
} | |||
[APITestCase(TestType.Game)] | |||
@@ -2,7 +2,7 @@ using System; | |||
using HarmonyLib; | |||
using RobocraftX.Services; | |||
using TechbloxModdingAPI.Client.App; | |||
using TechbloxModdingAPI.Tests; | |||
namespace TechbloxModdingAPI.App | |||
@@ -42,25 +42,25 @@ namespace TechbloxModdingAPI.App | |||
[APITestCase(TestType.Menu)] | |||
public static void TestPopUp2() | |||
{ | |||
Client.Instance.PromptUser(popup2); | |||
Popup.PromptUser(popup2); | |||
} | |||
[APITestCase(TestType.Menu)] | |||
public static void TestPopUp1() | |||
{ | |||
Client.Instance.PromptUser(popup1); | |||
Popup.PromptUser(popup1); | |||
} | |||
[APITestCase(TestType.Menu)] | |||
public static void TestPopUpClose1() | |||
{ | |||
Client.Instance.CloseCurrentPrompt(); | |||
Popup.CloseCurrentPrompt(); | |||
} | |||
[APITestCase(TestType.Menu)] | |||
public static void TestPopUpClose2() | |||
{ | |||
Client.Instance.CloseCurrentPrompt(); | |||
Popup.CloseCurrentPrompt(); | |||
} | |||
} | |||
#endif |
@@ -7,6 +7,7 @@ using Svelto.ECS; | |||
using Techblox.GameSelection; | |||
using TechbloxModdingAPI.Blocks; | |||
using TechbloxModdingAPI.Common.Engines; | |||
using TechbloxModdingAPI.Tasks; | |||
using TechbloxModdingAPI.Utility; | |||
@@ -481,10 +482,10 @@ namespace TechbloxModdingAPI.App | |||
internal static void Init() | |||
{ | |||
GameEngineManager.AddGameEngine(gameEngine); | |||
GameEngineManager.AddGameEngine(debugOverlayEngine); | |||
GameEngineManager.AddGameEngine(buildSimEventEngine); | |||
MenuEngineManager.AddMenuEngine(menuEngine); | |||
EngineManager.AddEngine(gameEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer); | |||
EngineManager.AddEngine(debugOverlayEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer); | |||
EngineManager.AddEngine(buildSimEventEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer); | |||
EngineManager.AddEngine(menuEngine, ApiEngineType.Menu); | |||
} | |||
} | |||
} |
@@ -14,6 +14,8 @@ using RobocraftX.Rendering; | |||
using Techblox.BlockLabelsServer; | |||
using TechbloxModdingAPI.Blocks; | |||
using TechbloxModdingAPI.Blocks.Engines; | |||
using TechbloxModdingAPI.Client.App; | |||
using TechbloxModdingAPI.Common.Engines; | |||
using TechbloxModdingAPI.Tests; | |||
using TechbloxModdingAPI.Utility; | |||
@@ -48,7 +50,7 @@ namespace TechbloxModdingAPI | |||
/// <returns>The placed block or null if failed</returns> | |||
public static Block PlaceNew(BlockIDs block, float3 position, bool autoWire = false, Player player = null) | |||
{ | |||
if (PlacementEngine.IsInGame && GameState.IsBuildMode()) | |||
if (PlacementEngine.IsInGame && GameClient.IsBuildMode) | |||
{ | |||
var initializer = PlacementEngine.PlaceBlock(block, position, player, autoWire); | |||
var egid = initializer.EGID; | |||
@@ -346,7 +348,7 @@ namespace TechbloxModdingAPI | |||
get | |||
{ | |||
if (blockGroup != null) return blockGroup; | |||
if (!GameState.IsBuildMode()) return null; // Breaks in simulation | |||
if (!GameClient.IsBuildMode) return null; // Breaks in simulation | |||
var bgec = BlockEngine.GetBlockInfo<BlockGroupEntityComponent>(this); | |||
return blockGroup = bgec.currentBlockGroup == -1 | |||
? null | |||
@@ -484,15 +486,15 @@ namespace TechbloxModdingAPI | |||
public static void Init() | |||
{ | |||
GameEngineManager.AddGameEngine(PlacementEngine); | |||
GameEngineManager.AddGameEngine(MovementEngine); | |||
GameEngineManager.AddGameEngine(RotationEngine); | |||
GameEngineManager.AddGameEngine(RemovalEngine); | |||
GameEngineManager.AddGameEngine(BlockEngine); | |||
GameEngineManager.AddGameEngine(BlockEventsEngine); | |||
GameEngineManager.AddGameEngine(ScalingEngine); | |||
GameEngineManager.AddGameEngine(SignalEngine); | |||
GameEngineManager.AddGameEngine(BlockCloneEngine); | |||
EngineManager.AddEngine(PlacementEngine, ApiEngineType.Build); | |||
EngineManager.AddEngine(MovementEngine, ApiEngineType.Build); | |||
EngineManager.AddEngine(RotationEngine, ApiEngineType.Build); | |||
EngineManager.AddEngine(RemovalEngine, ApiEngineType.Build); | |||
EngineManager.AddEngine(BlockEngine, ApiEngineType.Build, ApiEngineType.PlayServer, ApiEngineType.PlayClient); | |||
EngineManager.AddEngine(BlockEventsEngine, ApiEngineType.Build); | |||
EngineManager.AddEngine(ScalingEngine, ApiEngineType.Build); | |||
EngineManager.AddEngine(SignalEngine, ApiEngineType.Build); | |||
EngineManager.AddEngine(BlockCloneEngine, ApiEngineType.Build); | |||
Wire.signalEngine = SignalEngine; // requires same functionality, no need to duplicate the engine | |||
} | |||
} |
@@ -9,6 +9,7 @@ using UnityEngine; | |||
using TechbloxModdingAPI.Blocks; | |||
using TechbloxModdingAPI.Blocks.Engines; | |||
using TechbloxModdingAPI.Common.Engines; | |||
using TechbloxModdingAPI.Utility; | |||
namespace TechbloxModdingAPI | |||
@@ -149,7 +150,7 @@ namespace TechbloxModdingAPI | |||
internal static void Init() | |||
{ | |||
GameEngineManager.AddGameEngine(_engine); | |||
EngineManager.AddEngine(_engine, ApiEngineType.Build); | |||
} | |||
public IEnumerator<Block> GetEnumerator() => blocks.GetEnumerator(); | |||
@@ -23,18 +23,18 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
} | |||
/*/// <summary> - TODO: Internal struct access | |||
/// <summary> | |||
/// Gets or sets the Engine's On property. May not be saved. | |||
/// </summary> | |||
public bool On | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).engineOn; | |||
return ((bool)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "engineOn"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).engineOn = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "engineOn", value); | |||
} | |||
} | |||
@@ -45,11 +45,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentGear; | |||
return ((int)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentGear"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentGear = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentGear", value); | |||
} | |||
} | |||
@@ -60,11 +60,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).gearChangeCountdown; | |||
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "gearChangeCountdown"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).gearChangeCountdown = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "gearChangeCountdown", value); | |||
} | |||
} | |||
@@ -75,11 +75,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentRpmAV; | |||
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentRpmAV"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentRpmAV = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentRpmAV", value); | |||
} | |||
} | |||
@@ -90,11 +90,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentRpmLV; | |||
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentRpmLV"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentRpmLV = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentRpmLV", value); | |||
} | |||
} | |||
@@ -105,11 +105,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).targetRpmAV; | |||
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "targetRpmAV"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).targetRpmAV = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "targetRpmAV", value); | |||
} | |||
} | |||
@@ -120,11 +120,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).targetRpmLV; | |||
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "targetRpmLV"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).targetRpmLV = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "targetRpmLV", value); | |||
} | |||
} | |||
@@ -135,11 +135,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentTorque; | |||
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentTorque"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentTorque = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentTorque", value); | |||
} | |||
} | |||
@@ -150,11 +150,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelVelocityAV; | |||
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelVelocityAV"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelVelocityAV = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelVelocityAV", value); | |||
} | |||
} | |||
@@ -165,11 +165,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelVelocityLV; | |||
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelVelocityLV"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelVelocityLV = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelVelocityLV", value); | |||
} | |||
} | |||
@@ -180,11 +180,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelCount; | |||
return ((int)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelCount"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelCount = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelCount", value); | |||
} | |||
} | |||
@@ -195,11 +195,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).lastGearUpInput; | |||
return ((bool)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "lastGearUpInput"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).lastGearUpInput = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "lastGearUpInput", value); | |||
} | |||
} | |||
@@ -210,11 +210,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).lastGearDownInput; | |||
return ((bool)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "lastGearDownInput"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).lastGearDownInput = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "lastGearDownInput", value); | |||
} | |||
} | |||
@@ -225,11 +225,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).manualToAutoGearCoolOffCounter; | |||
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "manualToAutoGearCoolOffCounter"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).manualToAutoGearCoolOffCounter = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "manualToAutoGearCoolOffCounter", value); | |||
} | |||
} | |||
@@ -240,11 +240,11 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).load; | |||
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "load"))); | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).load = value; | |||
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "load", value); | |||
} | |||
} | |||
@@ -324,13 +324,17 @@ namespace TechbloxModdingAPI.Blocks | |||
} | |||
/// <summary> | |||
/// Gets the Engine's GearDownRpms property. May not be saved. | |||
/// Gets or sets the Engine's GearDownRpms property. May not be saved. | |||
/// </summary> | |||
public float[] GearDownRpms | |||
public Svelto.ECS.DataStructures.NativeDynamicArray GearDownRpms | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).gearDownRpms.ToManagedArray<float>(); | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).gearDownRpms; | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).gearDownRpms = value; | |||
} | |||
} | |||
@@ -377,6 +381,21 @@ namespace TechbloxModdingAPI.Blocks | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).manualToAutoGearCoolOffTime = value; | |||
} | |||
}*/ | |||
} | |||
/// <summary> | |||
/// Gets or sets the Engine's EngineBlockDataId property. May not be saved. | |||
/// </summary> | |||
public int EngineBlockDataId | |||
{ | |||
get | |||
{ | |||
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).engineBlockDataId; | |||
} | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).engineBlockDataId = value; | |||
} | |||
} | |||
} | |||
} |
@@ -1,4 +1,7 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
using Svelto.Tasks; | |||
using TechbloxModdingAPI.Client.Game; | |||
using TechbloxModdingAPI.Common.Engines; | |||
using TechbloxModdingAPI.Utility; | |||
@@ -26,6 +29,11 @@ public static class GameClient | |||
private static GameState _currentState; | |||
public static bool IsBuildMode => | |||
CurrentState is GameState.InMachineEditor or GameState.InWorldEditor; | |||
public static bool IsSimulationMode => | |||
CurrentState is GameState.InTestMode or GameState.InWorldTestMode or GameState.InOnlineMatch; | |||
/// <summary> | |||
/// An event that fires whenever the game's state changes | |||
@@ -62,10 +70,39 @@ public static class GameClient | |||
public static void EnterBuildMode(ClientEnvironment environment, ClientMachine machine) | |||
{ | |||
if (CurrentState == GameState.InMenu) | |||
throw new InvalidOperationException($"Can only enter test mode from build mode! Current mode: {CurrentState}"); | |||
var env = new ClientEnvironment("GAMEID_Road_Track"); // TODO: The options are hardcoded | |||
_engine.EnterBuildMode(env, machine); | |||
} | |||
public static IEnumerator<TaskContract> EnterTestMode() | |||
{ | |||
if (!IsBuildMode) | |||
throw new InvalidOperationException($"Can only enter test mode from build mode! Current mode: {CurrentState}"); | |||
// TODO | |||
//return Task.CompletedTask; | |||
yield break; | |||
} | |||
public static IEnumerator<TaskContract> ExitSimulationMode() | |||
{ // TODO: Separate these based on the current game state? | |||
if (!IsSimulationMode) | |||
throw new InvalidOperationException($"Can only exit test mode when in it! Current mode: {CurrentState}"); | |||
// TODO | |||
//return Task.CompletedTask; | |||
yield break; | |||
} | |||
public static IEnumerator<TaskContract> ExitBuildMode() | |||
{ | |||
if (!IsBuildMode) | |||
throw new InvalidOperationException($"Can only exit test mode when in it! Current mode: {CurrentState}"); | |||
// TODO | |||
//return Task.CompletedTask; | |||
yield break; | |||
} | |||
public static void Init() | |||
{ | |||
EngineManager.AddEngine(_engine, ApiEngineType.Menu); | |||
@@ -2,10 +2,32 @@ namespace TechbloxModdingAPI.Client.App; | |||
public enum GameState | |||
{ | |||
/// <summary> | |||
/// In the environment/game selection menu. | |||
/// </summary> | |||
InMenu, | |||
/// <summary> | |||
/// In machine editor mode in a selected environment. | |||
/// </summary> | |||
InMachineEditor, | |||
/// <summary> | |||
/// In world editor mode. | |||
/// </summary> | |||
InWorldEditor, | |||
/// <summary> | |||
/// In test mode in a selected environment. | |||
/// </summary> | |||
InTestMode, | |||
InMatch, | |||
/// <summary> | |||
/// In world test mode. | |||
/// </summary> | |||
InWorldTestMode, | |||
/// <summary> | |||
/// In an online match as a client. | |||
/// </summary> | |||
InOnlineMatch, | |||
/// <summary> | |||
/// The loading screen is active or otherwise transitioning between modes. | |||
/// </summary> | |||
Loading | |||
} |
@@ -18,7 +18,7 @@ namespace TechbloxModdingAPI.Common.Engines | |||
{ | |||
Client.App.GameClient.CurrentState = GameState.InMachineEditor; // TODO: World editor | |||
// register all game engines, including deterministic | |||
GameEngineManager.RegisterEngines(stateSyncReg); | |||
EngineManager.RegisterEngines(stateSyncReg, stateSyncReg.enginesRoot, ApiEngineType.Build); | |||
// register command engines | |||
CommandManager.RegisterEngines(stateSyncReg.enginesRoot); | |||
} | |||
@@ -35,7 +35,7 @@ namespace TechbloxModdingAPI.Common.Engines | |||
public static void Postfix(StateSyncRegistrationHelper stateSyncReg) | |||
{ | |||
Client.App.GameClient.CurrentState = GameState.InTestMode; // TODO: Client/server | |||
GameEngineManager.RegisterEngines(stateSyncReg); | |||
EngineManager.RegisterEngines(stateSyncReg, stateSyncReg.enginesRoot, ApiEngineType.PlayClient); // TODO: Client/server | |||
CommandManager.RegisterEngines(stateSyncReg.enginesRoot); | |||
} | |||
@@ -89,7 +89,7 @@ namespace TechbloxModdingAPI.Common.Engines | |||
{ | |||
Client.App.GameClient.CurrentState = GameState.InMenu; // TODO: Loaded states | |||
// register menu engines | |||
MenuEngineManager.RegisterEngines(enginesRoot); | |||
EngineManager.RegisterEngines(null, enginesRoot, ApiEngineType.Menu); | |||
} | |||
public static MethodBase TargetMethod() | |||
@@ -0,0 +1,38 @@ | |||
using System.Threading.Tasks; | |||
using RobocraftX.Schedulers; | |||
using Svelto.ECS; | |||
using Techblox.Server.Schedulers; | |||
using TechbloxModdingAPI.Common.Engines; | |||
using TechbloxModdingAPI.Utility; | |||
namespace TechbloxModdingAPI.Common.Utils; | |||
public static class AsyncUtils | |||
{ | |||
private static AsyncUtilsEngine gameEngine = new(); | |||
/// <summary> | |||
/// Waits for entity submission asynchronously. | |||
/// Use after placing a block or otherwise creating things in the game to access their properties. | |||
/// </summary> | |||
public static async Task WaitForSubmission() | |||
{ | |||
await gameEngine.WaitForSubmission(); | |||
} | |||
public static async Task WaitForNextFrame() | |||
{ | |||
await gameEngine.WaitForNextFrame(); | |||
} | |||
public static void Setup(EnginesRoot enginesRoot, bool clientside) | |||
{ | |||
gameEngine.Setup(enginesRoot, | |||
clientside ? ClientExtraLean.UIScheduler : ServerExtraLean.DeterministicTimeRunningStepRunner); | |||
} | |||
public static void Init() | |||
{ | |||
EngineManager.AddEngine(gameEngine, ApiEngineType.Build, ApiEngineType.Menu, ApiEngineType.PlayClient, ApiEngineType.PlayServer); | |||
} | |||
} |
@@ -0,0 +1,56 @@ | |||
using System.Collections; | |||
using System.Threading.Tasks; | |||
using RobocraftX.Schedulers; | |||
using Svelto.ECS; | |||
using Svelto.Tasks; | |||
using Svelto.Tasks.ExtraLean; | |||
namespace TechbloxModdingAPI.Common.Utils; | |||
public class AsyncUtilsEngine : IApiEngine | |||
{ | |||
private EnginesRoot _enginesRoot; | |||
private IRunner<ExtraLeanSveltoTask<IEnumerator>> _runner; | |||
private IEnumerator WaitForSubmissionInternal(TaskCompletionSource<object> task) | |||
{ | |||
var waitEnumerator = new WaitForSubmissionEnumerator(_enginesRoot.scheduler); | |||
while (waitEnumerator.MoveNext()) | |||
yield return null; | |||
task.SetResult(null); | |||
} | |||
private IEnumerator WaitForNextFrameInternal(TaskCompletionSource<object> task) | |||
{ | |||
yield return null; | |||
task.SetResult(null); | |||
} | |||
public Task WaitForSubmission() | |||
{ | |||
var task = new TaskCompletionSource<object>(); | |||
WaitForSubmissionInternal(task).RunOn(_runner); | |||
return task.Task; | |||
} | |||
public Task WaitForNextFrame() | |||
{ | |||
var task = new TaskCompletionSource<object>(); | |||
WaitForNextFrameInternal(task).RunOn(_runner); | |||
return task.Task; | |||
} | |||
public void Setup(EnginesRoot enginesRoot, IRunner<ExtraLeanSveltoTask<IEnumerator>> runner) | |||
{ // TODO: Different engines roots for different sides | |||
_enginesRoot = enginesRoot; | |||
_runner = runner; | |||
} | |||
public void Ready() | |||
{ | |||
} | |||
public EntitiesDB entitiesDB { get; set; } | |||
public void Dispose() | |||
{ | |||
} | |||
} |
@@ -1,6 +1,7 @@ | |||
using RobocraftX.Common.Input; | |||
using TechbloxModdingAPI.App; | |||
using TechbloxModdingAPI.Common.Engines; | |||
using TechbloxModdingAPI.Utility; | |||
namespace TechbloxModdingAPI.Input | |||
@@ -138,8 +139,7 @@ namespace TechbloxModdingAPI.Input | |||
public static void Init() | |||
{ | |||
GameEngineManager.AddGameEngine(inputEngine); | |||
MenuEngineManager.AddMenuEngine(inputEngine); | |||
EngineManager.AddEngine(inputEngine, ApiEngineType.Build, ApiEngineType.Menu, ApiEngineType.PlayClient, ApiEngineType.PlayServer); | |||
} | |||
} | |||
} |
@@ -56,9 +56,6 @@ namespace TechbloxModdingAPI | |||
try | |||
{ | |||
// init utility | |||
Logging.MetaDebugLog($"Initializing Utility"); | |||
Utility.GameState.Init(); | |||
// init block implementors | |||
Logging.MetaDebugLog($"Initializing Blocks"); | |||
// init input | |||
@@ -1,6 +1,4 @@ | |||
using System; | |||
using Svelto.ECS; | |||
using Svelto.ECS; | |||
using Svelto.ECS.Serialization; | |||
using RobocraftX.Common; | |||
@@ -12,6 +12,8 @@ using Techblox.BuildingDrone; | |||
using Techblox.Camera; | |||
using Techblox.Character; | |||
using TechbloxModdingAPI.Blocks; | |||
using TechbloxModdingAPI.Client.App; | |||
using TechbloxModdingAPI.Common.Engines; | |||
using TechbloxModdingAPI.Players; | |||
using TechbloxModdingAPI.Utility; | |||
using UnityEngine; | |||
@@ -131,10 +133,10 @@ namespace TechbloxModdingAPI | |||
/// <value>The rotation.</value> | |||
public float3 Rotation | |||
{ | |||
get => ((Quaternion) (GameState.IsBuildMode() | |||
get => ((Quaternion) (GameClient.IsBuildMode | |||
? playerEngine.GetCameraStruct<CameraEntityStruct>(Id).Get().rotation | |||
: playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().rotation)).eulerAngles; | |||
set => _ = GameState.IsBuildMode() | |||
set => _ = GameClient.IsBuildMode | |||
? playerEngine.GetCameraStruct<CameraEntityStruct>(Id).Get().rotation = quaternion.Euler(value) | |||
: playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().rotation = quaternion.Euler(value); | |||
} | |||
@@ -344,10 +346,10 @@ namespace TechbloxModdingAPI | |||
/// </summary> | |||
public bool Sprinting | |||
{ | |||
get => GameState.IsBuildMode() | |||
get => GameClient.IsBuildMode | |||
? playerEngine.GetCharacterStruct<BuildingDroneMovementComponent>(Id).Get().sprinting | |||
: playerEngine.GetCharacterStruct<CharacterMovementEntityStruct>(Id).Get().isSprinting; | |||
set => _ = GameState.IsBuildMode() | |||
set => _ = GameClient.IsBuildMode | |||
? playerEngine.GetCharacterStruct<BuildingDroneMovementComponent>(Id).Get().sprinting = value | |||
: playerEngine.GetCharacterStruct<CharacterMovementEntityStruct>(Id).Get().isSprinting = value; | |||
} | |||
@@ -357,10 +359,10 @@ namespace TechbloxModdingAPI | |||
/// </summary> | |||
public float SpeedSetting | |||
{ | |||
get => GameState.IsBuildMode() | |||
get => GameClient.IsBuildMode | |||
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speed | |||
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().moveSpeed; | |||
set => _ = GameState.IsBuildMode() | |||
set => _ = GameClient.IsBuildMode | |||
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speed = value | |||
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().moveSpeed = value; | |||
} | |||
@@ -370,10 +372,10 @@ namespace TechbloxModdingAPI | |||
/// </summary> | |||
public float SpeedSprintMultiplierSetting | |||
{ | |||
get => GameState.IsBuildMode() | |||
get => GameClient.IsBuildMode | |||
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speedSprintMultiplier | |||
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().sprintSpeedMultiplier; | |||
set => _ = GameState.IsBuildMode() | |||
set => _ = GameClient.IsBuildMode | |||
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speedSprintMultiplier = value | |||
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().sprintSpeedMultiplier = value; | |||
} | |||
@@ -383,10 +385,10 @@ namespace TechbloxModdingAPI | |||
/// </summary> | |||
public float AccelerationSetting | |||
{ | |||
get => GameState.IsBuildMode() | |||
get => GameClient.IsBuildMode | |||
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().acceleration | |||
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().acceleration; | |||
set => _ = GameState.IsBuildMode() | |||
set => _ = GameClient.IsBuildMode | |||
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().acceleration = value | |||
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().acceleration = value; | |||
} | |||
@@ -539,8 +541,9 @@ namespace TechbloxModdingAPI | |||
internal static void Init() | |||
{ | |||
Utility.GameEngineManager.AddGameEngine(playerEngine); | |||
Utility.GameEngineManager.AddGameEngine(playerEventsEngine); | |||
// TODO: Separate build mode, client and server into separate classes | |||
EngineManager.AddEngine(playerEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer); | |||
EngineManager.AddEngine(playerEventsEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer); | |||
} | |||
} | |||
} |
@@ -16,6 +16,7 @@ using Techblox.Camera; | |||
using Unity.Mathematics; | |||
using Techblox.BuildingDrone; | |||
using Techblox.Character; | |||
using TechbloxModdingAPI.Client.App; | |||
using TechbloxModdingAPI.Common.Engines; | |||
using TechbloxModdingAPI.Input; | |||
using TechbloxModdingAPI.Utility; | |||
@@ -129,7 +130,7 @@ namespace TechbloxModdingAPI.Players | |||
public OptionalRef<T> GetCharacterStruct<T>(uint playerId, out ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent | |||
{ | |||
group = default; | |||
if (GameState.IsBuildMode()) | |||
if (GameClient.IsBuildMode) | |||
return entitiesDB.QueryEntityOptional<T>(new EGID(playerId, LocalBuildingDrone.BuildGroup)); | |||
var characterGroups = CharacterExclusiveGroups.AllCharacters; | |||
@@ -9,6 +9,7 @@ using Svelto.Tasks.Lean; | |||
using Svelto.Tasks.Enumerators; | |||
using Svelto.Tasks.Lean.Unity; | |||
using TechbloxModdingAPI.Client.App; | |||
using TechbloxModdingAPI.Client.Game; | |||
using UnityEngine; | |||
using TechbloxModdingAPI.Tasks; | |||
@@ -155,7 +156,7 @@ namespace TechbloxModdingAPI.Tests | |||
yield return Yield.It; | |||
try | |||
{ | |||
GameClient.Machines[0].EnterGame(); | |||
GameClient.EnterBuildMode(new ClientEnvironment("GAMEID_Road_Track"), GameClient.Machines[0]); | |||
} | |||
catch (Exception e) | |||
{ | |||
@@ -170,7 +171,6 @@ namespace TechbloxModdingAPI.Tests | |||
private static IEnumerator<TaskContract> GameTests() | |||
{ | |||
yield return Yield.It; | |||
Game currentGame = Game.CurrentGame(); | |||
// in-game tests | |||
yield return new WaitForSecondsEnumerator(5).Continue(); // wait for game to finish loading | |||
var testTypesToRun = new[] | |||
@@ -225,13 +225,9 @@ 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(); | |||
} | |||
bool running = GameClient.IsSimulationMode; | |||
if (running) yield return GameClient.EnterTestMode().Continue(); | |||
else yield return GameClient.ExitSimulationMode().Continue(); | |||
} | |||
yield return new WaitForSecondsEnumerator(5).Continue(); | |||
@@ -244,7 +240,7 @@ namespace TechbloxModdingAPI.Tests | |||
{ | |||
Logging.MetaLog("Returning to main menu"); | |||
yield return Yield.It; | |||
Game.CurrentGame().ExitGame(); | |||
yield return GameClient.ExitSimulationMode().Continue(); | |||
} | |||
private static IEnumerator<TaskContract> TearDown() | |||
@@ -1,82 +0,0 @@ | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using RobocraftX.StateSync; | |||
using Svelto.ECS; | |||
using TechbloxModdingAPI.Common; | |||
using TechbloxModdingAPI.Common.Engines; | |||
namespace TechbloxModdingAPI.Utility | |||
{ | |||
/// <summary> | |||
/// Keeps track of custom game-modifying engines | |||
/// </summary> | |||
public static class GameEngineManager | |||
{ | |||
private static Dictionary<string, IApiEngine> _gameEngines = new(); | |||
private static EnginesRoot _lastEngineRoot; | |||
public static void AddGameEngine(IApiEngine engine) | |||
{ | |||
_gameEngines[engine.Name] = engine; | |||
if (_lastEngineRoot != null) | |||
{ | |||
Logging.MetaDebugLog($"Registering Game IApiEngine {engine.Name}"); | |||
_lastEngineRoot.AddEngine(engine); | |||
if (engine is IFactoryEngine factoryEngine) | |||
factoryEngine.Factory = _lastEngineRoot.GenerateEntityFactory(); | |||
if (engine is IFunEngine funEngine) | |||
funEngine.Functions = _lastEngineRoot.GenerateEntityFunctions(); | |||
} | |||
} | |||
public static bool ExistsGameEngine(string name) | |||
{ | |||
return _gameEngines.ContainsKey(name); | |||
} | |||
public static bool ExistsGameEngine(IApiEngine engine) | |||
{ | |||
return ExistsGameEngine(engine.Name); | |||
} | |||
public static IApiEngine GetGameEngine(string name) | |||
{ | |||
return _gameEngines[name]; | |||
} | |||
public static string[] GetGameEngineNames() | |||
{ | |||
return _gameEngines.Keys.ToArray(); | |||
} | |||
public static void RemoveGameEngine(string name) | |||
{ | |||
if (_gameEngines[name].isRemovable) | |||
{ | |||
_gameEngines.Remove(name); | |||
} | |||
} | |||
public static void RegisterEngines(StateSyncRegistrationHelper helper) | |||
{ | |||
var enginesRoot = helper.enginesRoot; | |||
_lastEngineRoot = enginesRoot; | |||
IEntityFactory factory = enginesRoot.GenerateEntityFactory(); | |||
IEntityFunctions functions = enginesRoot.GenerateEntityFunctions(); | |||
foreach (var key in _gameEngines.Keys) | |||
{ | |||
Logging.MetaDebugLog($"Registering Game IApiEngine {_gameEngines[key].Name}"); | |||
if (_gameEngines[key] is IDeterministicEngine detEngine) | |||
helper.AddDeterministicEngine(detEngine); | |||
else | |||
enginesRoot.AddEngine(_gameEngines[key]); | |||
if (_gameEngines[key] is IFactoryEngine factEngine) | |||
factEngine.Factory = factory; | |||
if (_gameEngines[key] is IFunEngine funEngine) | |||
funEngine.Functions = functions; | |||
} | |||
} | |||
} | |||
} |
@@ -1,48 +0,0 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace TechbloxModdingAPI.Utility | |||
{ | |||
/// <summary> | |||
/// Utility to get the state of the current Techblox game | |||
/// </summary> | |||
public static class GameState | |||
{ | |||
private static GameStateEngine gameEngine = new(); | |||
/// <summary> | |||
/// Is the game in edit mode? | |||
/// </summary> | |||
/// <returns>Whether the game is in build mode</returns> | |||
public static bool IsBuildMode() | |||
{ | |||
return gameEngine.IsBuildMode(); | |||
} | |||
/// <summary> | |||
/// Is the game in simulation mode? | |||
/// </summary> | |||
/// <returns>Whether the game is in simulation mode</returns> | |||
public static bool IsSimulationMode() | |||
{ | |||
return gameEngine.IsSimulationMode(); | |||
} | |||
/// <summary> | |||
/// Is a game loaded? | |||
/// </summary> | |||
/// <returns>Whether Techblox has a game open (false = Main Menu)</returns> | |||
public static bool IsInGame() | |||
{ | |||
return gameEngine.IsInGame; | |||
} | |||
public static void Init() | |||
{ | |||
GameEngineManager.AddGameEngine(gameEngine); | |||
} | |||
} | |||
} |
@@ -1,75 +0,0 @@ | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using Svelto.ECS; | |||
using TechbloxModdingAPI.Common; | |||
using TechbloxModdingAPI.Common.Engines; | |||
namespace TechbloxModdingAPI.Utility | |||
{ | |||
/// <summary> | |||
/// Keeps track of custom menu-modifying engines | |||
/// </summary> | |||
public static class MenuEngineManager | |||
{ | |||
private static Dictionary<string, IApiEngine> _menuEngines = new(); | |||
private static EnginesRoot _lastEngineRoot; | |||
// menu engine management | |||
public static void AddMenuEngine(IApiEngine engine) | |||
{ | |||
_menuEngines[engine.Name] = engine; | |||
if (_lastEngineRoot != null) | |||
{ | |||
Logging.MetaDebugLog($"Registering Menu IApiEngine {engine.Name}"); | |||
_lastEngineRoot.AddEngine(engine); | |||
if (engine is IFactoryEngine factoryEngine) | |||
factoryEngine.Factory = _lastEngineRoot.GenerateEntityFactory(); | |||
if (engine is IFunEngine funEngine) | |||
funEngine.Functions = _lastEngineRoot.GenerateEntityFunctions(); | |||
} | |||
} | |||
public static bool ExistsMenuEngine(string name) | |||
{ | |||
return _menuEngines.ContainsKey(name); | |||
} | |||
public static bool ExistsMenuEngine(IApiEngine engine) | |||
{ | |||
return ExistsMenuEngine(engine.Name); | |||
} | |||
public static IApiEngine GetMenuEngine(string name) | |||
{ | |||
return _menuEngines[name]; | |||
} | |||
public static string[] GetMenuEngineNames() | |||
{ | |||
return _menuEngines.Keys.ToArray(); | |||
} | |||
public static void RemoveMenuEngine(string name) | |||
{ | |||
if (_menuEngines[name].isRemovable) | |||
{ | |||
_menuEngines.Remove(name); | |||
} | |||
} | |||
public static void RegisterEngines(EnginesRoot enginesRoot) | |||
{ | |||
_lastEngineRoot = enginesRoot; | |||
IEntityFactory factory = enginesRoot.GenerateEntityFactory(); | |||
IEntityFunctions functions = enginesRoot.GenerateEntityFunctions(); | |||
foreach (var key in _menuEngines.Keys) | |||
{ | |||
Logging.MetaDebugLog($"Registering Menu IApiEngine {_menuEngines[key].Name}"); | |||
enginesRoot.AddEngine(_menuEngines[key]); | |||
if (_menuEngines[key] is IFactoryEngine factEngine) factEngine.Factory = factory; | |||
if(_menuEngines[key] is IFunEngine funEngine) funEngine.Functions = functions; | |||
} | |||
} | |||
} | |||
} |