Browse Source

Added WaitForNextFrame() and fixed block scaling

A bit hacky, but it works
tags/v1.2.0
NorbiPeti 3 years ago
parent
commit
f62211309e
7 changed files with 98 additions and 33 deletions
  1. +11
    -1
      GamecraftModdingAPI/Block.cs
  2. +62
    -0
      GamecraftModdingAPI/Blocks/ScalingEngine.cs
  3. +6
    -4
      GamecraftModdingAPI/Events/GameActivatedComposePatch.cs
  4. +1
    -1
      GamecraftModdingAPI/Player.cs
  5. +0
    -27
      GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs
  6. +5
    -0
      GamecraftModdingAPI/Utility/AsyncUtils.cs
  7. +13
    -0
      GamecraftModdingAPI/Utility/AsyncUtilsEngine.cs

+ 11
- 1
GamecraftModdingAPI/Block.cs View File

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

+ 62
- 0
GamecraftModdingAPI/Blocks/ScalingEngine.cs View File

@@ -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
- 4
GamecraftModdingAPI/Events/GameActivatedComposePatch.cs View File

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


+ 1
- 1
GamecraftModdingAPI/Player.cs View File

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


+ 0
- 27
GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs View File

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


+ 5
- 0
GamecraftModdingAPI/Utility/AsyncUtils.cs View File

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


+ 13
- 0
GamecraftModdingAPI/Utility/AsyncUtilsEngine.cs View File

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


Loading…
Cancel
Save