diff --git a/GamecraftModdingAPI/Blocks/BlockUtility.cs b/GamecraftModdingAPI/Blocks/BlockUtility.cs
new file mode 100644
index 0000000..342ee73
--- /dev/null
+++ b/GamecraftModdingAPI/Blocks/BlockUtility.cs
@@ -0,0 +1,31 @@
+using RobocraftX.Blocks.Ghost;
+using RobocraftX.Character.Camera;
+using RobocraftX.Character.Factories;
+using Svelto.ECS;
+
+namespace GamecraftModdingAPI.Blocks
+{
+ public class BlockUtility
+ {
+ ///
+ /// Returns the block the player is currently looking at.
+ ///
+ /// The player's ID
+ /// The entities DB
+ /// The maximum distance from the player (default is the player's building reach)
+ /// The block's EGID or null if not found
+ public static EGID? GetBlockLookedAt(uint playerId, EntitiesDB entitiesDB, float maxDistance = -1f)
+ {
+ if (!entitiesDB.TryQueryMappedEntities(
+ CameraExclusiveGroups.CameraGroup, out var mapper))
+ return null;
+ mapper.TryGetEntity(playerId, out CharacterCameraRayCastEntityStruct rayCast);
+ float distance = maxDistance < 0
+ ? GhostBlockUtils.GetBuildInteractionDistance(entitiesDB, rayCast)
+ : maxDistance;
+ if (rayCast.hit && rayCast.distance <= distance)
+ return rayCast.hitEgid;
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/GamecraftModdingAPI/Blocks/Movement.cs b/GamecraftModdingAPI/Blocks/Movement.cs
index 132fedf..28575a9 100644
--- a/GamecraftModdingAPI/Blocks/Movement.cs
+++ b/GamecraftModdingAPI/Blocks/Movement.cs
@@ -26,7 +26,7 @@ namespace GamecraftModdingAPI.Blocks
/// Whether the operation was successful
public static bool MoveBlock(uint id, float3 vector)
{
- if (movementEngine.IsInGame && movementEngine.IsBuildMode())
+ if (movementEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode())
{
movementEngine.MoveBlock(id, vector);
return true;
@@ -45,7 +45,7 @@ namespace GamecraftModdingAPI.Blocks
/// Whether the operation was successful
public static bool MoveConnectedBlocks(uint id, float3 vector)
{
- if (movementEngine.IsInGame && movementEngine.IsBuildMode())
+ if (movementEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode())
{
movementEngine.MoveConnectedBlocks(id, vector);
return true;
diff --git a/GamecraftModdingAPI/Blocks/MovementEngine.cs b/GamecraftModdingAPI/Blocks/MovementEngine.cs
index 77d73c4..ab4eaa4 100644
--- a/GamecraftModdingAPI/Blocks/MovementEngine.cs
+++ b/GamecraftModdingAPI/Blocks/MovementEngine.cs
@@ -79,10 +79,5 @@ namespace GamecraftModdingAPI.Blocks
}
return this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).position;
}
-
- public bool IsBuildMode()
- {
- return GamecraftModdingAPI.Utility.GameState.IsBuildMode();
- }
}
}
diff --git a/GamecraftModdingAPI/Blocks/Placement.cs b/GamecraftModdingAPI/Blocks/Placement.cs
index 11c11eb..c029ebb 100644
--- a/GamecraftModdingAPI/Blocks/Placement.cs
+++ b/GamecraftModdingAPI/Blocks/Placement.cs
@@ -1,6 +1,7 @@
using System;
using Unity.Mathematics;
+using Svelto.ECS;
using GamecraftModdingAPI.Utility;
@@ -27,8 +28,8 @@ namespace GamecraftModdingAPI.Blocks
/// The block's uniform scale - default scale is 1 (with 0.2 width)
/// The block's non-uniform scale - 0 means is used
/// The player who placed the block
- /// Whether the operation was successful
- public static bool PlaceBlock(BlockIDs block, float3 position,
+ /// The placed block's ID or null if failed
+ public static EGID? PlaceBlock(BlockIDs block, float3 position,
float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0,
int uscale = 1, float3 scale = default, uint playerId = 0)
{
@@ -36,19 +37,14 @@ namespace GamecraftModdingAPI.Blocks
{
try
{
- placementEngine.PlaceBlock(block, color, darkness, position, uscale, scale, playerId, rotation);
+ return placementEngine.PlaceBlock(block, color, darkness, position, uscale, scale, playerId, rotation);
}
catch (Exception e)
{
- uREPL.Log.Output(e.Message);
-#if DEBUG
- //Logging.LogException(e);
-#endif
- return false;
- }
- return true;
+ Logging.MetaDebugLog(e);
+ }
}
- return false;
+ return null;
}
public static void Init()
diff --git a/GamecraftModdingAPI/Blocks/PlacementEngine.cs b/GamecraftModdingAPI/Blocks/PlacementEngine.cs
index 1101431..0b9293c 100644
--- a/GamecraftModdingAPI/Blocks/PlacementEngine.cs
+++ b/GamecraftModdingAPI/Blocks/PlacementEngine.cs
@@ -42,17 +42,17 @@ namespace GamecraftModdingAPI.Blocks
}
public EntitiesDB entitiesDB { get; set; }
- internal static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine
+ private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine
- public void PlaceBlock(BlockIDs block, BlockColors color, byte darkness, float3 position, int uscale,
+ public EGID PlaceBlock(BlockIDs block, BlockColors color, byte darkness, float3 position, int uscale,
float3 scale, uint playerId, float3 rotation)
{ //It appears that only the non-uniform scale has any visible effect, but if that's not given here it will be set to the uniform one
if (darkness > 9)
throw new Exception("That is too dark. Make sure to use 0-9 as darkness. (0 is default.)");
- BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation, playerId);
+ return BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation, playerId);
}
- private void BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot, uint playerId)
+ private EGID BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot, uint playerId)
{
if (_blockEntityFactory == null)
throw new Exception("The factory is null.");
@@ -80,21 +80,21 @@ namespace GamecraftModdingAPI.Blocks
unitSnapOffset = 0, isUsingUnitSize = true
};
EquippedColourStruct colour = new EquippedColourStruct {indexInPalette = color};
- EGID egid2;
+ EGID newBlockID;
switch (category.category)
{
case CubeCategory.SpawnPoint:
case CubeCategory.BuildingSpawnPoint:
- egid2 = MachineEditingGroups.NewSpawnPointBlockID;
+ newBlockID = MachineEditingGroups.NewSpawnPointBlockID;
break;
default:
- egid2 = MachineEditingGroups.NewBlockID;
+ newBlockID = MachineEditingGroups.NewBlockID;
break;
}
EntityStructInitializer
structInitializer =
- _blockEntityFactory.Build(egid2, dbid); //The ghost block index is only used for triggers
+ _blockEntityFactory.Build(newBlockID, dbid); //The ghost block index is only used for triggers
if (colour.indexInPalette != byte.MaxValue)
structInitializer.Init(new ColourParameterEntityStruct
{
@@ -113,17 +113,17 @@ namespace GamecraftModdingAPI.Blocks
{
scaleFactor = placementScale.desiredScaleFactor
});
- structInitializer.Init(
- new BlockPlacementInfoStruct()
- {
- loadedFromDisk = false,
- placedBy = playerId
- });
+ structInitializer.Init(new BlockPlacementInfoStruct()
+ {
+ loadedFromDisk = false,
+ placedBy = playerId
+ });
PrimaryRotationUtility.InitialisePrimaryDirection(rotation.rotation, ref structInitializer);
EGID playerEGID = new EGID(playerId, CharacterExclusiveGroups.OnFootGroup);
ref PickedBlockExtraDataStruct pickedBlock = ref entitiesDB.QueryEntity(playerEGID);
pickedBlock.placedBlockEntityID = playerEGID;
pickedBlock.placedBlockWasAPickedBlock = false;
+ return newBlockID;
}
public string Name { get; } = "GamecraftModdingAPIPlacementGameEngine";
@@ -139,7 +139,7 @@ namespace GamecraftModdingAPI.Blocks
static MethodBase TargetMethod(HarmonyInstance instance)
{
- return AccessTools.TypeByName("RobocraftX.CR.MachineEditing.PlaceBlockEngine").GetConstructors()[0];
+ return AccessTools.TypeByName("RobocraftX.CR.MachineEditing.PlaceBlockEngine").GetConstructors()[0];
}
}
}
diff --git a/GamecraftModdingAPI/Blocks/Removal.cs b/GamecraftModdingAPI/Blocks/Removal.cs
new file mode 100644
index 0000000..0bb54fb
--- /dev/null
+++ b/GamecraftModdingAPI/Blocks/Removal.cs
@@ -0,0 +1,28 @@
+using Svelto.ECS;
+
+using GamecraftModdingAPI.Utility;
+
+namespace GamecraftModdingAPI.Blocks
+{
+ public class Removal
+ {
+ private static RemovalEngine _removalEngine = new RemovalEngine();
+
+ ///
+ /// Removes the block with the given ID. Returns false if the block doesn't exist or the game isn't in build mode.
+ ///
+ /// The block to remove
+ /// Whether the block was successfully removed
+ public static bool RemoveBlock(EGID targetBlock)
+ {
+ if (GameState.IsBuildMode())
+ return _removalEngine.RemoveBlock(targetBlock);
+ return false;
+ }
+
+ public static void Init()
+ {
+ GameEngineManager.AddGameEngine(_removalEngine);
+ }
+ }
+}
\ No newline at end of file
diff --git a/GamecraftModdingAPI/Blocks/RemovalEngine.cs b/GamecraftModdingAPI/Blocks/RemovalEngine.cs
new file mode 100644
index 0000000..41e3c03
--- /dev/null
+++ b/GamecraftModdingAPI/Blocks/RemovalEngine.cs
@@ -0,0 +1,74 @@
+using System.Reflection;
+
+using Harmony;
+using RobocraftX.Blocks;
+using RobocraftX.Blocks.Ghost;
+using RobocraftX.Character.Camera;
+using RobocraftX.Character.Factories;
+using RobocraftX.Common;
+using RobocraftX.Players;
+using Svelto.ECS;
+using uREPL;
+
+using GamecraftModdingAPI.Commands;
+using GamecraftModdingAPI.Utility;
+
+namespace GamecraftModdingAPI.Blocks
+{
+ public class RemovalEngine : IApiEngine
+ {
+ private static IEntityFunctions _entityFunctions;
+ private static MachineGraphConnectionEntityFactory _connectionFactory;
+
+ public bool RemoveBlock(EGID target)
+ {
+ if (!entitiesDB.Exists(target))
+ return false;
+ var connections = entitiesDB.QueryEntity(target);
+ for (int i = connections.connections.Length - 1; i >= 0; i--)
+ _connectionFactory.RemoveConnection(connections, i, entitiesDB);
+ _entityFunctions.RemoveEntity(target);
+ return true;
+ }
+
+ public void Ready()
+ {
+ /*CommandManager.AddCommand(new SimpleCustomCommandEngine(() =>
+ {
+ var block = BlockUtility.GetBlockLookedAt(LocalPlayerIDUtility.GetLocalPlayerID(entitiesDB), entitiesDB);
+ if (block.HasValue)
+ {
+ RemoveBlock(block.Value);
+ Log.Output("Removed block.");
+ }
+ else
+ Log.Output("No block found where you're looking at.");
+ }, "removeCube", "Removes the cube you're looking at."));*/
+ }
+
+ public EntitiesDB entitiesDB { get; set; }
+
+ public void Dispose()
+ {
+ }
+
+ public string Name { get; } = "GamecraftModdingAPIRemovalGameEngine";
+
+ [HarmonyPatch]
+ public class FactoryObtainerPatch
+ {
+ static void Postfix(IEntityFunctions entityFunctions,
+ MachineGraphConnectionEntityFactory machineGraphConnectionEntityFactory)
+ {
+ _entityFunctions = entityFunctions;
+ _connectionFactory = machineGraphConnectionEntityFactory;
+ Logging.MetaDebugLog("Requirements injected.");
+ }
+
+ static MethodBase TargetMethod(HarmonyInstance instance)
+ {
+ return AccessTools.TypeByName("RobocraftX.CR.MachineEditing.RemoveBlockEngine").GetConstructors()[0];
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/GamecraftModdingAPI/Blocks/Rotation.cs b/GamecraftModdingAPI/Blocks/Rotation.cs
index a0b6785..b881cdb 100644
--- a/GamecraftModdingAPI/Blocks/Rotation.cs
+++ b/GamecraftModdingAPI/Blocks/Rotation.cs
@@ -26,7 +26,7 @@ namespace GamecraftModdingAPI.Blocks
/// Whether the operation was successful
public static bool RotateBlock(uint id, float3 vector)
{
- if (rotationEngine.IsInGame && rotationEngine.IsBuildMode())
+ if (rotationEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode())
{
rotationEngine.RotateBlock(id, vector);
return true;
@@ -43,7 +43,7 @@ namespace GamecraftModdingAPI.Blocks
/// Whether the operation was successful
public static bool RotateConnectedBlocks(uint id, float3 vector)
{
- if (rotationEngine.IsInGame && rotationEngine.IsBuildMode())
+ if (rotationEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode())
{
rotationEngine.RotateConnectedBlocks(id, vector);
return true;
diff --git a/GamecraftModdingAPI/Blocks/RotationEngine.cs b/GamecraftModdingAPI/Blocks/RotationEngine.cs
index 50dbb4c..8038739 100644
--- a/GamecraftModdingAPI/Blocks/RotationEngine.cs
+++ b/GamecraftModdingAPI/Blocks/RotationEngine.cs
@@ -44,7 +44,7 @@ namespace GamecraftModdingAPI.Blocks
IsInGame = true;
}
- // implementations for Movement static class
+ // implementations for Rotation static class
public float3 RotateBlock(uint blockID, Vector3 vector)
{
@@ -78,10 +78,5 @@ namespace GamecraftModdingAPI.Blocks
// TODO: Implement and figure out the math
throw new NotImplementedException();
}
-
- public bool IsBuildMode()
- {
- return GamecraftModdingAPI.Utility.GameState.IsBuildMode();
- }
}
}
diff --git a/GamecraftModdingAPI/Blocks/SignalEngine.cs b/GamecraftModdingAPI/Blocks/SignalEngine.cs
index 6af4176..3b732ba 100644
--- a/GamecraftModdingAPI/Blocks/SignalEngine.cs
+++ b/GamecraftModdingAPI/Blocks/SignalEngine.cs
@@ -147,10 +147,5 @@ namespace GamecraftModdingAPI.Blocks
}
return res;
}
-
- public bool IsSimulationMode()
- {
- return GamecraftModdingAPI.Utility.GameState.IsSimulationMode();
- }
}
}
diff --git a/GamecraftModdingAPI/Blocks/Signals.cs b/GamecraftModdingAPI/Blocks/Signals.cs
index 6b6d779..c844d3a 100644
--- a/GamecraftModdingAPI/Blocks/Signals.cs
+++ b/GamecraftModdingAPI/Blocks/Signals.cs
@@ -34,7 +34,7 @@ namespace GamecraftModdingAPI.Blocks
public static void SetSignalByBlock(uint blockID, float signal, bool input = true, bool owned = true)
{
EGID egid = new EGID(blockID, owned ? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS);
- if (signalEngine.IsInGame && signalEngine.IsSimulationMode())
+ if (signalEngine.IsInGame && GameState.IsSimulationMode())
{
signalEngine.SetSignal(egid, signal, out uint _, input);
}
@@ -42,7 +42,7 @@ namespace GamecraftModdingAPI.Blocks
public static void SetSignalByBlock(EGID blockID, float signal, bool input = true)
{
- if (signalEngine.IsInGame && signalEngine.IsSimulationMode())
+ if (signalEngine.IsInGame && GameState.IsSimulationMode())
{
signalEngine.SetSignal(blockID, signal, out uint _, input);
}
@@ -56,7 +56,7 @@ namespace GamecraftModdingAPI.Blocks
/// Whether to retrieve input IDs (true) or output IDs (false).
public static void SetSignalByID(uint signalID, float signal, bool input = true)
{
- if (signalEngine.IsInGame && signalEngine.IsSimulationMode())
+ if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
{
signalEngine.SetSignal(signalID, signal, input);
}
@@ -74,7 +74,7 @@ namespace GamecraftModdingAPI.Blocks
public static float AddSignalByBlock(uint blockID, float signal, bool clamp = true, bool input = true, bool owned = true)
{
EGID egid = new EGID(blockID, owned ? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS);
- if (signalEngine.IsInGame && signalEngine.IsSimulationMode())
+ if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
{
return signalEngine.AddSignal(egid, signal, out uint _, clamp, input);
}
@@ -83,7 +83,7 @@ namespace GamecraftModdingAPI.Blocks
public static float AddSignalByBlock(EGID blockID, float signal, bool clamp = true, bool input = true)
{
- if (signalEngine.IsInGame && signalEngine.IsSimulationMode())
+ if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
{
return signalEngine.AddSignal(blockID, signal, out uint _, clamp, input);
}
@@ -100,7 +100,7 @@ namespace GamecraftModdingAPI.Blocks
/// The signal's new value.
public static float AddSignalByID(uint signalID, float signal, bool clamp = true, bool input = true)
{
- if (signalEngine.IsInGame && signalEngine.IsSimulationMode())
+ if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
{
return signalEngine.AddSignal(signalID, signal, clamp, input);
}
@@ -117,7 +117,7 @@ namespace GamecraftModdingAPI.Blocks
public static float GetSignalByBlock(uint blockID, bool input = true, bool owned = true)
{
EGID egid = new EGID(blockID, owned? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS);
- if (signalEngine.IsInGame && signalEngine.IsSimulationMode())
+ if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
{
return signalEngine.GetSignal(egid, out uint _, input);
}
@@ -126,7 +126,7 @@ namespace GamecraftModdingAPI.Blocks
public static float GetSignalByBlock(EGID blockID, bool input = true)
{
- if (signalEngine.IsInGame && signalEngine.IsSimulationMode())
+ if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
{
return signalEngine.GetSignal(blockID, out uint _, input);
}
@@ -141,7 +141,7 @@ namespace GamecraftModdingAPI.Blocks
/// The signal's value.
public static float GetSignalByID(uint signalID, bool input = true)
{
- if (signalEngine.IsInGame && signalEngine.IsSimulationMode())
+ if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
{
return signalEngine.GetSignal(signalID, input);
}
diff --git a/GamecraftModdingAPI/Main.cs b/GamecraftModdingAPI/Main.cs
index 6ce1126..ff8b63c 100644
--- a/GamecraftModdingAPI/Main.cs
+++ b/GamecraftModdingAPI/Main.cs
@@ -65,6 +65,7 @@ namespace GamecraftModdingAPI
Blocks.Signals.Init();
Blocks.Placement.Init();
Blocks.Tweakable.Init();
+ Blocks.Removal.Init();
// init inventory
Inventory.Hotbar.Init();
// init input