Re-add async stuff, use new engine manager everywhere

This commit is contained in:
Norbi Peti 2023-10-08 01:13:12 +02:00
parent 8a52095263
commit 27218aeb8d
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
20 changed files with 264 additions and 298 deletions

View file

@ -20,8 +20,8 @@ namespace TechbloxModdingAPI.App
Game.Exit += Assert.CallsBack<GameEventArgs>("GameExit"); Game.Exit += Assert.CallsBack<GameEventArgs>("GameExit");
Game.Simulate += Assert.CallsBack<GameEventArgs>("GameSimulate"); Game.Simulate += Assert.CallsBack<GameEventArgs>("GameSimulate");
Game.Edit += Assert.CallsBack<GameEventArgs>("GameEdit"); Game.Edit += Assert.CallsBack<GameEventArgs>("GameEdit");
Client.EnterMenu += Assert.CallsBack<MenuEventArgs>("MenuEnter"); /*Client.EnterMenu += Assert.CallsBack<MenuEventArgs>("MenuEnter");
Client.ExitMenu += Assert.CallsBack<MenuEventArgs>("MenuExit"); Client.ExitMenu += Assert.CallsBack<MenuEventArgs>("MenuExit");*/
} }
[APITestCase(TestType.Game)] [APITestCase(TestType.Game)]

View file

@ -2,7 +2,7 @@ using System;
using HarmonyLib; using HarmonyLib;
using RobocraftX.Services; using RobocraftX.Services;
using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Tests; using TechbloxModdingAPI.Tests;
namespace TechbloxModdingAPI.App namespace TechbloxModdingAPI.App
@ -42,25 +42,25 @@ namespace TechbloxModdingAPI.App
[APITestCase(TestType.Menu)] [APITestCase(TestType.Menu)]
public static void TestPopUp2() public static void TestPopUp2()
{ {
Client.Instance.PromptUser(popup2); Popup.PromptUser(popup2);
} }
[APITestCase(TestType.Menu)] [APITestCase(TestType.Menu)]
public static void TestPopUp1() public static void TestPopUp1()
{ {
Client.Instance.PromptUser(popup1); Popup.PromptUser(popup1);
} }
[APITestCase(TestType.Menu)] [APITestCase(TestType.Menu)]
public static void TestPopUpClose1() public static void TestPopUpClose1()
{ {
Client.Instance.CloseCurrentPrompt(); Popup.CloseCurrentPrompt();
} }
[APITestCase(TestType.Menu)] [APITestCase(TestType.Menu)]
public static void TestPopUpClose2() public static void TestPopUpClose2()
{ {
Client.Instance.CloseCurrentPrompt(); Popup.CloseCurrentPrompt();
} }
} }
#endif #endif

View file

@ -7,6 +7,7 @@ using Svelto.ECS;
using Techblox.GameSelection; using Techblox.GameSelection;
using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Tasks; using TechbloxModdingAPI.Tasks;
using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility;
@ -481,10 +482,10 @@ namespace TechbloxModdingAPI.App
internal static void Init() internal static void Init()
{ {
GameEngineManager.AddGameEngine(gameEngine); EngineManager.AddEngine(gameEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
GameEngineManager.AddGameEngine(debugOverlayEngine); EngineManager.AddEngine(debugOverlayEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
GameEngineManager.AddGameEngine(buildSimEventEngine); EngineManager.AddEngine(buildSimEventEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
MenuEngineManager.AddMenuEngine(menuEngine); EngineManager.AddEngine(menuEngine, ApiEngineType.Menu);
} }
} }
} }

View file

@ -14,6 +14,8 @@ using RobocraftX.Rendering;
using Techblox.BlockLabelsServer; using Techblox.BlockLabelsServer;
using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Blocks.Engines; using TechbloxModdingAPI.Blocks.Engines;
using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Tests; using TechbloxModdingAPI.Tests;
using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility;
@ -48,7 +50,7 @@ namespace TechbloxModdingAPI
/// <returns>The placed block or null if failed</returns> /// <returns>The placed block or null if failed</returns>
public static Block PlaceNew(BlockIDs block, float3 position, bool autoWire = false, Player player = null) 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 initializer = PlacementEngine.PlaceBlock(block, position, player, autoWire);
var egid = initializer.EGID; var egid = initializer.EGID;
@ -346,7 +348,7 @@ namespace TechbloxModdingAPI
get get
{ {
if (blockGroup != null) return blockGroup; 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); var bgec = BlockEngine.GetBlockInfo<BlockGroupEntityComponent>(this);
return blockGroup = bgec.currentBlockGroup == -1 return blockGroup = bgec.currentBlockGroup == -1
? null ? null
@ -484,15 +486,15 @@ namespace TechbloxModdingAPI
public static void Init() public static void Init()
{ {
GameEngineManager.AddGameEngine(PlacementEngine); EngineManager.AddEngine(PlacementEngine, ApiEngineType.Build);
GameEngineManager.AddGameEngine(MovementEngine); EngineManager.AddEngine(MovementEngine, ApiEngineType.Build);
GameEngineManager.AddGameEngine(RotationEngine); EngineManager.AddEngine(RotationEngine, ApiEngineType.Build);
GameEngineManager.AddGameEngine(RemovalEngine); EngineManager.AddEngine(RemovalEngine, ApiEngineType.Build);
GameEngineManager.AddGameEngine(BlockEngine); EngineManager.AddEngine(BlockEngine, ApiEngineType.Build, ApiEngineType.PlayServer, ApiEngineType.PlayClient);
GameEngineManager.AddGameEngine(BlockEventsEngine); EngineManager.AddEngine(BlockEventsEngine, ApiEngineType.Build);
GameEngineManager.AddGameEngine(ScalingEngine); EngineManager.AddEngine(ScalingEngine, ApiEngineType.Build);
GameEngineManager.AddGameEngine(SignalEngine); EngineManager.AddEngine(SignalEngine, ApiEngineType.Build);
GameEngineManager.AddGameEngine(BlockCloneEngine); EngineManager.AddEngine(BlockCloneEngine, ApiEngineType.Build);
Wire.signalEngine = SignalEngine; // requires same functionality, no need to duplicate the engine Wire.signalEngine = SignalEngine; // requires same functionality, no need to duplicate the engine
} }
} }

View file

@ -9,6 +9,7 @@ using UnityEngine;
using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Blocks.Engines; using TechbloxModdingAPI.Blocks.Engines;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility;
namespace TechbloxModdingAPI namespace TechbloxModdingAPI
@ -149,7 +150,7 @@ namespace TechbloxModdingAPI
internal static void Init() internal static void Init()
{ {
GameEngineManager.AddGameEngine(_engine); EngineManager.AddEngine(_engine, ApiEngineType.Build);
} }
public IEnumerator<Block> GetEnumerator() => blocks.GetEnumerator(); public IEnumerator<Block> GetEnumerator() => blocks.GetEnumerator();

View file

@ -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. /// Gets or sets the Engine's On property. May not be saved.
/// </summary> /// </summary>
public bool On public bool On
{ {
get get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).engineOn; return ((bool)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "engineOn")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentGear; return ((int)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentGear")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).gearChangeCountdown; return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "gearChangeCountdown")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentRpmAV; return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentRpmAV")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentRpmLV; return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentRpmLV")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).targetRpmAV; return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "targetRpmAV")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).targetRpmLV; return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "targetRpmLV")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentTorque; return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentTorque")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelVelocityAV; return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelVelocityAV")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelVelocityLV; return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelVelocityLV")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelCount; return ((int)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelCount")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).lastGearUpInput; return ((bool)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "lastGearUpInput")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).lastGearDownInput; return ((bool)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "lastGearDownInput")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).manualToAutoGearCoolOffCounter; return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "manualToAutoGearCoolOffCounter")));
} }
set 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 get
{ {
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).load; return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "load")));
} }
set 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> /// <summary>
/// Gets the Engine's GearDownRpms property. May not be saved. /// Gets or sets the Engine's GearDownRpms property. May not be saved.
/// </summary> /// </summary>
public float[] GearDownRpms public Svelto.ECS.DataStructures.NativeDynamicArray GearDownRpms
{ {
get 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; 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;
}
}
} }
} }

View file

@ -1,4 +1,7 @@
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Svelto.Tasks;
using TechbloxModdingAPI.Client.Game; using TechbloxModdingAPI.Client.Game;
using TechbloxModdingAPI.Common.Engines; using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility;
@ -26,6 +29,11 @@ public static class GameClient
private static GameState _currentState; 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> /// <summary>
/// An event that fires whenever the game's state changes /// 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) 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 var env = new ClientEnvironment("GAMEID_Road_Track"); // TODO: The options are hardcoded
_engine.EnterBuildMode(env, machine); _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() public static void Init()
{ {
EngineManager.AddEngine(_engine, ApiEngineType.Menu); EngineManager.AddEngine(_engine, ApiEngineType.Menu);

View file

@ -2,10 +2,32 @@ namespace TechbloxModdingAPI.Client.App;
public enum GameState public enum GameState
{ {
/// <summary>
/// In the environment/game selection menu.
/// </summary>
InMenu, InMenu,
/// <summary>
/// In machine editor mode in a selected environment.
/// </summary>
InMachineEditor, InMachineEditor,
/// <summary>
/// In world editor mode.
/// </summary>
InWorldEditor, InWorldEditor,
/// <summary>
/// In test mode in a selected environment.
/// </summary>
InTestMode, 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 Loading
} }

View file

@ -18,7 +18,7 @@ namespace TechbloxModdingAPI.Common.Engines
{ {
Client.App.GameClient.CurrentState = GameState.InMachineEditor; // TODO: World editor Client.App.GameClient.CurrentState = GameState.InMachineEditor; // TODO: World editor
// register all game engines, including deterministic // register all game engines, including deterministic
GameEngineManager.RegisterEngines(stateSyncReg); EngineManager.RegisterEngines(stateSyncReg, stateSyncReg.enginesRoot, ApiEngineType.Build);
// register command engines // register command engines
CommandManager.RegisterEngines(stateSyncReg.enginesRoot); CommandManager.RegisterEngines(stateSyncReg.enginesRoot);
} }
@ -35,7 +35,7 @@ namespace TechbloxModdingAPI.Common.Engines
public static void Postfix(StateSyncRegistrationHelper stateSyncReg) public static void Postfix(StateSyncRegistrationHelper stateSyncReg)
{ {
Client.App.GameClient.CurrentState = GameState.InTestMode; // TODO: Client/server 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); CommandManager.RegisterEngines(stateSyncReg.enginesRoot);
} }
@ -89,7 +89,7 @@ namespace TechbloxModdingAPI.Common.Engines
{ {
Client.App.GameClient.CurrentState = GameState.InMenu; // TODO: Loaded states Client.App.GameClient.CurrentState = GameState.InMenu; // TODO: Loaded states
// register menu engines // register menu engines
MenuEngineManager.RegisterEngines(enginesRoot); EngineManager.RegisterEngines(null, enginesRoot, ApiEngineType.Menu);
} }
public static MethodBase TargetMethod() public static MethodBase TargetMethod()

View file

@ -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);
}
}

View file

@ -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()
{
}
}

View file

@ -1,6 +1,7 @@
using RobocraftX.Common.Input; using RobocraftX.Common.Input;
using TechbloxModdingAPI.App; using TechbloxModdingAPI.App;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility;
namespace TechbloxModdingAPI.Input namespace TechbloxModdingAPI.Input
@ -138,8 +139,7 @@ namespace TechbloxModdingAPI.Input
public static void Init() public static void Init()
{ {
GameEngineManager.AddGameEngine(inputEngine); EngineManager.AddEngine(inputEngine, ApiEngineType.Build, ApiEngineType.Menu, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
MenuEngineManager.AddMenuEngine(inputEngine);
} }
} }
} }

View file

@ -56,9 +56,6 @@ namespace TechbloxModdingAPI
try try
{ {
// init utility
Logging.MetaDebugLog($"Initializing Utility");
Utility.GameState.Init();
// init block implementors // init block implementors
Logging.MetaDebugLog($"Initializing Blocks"); Logging.MetaDebugLog($"Initializing Blocks");
// init input // init input

View file

@ -1,6 +1,4 @@
using System; using Svelto.ECS;
using Svelto.ECS;
using Svelto.ECS.Serialization; using Svelto.ECS.Serialization;
using RobocraftX.Common; using RobocraftX.Common;

View file

@ -12,6 +12,8 @@ using Techblox.BuildingDrone;
using Techblox.Camera; using Techblox.Camera;
using Techblox.Character; using Techblox.Character;
using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Players; using TechbloxModdingAPI.Players;
using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility;
using UnityEngine; using UnityEngine;
@ -131,10 +133,10 @@ namespace TechbloxModdingAPI
/// <value>The rotation.</value> /// <value>The rotation.</value>
public float3 Rotation public float3 Rotation
{ {
get => ((Quaternion) (GameState.IsBuildMode() get => ((Quaternion) (GameClient.IsBuildMode
? playerEngine.GetCameraStruct<CameraEntityStruct>(Id).Get().rotation ? playerEngine.GetCameraStruct<CameraEntityStruct>(Id).Get().rotation
: playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().rotation)).eulerAngles; : playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().rotation)).eulerAngles;
set => _ = GameState.IsBuildMode() set => _ = GameClient.IsBuildMode
? playerEngine.GetCameraStruct<CameraEntityStruct>(Id).Get().rotation = quaternion.Euler(value) ? playerEngine.GetCameraStruct<CameraEntityStruct>(Id).Get().rotation = quaternion.Euler(value)
: playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().rotation = quaternion.Euler(value); : playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().rotation = quaternion.Euler(value);
} }
@ -344,10 +346,10 @@ namespace TechbloxModdingAPI
/// </summary> /// </summary>
public bool Sprinting public bool Sprinting
{ {
get => GameState.IsBuildMode() get => GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementComponent>(Id).Get().sprinting ? playerEngine.GetCharacterStruct<BuildingDroneMovementComponent>(Id).Get().sprinting
: playerEngine.GetCharacterStruct<CharacterMovementEntityStruct>(Id).Get().isSprinting; : playerEngine.GetCharacterStruct<CharacterMovementEntityStruct>(Id).Get().isSprinting;
set => _ = GameState.IsBuildMode() set => _ = GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementComponent>(Id).Get().sprinting = value ? playerEngine.GetCharacterStruct<BuildingDroneMovementComponent>(Id).Get().sprinting = value
: playerEngine.GetCharacterStruct<CharacterMovementEntityStruct>(Id).Get().isSprinting = value; : playerEngine.GetCharacterStruct<CharacterMovementEntityStruct>(Id).Get().isSprinting = value;
} }
@ -357,10 +359,10 @@ namespace TechbloxModdingAPI
/// </summary> /// </summary>
public float SpeedSetting public float SpeedSetting
{ {
get => GameState.IsBuildMode() get => GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speed ? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speed
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().moveSpeed; : playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().moveSpeed;
set => _ = GameState.IsBuildMode() set => _ = GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speed = value ? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speed = value
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().moveSpeed = value; : playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().moveSpeed = value;
} }
@ -370,10 +372,10 @@ namespace TechbloxModdingAPI
/// </summary> /// </summary>
public float SpeedSprintMultiplierSetting public float SpeedSprintMultiplierSetting
{ {
get => GameState.IsBuildMode() get => GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speedSprintMultiplier ? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speedSprintMultiplier
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().sprintSpeedMultiplier; : playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().sprintSpeedMultiplier;
set => _ = GameState.IsBuildMode() set => _ = GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speedSprintMultiplier = value ? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speedSprintMultiplier = value
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().sprintSpeedMultiplier = value; : playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().sprintSpeedMultiplier = value;
} }
@ -383,10 +385,10 @@ namespace TechbloxModdingAPI
/// </summary> /// </summary>
public float AccelerationSetting public float AccelerationSetting
{ {
get => GameState.IsBuildMode() get => GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().acceleration ? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().acceleration
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().acceleration; : playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().acceleration;
set => _ = GameState.IsBuildMode() set => _ = GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().acceleration = value ? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().acceleration = value
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().acceleration = value; : playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().acceleration = value;
} }
@ -539,8 +541,9 @@ namespace TechbloxModdingAPI
internal static void Init() internal static void Init()
{ {
Utility.GameEngineManager.AddGameEngine(playerEngine); // TODO: Separate build mode, client and server into separate classes
Utility.GameEngineManager.AddGameEngine(playerEventsEngine); EngineManager.AddEngine(playerEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
EngineManager.AddEngine(playerEventsEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
} }
} }
} }

View file

@ -16,6 +16,7 @@ using Techblox.Camera;
using Unity.Mathematics; using Unity.Mathematics;
using Techblox.BuildingDrone; using Techblox.BuildingDrone;
using Techblox.Character; using Techblox.Character;
using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Common.Engines; using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Input; using TechbloxModdingAPI.Input;
using TechbloxModdingAPI.Utility; using TechbloxModdingAPI.Utility;
@ -129,7 +130,7 @@ namespace TechbloxModdingAPI.Players
public OptionalRef<T> GetCharacterStruct<T>(uint playerId, out ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent public OptionalRef<T> GetCharacterStruct<T>(uint playerId, out ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent
{ {
group = default; group = default;
if (GameState.IsBuildMode()) if (GameClient.IsBuildMode)
return entitiesDB.QueryEntityOptional<T>(new EGID(playerId, LocalBuildingDrone.BuildGroup)); return entitiesDB.QueryEntityOptional<T>(new EGID(playerId, LocalBuildingDrone.BuildGroup));
var characterGroups = CharacterExclusiveGroups.AllCharacters; var characterGroups = CharacterExclusiveGroups.AllCharacters;

View file

@ -9,6 +9,7 @@ using Svelto.Tasks.Lean;
using Svelto.Tasks.Enumerators; using Svelto.Tasks.Enumerators;
using Svelto.Tasks.Lean.Unity; using Svelto.Tasks.Lean.Unity;
using TechbloxModdingAPI.Client.App; using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Client.Game;
using UnityEngine; using UnityEngine;
using TechbloxModdingAPI.Tasks; using TechbloxModdingAPI.Tasks;
@ -155,7 +156,7 @@ namespace TechbloxModdingAPI.Tests
yield return Yield.It; yield return Yield.It;
try try
{ {
GameClient.Machines[0].EnterGame(); GameClient.EnterBuildMode(new ClientEnvironment("GAMEID_Road_Track"), GameClient.Machines[0]);
} }
catch (Exception e) catch (Exception e)
{ {
@ -170,7 +171,6 @@ namespace TechbloxModdingAPI.Tests
private static IEnumerator<TaskContract> GameTests() private static IEnumerator<TaskContract> GameTests()
{ {
yield return Yield.It; yield return Yield.It;
Game currentGame = Game.CurrentGame();
// in-game tests // in-game tests
yield return new WaitForSecondsEnumerator(5).Continue(); // wait for game to finish loading yield return new WaitForSecondsEnumerator(5).Continue(); // wait for game to finish loading
var testTypesToRun = new[] var testTypesToRun = new[]
@ -225,13 +225,9 @@ namespace TechbloxModdingAPI.Tests
if (index + 1 < testTypesToRun.Length) //Don't toggle on the last test if (index + 1 < testTypesToRun.Length) //Don't toggle on the last test
{ {
bool running = currentGame.IsTimeRunning; bool running = GameClient.IsSimulationMode;
currentGame.ToggleTimeMode(); if (running) yield return GameClient.EnterTestMode().Continue();
while (running ? !currentGame.IsTimeStopped : !currentGame.IsTimeRunning) else yield return GameClient.ExitSimulationMode().Continue();
{
Logging.MetaLog($"Waiting for time to {(running?"stop":"start")}...");
yield return new WaitForSecondsEnumerator(1).Continue();
}
} }
yield return new WaitForSecondsEnumerator(5).Continue(); yield return new WaitForSecondsEnumerator(5).Continue();
@ -244,7 +240,7 @@ namespace TechbloxModdingAPI.Tests
{ {
Logging.MetaLog("Returning to main menu"); Logging.MetaLog("Returning to main menu");
yield return Yield.It; yield return Yield.It;
Game.CurrentGame().ExitGame(); yield return GameClient.ExitSimulationMode().Continue();
} }
private static IEnumerator<TaskContract> TearDown() private static IEnumerator<TaskContract> TearDown()

View file

@ -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;
}
}
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
}
}
}