Add object ID block and label support

This commit is contained in:
Norbi Peti 2020-05-24 19:29:02 +02:00
parent dca6fe4c1b
commit ab7c5805fe
5 changed files with 125 additions and 13 deletions

View file

@ -7,6 +7,7 @@ using Svelto.ECS.EntityStructs;
using RobocraftX.Common;
using RobocraftX.Blocks;
using Unity.Mathematics;
using Gamecraft.Blocks.GUI;
using GamecraftModdingAPI.Blocks;
using GamecraftModdingAPI.Utility;
@ -231,6 +232,20 @@ namespace GamecraftModdingAPI
}
}
/// <summary>
/// The short text displayed on the block if applicable, or null.
/// Setting it is temporary to the session, it won't be saved.
/// </summary>
public string Label
{
get => BlockEngine.GetBlockInfo<TextLabelEntityViewStruct>(Id).textLabelComponent?.text;
set
{
ref var text = ref BlockEngine.GetBlockInfo<TextLabelEntityViewStruct>(Id);
if (text.textLabelComponent != null) text.textLabelComponent.text = value;
}
}
/// <summary>
/// Whether the block exists. The other properties will return a default value if the block doesn't exist.
/// </summary>
@ -251,8 +266,8 @@ namespace GamecraftModdingAPI
/// Returns the rigid body of the cluster of blocks this one belongs to during simulation.
/// Can be used to apply forces or move the block around while the simulation is running.
/// </summary>
/// <returns></returns>
public SimBody ToSimBody()
/// <returns>The SimBody of the cluster</returns>
public SimBody GetSimBody()
{
uint id = BlockEngine.GetBlockInfo<GridConnectionsEntityStruct>(Id).machineRigidBodyId;
return new SimBody(id);
@ -260,7 +275,7 @@ namespace GamecraftModdingAPI
public override string ToString()
{
return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Rotation)}: {Rotation}";
return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Type)}: {Type}, {nameof(Color)}: {Color}, {nameof(Exists)}: {Exists}";
}
public static void Init()

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using Gamecraft.Wires;
using RobocraftX.Blocks;
using RobocraftX.Common;
using RobocraftX.GUI.Hotbar.Colours;
@ -91,6 +92,40 @@ namespace GamecraftModdingAPI.Blocks
return entitiesDB.Exists<T>(blockID);
}
public SimBody[] GetSimBodiesFromID(byte id)
{
var ret = new FasterList<SimBody>(4);
if (!entitiesDB.HasAny<ObjectIdEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP))
return new SimBody[0];
var oids = entitiesDB.QueryEntities<ObjectIdEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
var connections = entitiesDB.QueryMappedEntities<GridConnectionsEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
foreach (ref ObjectIdEntityStruct oid in oids)
{
if (oid.objectId != id) continue;
var rid = connections.Entity(oid.ID.entityID).machineRigidBodyId;
foreach (var rb in ret)
{
if (rb.Id.entityID == rid)
goto DUPLICATE; //Multiple Object Identifiers on one rigid body
}
ret.Add(new SimBody(rid));
DUPLICATE: ;
}
return ret.ToArray();
}
public ObjectIdentifier[] GetObjectIDsFromID(byte id)
{
var ret = new FasterList<ObjectIdentifier>(4);
if (!entitiesDB.HasAny<ObjectIdEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP))
return new ObjectIdentifier[0];
var oids = entitiesDB.QueryEntities<ObjectIdEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
foreach (ref ObjectIdEntityStruct oid in oids)
if (oid.objectId == id)
ret.Add(new ObjectIdentifier(oid.ID));
return ret.ToArray();
}
#if DEBUG
public EntitiesDB GetEntitiesDB()
{

View file

@ -0,0 +1,41 @@
using Gamecraft.Wires;
using Svelto.ECS;
namespace GamecraftModdingAPI.Blocks
{
public class ObjectIdentifier : Block
{
public ObjectIdentifier(EGID id) : base(id)
{
if (!BlockEngine.GetBlockInfoExists<ObjectIdEntityStruct>(Id))
{
throw new BlockTypeException($"Block is not a {GetType().Name} block");
}
}
public ObjectIdentifier(uint id) : base(id)
{
if (!BlockEngine.GetBlockInfoExists<ObjectIdEntityStruct>(Id))
{
throw new BlockTypeException($"Block is not a {GetType().Name} block");
}
}
public char Identifier
{
get => (char) (BlockEngine.GetBlockInfo<ObjectIdEntityStruct>(Id).objectId + 'A');
set
{
BlockEngine.GetBlockInfo<ObjectIdEntityStruct>(Id).objectId = (byte) (value - 'A');
Label = value + ""; //The label isn't updated automatically
}
}
/// <summary>
/// Finds the identfier blocks with the given ID.
/// </summary>
/// <param name="id">The ID to look for</param>
/// <returns>An array that may be empty</returns>
public static ObjectIdentifier[] GetByID(char id) => BlockEngine.GetObjectIDsFromID((byte) (id - 'A'));
}
}

View file

@ -1,8 +1,8 @@
using RobocraftX.Common;
using Gamecraft.Wires;
using RobocraftX.Common;
using RobocraftX.Physics;
using Svelto.ECS;
using Unity.Mathematics;
using Unity.Physics;
using UnityEngine;
namespace GamecraftModdingAPI
@ -74,15 +74,25 @@ namespace GamecraftModdingAPI
/// <summary>
/// Whether the body can be moved or static
/// </summary>
public bool Static
{
get => Block.BlockEngine.GetBlockInfo<MassEntityStruct>(Id).isStatic;
set => Block.BlockEngine.GetBlockInfo<MassEntityStruct>(Id).isStatic = value;
}
public bool Static => Block.BlockEngine.GetBlockInfo<MassEntityStruct>(Id).isStatic;
//Setting it doesn't have any effect
private ref RigidBodyEntityStruct GetStruct()
{
return ref Block.BlockEngine.GetBlockInfo<RigidBodyEntityStruct>(Id);
}
public override string ToString()
{
return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Mass)}: {Mass}, {nameof(Static)}: {Static}";
}
/// <summary>
/// Returns the object identified by the given ID (A-Z).
/// This has the same result as calling ObjectIdentifier.GetByID(id) and then GetRigidBody() with the duplicates filtered out.
/// </summary>
/// <param name="id">The alphabetical ID</param>
/// <returns>An array that may be empty</returns>
public static SimBody[] GetFromObjectID(char id) => Block.BlockEngine.GetSimBodiesFromID((byte) (id - 'A'));
}
}

View file

@ -175,7 +175,7 @@ namespace GamecraftModdingAPI.Tests
//With Sync() at the end: 380ms
Block b = null;
CommandBuilder.Builder("moveBlockInSim", "Run in build mode first, then in sim while looking at a block to move it up")
CommandBuilder.Builder("moveBlockInSim", "Run in build mode first while looking at a block, then in sim to move it up")
.Action(() =>
{
if (b == null)
@ -184,7 +184,7 @@ namespace GamecraftModdingAPI.Tests
Logging.CommandLog("Block saved: " + b);
}
else
Logging.CommandLog("Block moved to: " + (b.ToSimBody().Position += new float3(0, 2, 0)));
Logging.CommandLog("Block moved to: " + (b.GetSimBody().Position += new float3(0, 2, 0)));
}).Build();
CommandBuilder.Builder("Error", "Throw an error to make sure SimpleCustomCommandEngine's wrapper catches it.")
@ -209,6 +209,16 @@ namespace GamecraftModdingAPI.Tests
}).Build();
CommandBuilder.Builder("GetBlockByID", "Gets a block based on its object identifier and teleports it up.")
.Action<char>(ch =>
{
foreach (var body in SimBody.GetFromObjectID(ch))
{
Logging.CommandLog("SimBody: " + body);
body.Position += new float3(0, 10, 0);
}
}).Build();
GameClient.SetDebugInfo("lookedAt", LookedAt);
GameClient.SetDebugInfo("InstalledMods", InstalledMods);
@ -277,7 +287,8 @@ namespace GamecraftModdingAPI.Tests
{
Block block = player.GetBlockLookedAt();
if (block == null) return "Block: none";
return "Block: " + block.Type + "\nColor: " + block.Color + "\n" + "At: " + block.Position;
return "Block: " + block.Type + "\nColor: " + block.Color + "\n" + "At: " + block.Position
+ "\nText: " + block.Label;
}
if (GameState.IsSimulationMode())
{