Create Block class with existing functionality
Placement, movement, rotation, removal Block looked at (in Player class), connected blocks
This commit is contained in:
parent
5168bfbad7
commit
ff57a16565
14 changed files with 218 additions and 268 deletions
115
GamecraftModdingAPI/Block.cs
Normal file
115
GamecraftModdingAPI/Block.cs
Normal file
|
@ -0,0 +1,115 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using GamecraftModdingAPI.Blocks;
|
||||
using GamecraftModdingAPI.Utility;
|
||||
using RobocraftX.Common;
|
||||
using Svelto.ECS;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace GamecraftModdingAPI
|
||||
{
|
||||
public class Block
|
||||
{
|
||||
private static readonly PlacementEngine PlacementEngine = new PlacementEngine();
|
||||
private static readonly MovementEngine MovementEngine = new MovementEngine();
|
||||
private static readonly RotationEngine RotationEngine = new RotationEngine();
|
||||
private static readonly RemovalEngine RemovalEngine = new RemovalEngine();
|
||||
private static readonly BlockEngine BlockEngine = new BlockEngine();
|
||||
|
||||
/// <summary>
|
||||
/// Place a new block at the given position. If scaled, position means the center of the block. The default block size is 0.2 in terms of position.
|
||||
/// Place blocks next to each other to connect them.
|
||||
/// The placed block will be a complete block with a placement grid and collision which will be saved along with the game.
|
||||
/// </summary>
|
||||
/// <param name="block">The block's type</param>
|
||||
/// <param name="color">The block's color</param>
|
||||
/// <param name="darkness">The block color's darkness (0-9) - 0 is default color</param>
|
||||
/// <param name="position">The block's position in the grid - default block size is 0.2</param>
|
||||
/// <param name="rotation">The block's rotation in degrees</param>
|
||||
/// <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="player">The player who placed the block</param>
|
||||
/// <returns>The placed block or null if failed</returns>
|
||||
public static Block PlaceNew(BlockIDs block, float3 position,
|
||||
float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0,
|
||||
int uscale = 1, float3 scale = default, Player player = null)
|
||||
{
|
||||
if (PlacementEngine.IsInGame && GameState.IsBuildMode())
|
||||
{
|
||||
try
|
||||
{
|
||||
return new Block(PlacementEngine.PlaceBlock(block, color, darkness,
|
||||
position, uscale, scale, player, rotation));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.MetaDebugLog(e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the most recently placed block.
|
||||
/// </summary>
|
||||
/// <returns>The block object</returns>
|
||||
public static Block GetLastPlacedBlock()
|
||||
{
|
||||
return new Block(BlockIdentifiers.LatestBlockID);
|
||||
}
|
||||
|
||||
public Block(EGID id)
|
||||
{
|
||||
Id = id;
|
||||
}
|
||||
|
||||
public Block(uint id)
|
||||
{
|
||||
Id = new EGID(id, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||
}
|
||||
|
||||
public EGID Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The block's current position.
|
||||
/// </summary>
|
||||
public float3 Position
|
||||
{
|
||||
get => MovementEngine.GetPosition(Id.entityID);
|
||||
set => MovementEngine.MoveBlock(Id.entityID, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array of blocks that are connected to this one.
|
||||
/// </summary>
|
||||
public Block[] ConnectedCubes => BlockEngine.GetConnectedBlocks(Id.entityID);
|
||||
|
||||
/// <summary>
|
||||
/// The block's current rotation in degrees.
|
||||
/// </summary>
|
||||
public float3 Rotation
|
||||
{
|
||||
get => RotationEngine.GetRotation(Id.entityID);
|
||||
set => RotationEngine.RotateBlock(Id.entityID, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes this block.
|
||||
/// </summary>
|
||||
/// <returns>True if the block exists and could be removed.</returns>
|
||||
public bool Remove()
|
||||
{
|
||||
return RemovalEngine.RemoveBlock(Id);
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
GameEngineManager.AddGameEngine(PlacementEngine);
|
||||
GameEngineManager.AddGameEngine(MovementEngine);
|
||||
GameEngineManager.AddGameEngine(RotationEngine);
|
||||
GameEngineManager.AddGameEngine(RemovalEngine);
|
||||
GameEngineManager.AddGameEngine(BlockEngine);
|
||||
}
|
||||
}
|
||||
}
|
39
GamecraftModdingAPI/Blocks/BlockEngine.cs
Normal file
39
GamecraftModdingAPI/Blocks/BlockEngine.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using System.Collections.Generic;
|
||||
using GamecraftModdingAPI.Engines;
|
||||
using RobocraftX.Blocks;
|
||||
using RobocraftX.Common;
|
||||
using Svelto.DataStructures;
|
||||
using Svelto.ECS;
|
||||
using Svelto.ECS.EntityStructs;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace GamecraftModdingAPI.Blocks
|
||||
{
|
||||
public class BlockEngine : IApiEngine
|
||||
{
|
||||
public string Name { get; } = "GamecraftModdingAPIBlockGameEngine";
|
||||
|
||||
public EntitiesDB entitiesDB { set; private get; }
|
||||
|
||||
public bool isRemovable => false;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public void Ready()
|
||||
{
|
||||
}
|
||||
|
||||
public Block[] GetConnectedBlocks(uint blockID)
|
||||
{
|
||||
Stack<uint> cubeStack = new Stack<uint>();
|
||||
FasterList<uint> cubesToProcess = new FasterList<uint>();
|
||||
ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubeStack, cubesToProcess, (in GridConnectionsEntityStruct g) => { return false; });
|
||||
var ret = new Block[cubesToProcess.count];
|
||||
for (int i = 0; i < cubesToProcess.count; i++)
|
||||
ret[i] = new Block(cubesToProcess[i]);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace GamecraftModdingAPI.Blocks
|
||||
{
|
||||
/// <summary>
|
||||
/// Common block movement operations.
|
||||
/// The functionality of this class only works in build mode.
|
||||
/// </summary>
|
||||
public static class Movement
|
||||
{
|
||||
private static MovementEngine movementEngine = new MovementEngine();
|
||||
|
||||
/// <summary>
|
||||
/// Move a single block by a specific (x,y,z) amount (offset).
|
||||
/// The moved block will remain connected to the blocks it was touching before it was moved.
|
||||
/// The block's placement grid and collision box are also moved.
|
||||
/// </summary>
|
||||
/// <param name="id">The block's id</param>
|
||||
/// <param name="vector">The movement amount (x,y,z)</param>
|
||||
/// <returns>Whether the operation was successful</returns>
|
||||
public static bool MoveBlock(uint id, float3 vector)
|
||||
{
|
||||
if (movementEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode())
|
||||
{
|
||||
movementEngine.MoveBlock(id, vector);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move all connected blocks by a specific (x,y,z) amount (offset).
|
||||
/// The moved blocks will remain connected to the block they're touching.
|
||||
/// All of the block's placement grids and collision boxes are also moved.
|
||||
/// This is equivalent to calling MoveBlock() for every connected block.
|
||||
/// </summary>
|
||||
/// <param name="id">The starting block's id</param>
|
||||
/// <param name="vector">The movement amount (x,y,z)</param>
|
||||
/// <returns>Whether the operation was successful</returns>
|
||||
public static bool MoveConnectedBlocks(uint id, float3 vector)
|
||||
{
|
||||
if (movementEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode())
|
||||
{
|
||||
movementEngine.MoveConnectedBlocks(id, vector);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
GamecraftModdingAPI.Utility.GameEngineManager.AddGameEngine(movementEngine);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,30 +57,24 @@ namespace GamecraftModdingAPI.Blocks
|
|||
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity<LocalTransformEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||
ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||
// main (persistent) position
|
||||
posStruct.position += vector;
|
||||
posStruct.position = vector;
|
||||
// placement grid position
|
||||
gridStruct.position += vector;
|
||||
gridStruct.position = vector;
|
||||
// rendered position
|
||||
transStruct.position += vector;
|
||||
transStruct.position = vector;
|
||||
// collision position
|
||||
FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation
|
||||
{
|
||||
Value = posStruct.position
|
||||
});
|
||||
entitiesDB.QueryEntity<GridConnectionsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false;
|
||||
return posStruct.position;
|
||||
}
|
||||
|
||||
public float3 MoveConnectedBlocks(uint blockID, float3 vector)
|
||||
public float3 GetPosition(uint blockID)
|
||||
{
|
||||
Stack<uint> cubeStack = new Stack<uint>();
|
||||
FasterList<uint> cubesToMove = new FasterList<uint>();
|
||||
ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubeStack, cubesToMove, (in GridConnectionsEntityStruct g) => { return false; });
|
||||
for (int i = 0; i < cubesToMove.count; i++)
|
||||
{
|
||||
MoveBlock(cubesToMove[i], vector);
|
||||
entitiesDB.QueryEntity<GridConnectionsEntityStruct>(cubesToMove[i], CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false;
|
||||
}
|
||||
return this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).position;
|
||||
ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||
return posStruct.position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
using System;
|
||||
|
||||
using Unity.Mathematics;
|
||||
using Svelto.ECS;
|
||||
|
||||
using GamecraftModdingAPI.Utility;
|
||||
|
||||
namespace GamecraftModdingAPI.Blocks
|
||||
{
|
||||
/// <summary>
|
||||
/// Common block placement operations.
|
||||
/// The functionality in this class is for build mode.
|
||||
/// </summary>
|
||||
public static class Placement
|
||||
{
|
||||
private static PlacementEngine placementEngine = new PlacementEngine();
|
||||
|
||||
/// <summary>
|
||||
/// Place a new block at the given position. If scaled, position means the center of the block. The default block size is 0.2 in terms of position.
|
||||
/// Place blocks next to each other to connect them.
|
||||
/// The placed block will be a complete block with a placement grid and collision which will be saved along with the game.
|
||||
/// </summary>
|
||||
/// <param name="block">The block's type</param>
|
||||
/// <param name="color">The block's color</param>
|
||||
/// <param name="darkness">The block color's darkness (0-9) - 0 is default color</param>
|
||||
/// <param name="position">The block's position in the grid - default block size is 0.2</param>
|
||||
/// <param name="rotation">The block's rotation in degrees</param>
|
||||
/// <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>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)
|
||||
{
|
||||
if (placementEngine.IsInGame && GameState.IsBuildMode())
|
||||
{
|
||||
try
|
||||
{
|
||||
return placementEngine.PlaceBlock(block, color, darkness, position, uscale, scale, playerId, rotation);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.MetaDebugLog(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
GameEngineManager.AddGameEngine(placementEngine);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ using uREPL;
|
|||
|
||||
using GamecraftModdingAPI.Utility;
|
||||
using GamecraftModdingAPI.Engines;
|
||||
using GamecraftModdingAPI.Players;
|
||||
|
||||
namespace GamecraftModdingAPI.Blocks
|
||||
{
|
||||
|
@ -46,11 +47,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine
|
||||
|
||||
public EGID PlaceBlock(BlockIDs block, BlockColors color, byte darkness, float3 position, int uscale,
|
||||
float3 scale, uint playerId, float3 rotation)
|
||||
float3 scale, Player player, 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.)");
|
||||
return BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation, playerId);
|
||||
return BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation,
|
||||
(player ?? new Player(PlayerType.Local)).Id);
|
||||
}
|
||||
|
||||
private EGID BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot, uint playerId)
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace GamecraftModdingAPI.Blocks
|
||||
{
|
||||
/// <summary>
|
||||
/// Common block rotation operations.
|
||||
/// The functionality in this class is not completely implemented and will only work in build mode.
|
||||
/// </summary>
|
||||
public static class Rotation
|
||||
{
|
||||
private static RotationEngine rotationEngine = new RotationEngine();
|
||||
|
||||
/// <summary>
|
||||
/// Rotate a single block by a specific amount in degrees.
|
||||
/// This not destroy inter-block connections, so neighbouring blocks will remain attached despite appearances.
|
||||
/// The cube placement grid and collision are also rotated.
|
||||
/// </summary>
|
||||
/// <param name="id">The block's id</param>
|
||||
/// <param name="vector">The rotation amount around the x,y,z-axis</param>
|
||||
/// <returns>Whether the operation was successful</returns>
|
||||
public static bool RotateBlock(uint id, float3 vector)
|
||||
{
|
||||
if (rotationEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode())
|
||||
{
|
||||
rotationEngine.RotateBlock(id, vector);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rotate all connected blocks by a specific amount in degrees.
|
||||
/// This does not do anything because it has not been implemented.
|
||||
/// </summary>
|
||||
/// <param name="id">The starting block's id</param>
|
||||
/// <param name="vector">The rotation around the x,y,z-axis</param>
|
||||
/// <returns>Whether the operation was successful</returns>
|
||||
public static bool RotateConnectedBlocks(uint id, float3 vector)
|
||||
{
|
||||
if (rotationEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode())
|
||||
{
|
||||
rotationEngine.RotateConnectedBlocks(id, vector);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
GamecraftModdingAPI.Utility.GameEngineManager.AddGameEngine(rotationEngine);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -72,14 +72,15 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
Value = rotStruct.rotation
|
||||
});
|
||||
entitiesDB.QueryEntity<GridConnectionsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false;
|
||||
return ((Quaternion)rotStruct.rotation).eulerAngles;
|
||||
|
||||
}
|
||||
|
||||
public float3 RotateConnectedBlocks(uint blockID, Vector3 vector)
|
||||
public float3 GetRotation(uint blockID)
|
||||
{
|
||||
// TODO: Implement and figure out the math
|
||||
throw new NotImplementedException();
|
||||
ref RotationEntityStruct rotStruct = ref entitiesDB.QueryEntity<RotationEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||
return ((Quaternion) rotStruct.rotation).eulerAngles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ using HarmonyLib;
|
|||
|
||||
using GamecraftModdingAPI.Utility;
|
||||
using GamecraftModdingAPI.Events;
|
||||
using GamecraftModdingAPI.Players;
|
||||
using GamecraftModdingAPI.Tasks;
|
||||
using uREPL;
|
||||
|
||||
namespace GamecraftModdingAPI
|
||||
{
|
||||
|
@ -61,18 +63,16 @@ namespace GamecraftModdingAPI
|
|||
EventManager.AddEventEmitter(GameHostTransitionDeterministicGroupEnginePatch.simEngine);
|
||||
// init block implementors
|
||||
Logging.MetaDebugLog($"Initializing Blocks");
|
||||
Blocks.Movement.Init();
|
||||
Blocks.Rotation.Init();
|
||||
Blocks.Signals.Init();
|
||||
Blocks.Placement.Init();
|
||||
Blocks.Tweakable.Init();
|
||||
Blocks.Removal.Init();
|
||||
// init inventory
|
||||
Inventory.Hotbar.Init();
|
||||
// init input
|
||||
Input.FakeInput.Init();
|
||||
// init object-oriented classes
|
||||
Player.Init();
|
||||
Block.Init();
|
||||
RuntimeCommands.Register("getblock", () => new Player(PlayerType.Local).GetBlockLookedAt());
|
||||
Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized");
|
||||
}
|
||||
|
||||
|
|
|
@ -218,6 +218,18 @@ namespace GamecraftModdingAPI
|
|||
}
|
||||
playerEngine.SetLocation(Id, location, exitSeat: exitSeat);
|
||||
}
|
||||
|
||||
/// <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 Block GetBlockLookedAt(float maxDistance = -1f)
|
||||
{
|
||||
return playerEngine.GetBlockLookedAt(Id, maxDistance);
|
||||
}
|
||||
|
||||
// internal methods
|
||||
|
||||
|
|
|
@ -11,6 +11,9 @@ using Unity.Mathematics;
|
|||
using Unity.Physics;
|
||||
|
||||
using GamecraftModdingAPI.Engines;
|
||||
using RobocraftX.Blocks.Ghost;
|
||||
using RobocraftX.Character.Camera;
|
||||
using RobocraftX.Character.Factories;
|
||||
|
||||
namespace GamecraftModdingAPI.Players
|
||||
{
|
||||
|
@ -234,5 +237,23 @@ namespace GamecraftModdingAPI.Players
|
|||
s = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public Block GetBlockLookedAt(uint playerId, 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)
|
||||
{
|
||||
Console.WriteLine("Hit block: " + rayCast.hitEgid);
|
||||
return new Block(rayCast.hitEgid);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
using HarmonyLib;
|
||||
|
@ -94,22 +95,21 @@ namespace GamecraftModdingAPI.Tests
|
|||
.Build();
|
||||
|
||||
CommandBuilder.Builder()
|
||||
.Name("MoveLastBlock")
|
||||
.Description("Move the most-recently-placed block, and any connected blocks by the given offset")
|
||||
.Action((float x, float y, float z) => {
|
||||
bool success = GamecraftModdingAPI.Blocks.Movement.MoveConnectedBlocks(
|
||||
GamecraftModdingAPI.Blocks.BlockIdentifiers.LatestBlockID,
|
||||
new Unity.Mathematics.float3(x, y, z));
|
||||
if (!success)
|
||||
{
|
||||
GamecraftModdingAPI.Utility.Logging.CommandLogError("Blocks can only be moved in Build mode!");
|
||||
}
|
||||
}).Build();
|
||||
.Name("MoveLastBlock")
|
||||
.Description("Move the most-recently-placed block, and any connected blocks by the given offset")
|
||||
.Action((float x, float y, float z) =>
|
||||
{
|
||||
if (GameState.IsBuildMode())
|
||||
foreach (var block in Block.GetLastPlacedBlock().ConnectedCubes)
|
||||
block.Position += new Unity.Mathematics.float3(x, y, z);
|
||||
else
|
||||
GamecraftModdingAPI.Utility.Logging.CommandLogError("Blocks can only be moved in Build mode!");
|
||||
}).Build();
|
||||
|
||||
CommandBuilder.Builder()
|
||||
.Name("PlaceAluminium")
|
||||
.Description("Place a block of aluminium at the given coordinates")
|
||||
.Action((float x, float y, float z) => { Blocks.Placement.PlaceBlock(Blocks.BlockIDs.AluminiumCube, new Unity.Mathematics.float3(x, y, z)); })
|
||||
.Action((float x, float y, float z) => { Block.PlaceNew(Blocks.BlockIDs.AluminiumCube, new Unity.Mathematics.float3(x, y, z)); })
|
||||
.Build();
|
||||
|
||||
System.Random random = new System.Random(); // for command below
|
||||
|
|
Loading…
Reference in a new issue