A bit hacky, but it workstags/v1.2.0
@@ -7,6 +7,7 @@ using Svelto.ECS.EntityStructs; | |||
using RobocraftX.Common; | |||
using RobocraftX.Blocks; | |||
using Unity.Mathematics; | |||
using Unity.Entities; | |||
using Gamecraft.Blocks.GUI; | |||
using GamecraftModdingAPI.Blocks; | |||
@@ -26,6 +27,7 @@ namespace GamecraftModdingAPI | |||
protected static readonly RemovalEngine RemovalEngine = new RemovalEngine(); | |||
protected static readonly SignalEngine SignalEngine = new SignalEngine(); | |||
protected static readonly BlockEventsEngine BlockEventsEngine = new BlockEventsEngine(); | |||
protected static readonly ScalingEngine ScalingEngine = new ScalingEngine(); | |||
protected internal static readonly BlockEngine BlockEngine = new BlockEngine(); | |||
@@ -173,7 +175,10 @@ namespace GamecraftModdingAPI | |||
get => BlockEngine.GetBlockInfo<ScalingEntityStruct>(Id).scale; | |||
set | |||
{ | |||
BlockEngine.GetBlockInfo<ScalingEntityStruct>(Id).scale = value; | |||
if (!Exists) return; //UpdateCollision needs the block to exist | |||
ref var scaling = ref BlockEngine.GetBlockInfo<ScalingEntityStruct>(Id); | |||
scaling.scale = value; | |||
ScalingEngine.UpdateCollision(Id); | |||
} | |||
} | |||
@@ -295,6 +300,7 @@ namespace GamecraftModdingAPI | |||
GameEngineManager.AddGameEngine(RemovalEngine); | |||
GameEngineManager.AddGameEngine(BlockEngine); | |||
GameEngineManager.AddGameEngine(BlockEventsEngine); | |||
GameEngineManager.AddGameEngine(ScalingEngine); | |||
} | |||
/// <summary> | |||
@@ -325,5 +331,9 @@ namespace GamecraftModdingAPI | |||
} | |||
} | |||
#endif | |||
internal static void Setup(World physicsWorld) | |||
{ | |||
ScalingEngine.Setup(physicsWorld.EntityManager); | |||
} | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
using System.Reflection; | |||
using HarmonyLib; | |||
using RobocraftX.Common; | |||
using RobocraftX.UECS; | |||
using Svelto.ECS; | |||
using Unity.Entities; | |||
using GamecraftModdingAPI.Engines; | |||
using GamecraftModdingAPI.Utility; | |||
namespace GamecraftModdingAPI.Blocks | |||
{ | |||
public class ScalingEngine : IApiEngine | |||
{ | |||
private static IReactOnAddAndRemove<UECSPhysicsEntityCreationStruct> physicsEngine; | |||
public void Ready() | |||
{ | |||
} | |||
public EntitiesDB entitiesDB { get; set; } | |||
public void Dispose() | |||
{ | |||
} | |||
public string Name { get; } = "GamecraftModdingAPIScalingEngine"; | |||
public bool isRemovable { get; } = false; | |||
private static EntityManager _entityManager; //Unity entity manager | |||
public void UpdateCollision(EGID egid) | |||
{ | |||
//Assuming the block exists | |||
var entity = entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(egid).uecsEntity; | |||
var pes = new UECSPhysicsEntityCreationStruct(); | |||
physicsEngine.Add(ref pes, egid); //Create new UECS entity | |||
_entityManager.DestroyEntity(entity); | |||
} | |||
internal void Setup(EntityManager entityManager) | |||
{ | |||
_entityManager = entityManager; | |||
} | |||
[HarmonyPatch] | |||
public class PhysicsEnginePatch | |||
{ | |||
static void Postfix(IReactOnAddAndRemove<UECSPhysicsEntityCreationStruct> __instance) | |||
{ | |||
physicsEngine = __instance; | |||
Logging.MetaDebugLog("Physics engine injected."); | |||
} | |||
static MethodBase TargetMethod(Harmony instance) | |||
{ | |||
return AccessTools.Method("RobocraftX.StateSync.HandleUECSPhysicEntitiesWithPrefabCreationEngine" + | |||
":Ready"); | |||
} | |||
} | |||
} | |||
} |
@@ -6,11 +6,11 @@ using System.Text; | |||
using System.Threading.Tasks; | |||
using HarmonyLib; | |||
using RobocraftX; | |||
using RobocraftX.CR.MainGame; | |||
using Svelto.ECS; | |||
using Unity.Entities; | |||
using GamecraftModdingAPI.Utility; | |||
using RobocraftX.CR.MainGame; | |||
namespace GamecraftModdingAPI.Events | |||
{ | |||
@@ -24,13 +24,15 @@ namespace GamecraftModdingAPI.Events | |||
public static bool IsGameReloading = false; | |||
public static void Postfix(ref object contextHolder, ref EnginesRoot enginesRoot) | |||
public static void Postfix(ref object contextHolder, ref EnginesRoot enginesRoot, World physicsWorld) | |||
{ | |||
// register custom game engines | |||
GameEngineManager.RegisterEngines(enginesRoot); | |||
// initialize AsyncUtils | |||
AsyncUtils.Setup(enginesRoot); | |||
// A new EnginesRoot is always created when ActivateGame is called | |||
// initialize Block | |||
Block.Setup(physicsWorld); | |||
// A new EnginesRoot is always created when ActivateGame is called | |||
// so all event emitters and handlers must be re-registered. | |||
EventManager.RegisterEngines(enginesRoot); | |||
Logging.Log("Dispatching Game Activated event"); | |||
@@ -340,7 +340,7 @@ namespace GamecraftModdingAPI | |||
} | |||
/// <summary> | |||
/// Returns the block the player is currently looking at. | |||
/// Returns the block the player is currently looking at in build mode. | |||
/// </summary> | |||
/// <param name="maxDistance">The maximum distance from the player (default is the player's building reach)</param> | |||
/// <returns>The block or null if not found</returns> | |||
@@ -224,7 +224,6 @@ namespace GamecraftModdingAPI.Tests | |||
} | |||
}).Build(); | |||
GameClient.SetDebugInfo("lookedAt", LookedAt); | |||
GameClient.SetDebugInfo("InstalledMods", InstalledMods); | |||
Block.Placed += (sender, args) => | |||
Logging.MetaDebugLog("Placed block " + args.Type + " with ID " + args.ID); | |||
@@ -286,32 +285,6 @@ namespace GamecraftModdingAPI.Tests | |||
} | |||
} | |||
private Player player; | |||
private string LookedAt() | |||
{ | |||
if (player == null) | |||
player = new Player(PlayerType.Local); | |||
if (GameState.IsBuildMode()) | |||
{ | |||
Block block = player.GetBlockLookedAt(); | |||
if (block == null) return "Block: none"; | |||
return "Block: " + block.Type + "\nColor: " + block.Color + "\n" + "At: " + block.Position | |||
+ "\nText: " + block.Label; | |||
} | |||
if (GameState.IsSimulationMode()) | |||
{ | |||
SimBody body = player.GetSimBodyLookedAt(); | |||
if (body == null) return "Body: none"; | |||
return "Body: " + (body.Static ? "static" : "non-static") | |||
+ "\nAt: " + body.Position + " - rotated: " + body.Rotation | |||
+ "\nWith mass: " + body.Mass + " - center: " + body.CenterOfMass | |||
+ "\nVelocity: " + body.Velocity + " - angular: " + body.AngularVelocity; | |||
} | |||
return "Switching modes..."; | |||
} | |||
private string modsString; | |||
private string InstalledMods() | |||
{ | |||
@@ -17,6 +17,11 @@ namespace GamecraftModdingAPI.Utility | |||
await gameEngine.WaitForSubmission(); | |||
} | |||
public static async Task WaitForNextFrame() | |||
{ | |||
await gameEngine.WaitForNextFrame(); | |||
} | |||
public static void Setup(EnginesRoot enginesRoot) | |||
{ | |||
gameEngine.Setup(enginesRoot.GenerateEntityFunctions(), enginesRoot.GenerateEntityFactory()); | |||
@@ -22,6 +22,12 @@ namespace GamecraftModdingAPI.Utility | |||
task.SetResult(null); | |||
} | |||
private IEnumerator WaitForNextFrameInternal(TaskCompletionSource<object> task) | |||
{ | |||
yield return null; | |||
task.SetResult(null); | |||
} | |||
public Task WaitForSubmission() | |||
{ | |||
var task = new TaskCompletionSource<object>(); | |||
@@ -29,6 +35,13 @@ namespace GamecraftModdingAPI.Utility | |||
return task.Task; | |||
} | |||
public Task WaitForNextFrame() | |||
{ | |||
var task = new TaskCompletionSource<object>(); | |||
WaitForNextFrameInternal(task).RunOn(ExtraLean.EveryFrameStepRunner); | |||
return task.Task; | |||
} | |||
public void Setup(IEntityFunctions efu, IEntityFactory efa) | |||
{ | |||
_efu = efu; | |||