diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 7a65d04..d7752c8 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -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(Id).scale; set { - BlockEngine.GetBlockInfo(Id).scale = value; + if (!Exists) return; //UpdateCollision needs the block to exist + ref var scaling = ref BlockEngine.GetBlockInfo(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); } /// @@ -325,5 +331,9 @@ namespace GamecraftModdingAPI } } #endif + internal static void Setup(World physicsWorld) + { + ScalingEngine.Setup(physicsWorld.EntityManager); + } } } \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/ScalingEngine.cs b/GamecraftModdingAPI/Blocks/ScalingEngine.cs new file mode 100644 index 0000000..a531865 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/ScalingEngine.cs @@ -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 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(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 __instance) + { + physicsEngine = __instance; + Logging.MetaDebugLog("Physics engine injected."); + } + + static MethodBase TargetMethod(Harmony instance) + { + return AccessTools.Method("RobocraftX.StateSync.HandleUECSPhysicEntitiesWithPrefabCreationEngine" + + ":Ready"); + } + } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Events/GameActivatedComposePatch.cs b/GamecraftModdingAPI/Events/GameActivatedComposePatch.cs index 35f075e..4481f4b 100644 --- a/GamecraftModdingAPI/Events/GameActivatedComposePatch.cs +++ b/GamecraftModdingAPI/Events/GameActivatedComposePatch.cs @@ -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"); diff --git a/GamecraftModdingAPI/Player.cs b/GamecraftModdingAPI/Player.cs index 501c3df..af20e36 100644 --- a/GamecraftModdingAPI/Player.cs +++ b/GamecraftModdingAPI/Player.cs @@ -340,7 +340,7 @@ namespace GamecraftModdingAPI } /// - /// Returns the block the player is currently looking at. + /// Returns the block the player is currently looking at in build mode. /// /// The maximum distance from the player (default is the player's building reach) /// The block or null if not found diff --git a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs index 1e249bb..d505806 100644 --- a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs +++ b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs @@ -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() { diff --git a/GamecraftModdingAPI/Utility/AsyncUtils.cs b/GamecraftModdingAPI/Utility/AsyncUtils.cs index c646f8f..8fed9ee 100644 --- a/GamecraftModdingAPI/Utility/AsyncUtils.cs +++ b/GamecraftModdingAPI/Utility/AsyncUtils.cs @@ -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()); diff --git a/GamecraftModdingAPI/Utility/AsyncUtilsEngine.cs b/GamecraftModdingAPI/Utility/AsyncUtilsEngine.cs index 9027de1..f46bd6c 100644 --- a/GamecraftModdingAPI/Utility/AsyncUtilsEngine.cs +++ b/GamecraftModdingAPI/Utility/AsyncUtilsEngine.cs @@ -22,6 +22,12 @@ namespace GamecraftModdingAPI.Utility task.SetResult(null); } + private IEnumerator WaitForNextFrameInternal(TaskCompletionSource task) + { + yield return null; + task.SetResult(null); + } + public Task WaitForSubmission() { var task = new TaskCompletionSource(); @@ -29,6 +35,13 @@ namespace GamecraftModdingAPI.Utility return task.Task; } + public Task WaitForNextFrame() + { + var task = new TaskCompletionSource(); + WaitForNextFrameInternal(task).RunOn(ExtraLean.EveryFrameStepRunner); + return task.Task; + } + public void Setup(IEntityFunctions efu, IEntityFactory efa) { _efu = efu;