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 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);
|
ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
// main (persistent) position
|
// main (persistent) position
|
||||||
posStruct.position += vector;
|
posStruct.position = vector;
|
||||||
// placement grid position
|
// placement grid position
|
||||||
gridStruct.position += vector;
|
gridStruct.position = vector;
|
||||||
// rendered position
|
// rendered position
|
||||||
transStruct.position += vector;
|
transStruct.position = vector;
|
||||||
// collision position
|
// collision position
|
||||||
FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation
|
FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation
|
||||||
{
|
{
|
||||||
Value = posStruct.position
|
Value = posStruct.position
|
||||||
});
|
});
|
||||||
|
entitiesDB.QueryEntity<GridConnectionsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false;
|
||||||
return posStruct.position;
|
return posStruct.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float3 MoveConnectedBlocks(uint blockID, float3 vector)
|
public float3 GetPosition(uint blockID)
|
||||||
{
|
{
|
||||||
Stack<uint> cubeStack = new Stack<uint>();
|
ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
FasterList<uint> cubesToMove = new FasterList<uint>();
|
return posStruct.position;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.Utility;
|
||||||
using GamecraftModdingAPI.Engines;
|
using GamecraftModdingAPI.Engines;
|
||||||
|
using GamecraftModdingAPI.Players;
|
||||||
|
|
||||||
namespace GamecraftModdingAPI.Blocks
|
namespace GamecraftModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
|
@ -46,11 +47,12 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine
|
private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine
|
||||||
|
|
||||||
public EGID 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)
|
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
|
{ //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)
|
if (darkness > 9)
|
||||||
throw new Exception("That is too dark. Make sure to use 0-9 as darkness. (0 is default.)");
|
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)
|
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
|
Value = rotStruct.rotation
|
||||||
});
|
});
|
||||||
|
entitiesDB.QueryEntity<GridConnectionsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false;
|
||||||
return ((Quaternion)rotStruct.rotation).eulerAngles;
|
return ((Quaternion)rotStruct.rotation).eulerAngles;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float3 RotateConnectedBlocks(uint blockID, Vector3 vector)
|
public float3 GetRotation(uint blockID)
|
||||||
{
|
{
|
||||||
// TODO: Implement and figure out the math
|
ref RotationEntityStruct rotStruct = ref entitiesDB.QueryEntity<RotationEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
throw new NotImplementedException();
|
return ((Quaternion) rotStruct.rotation).eulerAngles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,9 @@ using HarmonyLib;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Utility;
|
using GamecraftModdingAPI.Utility;
|
||||||
using GamecraftModdingAPI.Events;
|
using GamecraftModdingAPI.Events;
|
||||||
|
using GamecraftModdingAPI.Players;
|
||||||
using GamecraftModdingAPI.Tasks;
|
using GamecraftModdingAPI.Tasks;
|
||||||
|
using uREPL;
|
||||||
|
|
||||||
namespace GamecraftModdingAPI
|
namespace GamecraftModdingAPI
|
||||||
{
|
{
|
||||||
|
@ -61,18 +63,16 @@ namespace GamecraftModdingAPI
|
||||||
EventManager.AddEventEmitter(GameHostTransitionDeterministicGroupEnginePatch.simEngine);
|
EventManager.AddEventEmitter(GameHostTransitionDeterministicGroupEnginePatch.simEngine);
|
||||||
// init block implementors
|
// init block implementors
|
||||||
Logging.MetaDebugLog($"Initializing Blocks");
|
Logging.MetaDebugLog($"Initializing Blocks");
|
||||||
Blocks.Movement.Init();
|
|
||||||
Blocks.Rotation.Init();
|
|
||||||
Blocks.Signals.Init();
|
Blocks.Signals.Init();
|
||||||
Blocks.Placement.Init();
|
|
||||||
Blocks.Tweakable.Init();
|
Blocks.Tweakable.Init();
|
||||||
Blocks.Removal.Init();
|
|
||||||
// init inventory
|
// init inventory
|
||||||
Inventory.Hotbar.Init();
|
Inventory.Hotbar.Init();
|
||||||
// init input
|
// init input
|
||||||
Input.FakeInput.Init();
|
Input.FakeInput.Init();
|
||||||
// init object-oriented classes
|
// init object-oriented classes
|
||||||
Player.Init();
|
Player.Init();
|
||||||
|
Block.Init();
|
||||||
|
RuntimeCommands.Register("getblock", () => new Player(PlayerType.Local).GetBlockLookedAt());
|
||||||
Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized");
|
Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,6 +218,18 @@ namespace GamecraftModdingAPI
|
||||||
}
|
}
|
||||||
playerEngine.SetLocation(Id, location, exitSeat: exitSeat);
|
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
|
// internal methods
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,9 @@ using Unity.Mathematics;
|
||||||
using Unity.Physics;
|
using Unity.Physics;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Engines;
|
using GamecraftModdingAPI.Engines;
|
||||||
|
using RobocraftX.Blocks.Ghost;
|
||||||
|
using RobocraftX.Character.Camera;
|
||||||
|
using RobocraftX.Character.Factories;
|
||||||
|
|
||||||
namespace GamecraftModdingAPI.Players
|
namespace GamecraftModdingAPI.Players
|
||||||
{
|
{
|
||||||
|
@ -234,5 +237,23 @@ namespace GamecraftModdingAPI.Players
|
||||||
s = default;
|
s = default;
|
||||||
return false;
|
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;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
@ -94,22 +95,21 @@ namespace GamecraftModdingAPI.Tests
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
CommandBuilder.Builder()
|
CommandBuilder.Builder()
|
||||||
.Name("MoveLastBlock")
|
.Name("MoveLastBlock")
|
||||||
.Description("Move the most-recently-placed block, and any connected blocks by the given offset")
|
.Description("Move the most-recently-placed block, and any connected blocks by the given offset")
|
||||||
.Action((float x, float y, float z) => {
|
.Action((float x, float y, float z) =>
|
||||||
bool success = GamecraftModdingAPI.Blocks.Movement.MoveConnectedBlocks(
|
{
|
||||||
GamecraftModdingAPI.Blocks.BlockIdentifiers.LatestBlockID,
|
if (GameState.IsBuildMode())
|
||||||
new Unity.Mathematics.float3(x, y, z));
|
foreach (var block in Block.GetLastPlacedBlock().ConnectedCubes)
|
||||||
if (!success)
|
block.Position += new Unity.Mathematics.float3(x, y, z);
|
||||||
{
|
else
|
||||||
GamecraftModdingAPI.Utility.Logging.CommandLogError("Blocks can only be moved in Build mode!");
|
GamecraftModdingAPI.Utility.Logging.CommandLogError("Blocks can only be moved in Build mode!");
|
||||||
}
|
}).Build();
|
||||||
}).Build();
|
|
||||||
|
|
||||||
CommandBuilder.Builder()
|
CommandBuilder.Builder()
|
||||||
.Name("PlaceAluminium")
|
.Name("PlaceAluminium")
|
||||||
.Description("Place a block of aluminium at the given coordinates")
|
.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();
|
.Build();
|
||||||
|
|
||||||
System.Random random = new System.Random(); // for command below
|
System.Random random = new System.Random(); // for command below
|
||||||
|
|
Loading…
Reference in a new issue