Merge branch 'preview'
# Conflicts: # Automation/gen_csproj.py # TechbloxModdingAPI/TechbloxModdingAPI.csproj
This commit is contained in:
commit
09d3c5e81c
43 changed files with 623 additions and 317 deletions
56
TechbloxModdingAPI/App/AntiAntiCheatPatch.cs
Normal file
56
TechbloxModdingAPI/App/AntiAntiCheatPatch.cs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HarmonyLib;
|
||||||
|
using Svelto.Tasks;
|
||||||
|
|
||||||
|
namespace TechbloxModdingAPI.App
|
||||||
|
{
|
||||||
|
public static class AntiAntiCheatPatch
|
||||||
|
{
|
||||||
|
private delegate bool AntiAnticheatDelegate(ref object __result);
|
||||||
|
|
||||||
|
private delegate bool AntiAnticheatDelegateBool(ref bool __result);
|
||||||
|
|
||||||
|
private delegate bool AntiAnticheatDelegateTask(ref IEnumerator<TaskContract> __result);
|
||||||
|
|
||||||
|
public static void Init(Harmony harmony)
|
||||||
|
{
|
||||||
|
var type = AccessTools.TypeByName("Techblox.Services.Eos.Anticheat.Client.Services.AnticheatClientService");
|
||||||
|
harmony.Patch(type.GetConstructors()[0], new HarmonyMethod(((Func<bool>) AntiAntiCheat).Method));
|
||||||
|
harmony.Patch(AccessTools.Method(type, "Shutdown"), new HarmonyMethod(((Func<bool>) AntiAntiCheat).Method));
|
||||||
|
harmony.Patch(AccessTools.Method(type, "StartProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegate) AntiAntiCheat).Method));
|
||||||
|
harmony.Patch(AccessTools.Method(type, "StopProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegateBool) AntiAntiCheat).Method));
|
||||||
|
harmony.Patch(AccessTools.Method("Techblox.Services.Eos.Anticheat.Client.EosGetPendingMessagesToSendServiceRequest:Execute"), new HarmonyMethod(((AntiAnticheatDelegateTask)AntiAntiCheatTask).Method));
|
||||||
|
harmony.Patch(AccessTools.Method("Techblox.Anticheat.Client.Engines.ShowFeedbackDialogEngine:PollAnticheatStatus"), new HarmonyMethod(((AntiAnticheatDelegateTask)AntiAntiCheatTask).Method));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool AntiAntiCheat() => false;
|
||||||
|
|
||||||
|
private static bool AntiAntiCheat(ref object __result)
|
||||||
|
{
|
||||||
|
var targetType =
|
||||||
|
AccessTools.TypeByName("Techblox.Services.Eos.Anticheat.Client.Services.StartProtectedSessionResult");
|
||||||
|
var target = Activator.CreateInstance(targetType);
|
||||||
|
targetType.GetField("Success").SetValue(target, true);
|
||||||
|
__result = target;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool AntiAntiCheat(ref bool __result)
|
||||||
|
{
|
||||||
|
__result = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool AntiAntiCheatTask(ref IEnumerator<TaskContract> __result)
|
||||||
|
{
|
||||||
|
IEnumerator<TaskContract> Func()
|
||||||
|
{
|
||||||
|
yield return Yield.It;
|
||||||
|
}
|
||||||
|
|
||||||
|
__result = Func();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,44 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
using RobocraftX.GUI.MyGamesScreen;
|
|
||||||
using Svelto.ECS;
|
|
||||||
using TechbloxModdingAPI.Engines;
|
|
||||||
using TechbloxModdingAPI.Utility;
|
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.App
|
|
||||||
{
|
|
||||||
public class AppEngine : IFactoryEngine
|
|
||||||
{
|
|
||||||
public WrappedHandler<MenuEventArgs> EnterMenu;
|
|
||||||
|
|
||||||
public WrappedHandler<MenuEventArgs> ExitMenu;
|
|
||||||
|
|
||||||
public IEntityFactory Factory { set; private get; }
|
|
||||||
|
|
||||||
public string Name => "TechbloxModdingAPIAppEngine";
|
|
||||||
|
|
||||||
public bool isRemovable => false;
|
|
||||||
|
|
||||||
public EntitiesDB entitiesDB { set; private get; }
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
IsInMenu = false;
|
|
||||||
ExitMenu.Invoke(this, new MenuEventArgs { });
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
|
||||||
IsInMenu = true;
|
|
||||||
EnterMenu.Invoke(this, new MenuEventArgs { });
|
|
||||||
}
|
|
||||||
|
|
||||||
// app functionality
|
|
||||||
|
|
||||||
public bool IsInMenu
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
} = false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,12 +14,12 @@ namespace TechbloxModdingAPI.App
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Client
|
public class Client
|
||||||
{
|
{
|
||||||
|
public static Client Instance { get; } = new Client();
|
||||||
|
|
||||||
protected static Func<object> ErrorHandlerInstanceGetter;
|
protected static Func<object> ErrorHandlerInstanceGetter;
|
||||||
|
|
||||||
protected static Action<object, Error> EnqueueError;
|
protected static Action<object, Error> EnqueueError;
|
||||||
|
|
||||||
protected static Action<object> HandleErrorClosed;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An event that fires whenever the main menu is loaded.
|
/// An event that fires whenever the main menu is loaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -93,14 +93,31 @@ namespace TechbloxModdingAPI.App
|
||||||
EnqueueError(errorHandlerInstance, popup);
|
EnqueueError(errorHandlerInstance, popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
public void CloseCurrentPrompt()
|
||||||
/*public void CloseCurrentPrompt()
|
|
||||||
{
|
{
|
||||||
// RobocraftX.Services.ErrorHandler.Instance.HandlePopupClosed();
|
|
||||||
// FIXME: this is a call that is also called when closing, not the actual closing action itself (so it doesn't work)
|
|
||||||
object errorHandlerInstance = ErrorHandlerInstanceGetter();
|
object errorHandlerInstance = ErrorHandlerInstanceGetter();
|
||||||
HandleErrorClosed(errorHandlerInstance);
|
var popup = GetPopupCloseMethods(errorHandlerInstance);
|
||||||
}*/
|
popup.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectFirstPromptButton()
|
||||||
|
{
|
||||||
|
object errorHandlerInstance = ErrorHandlerInstanceGetter();
|
||||||
|
var popup = GetPopupCloseMethods(errorHandlerInstance);
|
||||||
|
popup.FirstButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectSecondPromptButton()
|
||||||
|
{
|
||||||
|
object errorHandlerInstance = ErrorHandlerInstanceGetter();
|
||||||
|
var popup = GetPopupCloseMethods(errorHandlerInstance);
|
||||||
|
popup.SecondButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void CloseBetaPopup()
|
||||||
|
{
|
||||||
|
Game.menuEngine.CloseBetaPopup();
|
||||||
|
}
|
||||||
|
|
||||||
internal static void Init()
|
internal static void Init()
|
||||||
{
|
{
|
||||||
|
@ -113,9 +130,6 @@ namespace TechbloxModdingAPI.App
|
||||||
EnqueueError = (Action<object, Error>) AccessTools.Method("TechbloxModdingAPI.App.Client:GenEnqueueError")
|
EnqueueError = (Action<object, Error>) AccessTools.Method("TechbloxModdingAPI.App.Client:GenEnqueueError")
|
||||||
.MakeGenericMethod(errorHandler, errorHandle)
|
.MakeGenericMethod(errorHandler, errorHandle)
|
||||||
.Invoke(null, new object[0]);
|
.Invoke(null, new object[0]);
|
||||||
/*HandleErrorClosed = (Action<object>) AccessTools.Method("TechbloxModdingAPI.App.Client:GenHandlePopupClosed")
|
|
||||||
.MakeGenericMethod(errorHandler)
|
|
||||||
.Invoke(null, new object[0]);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creating delegates once is faster than reflection every time
|
// Creating delegates once is faster than reflection every time
|
||||||
|
@ -140,14 +154,23 @@ namespace TechbloxModdingAPI.App
|
||||||
return enqueueCasted;
|
return enqueueCasted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Action<object> GenHandlePopupClosed<T>()
|
private static (Action Close, Action FirstButton, Action SecondButton) _errorPopup;
|
||||||
|
|
||||||
|
private static (Action Close, Action FirstButton, Action SecondButton) GetPopupCloseMethods(object handler)
|
||||||
{
|
{
|
||||||
Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler");
|
if (_errorPopup.Close != null)
|
||||||
MethodInfo handlePopupClosed = AccessTools.Method(errorHandler, "HandlePopupClosed");
|
return _errorPopup;
|
||||||
Action<T> handleSimple =
|
Type errorHandler = handler.GetType();
|
||||||
(Action<T>) Delegate.CreateDelegate(typeof(Action<T>), handlePopupClosed);
|
FieldInfo field = AccessTools.Field(errorHandler, "errorPopup");
|
||||||
Action<object> handleCasted = (object instance) => handleSimple((T) instance);
|
var errorPopup = (ErrorPopup)field.GetValue(handler);
|
||||||
return handleCasted;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,17 +42,25 @@ namespace TechbloxModdingAPI.App
|
||||||
[APITestCase(TestType.Menu)]
|
[APITestCase(TestType.Menu)]
|
||||||
public static void TestPopUp2()
|
public static void TestPopUp2()
|
||||||
{
|
{
|
||||||
Client c = new Client();
|
Client.Instance.PromptUser(popup2);
|
||||||
c.PromptUser(popup2);
|
|
||||||
//c.CloseCurrentPrompt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[APITestCase(TestType.Menu)]
|
[APITestCase(TestType.Menu)]
|
||||||
public static void TestPopUp1()
|
public static void TestPopUp1()
|
||||||
{
|
{
|
||||||
Client c = new Client();
|
Client.Instance.PromptUser(popup1);
|
||||||
c.PromptUser(popup1);
|
}
|
||||||
//c.CloseCurrentPrompt();
|
|
||||||
|
[APITestCase(TestType.Menu)]
|
||||||
|
public static void TestPopUpClose1()
|
||||||
|
{
|
||||||
|
Client.Instance.CloseCurrentPrompt();
|
||||||
|
}
|
||||||
|
|
||||||
|
[APITestCase(TestType.Menu)]
|
||||||
|
public static void TestPopUpClose2()
|
||||||
|
{
|
||||||
|
Client.Instance.CloseCurrentPrompt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,23 +1,27 @@
|
||||||
namespace TechbloxModdingAPI.App
|
using System;
|
||||||
|
|
||||||
|
namespace TechbloxModdingAPI.App
|
||||||
{
|
{
|
||||||
public enum CurrentGameMode
|
public enum CurrentGameMode
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Building a game
|
/// Building a world
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Build,
|
Build,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Playing a game
|
/// Playing on a map
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Play,
|
Play,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Viewing a prefab
|
/// Viewing a prefab (doesn't exist anymore)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete]
|
||||||
View,
|
View,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Viewing a tutorial
|
/// Viewing a tutorial (doesn't exist anymore)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete]
|
||||||
Tutorial
|
Tutorial
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,12 +2,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
using RobocraftX.Common;
|
|
||||||
using RobocraftX.GUI.MyGamesScreen;
|
using RobocraftX.GUI.MyGamesScreen;
|
||||||
using RobocraftX.StateSync;
|
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
|
using Techblox.GameSelection;
|
||||||
|
|
||||||
using TechbloxModdingAPI;
|
|
||||||
using TechbloxModdingAPI.Blocks;
|
using TechbloxModdingAPI.Blocks;
|
||||||
using TechbloxModdingAPI.Tasks;
|
using TechbloxModdingAPI.Tasks;
|
||||||
using TechbloxModdingAPI.Utility;
|
using TechbloxModdingAPI.Utility;
|
||||||
|
@ -318,7 +316,7 @@ namespace TechbloxModdingAPI.App
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (menuMode || !VerifyMode()) return CurrentGameMode.None;
|
if (menuMode || !VerifyMode()) return CurrentGameMode.None;
|
||||||
return (CurrentGameMode) GameMode.CurrentMode;
|
return gameEngine.GetGameData().gameMode == GameMode.CreateWorld ? CurrentGameMode.Build : CurrentGameMode.Play;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,14 @@ namespace TechbloxModdingAPI.App
|
||||||
|
|
||||||
public JobHandle OnInitializeTimeRunningMode(JobHandle inputDeps)
|
public JobHandle OnInitializeTimeRunningMode(JobHandle inputDeps)
|
||||||
{
|
{
|
||||||
|
Console.WriteLine("Init time running mode");
|
||||||
SimulationMode.Invoke(this, new GameEventArgs { GameName = "", GamePath = "" }); // TODO
|
SimulationMode.Invoke(this, new GameEventArgs { GameName = "", GamePath = "" }); // TODO
|
||||||
return inputDeps;
|
return inputDeps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JobHandle OnInitializeTimeStoppedMode(JobHandle inputDeps)
|
public JobHandle OnInitializeTimeStoppedMode(JobHandle inputDeps)
|
||||||
{
|
{
|
||||||
|
Console.WriteLine("Init time stopped mode");
|
||||||
BuildMode.Invoke(this, new GameEventArgs { GameName = "", GamePath = "" });
|
BuildMode.Invoke(this, new GameEventArgs { GameName = "", GamePath = "" });
|
||||||
return inputDeps;
|
return inputDeps;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using HarmonyLib;
|
||||||
|
using RobocraftX;
|
||||||
using RobocraftX.Common;
|
using RobocraftX.Common;
|
||||||
using RobocraftX.Schedulers;
|
using RobocraftX.Schedulers;
|
||||||
using RobocraftX.SimulationModeState;
|
using RobocraftX.SimulationModeState;
|
||||||
|
@ -8,11 +10,15 @@ using Svelto.Tasks;
|
||||||
using Svelto.Tasks.Lean;
|
using Svelto.Tasks.Lean;
|
||||||
using RobocraftX.Blocks;
|
using RobocraftX.Blocks;
|
||||||
using RobocraftX.Common.Loading;
|
using RobocraftX.Common.Loading;
|
||||||
|
using RobocraftX.Multiplayer;
|
||||||
using RobocraftX.ScreenshotTaker;
|
using RobocraftX.ScreenshotTaker;
|
||||||
using Techblox.Environment.Transition;
|
using Techblox.Environment.Transition;
|
||||||
using Techblox.GameSelection;
|
using Techblox.GameSelection;
|
||||||
|
|
||||||
using TechbloxModdingAPI.Blocks;
|
using TechbloxModdingAPI.Blocks;
|
||||||
using TechbloxModdingAPI.Engines;
|
using TechbloxModdingAPI.Engines;
|
||||||
|
using TechbloxModdingAPI.Input;
|
||||||
|
using TechbloxModdingAPI.Players;
|
||||||
using TechbloxModdingAPI.Utility;
|
using TechbloxModdingAPI.Utility;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.App
|
namespace TechbloxModdingAPI.App
|
||||||
|
@ -30,16 +36,34 @@ namespace TechbloxModdingAPI.App
|
||||||
public EntitiesDB entitiesDB { set; private get; }
|
public EntitiesDB entitiesDB { set; private get; }
|
||||||
|
|
||||||
private bool enteredGame;
|
private bool enteredGame;
|
||||||
|
private bool loadingFinished;
|
||||||
|
private bool playerJoined;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
if (GameReloadedPatch.IsReload)
|
||||||
|
return; // Toggling time mode
|
||||||
ExitGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID });
|
ExitGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID });
|
||||||
IsInGame = false;
|
IsInGame = false;
|
||||||
|
loadingFinished = false;
|
||||||
|
playerJoined = false;
|
||||||
|
enteredGame = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Ready()
|
public void Ready()
|
||||||
{
|
{
|
||||||
|
if (GameReloadedPatch.IsReload)
|
||||||
|
return; // Toggling time mode
|
||||||
enteredGame = true;
|
enteredGame = true;
|
||||||
|
Player.Joined += OnPlayerJoined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPlayerJoined(object sender, PlayerEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.Player.Type != PlayerType.Local) return;
|
||||||
|
playerJoined = true;
|
||||||
|
Player.Joined -= OnPlayerJoined;
|
||||||
|
CheckJoinEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
// game functionality
|
// game functionality
|
||||||
|
@ -54,7 +78,7 @@ namespace TechbloxModdingAPI.App
|
||||||
{
|
{
|
||||||
if (async)
|
if (async)
|
||||||
{
|
{
|
||||||
ExitCurrentGameAsync().RunOn(Lean.EveryFrameStepRunner_TimeRunningAndStopped);
|
ExitCurrentGameAsync().RunOn(ClientLean.EveryFrameStepRunner_TimeRunningAndStopped);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -94,10 +118,23 @@ namespace TechbloxModdingAPI.App
|
||||||
|
|
||||||
public void ToggleTimeMode()
|
public void ToggleTimeMode()
|
||||||
{
|
{
|
||||||
if (!entitiesDB.FoundInGroups<BlockTagEntityStruct>())
|
if (TimeRunningModeUtil.IsTimeStoppedMode(entitiesDB))
|
||||||
throw new AppStateException("At least one block must exist in the world to enter simulation");
|
FakeInput.ActionInput(toggleMode: true);
|
||||||
SwitchAnimationUtil.Start(entitiesDB);
|
else
|
||||||
}
|
{
|
||||||
|
IEnumerator<TaskContract> ReloadBuildModeTask()
|
||||||
|
{
|
||||||
|
SwitchAnimationUtil.Start(entitiesDB);
|
||||||
|
while (SwitchAnimationUtil.IsFadeOutActive(entitiesDB))
|
||||||
|
yield return (TaskContract)Yield.It;
|
||||||
|
FullGameFields._multiplayerParams.MultiplayerMode = MultiplayerMode.SinglePlayer;
|
||||||
|
AccessTools.Method(typeof(FullGameCompositionRoot), "ReloadGame")
|
||||||
|
.Invoke(FullGameFields.Instance, new object[] { });
|
||||||
|
}
|
||||||
|
|
||||||
|
ReloadBuildModeTask().RunOn(ClientLean.UIScheduler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public EGID[] GetAllBlocksInGame(BlockIDs filter = BlockIDs.Invalid)
|
public EGID[] GetAllBlocksInGame(BlockIDs filter = BlockIDs.Invalid)
|
||||||
{
|
{
|
||||||
|
@ -142,9 +179,16 @@ namespace TechbloxModdingAPI.App
|
||||||
public void Remove(ref LoadingActionEntityStruct entityComponent, EGID egid)
|
public void Remove(ref LoadingActionEntityStruct entityComponent, EGID egid)
|
||||||
{ // Finished loading
|
{ // Finished loading
|
||||||
if (!enteredGame) return;
|
if (!enteredGame) return;
|
||||||
|
enteredGame = false;
|
||||||
|
loadingFinished = true;
|
||||||
|
CheckJoinEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckJoinEvent()
|
||||||
|
{
|
||||||
|
if (!loadingFinished || !playerJoined) return;
|
||||||
EnterGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID });
|
EnterGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID });
|
||||||
IsInGame = true;
|
IsInGame = true;
|
||||||
enteredGame = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,15 @@ using System.Reflection;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
using RobocraftX.Common;
|
|
||||||
using RobocraftX.FrontEnd;
|
|
||||||
using RobocraftX.GUI;
|
using RobocraftX.GUI;
|
||||||
using RobocraftX.GUI.MyGamesScreen;
|
using RobocraftX.GUI.MyGamesScreen;
|
||||||
|
using RobocraftX.Multiplayer;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Svelto.ECS.Experimental;
|
using Svelto.ECS.Experimental;
|
||||||
using Techblox.GameSelection;
|
using Techblox.GameSelection;
|
||||||
|
|
||||||
using TechbloxModdingAPI.Engines;
|
using TechbloxModdingAPI.Engines;
|
||||||
using TechbloxModdingAPI.Utility;
|
using TechbloxModdingAPI.Utility;
|
||||||
using GameMode = RobocraftX.Common.GameMode;
|
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.App
|
namespace TechbloxModdingAPI.App
|
||||||
{
|
{
|
||||||
|
@ -105,20 +104,16 @@ namespace TechbloxModdingAPI.App
|
||||||
return EnterGame(mgdes.GameName, mgdes.FileId);
|
return EnterGame(mgdes.GameName, mgdes.FileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool EnterGame(string gameName, string fileId, bool autoEnterSim = false)
|
public bool EnterGame(ECSString gameName, string fileId, bool autoEnterSim = false)
|
||||||
{
|
{
|
||||||
GameMode.CurrentMode = autoEnterSim ? RCXMode.Play : RCXMode.Build;
|
FullGameFields._multiplayerParams.MultiplayerMode = MultiplayerMode.SinglePlayer;
|
||||||
var data = new GameSelectionData
|
ref var selection = ref entitiesDB.QueryEntity<GameSelectionComponent>(GameSelectionConstants.GameSelectionEGID);
|
||||||
{
|
selection.userContentID.Set(fileId);
|
||||||
gameMode = Techblox.GameSelection.GameMode.PlayGame,
|
selection.triggerStart = true;
|
||||||
gameType = GameType.MachineEditor,
|
selection.saveType = SaveType.ExistingSave;
|
||||||
saveName = gameName,
|
selection.saveName = gameName;
|
||||||
saveType = SaveType.ExistingSave,
|
selection.gameMode = GameMode.PlayGame;
|
||||||
gameID = "GAMEID_Road_Track", //TODO: Expose to the API
|
selection.gameID.Set("GAMEID_Road_Track"); //TODO: Expose to the API
|
||||||
userContentID = fileId
|
|
||||||
};
|
|
||||||
// the private FullGameCompositionRoot.SwitchToGame() method gets passed to menu items for this reason
|
|
||||||
AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToGame").Invoke(FullGameFields.Instance, new object[]{data});
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +156,16 @@ namespace TechbloxModdingAPI.App
|
||||||
{
|
{
|
||||||
return ref entitiesDB.QueryEntity<T>(id);
|
return ref entitiesDB.QueryEntity<T>(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void CloseBetaPopup()
|
||||||
|
{
|
||||||
|
var (buffer, count) = entitiesDB.QueryEntities<TogglePanelButtonEntityViewStruct>(ExclusiveGroup.Search("BetaPopup"));
|
||||||
|
for (int index = 0; index < count; ++index)
|
||||||
|
{
|
||||||
|
entitiesDB.QueryEntity<GUIEntityViewStruct>(buffer[index].TogglePanelButtonComponent.targetPanel)
|
||||||
|
.guiRoot.enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class MyGameDataEntityDescriptor_DamnItFJWhyDidYouMakeThisInternal : GenericEntityDescriptor<MyGameDataEntityStruct> { }
|
internal class MyGameDataEntityDescriptor_DamnItFJWhyDidYouMakeThisInternal : GenericEntityDescriptor<MyGameDataEntityStruct> { }
|
||||||
|
@ -178,7 +183,7 @@ namespace TechbloxModdingAPI.App
|
||||||
|
|
||||||
public static MethodBase TargetMethod()
|
public static MethodBase TargetMethod()
|
||||||
{
|
{
|
||||||
return AccessTools.Method(typeof(FullGameCompositionRoot), "GoToMenu");
|
return AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToMenu");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,10 @@ using Svelto.ECS.EntityStructs;
|
||||||
using RobocraftX.Common;
|
using RobocraftX.Common;
|
||||||
using RobocraftX.Blocks;
|
using RobocraftX.Blocks;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using Gamecraft.Blocks.GUI;
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using RobocraftX.PilotSeat;
|
using RobocraftX.PilotSeat;
|
||||||
|
using RobocraftX.Rendering;
|
||||||
|
using Techblox.BlockLabels;
|
||||||
|
|
||||||
using TechbloxModdingAPI.Blocks;
|
using TechbloxModdingAPI.Blocks;
|
||||||
using TechbloxModdingAPI.Blocks.Engines;
|
using TechbloxModdingAPI.Blocks.Engines;
|
||||||
|
@ -339,11 +340,9 @@ namespace TechbloxModdingAPI
|
||||||
[TestValue(null)]
|
[TestValue(null)]
|
||||||
public string Label
|
public string Label
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfoViewComponent<TextLabelEntityViewStruct>(this).textLabelComponent?.text;
|
get => BlockEngine.GetBlockInfo<LabelResourceIDComponent>(this).ToString(); //TODO: Block labels
|
||||||
set
|
set
|
||||||
{
|
{ //TODO
|
||||||
var comp = BlockEngine.GetBlockInfoViewComponent<TextLabelEntityViewStruct>(this).textLabelComponent;
|
|
||||||
if (comp != null) comp.text = value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
|
@ -273,6 +273,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The grid block used by the world editor, named Small Grid like the other one
|
/// The grid block used by the world editor, named Small Grid like the other one
|
||||||
/// </summary>
|
/// </summary>
|
||||||
SmallGridInWorldEditor
|
SmallGridInWorldEditor,
|
||||||
|
SegoeUITextblock = 376,
|
||||||
|
GravtracTextblock,
|
||||||
|
HauserTextblock,
|
||||||
|
TechnopollasTextblock,
|
||||||
|
BitBlock = 385,
|
||||||
|
Timer
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
base(new EGID(id, CommonExclusiveGroups.ENGINE_BLOCK_BUILD_GROUP))
|
base(new EGID(id, CommonExclusiveGroups.ENGINE_BLOCK_BUILD_GROUP))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
/// <summary>
|
/// <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>
|
||||||
|
@ -34,6 +34,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
Techblox.BlockColours.BlockColoursCompositionRoot
|
||||||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).engineOn = value;
|
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).engineOn = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -377,6 +378,6 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).manualToAutoGearCoolOffTime = value;
|
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).manualToAutoGearCoolOffTime = value;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
|
|
||||||
copyToBlock.Invoke(Patch.copyEngine, new object[] {pickedBlock.ID, pickedBlock});
|
copyToBlock.Invoke(Patch.copyEngine, new object[] {pickedBlock.ID, pickedBlock});
|
||||||
|
|
||||||
ExclusiveGroupStruct group = WiresExclusiveGroups.WIRES_COPY_GROUP + playerID;
|
ExclusiveGroupStruct group = BuildModeWiresGroups.WIRES_COPY_GROUP + playerID;
|
||||||
copyWireToBlock.Invoke(Patch.createWireEngine, new object[] {group, pickedBlock.ID});
|
copyWireToBlock.Invoke(Patch.createWireEngine, new object[] {group, pickedBlock.ID});
|
||||||
|
|
||||||
pickedBlock.placedBlockTweaksMustCopy = false;
|
pickedBlock.placedBlockTweaksMustCopy = false;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Gamecraft.Blocks.BlockGroups;
|
using Gamecraft.Blocks.BlockGroups;
|
||||||
|
@ -173,7 +173,8 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
foreach (var block in blocks)
|
foreach (var block in blocks)
|
||||||
{
|
{
|
||||||
GhostChildUtility.BuildGhostChild(in playerID, block.Id, in pos, in rot, entitiesDB,
|
GhostChildUtility.BuildGhostChild(in playerID, block.Id, in pos, in rot, entitiesDB,
|
||||||
BuildGhostBlueprintFactory, false, bssesopt.Get().buildingDroneReference);
|
BuildGhostBlueprintFactory, false, bssesopt.Get().buildingDroneReference,
|
||||||
|
FullGameFields._managers.blockLabelResourceManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +273,8 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
uint ghostChildBlockId = CommonExclusiveGroups.GetNewGhostChildBlockID();
|
uint ghostChildBlockId = CommonExclusiveGroups.GetNewGhostChildBlockID();
|
||||||
var ghostEntityReference = GhostBlockUtils.GetGhostEntityReference(sourceId.entityID, entitiesDB);
|
var ghostEntityReference = GhostBlockUtils.GetGhostEntityReference(sourceId.entityID, entitiesDB);
|
||||||
var entityInitializer = BuildGhostBlueprintFactory.Build(
|
var entityInitializer = BuildGhostBlueprintFactory.Build(
|
||||||
new EGID(ghostChildBlockId, BoxSelectExclusiveGroups.GhostChildEntitiesExclusiveGroup), /*dbStruct.DBID*/ (uint)BlockIDs.Cube);
|
new EGID(ghostChildBlockId, BoxSelectExclusiveGroups.GhostChildEntitiesExclusiveGroup), /*dbStruct.DBID*/ (uint)BlockIDs.Cube,
|
||||||
|
FullGameFields._managers.blockLabelResourceManager);
|
||||||
entityInitializer.Init(dbStruct);
|
entityInitializer.Init(dbStruct);
|
||||||
entityInitializer.Init(new GFXPrefabEntityStructGPUI(
|
entityInitializer.Init(new GFXPrefabEntityStructGPUI(
|
||||||
PrefabsID.GetOrCreatePrefabID((ushort)entityInitializer.Get<PrefabAssetIDComponent>().prefabAssetID,
|
PrefabsID.GetOrCreatePrefabID((ushort)entityInitializer.Get<PrefabAssetIDComponent>().prefabAssetID,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using RobocraftX.Common;
|
using RobocraftX.Common;
|
||||||
using RobocraftX.UECS;
|
using RobocraftX.DOTS;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Svelto.ECS.EntityStructs;
|
using Svelto.ECS.EntityStructs;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
|
@ -40,7 +40,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntityOrDefault<PositionEntityStruct>(block);
|
ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntityOrDefault<PositionEntityStruct>(block);
|
||||||
ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntityOrDefault<GridRotationStruct>(block);
|
ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntityOrDefault<GridRotationStruct>(block);
|
||||||
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntityOrDefault<LocalTransformEntityStruct>(block);
|
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntityOrDefault<LocalTransformEntityStruct>(block);
|
||||||
ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntityOrDefault<UECSPhysicsEntityStruct>(block);
|
ref DOTSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntityOrDefault<DOTSPhysicsEntityStruct>(block);
|
||||||
// main (persistent) position
|
// main (persistent) position
|
||||||
posStruct.position = vector;
|
posStruct.position = vector;
|
||||||
// placement grid position
|
// placement grid position
|
||||||
|
@ -50,7 +50,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
// collision position
|
// collision position
|
||||||
if (phyStruct.ID != default)
|
if (phyStruct.ID != default)
|
||||||
{ //It exists
|
{ //It exists
|
||||||
FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation
|
FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.dotsEntity, new Translation
|
||||||
{
|
{
|
||||||
Value = posStruct.position
|
Value = posStruct.position
|
||||||
});
|
});
|
||||||
|
|
|
@ -54,7 +54,8 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
//RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine
|
//RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine
|
||||||
DBEntityStruct dbEntity = new DBEntityStruct {DBID = block};
|
DBEntityStruct dbEntity = new DBEntityStruct {DBID = block};
|
||||||
|
|
||||||
EntityInitializer structInitializer = _blockEntityFactory.Build(CommonExclusiveGroups.nextBlockEntityID, block); //The ghost block index is only used for triggers
|
//TODO: Test
|
||||||
|
EntityInitializer structInitializer = _blockEntityFactory.Build(CommonExclusiveGroups.blockIDGeneratorClient.Next(), block); //The ghost block index is only used for triggers
|
||||||
uint prefabAssetID = structInitializer.Has<PrefabAssetIDComponent>()
|
uint prefabAssetID = structInitializer.Has<PrefabAssetIDComponent>()
|
||||||
? structInitializer.Get<PrefabAssetIDComponent>().prefabAssetID
|
? structInitializer.Get<PrefabAssetIDComponent>().prefabAssetID
|
||||||
: throw new BlockException("Prefab asset ID not found!"); //Set by the game
|
: throw new BlockException("Prefab asset ID not found!"); //Set by the game
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using RobocraftX.Common;
|
using RobocraftX.Common;
|
||||||
using RobocraftX.UECS;
|
using RobocraftX.DOTS;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Svelto.ECS.EntityStructs;
|
using Svelto.ECS.EntityStructs;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
|
@ -40,7 +40,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
ref RotationEntityStruct rotStruct = ref this.entitiesDB.QueryEntityOrDefault<RotationEntityStruct>(block);
|
ref RotationEntityStruct rotStruct = ref this.entitiesDB.QueryEntityOrDefault<RotationEntityStruct>(block);
|
||||||
ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntityOrDefault<GridRotationStruct>(block);
|
ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntityOrDefault<GridRotationStruct>(block);
|
||||||
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntityOrDefault<LocalTransformEntityStruct>(block);
|
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntityOrDefault<LocalTransformEntityStruct>(block);
|
||||||
ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntityOrDefault<UECSPhysicsEntityStruct>(block);
|
ref DOTSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntityOrDefault<DOTSPhysicsEntityStruct>(block);
|
||||||
// main (persistent) rotation
|
// main (persistent) rotation
|
||||||
Quaternion newRotation = rotStruct.rotation;
|
Quaternion newRotation = rotStruct.rotation;
|
||||||
newRotation.eulerAngles = vector;
|
newRotation.eulerAngles = vector;
|
||||||
|
@ -52,7 +52,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
// collision rotation
|
// collision rotation
|
||||||
if (phyStruct.ID != default)
|
if (phyStruct.ID != default)
|
||||||
{ //It exists
|
{ //It exists
|
||||||
FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity,
|
FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.dotsEntity,
|
||||||
new Unity.Transforms.Rotation
|
new Unity.Transforms.Rotation
|
||||||
{
|
{
|
||||||
Value = rotStruct.rotation
|
Value = rotStruct.rotation
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using RobocraftX.Common;
|
using RobocraftX.Common;
|
||||||
using RobocraftX.UECS;
|
using RobocraftX.DOTS;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Unity.Entities;
|
using Unity.Entities;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
{
|
{
|
||||||
public class ScalingEngine : IApiEngine
|
public class ScalingEngine : IApiEngine
|
||||||
{
|
{
|
||||||
private static IReactOnAddAndRemove<UECSPhysicsEntityCreationStruct> physicsEngine;
|
private static IReactOnAddAndRemove<DOTSPhysicsEntityCreationStruct> physicsEngine;
|
||||||
|
|
||||||
public void Ready()
|
public void Ready()
|
||||||
{
|
{
|
||||||
|
@ -34,16 +34,16 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
if (_entityManager == default)
|
if (_entityManager == default)
|
||||||
_entityManager = FullGameFields._physicsWorld.EntityManager;
|
_entityManager = FullGameFields._physicsWorld.EntityManager;
|
||||||
//Assuming the block exists
|
//Assuming the block exists
|
||||||
var entity = entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(egid).uecsEntity;
|
var entity = entitiesDB.QueryEntity<DOTSPhysicsEntityStruct>(egid).dotsEntity;
|
||||||
var pes = new UECSPhysicsEntityCreationStruct();
|
var pes = new DOTSPhysicsEntityCreationStruct();
|
||||||
physicsEngine.Add(ref pes, egid); //Create new UECS entity
|
physicsEngine.Add(ref pes, egid); //Create new DOTS entity
|
||||||
_entityManager.DestroyEntity(entity);
|
_entityManager.DestroyEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPatch]
|
[HarmonyPatch]
|
||||||
class PhysicsEnginePatch
|
class PhysicsEnginePatch
|
||||||
{
|
{
|
||||||
static void Postfix(IReactOnAddAndRemove<UECSPhysicsEntityCreationStruct> __instance)
|
static void Postfix(IReactOnAddAndRemove<DOTSPhysicsEntityCreationStruct> __instance)
|
||||||
{
|
{
|
||||||
physicsEngine = __instance;
|
physicsEngine = __instance;
|
||||||
Logging.MetaDebugLog("Physics engine injected.");
|
Logging.MetaDebugLog("Physics engine injected.");
|
||||||
|
@ -51,7 +51,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
|
|
||||||
static MethodBase TargetMethod(Harmony instance)
|
static MethodBase TargetMethod(Harmony instance)
|
||||||
{
|
{
|
||||||
return AccessTools.Method("RobocraftX.StateSync.HandleUECSPhysicEntitiesWithPrefabCreationEngine" +
|
return AccessTools.Method("RobocraftX.StateSync.HandleDOTSPhysicEntitiesWithPrefabCreationEngine" +
|
||||||
":Ready");
|
":Ready");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
|
|
||||||
public WireEntityStruct CreateNewWire(EGID startBlock, byte startPort, EGID endBlock, byte endPort)
|
public WireEntityStruct CreateNewWire(EGID startBlock, byte startPort, EGID endBlock, byte endPort)
|
||||||
{
|
{
|
||||||
EGID wireEGID = new EGID(WiresExclusiveGroups.NewWireEntityId, NamedExclusiveGroup<WiresGroup>.Group);
|
EGID wireEGID = new EGID(BuildModeWiresGroups.NewWireEntityId, BuildModeWiresGroups.WiresGroup.Group);
|
||||||
EntityInitializer wireInitializer = Factory.BuildEntity<WireEntityDescriptor>(wireEGID);
|
EntityInitializer wireInitializer = Factory.BuildEntity<WireEntityDescriptor>(wireEGID);
|
||||||
wireInitializer.Init(new WireEntityStruct
|
wireInitializer.Init(new WireEntityStruct
|
||||||
{
|
{
|
||||||
|
@ -77,8 +77,8 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
public ref PortEntityStruct GetPortByOffset(BlockPortsStruct bps, byte portNumber, bool input)
|
public ref PortEntityStruct GetPortByOffset(BlockPortsStruct bps, byte portNumber, bool input)
|
||||||
{
|
{
|
||||||
ExclusiveGroup group = input
|
ExclusiveGroup group = input
|
||||||
? NamedExclusiveGroup<InputPortsGroup>.Group
|
? NamedExclusiveGroup<BuildModeWiresGroups.InputPortsGroup>.Group
|
||||||
: NamedExclusiveGroup<OutputPortsGroup>.Group;
|
: NamedExclusiveGroup<BuildModeWiresGroups.OutputPortsGroup>.Group;
|
||||||
uint id = (input ? bps.firstInputID : bps.firstOutputID) + portNumber;
|
uint id = (input ? bps.firstInputID : bps.firstOutputID) + portNumber;
|
||||||
EGID egid = new EGID(id, group);
|
EGID egid = new EGID(id, group);
|
||||||
if (!entitiesDB.Exists<PortEntityStruct>(egid))
|
if (!entitiesDB.Exists<PortEntityStruct>(egid))
|
||||||
|
@ -193,7 +193,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
EGID[] inputs = new EGID[ports.inputCount];
|
EGID[] inputs = new EGID[ports.inputCount];
|
||||||
for (uint i = 0; i < ports.inputCount; i++)
|
for (uint i = 0; i < ports.inputCount; i++)
|
||||||
{
|
{
|
||||||
inputs[i] = new EGID(i + ports.firstInputID, NamedExclusiveGroup<InputPortsGroup>.Group);
|
inputs[i] = new EGID(i + ports.firstInputID, NamedExclusiveGroup<BuildModeWiresGroups.InputPortsGroup>.Group);
|
||||||
}
|
}
|
||||||
return inputs;
|
return inputs;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
EGID[] outputs = new EGID[ports.outputCount];
|
EGID[] outputs = new EGID[ports.outputCount];
|
||||||
for (uint i = 0; i < ports.outputCount; i++)
|
for (uint i = 0; i < ports.outputCount; i++)
|
||||||
{
|
{
|
||||||
outputs[i] = new EGID(i + ports.firstOutputID, NamedExclusiveGroup<OutputPortsGroup>.Group);
|
outputs[i] = new EGID(i + ports.firstOutputID, NamedExclusiveGroup<BuildModeWiresGroups.OutputPortsGroup>.Group);
|
||||||
}
|
}
|
||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
|
@ -219,8 +219,8 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
if (!entitiesDB.Exists<BlockPortsStruct>(block))
|
if (!entitiesDB.Exists<BlockPortsStruct>(block))
|
||||||
return default;
|
return default;
|
||||||
var group = output
|
var group = output
|
||||||
? NamedExclusiveGroup<OutputPortsGroup>.Group
|
? NamedExclusiveGroup<BuildModeWiresGroups.OutputPortsGroup>.Group
|
||||||
: NamedExclusiveGroup<InputPortsGroup>.Group;
|
: NamedExclusiveGroup<BuildModeWiresGroups.InputPortsGroup>.Group;
|
||||||
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(block);
|
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(block);
|
||||||
if (!entitiesDB.TryQueryMappedEntities<PortEntityStruct>(group, out var mapper))
|
if (!entitiesDB.TryQueryMappedEntities<PortEntityStruct>(group, out var mapper))
|
||||||
return default;
|
return default;
|
||||||
|
@ -237,7 +237,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
|
|
||||||
public ref WireEntityStruct MatchPortToWire(PortEntityStruct port, EGID blockID, out bool exists)
|
public ref WireEntityStruct MatchPortToWire(PortEntityStruct port, EGID blockID, out bool exists)
|
||||||
{
|
{
|
||||||
var wires = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<WiresGroup>.Group);
|
var wires = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group);
|
||||||
var wiresB = wires.ToBuffer().buffer;
|
var wiresB = wires.ToBuffer().buffer;
|
||||||
for (uint i = 0; i < wires.count; i++)
|
for (uint i = 0; i < wires.count; i++)
|
||||||
{
|
{
|
||||||
|
@ -264,7 +264,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(startBlock);
|
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(startBlock);
|
||||||
startPorts = new EGID[] {new EGID(ports.firstOutputID + startPort, NamedExclusiveGroup<OutputPortsGroup>.Group) };
|
startPorts = new EGID[] {new EGID(ports.firstOutputID + startPort, NamedExclusiveGroup<BuildModeWiresGroups.OutputPortsGroup>.Group) };
|
||||||
}
|
}
|
||||||
|
|
||||||
EGID[] endPorts;
|
EGID[] endPorts;
|
||||||
|
@ -276,10 +276,10 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(endBlock);
|
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(endBlock);
|
||||||
endPorts = new EGID[] {new EGID(ports.firstInputID + endPort, NamedExclusiveGroup<InputPortsGroup>.Group) };
|
endPorts = new EGID[] {new EGID(ports.firstInputID + endPort, NamedExclusiveGroup<BuildModeWiresGroups.InputPortsGroup>.Group) };
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityCollection<WireEntityStruct> wires = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<WiresGroup>.Group);
|
EntityCollection<WireEntityStruct> wires = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group);
|
||||||
var wiresB = wires.ToBuffer().buffer;
|
var wiresB = wires.ToBuffer().buffer;
|
||||||
for (int endIndex = 0; endIndex < endPorts.Length; endIndex++)
|
for (int endIndex = 0; endIndex < endPorts.Length; endIndex++)
|
||||||
{
|
{
|
||||||
|
@ -304,7 +304,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
public OptionalRef<ChannelDataStruct> GetChannelDataStruct(EGID portID)
|
public OptionalRef<ChannelDataStruct> GetChannelDataStruct(EGID portID)
|
||||||
{
|
{
|
||||||
var port = GetPort(portID);
|
var port = GetPort(portID);
|
||||||
var channels = entitiesDB.QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<ChannelDataGroup>.Group);
|
var channels = entitiesDB.QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<BuildModeWiresGroups.ChannelDataGroup>.Group);
|
||||||
var channelsB = channels.ToBuffer();
|
var channelsB = channels.ToBuffer();
|
||||||
return port.firstChannelIndexCachedInSim < channels.count
|
return port.firstChannelIndexCachedInSim < channels.count
|
||||||
? new OptionalRef<ChannelDataStruct>(channelsB.buffer, port.firstChannelIndexCachedInSim)
|
? new OptionalRef<ChannelDataStruct>(channelsB.buffer, port.firstChannelIndexCachedInSim)
|
||||||
|
@ -329,7 +329,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
|
|
||||||
public EGID[] WiredToInput(EGID block, byte port)
|
public EGID[] WiredToInput(EGID block, byte port)
|
||||||
{
|
{
|
||||||
WireEntityStruct[] wireEntityStructs = Search(NamedExclusiveGroup<WiresGroup>.Group,
|
WireEntityStruct[] wireEntityStructs = Search(NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group,
|
||||||
(WireEntityStruct wes) => wes.destinationPortUsage == port && wes.destinationBlockEGID == block);
|
(WireEntityStruct wes) => wes.destinationPortUsage == port && wes.destinationBlockEGID == block);
|
||||||
EGID[] result = new EGID[wireEntityStructs.Length];
|
EGID[] result = new EGID[wireEntityStructs.Length];
|
||||||
for (uint i = 0; i < wireEntityStructs.Length; i++)
|
for (uint i = 0; i < wireEntityStructs.Length; i++)
|
||||||
|
@ -342,7 +342,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
|
|
||||||
public EGID[] WiredToOutput(EGID block, byte port)
|
public EGID[] WiredToOutput(EGID block, byte port)
|
||||||
{
|
{
|
||||||
WireEntityStruct[] wireEntityStructs = Search(NamedExclusiveGroup<WiresGroup>.Group,
|
WireEntityStruct[] wireEntityStructs = Search(NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group,
|
||||||
(WireEntityStruct wes) => wes.sourcePortUsage == port && wes.sourceBlockEGID == block);
|
(WireEntityStruct wes) => wes.sourcePortUsage == port && wes.sourceBlockEGID == block);
|
||||||
EGID[] result = new EGID[wireEntityStructs.Length];
|
EGID[] result = new EGID[wireEntityStructs.Length];
|
||||||
for (uint i = 0; i < wireEntityStructs.Length; i++)
|
for (uint i = 0; i < wireEntityStructs.Length; i++)
|
||||||
|
@ -371,13 +371,13 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
private EntityCollection<ChannelDataStruct> GetSignalStruct(uint signalID, out uint index, bool input = true)
|
private EntityCollection<ChannelDataStruct> GetSignalStruct(uint signalID, out uint index, bool input = true)
|
||||||
{
|
{
|
||||||
ExclusiveGroup group = input
|
ExclusiveGroup group = input
|
||||||
? NamedExclusiveGroup<InputPortsGroup>.Group
|
? NamedExclusiveGroup<BuildModeWiresGroups.InputPortsGroup>.Group
|
||||||
: NamedExclusiveGroup<OutputPortsGroup>.Group;
|
: NamedExclusiveGroup<BuildModeWiresGroups.OutputPortsGroup>.Group;
|
||||||
if (entitiesDB.Exists<PortEntityStruct>(signalID, group))
|
if (entitiesDB.Exists<PortEntityStruct>(signalID, group))
|
||||||
{
|
{
|
||||||
index = entitiesDB.QueryEntity<PortEntityStruct>(signalID, group).anyChannelIndex;
|
index = entitiesDB.QueryEntity<PortEntityStruct>(signalID, group).anyChannelIndex;
|
||||||
var channelData =
|
var channelData =
|
||||||
entitiesDB.QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<ChannelDataGroup>.Group);
|
entitiesDB.QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<BuildModeWiresGroups.ChannelDataGroup>.Group);
|
||||||
return channelData;
|
return channelData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
using HarmonyLib;
|
|
||||||
using Svelto.ECS;
|
|
||||||
using RobocraftX.CR.MainGame;
|
|
||||||
using RobocraftX.Multiplayer;
|
|
||||||
using RobocraftX.StateSync;
|
|
||||||
using TechbloxModdingAPI.Utility;
|
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Commands
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Patch of RobocraftX.CR.MainGame.MainGameCompositionRoot.DeterministicCompose<T>()
|
|
||||||
/// Initializes custom commands
|
|
||||||
/// </summary>
|
|
||||||
[HarmonyPatch]
|
|
||||||
static class CommandPatch
|
|
||||||
{
|
|
||||||
public static void Postfix(StateSyncRegistrationHelper stateSyncReg)
|
|
||||||
{
|
|
||||||
/*CommandLineCompositionRoot.Compose(contextHolder, stateSyncReg.enginesRoot, reloadGame, multiplayerParameters,
|
|
||||||
stateSyncReg); - uREPL C# compilation not supported anymore */
|
|
||||||
var enginesRoot = stateSyncReg.enginesRoot;
|
|
||||||
CommandManager.RegisterEngines(enginesRoot);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MethodInfo TargetMethod()
|
|
||||||
{
|
|
||||||
return AccessTools.Method(typeof(MainGameCompositionRoot), "DeterministicCompose")
|
|
||||||
.MakeGenericMethod(typeof(object));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -62,6 +62,7 @@ namespace TechbloxModdingAPI
|
||||||
var id = initializer(this);
|
var id = initializer(this);
|
||||||
if (!dict.ContainsKey(id)) // Multiple instances may be created
|
if (!dict.ContainsKey(id)) // Multiple instances may be created
|
||||||
dict.Add(id, this);
|
dict.Add(id, this);
|
||||||
|
Id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region ECS initializer stuff
|
#region ECS initializer stuff
|
||||||
|
|
|
@ -6,27 +6,67 @@ using RobocraftX.FrontEnd;
|
||||||
using RobocraftX.StateSync;
|
using RobocraftX.StateSync;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Svelto.ECS.Schedulers;
|
using Svelto.ECS.Schedulers;
|
||||||
|
using TechbloxModdingAPI.Commands;
|
||||||
using TechbloxModdingAPI.Utility;
|
using TechbloxModdingAPI.Utility;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Engines
|
namespace TechbloxModdingAPI.Engines
|
||||||
{
|
{
|
||||||
[HarmonyPatch]
|
[HarmonyPatch]
|
||||||
class GameLoadedEnginePatch
|
static class GameLoadedTimeStoppedEnginePatch
|
||||||
{
|
{
|
||||||
public static EntitiesSubmissionScheduler Scheduler { get; private set; }
|
|
||||||
public static void Postfix(StateSyncRegistrationHelper stateSyncReg)
|
public static void Postfix(StateSyncRegistrationHelper stateSyncReg)
|
||||||
{
|
{
|
||||||
// register all game engines, including deterministic
|
// register all game engines, including deterministic
|
||||||
GameEngineManager.RegisterEngines(stateSyncReg);
|
GameEngineManager.RegisterEngines(stateSyncReg);
|
||||||
Scheduler = stateSyncReg.enginesRoot.scheduler;
|
// register command engines
|
||||||
|
/*CommandLineCompositionRoot.Compose(contextHolder, stateSyncReg.enginesRoot, reloadGame, multiplayerParameters,
|
||||||
|
stateSyncReg); - uREPL C# compilation not supported anymore */
|
||||||
|
CommandManager.RegisterEngines(stateSyncReg.enginesRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MethodBase TargetMethod()
|
public static MethodBase TargetMethod()
|
||||||
{
|
{
|
||||||
return AccessTools.Method(typeof(MainGameCompositionRoot), "DeterministicCompose").MakeGenericMethod(typeof(object));
|
return AccessTools.Method(typeof(MainGameCompositionRoot), "DeterministicTimeStoppedCompose").MakeGenericMethod(typeof(object));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
static class GameLoadedTimeRunningEnginePatch
|
||||||
|
{
|
||||||
|
public static void Postfix(StateSyncRegistrationHelper stateSyncReg)
|
||||||
|
{
|
||||||
|
GameEngineManager.RegisterEngines(stateSyncReg);
|
||||||
|
CommandManager.RegisterEngines(stateSyncReg.enginesRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodBase TargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method(typeof(MainGameCompositionRoot), "DeterministicTimeRunningCompose").MakeGenericMethod(typeof(object));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
static class GameReloadedPatch
|
||||||
|
{
|
||||||
|
internal static bool IsReload;
|
||||||
|
public static void Prefix() => IsReload = true;
|
||||||
|
public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "ReloadGame");
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
static class GameSwitchedToPatch
|
||||||
|
{
|
||||||
|
public static void Prefix() => GameReloadedPatch.IsReload = false;
|
||||||
|
public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToGame");
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
static class MenuSwitchedToPatch
|
||||||
|
{
|
||||||
|
public static void Prefix() => GameReloadedPatch.IsReload = false;
|
||||||
|
public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToMenu");
|
||||||
|
}
|
||||||
|
|
||||||
[HarmonyPatch]
|
[HarmonyPatch]
|
||||||
class MenuLoadedEnginePatch
|
class MenuLoadedEnginePatch
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
using System;
|
using RobocraftX.Common.Input;
|
||||||
|
|
||||||
using RobocraftX.Common;
|
using TechbloxModdingAPI.App;
|
||||||
using RobocraftX.Common.Input;
|
|
||||||
using Svelto.ECS;
|
|
||||||
using TechbloxModdingAPI.Utility;
|
using TechbloxModdingAPI.Utility;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Input
|
namespace TechbloxModdingAPI.Input
|
||||||
{
|
{
|
||||||
public static class FakeInput
|
public static class FakeInput
|
||||||
{
|
{
|
||||||
private static readonly FakeInputEngine inputEngine = new FakeInputEngine();
|
internal static readonly FakeInputEngine inputEngine = new FakeInputEngine();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customize the local input.
|
/// Customize the local input.
|
||||||
|
@ -103,39 +101,39 @@ namespace TechbloxModdingAPI.Input
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ActionInput(uint playerID = uint.MaxValue, bool toggleMode = false, bool forward = false, bool backward = false, bool up = false, bool down = false, bool left = false, bool right = false, bool sprint = false, bool toggleFly = false, bool alt = false, bool primary = false, bool secondary = false, bool tertiary = false, bool primaryHeld = false, bool secondaryHeld = false, bool toggleUnitGrid = false, bool ctrl = false, bool toggleColourMode = false, bool scaleBlockUp = false, bool scaleBlockDown = false, bool rotateBlockClockwise = false, bool rotateBlockCounterclockwise = false, bool cutSelection = false, bool copySelection = false, bool deleteSelection = false)
|
public static void ActionInput(uint playerID = uint.MaxValue, bool toggleMode = false, bool forward = false, bool backward = false, bool up = false, bool down = false, bool left = false, bool right = false, bool sprint = false, bool toggleFly = false, bool alt = false, bool primary = false, bool secondary = false, bool tertiary = false, bool primaryHeld = false, bool secondaryHeld = false, bool toggleUnitGrid = false, bool ctrl = false, bool toggleColourMode = false, bool scaleBlockUp = false, bool scaleBlockDown = false, bool rotateBlockClockwise = false, bool rotateBlockCounterclockwise = false, bool cutSelection = false, bool copySelection = false, bool deleteSelection = false)
|
||||||
{
|
{ // TODO: We can only alter our own inputs clientside
|
||||||
if (playerID == uint.MaxValue)
|
ref var currentInput = ref inputEngine._localInputCache;
|
||||||
{
|
|
||||||
playerID = inputEngine.GetLocalPlayerID();
|
|
||||||
}
|
|
||||||
ref LocalPlayerInputEntityStruct currentInput = ref inputEngine.GetPlayerInputRef(playerID);
|
|
||||||
//Utility.Logging.CommandLog($"Current sim frame {currentInput.frame}");
|
//Utility.Logging.CommandLog($"Current sim frame {currentInput.frame}");
|
||||||
// set inputs
|
// set inputs
|
||||||
if (toggleMode) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleTimeRunningMode;
|
if (toggleMode) currentInput |= RobocraftX.Common.Input.ActionInput.ToggleTimeRunningModePlay; //TODO: Test, play
|
||||||
if (forward) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Forward;
|
if (forward) currentInput |= RobocraftX.Common.Input.ActionInput.Forward;
|
||||||
if (backward) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Backward;
|
if (backward) currentInput |= RobocraftX.Common.Input.ActionInput.Backward;
|
||||||
if (up) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Up;
|
if (up) currentInput |= RobocraftX.Common.Input.ActionInput.Up;
|
||||||
if (down) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Down;
|
if (down) currentInput |= RobocraftX.Common.Input.ActionInput.Down;
|
||||||
if (left) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Left;
|
if (left) currentInput |= RobocraftX.Common.Input.ActionInput.Left;
|
||||||
if (right) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Right;
|
if (right) currentInput |= RobocraftX.Common.Input.ActionInput.Right;
|
||||||
if (sprint) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Sprint;
|
if (sprint) currentInput |= RobocraftX.Common.Input.ActionInput.Sprint;
|
||||||
//if (toggleFly) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.SwitchFlyMode;
|
//if (toggleFly) currentInput |= RobocraftX.Common.Input.ActionInput.SwitchFlyMode;
|
||||||
//if (alt) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.AltAction;
|
//if (alt) currentInput |= RobocraftX.Common.Input.ActionInput.AltAction;
|
||||||
if (primary) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.PrimaryAction;
|
if (primary) currentInput |= RobocraftX.Common.Input.ActionInput.PrimaryActionClick;
|
||||||
if (secondary) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.SecondaryAction;
|
if (secondary) currentInput |= RobocraftX.Common.Input.ActionInput.SecondaryActionClick;
|
||||||
if (tertiary) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.TertiaryAction;
|
if (tertiary) currentInput |= RobocraftX.Common.Input.ActionInput.TertiaryAction;
|
||||||
if (primaryHeld) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.PrimaryActionHeld;
|
if (primaryHeld) currentInput |= RobocraftX.Common.Input.ActionInput.PrimaryActionHeld;
|
||||||
if (secondaryHeld) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.SecondaryActionHeld;
|
if (secondaryHeld) currentInput |= RobocraftX.Common.Input.ActionInput.SecondaryActionHeld;
|
||||||
//if (toggleUnitGrid) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleUnitGrid;
|
//if (toggleUnitGrid) currentInput |= RobocraftX.Common.Input.ActionInput.ToggleUnitGrid;
|
||||||
if (ctrl) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.CtrlAction;
|
if (ctrl) currentInput |= RobocraftX.Common.Input.ActionInput.CtrlAction;
|
||||||
if (toggleColourMode) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleColourMode;
|
if (toggleColourMode) currentInput |= RobocraftX.Common.Input.ActionInput.ToggleColourMode;
|
||||||
if (scaleBlockUp) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ScaleBlockUp;
|
if (scaleBlockUp) currentInput |= RobocraftX.Common.Input.ActionInput.ScaleBlockUp;
|
||||||
if (scaleBlockDown) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ScaleBlockDown;
|
if (scaleBlockDown) currentInput |= RobocraftX.Common.Input.ActionInput.ScaleBlockDown;
|
||||||
if (rotateBlockClockwise) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.RotateBlockClockwise;
|
if (rotateBlockClockwise) currentInput |= RobocraftX.Common.Input.ActionInput.RotateBlockClockwise;
|
||||||
if (rotateBlockCounterclockwise) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.RotateBlockAnticlockwise;
|
if (rotateBlockCounterclockwise) currentInput |= RobocraftX.Common.Input.ActionInput.RotateBlockAnticlockwise;
|
||||||
if (cutSelection) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.CutSelection;
|
if (cutSelection) currentInput |= RobocraftX.Common.Input.ActionInput.CutSelection;
|
||||||
if (copySelection) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.CopySelection;
|
if (copySelection) currentInput |= RobocraftX.Common.Input.ActionInput.CopySelection;
|
||||||
if (deleteSelection) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.DeleteSelection;
|
if (deleteSelection) currentInput |= RobocraftX.Common.Input.ActionInput.DeleteSelection;
|
||||||
|
|
||||||
|
if(Game.CurrentGame().IsTimeStopped)
|
||||||
|
inputEngine.HandleCustomInput(); // Only gets called when online, so calling it here as well
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
|
|
|
@ -20,6 +20,8 @@ namespace TechbloxModdingAPI.Input
|
||||||
|
|
||||||
public bool IsReady = false;
|
public bool IsReady = false;
|
||||||
|
|
||||||
|
internal ActionInput _localInputCache;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
IsReady = false;
|
IsReady = false;
|
||||||
|
@ -86,6 +88,14 @@ namespace TechbloxModdingAPI.Input
|
||||||
return ref entitiesDB.QueryEntity<LocalPlayerInputEntityStruct>(egid);
|
return ref entitiesDB.QueryEntity<LocalPlayerInputEntityStruct>(egid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void HandleCustomInput()
|
||||||
|
{
|
||||||
|
if (!LocalPlayerIDUtility.DoesLocalPlayerExist(entitiesDB))
|
||||||
|
return;
|
||||||
|
GetPlayerInputRef(GetLocalPlayerID()).actionMask |= _localInputCache;
|
||||||
|
_localInputCache = default;
|
||||||
|
}
|
||||||
|
|
||||||
public uint GetLocalPlayerID()
|
public uint GetLocalPlayerID()
|
||||||
{
|
{
|
||||||
return LocalPlayerIDUtility.GetLocalPlayerID(entitiesDB);
|
return LocalPlayerIDUtility.GetLocalPlayerID(entitiesDB);
|
||||||
|
|
19
TechbloxModdingAPI/Input/FakeInputPatch.cs
Normal file
19
TechbloxModdingAPI/Input/FakeInputPatch.cs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace TechbloxModdingAPI.Input
|
||||||
|
{
|
||||||
|
[HarmonyPatch]
|
||||||
|
public static class FakeInputPatch
|
||||||
|
{
|
||||||
|
public static void Prefix()
|
||||||
|
{
|
||||||
|
FakeInput.inputEngine.HandleCustomInput(); // This gets called right before the input is sent to the server
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodBase TargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method("RobocraftX.Multiplayer.Input.NetworkInputRecorderEngine:RecordDeterministicInput");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,7 @@
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using TechbloxModdingAPI.App;
|
|
||||||
using TechbloxModdingAPI.Utility;
|
|
||||||
using Rewired.Internal;
|
|
||||||
using Svelto.DataStructures;
|
|
||||||
using Svelto.Tasks;
|
using Svelto.Tasks;
|
||||||
using Svelto.Tasks.ExtraLean;
|
using Svelto.Tasks.ExtraLean;
|
||||||
using Svelto.Tasks.ExtraLean.Unity;
|
using TechbloxModdingAPI.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Interface.IMGUI
|
namespace TechbloxModdingAPI.Interface.IMGUI
|
||||||
|
|
|
@ -3,13 +3,11 @@ using System.Reflection;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
using RobocraftX.Schedulers;
|
|
||||||
using RobocraftX.Services;
|
using RobocraftX.Services;
|
||||||
using Svelto.Context;
|
using Svelto.Context;
|
||||||
using Svelto.Tasks.ExtraLean;
|
|
||||||
using TechbloxModdingAPI.App;
|
using TechbloxModdingAPI.App;
|
||||||
using TechbloxModdingAPI.Blocks;
|
using TechbloxModdingAPI.Blocks;
|
||||||
using TechbloxModdingAPI.Events;
|
|
||||||
using TechbloxModdingAPI.Tasks;
|
using TechbloxModdingAPI.Tasks;
|
||||||
using TechbloxModdingAPI.Utility;
|
using TechbloxModdingAPI.Utility;
|
||||||
|
|
||||||
|
@ -51,34 +49,42 @@ namespace TechbloxModdingAPI
|
||||||
harmony.PatchAll(currentAssembly);
|
harmony.PatchAll(currentAssembly);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{ //Can't use ErrorBuilder or Logging.LogException (which eventually uses ErrorBuilder) yet
|
{
|
||||||
Logging.Log(e.ToString());
|
HandleError(e, "Failed to patch Techblox. Attempting to patch to display error...", OnPatchError);
|
||||||
Logging.LogWarning("Failed to patch Techblox. Attempting to patch to display error...");
|
|
||||||
harmony.Patch(AccessTools.Method(typeof(FullGameCompositionRoot), "OnContextInitialized")
|
|
||||||
.MakeGenericMethod(typeof(UnityContext<FullGameCompositionRoot>)),
|
|
||||||
new HarmonyMethod(((Action) OnPatchError).Method)); //Can't use lambdas here :(
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// init utility
|
try
|
||||||
Logging.MetaDebugLog($"Initializing Utility");
|
{
|
||||||
Utility.GameState.Init();
|
// init utility
|
||||||
// init block implementors
|
Logging.MetaDebugLog($"Initializing Utility");
|
||||||
Logging.MetaDebugLog($"Initializing Blocks");
|
Utility.GameState.Init();
|
||||||
// init input
|
// init block implementors
|
||||||
Input.FakeInput.Init();
|
Logging.MetaDebugLog($"Initializing Blocks");
|
||||||
// init object-oriented classes
|
// init input
|
||||||
Player.Init();
|
Input.FakeInput.Init();
|
||||||
Block.Init();
|
// init object-oriented classes
|
||||||
BlockGroup.Init();
|
Player.Init();
|
||||||
Wire.Init();
|
Block.Init();
|
||||||
Logging.MetaDebugLog($"Initializing Client");
|
BlockGroup.Init();
|
||||||
Client.Init();
|
Wire.Init();
|
||||||
Game.Init();
|
// init client
|
||||||
// init UI
|
Logging.MetaDebugLog($"Initializing Client");
|
||||||
Interface.IMGUI.Constants.Init();
|
Client.Init();
|
||||||
Interface.IMGUI.IMGUIManager.Init();
|
Game.Init();
|
||||||
Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized");
|
// init UI
|
||||||
|
Logging.MetaDebugLog($"Initializing UI");
|
||||||
|
Interface.IMGUI.Constants.Init();
|
||||||
|
Interface.IMGUI.IMGUIManager.Init();
|
||||||
|
// init anti-anticheat
|
||||||
|
Logging.MetaDebugLog("Initializing anti-anticheat");
|
||||||
|
AntiAntiCheatPatch.Init(harmony);
|
||||||
|
Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
HandleError(e, "Failed to initialize the API! Attempting to patch to display error...", OnInitError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -109,5 +115,26 @@ namespace TechbloxModdingAPI
|
||||||
ErrorBuilder.DisplayMustQuitError("Failed to patch Techblox!\n" +
|
ErrorBuilder.DisplayMustQuitError("Failed to patch Techblox!\n" +
|
||||||
"Make sure you're using the latest version of TechbloxModdingAPI or disable mods if the API isn't released yet.");
|
"Make sure you're using the latest version of TechbloxModdingAPI or disable mods if the API isn't released yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void OnInitError()
|
||||||
|
{
|
||||||
|
ErrorBuilder.DisplayMustQuitError("Failed to initialize the modding API!\n" +
|
||||||
|
"Make sure you're using the latest version. If you are, please report the error.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles an init error. Logs the exception, a log message, and allows displaying an error in-game.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">The exception</param>
|
||||||
|
/// <param name="logMsg">The log message</param>
|
||||||
|
/// <param name="onInit">The action to run when the game is ready to display error messages</param>
|
||||||
|
private static void HandleError(Exception e, string logMsg, Action onInit)
|
||||||
|
{ //Can't use ErrorBuilder or Logging.LogException (which eventually uses ErrorBuilder) yet
|
||||||
|
Logging.Log(e.ToString());
|
||||||
|
Logging.LogWarning(logMsg);
|
||||||
|
harmony.Patch(AccessTools.Method(typeof(FullGameCompositionRoot), "OnContextInitialized")
|
||||||
|
.MakeGenericMethod(typeof(UnityContext<FullGameCompositionRoot>)),
|
||||||
|
new HarmonyMethod(onInit.Method)); //Can't use lambdas here :(
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace TechbloxModdingAPI.Persistence
|
||||||
Logging.MetaDebugLog("Skipping component serialization: no serializers registered!");
|
Logging.MetaDebugLog("Skipping component serialization: no serializers registered!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
serializationData.data.ExpandBy((uint)frameStart.Length);
|
serializationData.data.IncreaseCapacityBy((uint)frameStart.Length);
|
||||||
BinaryBufferWriter bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out int buffLen), serializationData.dataPos);
|
BinaryBufferWriter bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out int buffLen), serializationData.dataPos);
|
||||||
uint originalPos = serializationData.dataPos;
|
uint originalPos = serializationData.dataPos;
|
||||||
Logging.MetaDebugLog($"dataPos: {originalPos}");
|
Logging.MetaDebugLog($"dataPos: {originalPos}");
|
||||||
|
@ -35,14 +35,14 @@ namespace TechbloxModdingAPI.Persistence
|
||||||
bbw.Write(frameStart[i]);
|
bbw.Write(frameStart[i]);
|
||||||
}
|
}
|
||||||
Logging.MetaDebugLog($"dataPos (after frame start): {bbw.Position}");
|
Logging.MetaDebugLog($"dataPos (after frame start): {bbw.Position}");
|
||||||
serializationData.data.ExpandBy(4u);
|
serializationData.data.IncreaseCapacityBy(4u);
|
||||||
bbw.Write((uint)SerializerManager.GetSerializersCount());
|
bbw.Write((uint)SerializerManager.GetSerializersCount());
|
||||||
string[] serializerKeys = SerializerManager.GetSerializerNames();
|
string[] serializerKeys = SerializerManager.GetSerializerNames();
|
||||||
for (uint c = 0; c < serializerKeys.Length; c++)
|
for (uint c = 0; c < serializerKeys.Length; c++)
|
||||||
{
|
{
|
||||||
Logging.MetaDebugLog($"dataPos (loop start): {bbw.Position}");
|
Logging.MetaDebugLog($"dataPos (loop start): {bbw.Position}");
|
||||||
// write component info
|
// write component info
|
||||||
serializationData.data.ExpandBy(4u + (uint)serializerKeys[c].Length);
|
serializationData.data.IncreaseCapacityBy(4u + (uint)serializerKeys[c].Length);
|
||||||
bbw.Write((uint)serializerKeys[c].Length);
|
bbw.Write((uint)serializerKeys[c].Length);
|
||||||
Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
|
Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
|
||||||
byte[] nameBytes = Encoding.UTF8.GetBytes(serializerKeys[c]);
|
byte[] nameBytes = Encoding.UTF8.GetBytes(serializerKeys[c]);
|
||||||
|
@ -51,7 +51,7 @@ namespace TechbloxModdingAPI.Persistence
|
||||||
bbw.Write(nameBytes[i]);
|
bbw.Write(nameBytes[i]);
|
||||||
}
|
}
|
||||||
Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
|
Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
|
||||||
serializationData.data.ExpandBy(4u);
|
serializationData.data.IncreaseCapacityBy(4u);
|
||||||
serializationData.dataPos = bbw.Position + 4u;
|
serializationData.dataPos = bbw.Position + 4u;
|
||||||
Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
|
Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
|
||||||
Logging.MetaDebugLog($"dataPos (appears to be): {serializationData.dataPos}");
|
Logging.MetaDebugLog($"dataPos (appears to be): {serializationData.dataPos}");
|
||||||
|
@ -73,8 +73,8 @@ namespace TechbloxModdingAPI.Persistence
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MethodBase TargetMethod()
|
public static MethodBase TargetMethod()
|
||||||
{
|
{
|
||||||
return typeof(SaveGameEngine).GetMethod("SerializeGameToBuffer");
|
return AccessTools.TypeByName("RobocraftX.SaveAndLoad.SaveGameEngine").GetMethod("SerializeGameToBuffer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace TechbloxModdingAPI.Persistence
|
||||||
|
|
||||||
public bool Serialize(ref ISerializationData serializationData, EntitiesDB entitiesDB, IEntitySerialization entitySerializer)
|
public bool Serialize(ref ISerializationData serializationData, EntitiesDB entitiesDB, IEntitySerialization entitySerializer)
|
||||||
{
|
{
|
||||||
serializationData.data.ExpandBy(4u);
|
serializationData.data.IncreaseCapacityBy(4u);
|
||||||
BinaryBufferWriter bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out int count), serializationData.dataPos);
|
BinaryBufferWriter bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out int count), serializationData.dataPos);
|
||||||
EGID[] toSerialize = getEntitiesToSerialize(entitiesDB);
|
EGID[] toSerialize = getEntitiesToSerialize(entitiesDB);
|
||||||
bbw.Write((uint)toSerialize.Length);
|
bbw.Write((uint)toSerialize.Length);
|
||||||
|
|
|
@ -20,6 +20,22 @@ namespace TechbloxModdingAPI
|
||||||
add => seatExited += value;
|
add => seatExited += value;
|
||||||
remove => seatExited -= value;
|
remove => seatExited -= value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static WrappedHandler<PlayerEventArgs> joined;
|
||||||
|
|
||||||
|
public static event EventHandler<PlayerEventArgs> Joined
|
||||||
|
{
|
||||||
|
add => joined += value;
|
||||||
|
remove => joined -= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static WrappedHandler<PlayerEventArgs> left;
|
||||||
|
|
||||||
|
public static event EventHandler<PlayerEventArgs> Left
|
||||||
|
{
|
||||||
|
add => left += value;
|
||||||
|
remove => left -= value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct PlayerSeatEventArgs
|
public struct PlayerSeatEventArgs
|
||||||
|
@ -27,4 +43,10 @@ namespace TechbloxModdingAPI
|
||||||
public EGID SeatId;
|
public EGID SeatId;
|
||||||
public Seat Seat => (Seat)Block.New(SeatId);
|
public Seat Seat => (Seat)Block.New(SeatId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct PlayerEventArgs
|
||||||
|
{
|
||||||
|
public EGID PlayerId;
|
||||||
|
public Player Player => Player.GetInstance(PlayerId.entityID);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -23,8 +23,8 @@ namespace TechbloxModdingAPI
|
||||||
public partial class Player : EcsObjectBase, IEquatable<Player>, IEquatable<EGID>
|
public partial class Player : EcsObjectBase, IEquatable<Player>, IEquatable<EGID>
|
||||||
{
|
{
|
||||||
// static functionality
|
// static functionality
|
||||||
private static PlayerEngine playerEngine = new PlayerEngine();
|
private static readonly PlayerEngine playerEngine = new PlayerEngine();
|
||||||
private static PlayerEventsEngine playerEventsEngine = new PlayerEventsEngine();
|
private static readonly PlayerEventsEngine playerEventsEngine = new PlayerEventsEngine();
|
||||||
private static Player localPlayer;
|
private static Player localPlayer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -76,6 +76,12 @@ namespace TechbloxModdingAPI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static Player GetInstance(uint id)
|
||||||
|
{
|
||||||
|
return EcsObjectBase.GetInstance(new EGID(id, CharacterExclusiveGroups.OnFootGroup),
|
||||||
|
e => new Player(e.entityID));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="T:TechbloxModdingAPI.Player"/> class.
|
/// Initializes a new instance of the <see cref="T:TechbloxModdingAPI.Player"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -119,6 +125,7 @@ namespace TechbloxModdingAPI
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
this.Type = player;
|
this.Type = player;
|
||||||
|
Id = base.Id.entityID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// object fields & properties
|
// object fields & properties
|
||||||
|
@ -187,8 +194,6 @@ namespace TechbloxModdingAPI
|
||||||
public float Mass =>
|
public float Mass =>
|
||||||
1f / playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().physicsMass.InverseMass;
|
1f / playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().physicsMass.InverseMass;
|
||||||
|
|
||||||
private float _ping = -1f;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The player's latest network ping time.
|
/// The player's latest network ping time.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -197,12 +202,7 @@ namespace TechbloxModdingAPI
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var opt = playerEngine.GetPlayerStruct<PlayerNetworkStatsEntityStruct>(Id, Type);
|
return playerEngine.GetPing() / 1000f;
|
||||||
if (opt)
|
|
||||||
{
|
|
||||||
_ping = opt.Get().lastPingTimeSinceLevelLoad ?? _ping;
|
|
||||||
}
|
|
||||||
return _ping;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,15 +435,38 @@ namespace TechbloxModdingAPI
|
||||||
playerEngine.SetLocation(Id, location, exitSeat: exitSeat);
|
playerEngine.SetLocation(Id, location, exitSeat: exitSeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enter the given seat.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="seat">The seat to enter.</param>
|
||||||
public void EnterSeat(Seat seat)
|
public void EnterSeat(Seat seat)
|
||||||
{
|
{
|
||||||
playerEngine.EnterSeat(Id, seat.Id);
|
playerEngine.EnterSeat(Id, seat.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exit the seat the player is currently in.
|
||||||
|
/// </summary>
|
||||||
public void ExitSeat()
|
public void ExitSeat()
|
||||||
{
|
{
|
||||||
playerEngine.ExitSeat(Id);
|
playerEngine.ExitSeat(Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Spawn the machine the player is holding in time running mode.
|
||||||
|
/// </summary>
|
||||||
|
public bool SpawnMachine()
|
||||||
|
{
|
||||||
|
return playerEngine.SpawnMachine(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Despawn the player's machine in time running mode and place it in their hand.
|
||||||
|
/// </summary>
|
||||||
|
public bool DespawnMachine()
|
||||||
|
{
|
||||||
|
return playerEngine.DespawnMachine(Id);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the block the player is currently looking at in build mode.
|
/// Returns the block the player is currently looking at in build mode.
|
||||||
|
@ -481,7 +504,7 @@ namespace TechbloxModdingAPI
|
||||||
{
|
{
|
||||||
var egid = playerEngine.GetThingLookedAt(Id, maxDistance);
|
var egid = playerEngine.GetThingLookedAt(Id, maxDistance);
|
||||||
return egid != default && egid.groupID == WiresGUIExclusiveGroups.WireGroup
|
return egid != default && egid.groupID == WiresGUIExclusiveGroups.WireGroup
|
||||||
? EcsObjectBase.GetInstance(new EGID(egid.entityID, NamedExclusiveGroup<WiresGroup>.Group),
|
? EcsObjectBase.GetInstance(new EGID(egid.entityID, BuildModeWiresGroups.WiresGroup.Group),
|
||||||
e => new Wire(e))
|
e => new Wire(e))
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,9 @@ using RobocraftX.Physics;
|
||||||
using RobocraftX.Blocks.Ghost;
|
using RobocraftX.Blocks.Ghost;
|
||||||
using Gamecraft.GUI.HUDFeedbackBlocks;
|
using Gamecraft.GUI.HUDFeedbackBlocks;
|
||||||
using RobocraftX.Blocks;
|
using RobocraftX.Blocks;
|
||||||
|
using RobocraftX.Multiplayer;
|
||||||
using RobocraftX.PilotSeat;
|
using RobocraftX.PilotSeat;
|
||||||
|
using RobocraftX.SimulationModeState;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Techblox.Camera;
|
using Techblox.Camera;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
|
@ -19,6 +21,7 @@ using Svelto.ECS.EntityStructs;
|
||||||
using Techblox.BuildingDrone;
|
using Techblox.BuildingDrone;
|
||||||
|
|
||||||
using TechbloxModdingAPI.Engines;
|
using TechbloxModdingAPI.Engines;
|
||||||
|
using TechbloxModdingAPI.Input;
|
||||||
using TechbloxModdingAPI.Utility;
|
using TechbloxModdingAPI.Utility;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Players
|
namespace TechbloxModdingAPI.Players
|
||||||
|
@ -204,6 +207,8 @@ namespace TechbloxModdingAPI.Players
|
||||||
|
|
||||||
public void EnterSeat(uint playerId, EGID seatId)
|
public void EnterSeat(uint playerId, EGID seatId)
|
||||||
{
|
{
|
||||||
|
if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB))
|
||||||
|
return;
|
||||||
PilotSeatGroupUtils.SwapTagTo<OCCUPIED_TAG>(Functions, seatId);
|
PilotSeatGroupUtils.SwapTagTo<OCCUPIED_TAG>(Functions, seatId);
|
||||||
var opt = GetCharacterStruct<CharacterPilotSeatEntityStruct>(playerId, out var group);
|
var opt = GetCharacterStruct<CharacterPilotSeatEntityStruct>(playerId, out var group);
|
||||||
if (!opt) return;
|
if (!opt) return;
|
||||||
|
@ -221,11 +226,46 @@ namespace TechbloxModdingAPI.Players
|
||||||
|
|
||||||
public void ExitSeat(uint playerId)
|
public void ExitSeat(uint playerId)
|
||||||
{
|
{
|
||||||
|
if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB))
|
||||||
|
return;
|
||||||
EGID egid = new EGID(playerId, CharacterExclusiveGroups.InPilotSeatGroup);
|
EGID egid = new EGID(playerId, CharacterExclusiveGroups.InPilotSeatGroup);
|
||||||
var opt = entitiesDB.QueryEntityOptional<CharacterPilotSeatEntityStruct>(egid);
|
var opt = entitiesDB.QueryEntityOptional<CharacterPilotSeatEntityStruct>(egid);
|
||||||
if (!opt) return;
|
if (!opt) return;
|
||||||
opt.Get().instantExit = true;
|
opt.Get().instantExit = true;
|
||||||
entitiesDB.PublishEntityChange<CharacterPilotSeatEntityStruct>(egid);
|
entitiesDB.PublishEntityChange<CharacterPilotSeatEntityStruct>(egid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SpawnMachine(uint playerId)
|
||||||
|
{
|
||||||
|
if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB))
|
||||||
|
return false;
|
||||||
|
EGID egid = new EGID(playerId, CharacterExclusiveGroups.MachineSpawningGroup);
|
||||||
|
if (!entitiesDB.Exists<CharacterTagEntityStruct>(egid))
|
||||||
|
return false;
|
||||||
|
//Functions.SwapEntityGroup<CharacterEntityDescriptor>(egid, CharacterExclusiveGroups.OnFootGroup);
|
||||||
|
FakeInput.ActionInput(playerId, primary: true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DespawnMachine(uint playerId)
|
||||||
|
{
|
||||||
|
if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB))
|
||||||
|
return false;
|
||||||
|
GetCharacterStruct<CharacterTagEntityStruct>(playerId, out var group);
|
||||||
|
if (group.isInvalid)
|
||||||
|
return false;
|
||||||
|
EGID egid = new EGID(playerId, group);
|
||||||
|
if (!entitiesDB.Exists<CharacterTagEntityStruct>(egid))
|
||||||
|
return false;
|
||||||
|
Functions.SwapEntityGroup<CharacterEntityDescriptor>(egid, CharacterExclusiveGroups.MachineSpawningGroup);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint GetPing()
|
||||||
|
{
|
||||||
|
return entitiesDB
|
||||||
|
.QueryUniqueEntity<NetworkStatsEntityStruct>(MultiplayerExclusiveGroups.MultiplayerStateGroup)
|
||||||
|
.networkStats.PingMs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
using RobocraftX.Character;
|
using RobocraftX.Character;
|
||||||
using RobocraftX.Character.Movement;
|
using RobocraftX.Character.Movement;
|
||||||
|
using RobocraftX.Common.Input;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
|
|
||||||
using TechbloxModdingAPI.Engines;
|
using TechbloxModdingAPI.Engines;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Players
|
namespace TechbloxModdingAPI.Players
|
||||||
{
|
{
|
||||||
public class PlayerEventsEngine : IApiEngine, IReactOnSwap<CharacterPilotSeatEntityStruct>
|
public class PlayerEventsEngine : IApiEngine, IReactOnSwap<CharacterPilotSeatEntityStruct>, IReactOnAddAndRemove<PlayerIDStruct>
|
||||||
{
|
{
|
||||||
public void Ready()
|
public void Ready()
|
||||||
{
|
{
|
||||||
|
@ -21,13 +23,22 @@ namespace TechbloxModdingAPI.Players
|
||||||
|
|
||||||
public void MovedTo(ref CharacterPilotSeatEntityStruct entityComponent, ExclusiveGroupStruct previousGroup, EGID egid)
|
public void MovedTo(ref CharacterPilotSeatEntityStruct entityComponent, ExclusiveGroupStruct previousGroup, EGID egid)
|
||||||
{
|
{
|
||||||
var seatId = entityComponent.pilotSeatEntity.ToEGID(entitiesDB);
|
entitiesDB.TryGetEGID(entityComponent.pilotSeatEntity, out var seatId); //TODO: Can't get EGID
|
||||||
var player = EcsObjectBase.GetInstance(new EGID(egid.entityID, CharacterExclusiveGroups.OnFootGroup),
|
var player = Player.GetInstance(egid.entityID);
|
||||||
e => new Player(e.entityID));
|
|
||||||
if (previousGroup == CharacterExclusiveGroups.InPilotSeatGroup)
|
if (previousGroup == CharacterExclusiveGroups.InPilotSeatGroup)
|
||||||
player.seatExited.Invoke(this, new PlayerSeatEventArgs { SeatId = seatId});
|
player.seatExited.Invoke(this, new PlayerSeatEventArgs { SeatId = seatId});
|
||||||
else if (egid.groupID == CharacterExclusiveGroups.InPilotSeatGroup)
|
else if (egid.groupID == CharacterExclusiveGroups.InPilotSeatGroup)
|
||||||
player.seatEntered.Invoke(this, new PlayerSeatEventArgs { SeatId = seatId });
|
player.seatEntered.Invoke(this, new PlayerSeatEventArgs { SeatId = seatId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Add(ref PlayerIDStruct entityComponent, EGID egid)
|
||||||
|
{
|
||||||
|
Player.joined.Invoke(this, new PlayerEventArgs { PlayerId = egid });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(ref PlayerIDStruct entityComponent, EGID egid)
|
||||||
|
{
|
||||||
|
Player.left.Invoke(this, new PlayerEventArgs { PlayerId = egid });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Svelto.Tasks;
|
using Svelto.Tasks;
|
||||||
using Svelto.Tasks.Enumerators;
|
using Svelto.Tasks.Enumerators;
|
||||||
|
@ -7,6 +8,7 @@ using Unity.Mathematics;
|
||||||
using TechbloxModdingAPI.App;
|
using TechbloxModdingAPI.App;
|
||||||
using TechbloxModdingAPI.Blocks;
|
using TechbloxModdingAPI.Blocks;
|
||||||
using TechbloxModdingAPI.Tests;
|
using TechbloxModdingAPI.Tests;
|
||||||
|
using TechbloxModdingAPI.Utility;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Players
|
namespace TechbloxModdingAPI.Players
|
||||||
{
|
{
|
||||||
|
@ -45,7 +47,20 @@ namespace TechbloxModdingAPI.Players
|
||||||
[APITestCase(TestType.SimulationMode)]
|
[APITestCase(TestType.SimulationMode)]
|
||||||
public static IEnumerator<TaskContract> SeatEventTestSim()
|
public static IEnumerator<TaskContract> SeatEventTestSim()
|
||||||
{
|
{
|
||||||
|
yield return new WaitForSecondsEnumerator(1).Continue();
|
||||||
|
Assert.Equal(Player.LocalPlayer.SpawnMachine(), true, "Failed to spawn the player's machine.", "Successfully spawned the player's machine.");
|
||||||
|
yield return new WaitForSecondsEnumerator(1).Continue();
|
||||||
var seats = Game.CurrentGame().GetBlocksInGame(BlockIDs.DriverSeat);
|
var seats = Game.CurrentGame().GetBlocksInGame(BlockIDs.DriverSeat);
|
||||||
|
int c = 0;
|
||||||
|
while (seats.Length == 0 && c < 10)
|
||||||
|
{
|
||||||
|
Logging.MetaLog("Waiting for a seat to be spawned...");
|
||||||
|
yield return new WaitForSecondsEnumerator(1).Continue();
|
||||||
|
Console.WriteLine("Spawn machine: " + Player.LocalPlayer.SpawnMachine());
|
||||||
|
seats = Game.CurrentGame().GetBlocksInGame(BlockIDs.DriverSeat);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
if (seats.Length == 0)
|
if (seats.Length == 0)
|
||||||
{
|
{
|
||||||
Assert.Fail("No driver seat found!");
|
Assert.Fail("No driver seat found!");
|
||||||
|
|
16
TechbloxModdingAPI/Tasks/OnGuiRunner.cs
Normal file
16
TechbloxModdingAPI/Tasks/OnGuiRunner.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
using System.Collections;
|
||||||
|
using Svelto.Tasks;
|
||||||
|
using Svelto.Tasks.ExtraLean;
|
||||||
|
using Svelto.Tasks.Unity.Internal;
|
||||||
|
|
||||||
|
namespace TechbloxModdingAPI.Tasks
|
||||||
|
{
|
||||||
|
public class OnGuiRunner : BaseRunner<ExtraLeanSveltoTask<IEnumerator>>
|
||||||
|
{
|
||||||
|
public OnGuiRunner(string name, uint runningOrder = 0)
|
||||||
|
: base(name)
|
||||||
|
{
|
||||||
|
UnityCoroutineRunner.StartOnGuiCoroutine(this._processEnumerator, runningOrder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ namespace TechbloxModdingAPI.Tasks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return RobocraftX.Schedulers.Lean.UIScheduler;
|
return RobocraftX.Schedulers.ClientLean.UIScheduler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ namespace TechbloxModdingAPI.Tasks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return RobocraftX.Schedulers.ExtraLean.UIScheduler;
|
return RobocraftX.Schedulers.ClientExtraLean.UIScheduler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,10 @@ using IllusionInjector;
|
||||||
using RobocraftX.FrontEnd;
|
using RobocraftX.FrontEnd;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using RobocraftX.Common.Input;
|
|
||||||
using Svelto.Tasks;
|
using Svelto.Tasks;
|
||||||
using Svelto.Tasks.Lean;
|
using Svelto.Tasks.Lean;
|
||||||
using TechbloxModdingAPI.Blocks;
|
using TechbloxModdingAPI.Blocks;
|
||||||
using TechbloxModdingAPI.Commands;
|
using TechbloxModdingAPI.Commands;
|
||||||
using TechbloxModdingAPI.Input;
|
|
||||||
using TechbloxModdingAPI.Players;
|
using TechbloxModdingAPI.Players;
|
||||||
using TechbloxModdingAPI.Tasks;
|
using TechbloxModdingAPI.Tasks;
|
||||||
using TechbloxModdingAPI.Utility;
|
using TechbloxModdingAPI.Utility;
|
||||||
|
@ -345,6 +343,11 @@ namespace TechbloxModdingAPI.Tests
|
||||||
Logging.CommandLog(asset);
|
Logging.CommandLog(asset);
|
||||||
}
|
}
|
||||||
}).Build();
|
}).Build();
|
||||||
|
Client.EnterMenu += (sender, args) => Scheduler.Schedule(new Once(() => Client.Instance.CloseBetaPopup()));
|
||||||
|
|
||||||
|
Game.Enter += (sender, args) =>
|
||||||
|
Console.WriteLine(
|
||||||
|
$"Current game selection data: {FullGameFields._gameSelectionData.gameMode} - {FullGameFields._gameSelectionData.saveType}");
|
||||||
#if TEST
|
#if TEST
|
||||||
TestRoot.RunTests();
|
TestRoot.RunTests();
|
||||||
#endif
|
#endif
|
||||||
|
@ -360,15 +363,6 @@ namespace TechbloxModdingAPI.Tests
|
||||||
return modsString = sb.ToString();
|
return modsString = sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnUpdate()
|
|
||||||
{
|
|
||||||
if (UnityEngine.Input.GetKeyDown(KeyCode.End))
|
|
||||||
{
|
|
||||||
Console.WriteLine("Pressed button to toggle console");
|
|
||||||
FakeInput.CustomInput(new LocalCosmeticInputEntityComponent {commandLineToggleInput = true});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HarmonyPatch]
|
[HarmonyPatch]
|
||||||
public class MinimumSpecsPatch
|
public class MinimumSpecsPatch
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,9 @@ using System.Linq; // welcome to the dark side
|
||||||
using Svelto.Tasks;
|
using Svelto.Tasks;
|
||||||
using Svelto.Tasks.Lean;
|
using Svelto.Tasks.Lean;
|
||||||
using Svelto.Tasks.Enumerators;
|
using Svelto.Tasks.Enumerators;
|
||||||
|
using Svelto.Tasks.Lean.Unity;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
using TechbloxModdingAPI.App;
|
using TechbloxModdingAPI.App;
|
||||||
using TechbloxModdingAPI.Tasks;
|
using TechbloxModdingAPI.Tasks;
|
||||||
using TechbloxModdingAPI.Utility;
|
using TechbloxModdingAPI.Utility;
|
||||||
|
@ -64,7 +66,7 @@ namespace TechbloxModdingAPI.Tests
|
||||||
_testsCountPassed = 0;
|
_testsCountPassed = 0;
|
||||||
_testsCountFailed = 0;
|
_testsCountFailed = 0;
|
||||||
// flow control
|
// flow control
|
||||||
Game.Enter += (sender, args) => { GameTests().RunOn(RobocraftX.Schedulers.Lean.EveryFrameStepRunner_TimeRunningAndStopped); };
|
Game.Enter += (sender, args) => { GameTests().RunOn(new UpdateMonoRunner("TechbloxModdingAPITestRunner")); };
|
||||||
Game.Exit += (s, a) => state = "ReturningFromGame";
|
Game.Exit += (s, a) => state = "ReturningFromGame";
|
||||||
Client.EnterMenu += (sender, args) =>
|
Client.EnterMenu += (sender, args) =>
|
||||||
{
|
{
|
||||||
|
@ -129,7 +131,7 @@ namespace TechbloxModdingAPI.Tests
|
||||||
|
|
||||||
private static IEnumerator<TaskContract> GoToGameTests()
|
private static IEnumerator<TaskContract> GoToGameTests()
|
||||||
{
|
{
|
||||||
Client app = new Client();
|
Client app = Client.Instance;
|
||||||
int oldLength = 0;
|
int oldLength = 0;
|
||||||
while (app.MyGames.Length == 0 || oldLength != app.MyGames.Length)
|
while (app.MyGames.Length == 0 || oldLength != app.MyGames.Length)
|
||||||
{
|
{
|
||||||
|
@ -137,7 +139,15 @@ namespace TechbloxModdingAPI.Tests
|
||||||
yield return new WaitForSecondsEnumerator(1).Continue();
|
yield return new WaitForSecondsEnumerator(1).Continue();
|
||||||
}
|
}
|
||||||
yield return Yield.It;
|
yield return Yield.It;
|
||||||
app.MyGames[0].EnterGame();
|
try
|
||||||
|
{
|
||||||
|
app.MyGames[0].EnterGame();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Failed to go to game tests");
|
||||||
|
Console.WriteLine(e);
|
||||||
|
}
|
||||||
/*Game newGame = Game.NewGame();
|
/*Game newGame = Game.NewGame();
|
||||||
yield return new WaitForSecondsEnumerator(5).Continue(); // wait for sync
|
yield return new WaitForSecondsEnumerator(5).Continue(); // wait for sync
|
||||||
newGame.EnterGame();*/
|
newGame.EnterGame();*/
|
||||||
|
@ -157,6 +167,7 @@ namespace TechbloxModdingAPI.Tests
|
||||||
};
|
};
|
||||||
for (var index = 0; index < testTypesToRun.Length; index++)
|
for (var index = 0; index < testTypesToRun.Length; index++)
|
||||||
{
|
{
|
||||||
|
Logging.MetaLog($"Running test type {testTypesToRun[index]}");
|
||||||
foreach (Type t in testTypes)
|
foreach (Type t in testTypes)
|
||||||
{
|
{
|
||||||
foreach (MethodBase m in t.GetMethods())
|
foreach (MethodBase m in t.GetMethods())
|
||||||
|
@ -198,7 +209,16 @@ 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;
|
||||||
currentGame.ToggleTimeMode();
|
currentGame.ToggleTimeMode();
|
||||||
|
while (running ? !currentGame.IsTimeStopped : !currentGame.IsTimeRunning)
|
||||||
|
{
|
||||||
|
Logging.MetaLog($"Waiting for time to {(running?"stop":"start")}...");
|
||||||
|
yield return new WaitForSecondsEnumerator(1).Continue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
yield return new WaitForSecondsEnumerator(5).Continue();
|
yield return new WaitForSecondsEnumerator(5).Continue();
|
||||||
}
|
}
|
||||||
// exit game
|
// exit game
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
using System;
|
using DataLoader;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
using DataLoader;
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
using RobocraftX.Common.Utilities;
|
using RobocraftX.CR.MainGame;
|
||||||
using RobocraftX.GUI;
|
using RobocraftX.GUI;
|
||||||
using RobocraftX.Multiplayer;
|
using RobocraftX.Multiplayer;
|
||||||
using RobocraftX.Rendering;
|
|
||||||
using Svelto.Context;
|
using Svelto.Context;
|
||||||
using Svelto.DataStructures;
|
using Svelto.DataStructures;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Svelto.ECS.Schedulers;
|
using Svelto.ECS.GUI;
|
||||||
|
using Techblox.GameSelection;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Unity.Entities;
|
using Unity.Entities;
|
||||||
using Unity.Physics.Systems;
|
using Unity.Physics.Systems;
|
||||||
|
@ -104,14 +98,6 @@ namespace TechbloxModdingAPI.Utility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PhysicsUtility _physicsUtility
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return (PhysicsUtility)fgcr?.Field("_physicsUtility").GetValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*public static UnityEntitySubmissionScheduler _frontEndSubmissionScheduler
|
/*public static UnityEntitySubmissionScheduler _frontEndSubmissionScheduler
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -136,11 +122,11 @@ namespace TechbloxModdingAPI.Utility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ECSGameObjectResourceManager _eCsGameObjectResourceManager
|
public static ECSResourceManagers _managers
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return (ECSGameObjectResourceManager)fgcr?.Field("_eCsGameObjectResourceManager").GetValue();
|
return (ECSResourceManagers)fgcr?.Field("_managers").GetValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +146,22 @@ namespace TechbloxModdingAPI.Utility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SveltoGUI _frontEndGUI
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (SveltoGUI)fgcr?.Field("_frontEndGUI").GetValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameSelectionData _gameSelectionData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (GameSelectionData)fgcr?.Field("_gameSelectionData").GetValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Traverse fgcr;
|
private static Traverse fgcr;
|
||||||
|
|
||||||
public static void Init(FullGameCompositionRoot instance)
|
public static void Init(FullGameCompositionRoot instance)
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
using RobocraftX.StateSync;
|
using RobocraftX.StateSync;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
|
|
|
@ -34,6 +34,12 @@ namespace TechbloxModdingAPI.Utility
|
||||||
Logging.LogWarning(wrappedException.ToString());
|
Logging.LogWarning(wrappedException.ToString());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if (wrappers.ContainsKey(added))
|
||||||
|
{
|
||||||
|
original.eventHandler -= wrapped;
|
||||||
|
wrappers.Remove(added);
|
||||||
|
}
|
||||||
|
|
||||||
wrappers.Add(added, wrapped);
|
wrappers.Add(added, wrapped);
|
||||||
return new WrappedHandler<T> { eventHandler = original.eventHandler + wrapped };
|
return new WrappedHandler<T> { eventHandler = original.eventHandler + wrapped };
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue