@@ -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 | |||
{ | |||
/// <summary> | |||
/// Returns the block the player is currently looking at. | |||
/// </summary> | |||
/// <param name="playerId">The player's ID</param> | |||
/// <param name="entitiesDB">The entities DB</param> | |||
/// <param name="maxDistance">The maximum distance from the player (default is the player's building reach)</param> | |||
/// <returns>The block's EGID or null if not found</returns> | |||
public static EGID? GetBlockLookedAt(uint playerId, EntitiesDB entitiesDB, float maxDistance = -1f) | |||
{ | |||
if (!entitiesDB.TryQueryMappedEntities<CharacterCameraRayCastEntityStruct>( | |||
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; | |||
} | |||
} | |||
} |
@@ -26,7 +26,7 @@ namespace GamecraftModdingAPI.Blocks | |||
/// <returns>Whether the operation was successful</returns> | |||
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 | |||
/// <returns>Whether the operation was successful</returns> | |||
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; | |||
@@ -79,10 +79,5 @@ namespace GamecraftModdingAPI.Blocks | |||
} | |||
return this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).position; | |||
} | |||
public bool IsBuildMode() | |||
{ | |||
return GamecraftModdingAPI.Utility.GameState.IsBuildMode(); | |||
} | |||
} | |||
} |
@@ -1,6 +1,7 @@ | |||
using System; | |||
using Unity.Mathematics; | |||
using Svelto.ECS; | |||
using GamecraftModdingAPI.Utility; | |||
@@ -27,8 +28,8 @@ namespace GamecraftModdingAPI.Blocks | |||
/// <param name="uscale">The block's uniform scale - default scale is 1 (with 0.2 width)</param> | |||
/// <param name="scale">The block's non-uniform scale - 0 means <paramref name="uscale"/> is used</param> | |||
/// <param name="playerId">The player who placed the block</param> | |||
/// <returns>Whether the operation was successful</returns> | |||
public static bool PlaceBlock(BlockIDs block, float3 position, | |||
/// <returns>The placed block's ID or null if failed</returns> | |||
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() | |||
@@ -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<PickedBlockExtraDataStruct>(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]; | |||
} | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
using Svelto.ECS; | |||
using GamecraftModdingAPI.Utility; | |||
namespace GamecraftModdingAPI.Blocks | |||
{ | |||
public class Removal | |||
{ | |||
private static RemovalEngine _removalEngine = new RemovalEngine(); | |||
/// <summary> | |||
/// Removes the block with the given ID. Returns false if the block doesn't exist or the game isn't in build mode. | |||
/// </summary> | |||
/// <param name="targetBlock">The block to remove</param> | |||
/// <returns>Whether the block was successfully removed</returns> | |||
public static bool RemoveBlock(EGID targetBlock) | |||
{ | |||
if (GameState.IsBuildMode()) | |||
return _removalEngine.RemoveBlock(targetBlock); | |||
return false; | |||
} | |||
public static void Init() | |||
{ | |||
GameEngineManager.AddGameEngine(_removalEngine); | |||
} | |||
} | |||
} |
@@ -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<MachineGraphConnectionsEntityStruct>(target)) | |||
return false; | |||
var connections = entitiesDB.QueryEntity<MachineGraphConnectionsEntityStruct>(target); | |||
for (int i = connections.connections.Length - 1; i >= 0; i--) | |||
_connectionFactory.RemoveConnection(connections, i, entitiesDB); | |||
_entityFunctions.RemoveEntity<BlockEntityDescriptor>(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]; | |||
} | |||
} | |||
} | |||
} |
@@ -26,7 +26,7 @@ namespace GamecraftModdingAPI.Blocks | |||
/// <returns>Whether the operation was successful</returns> | |||
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 | |||
/// <returns>Whether the operation was successful</returns> | |||
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; | |||
@@ -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(); | |||
} | |||
} | |||
} |
@@ -147,10 +147,5 @@ namespace GamecraftModdingAPI.Blocks | |||
} | |||
return res; | |||
} | |||
public bool IsSimulationMode() | |||
{ | |||
return GamecraftModdingAPI.Utility.GameState.IsSimulationMode(); | |||
} | |||
} | |||
} |
@@ -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 | |||
/// <param name="input">Whether to retrieve input IDs (true) or output IDs (false).</param> | |||
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 | |||
/// <returns>The signal's new value.</returns> | |||
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 | |||
/// <returns>The signal's value.</returns> | |||
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); | |||
} | |||
@@ -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 | |||