Integrate tweak and signal functionality into Blocks
This commit is contained in:
parent
fb841b6542
commit
8326d70cbf
14 changed files with 519 additions and 778 deletions
|
@ -23,6 +23,7 @@ namespace GamecraftModdingAPI
|
||||||
protected static readonly RotationEngine RotationEngine = new RotationEngine();
|
protected static readonly RotationEngine RotationEngine = new RotationEngine();
|
||||||
protected static readonly RemovalEngine RemovalEngine = new RemovalEngine();
|
protected static readonly RemovalEngine RemovalEngine = new RemovalEngine();
|
||||||
protected static readonly BlockEngine BlockEngine = new BlockEngine();
|
protected static readonly BlockEngine BlockEngine = new BlockEngine();
|
||||||
|
protected static readonly SignalEngine SignalEngine = new SignalEngine();
|
||||||
|
|
||||||
/// <summary>
|
/// <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 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.
|
||||||
|
|
|
@ -74,8 +74,8 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
if (exists)
|
if (exists)
|
||||||
return ref entitiesDB.QueryEntity<T>(blockID);
|
return ref entitiesDB.QueryEntity<T>(blockID);
|
||||||
T[] structHolder = new T[1];
|
T[] structHolder = new T[1];
|
||||||
ref T structRef = ref structHolder[0];
|
//ref T defRef = ref structHolder[0];
|
||||||
return ref structRef;
|
return ref structHolder[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BlockExists(EGID id)
|
public bool BlockExists(EGID id)
|
||||||
|
|
113
GamecraftModdingAPI/Blocks/Motor.cs
Normal file
113
GamecraftModdingAPI/Blocks/Motor.cs
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using RobocraftX.Blocks;
|
||||||
|
using Svelto.ECS;
|
||||||
|
using Unity.Mathematics;
|
||||||
|
|
||||||
|
using GamecraftModdingAPI.Utility;
|
||||||
|
|
||||||
|
namespace GamecraftModdingAPI.Blocks
|
||||||
|
{
|
||||||
|
public class Motor : Block
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Places a new motor.
|
||||||
|
/// Any valid motor type is accepted.
|
||||||
|
/// This re-implements Block.PlaceNew(...)
|
||||||
|
/// </summary>
|
||||||
|
public static new Motor 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 (!(block == BlockIDs.MotorS || block == BlockIDs.MotorM))
|
||||||
|
{
|
||||||
|
throw new BlockTypeException($"Block is not a {typeof(Motor).Name} block");
|
||||||
|
}
|
||||||
|
if (PlacementEngine.IsInGame && GameState.IsBuildMode())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
EGID id = PlacementEngine.PlaceBlock(block, color, darkness,
|
||||||
|
position, uscale, scale, player, rotation);
|
||||||
|
Sync();
|
||||||
|
return new Motor(id);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logging.MetaDebugLog(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Motor(EGID id) : base(id)
|
||||||
|
{
|
||||||
|
if (!BlockEngine.GetBlockInfoExists<MotorReadOnlyStruct>(this.Id))
|
||||||
|
{
|
||||||
|
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Motor(uint id) : base(id)
|
||||||
|
{
|
||||||
|
if (!BlockEngine.GetBlockInfoExists<MotorReadOnlyStruct>(this.Id))
|
||||||
|
{
|
||||||
|
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom motor properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The motor's maximum rotational velocity.
|
||||||
|
/// </summary>
|
||||||
|
public float TopSpeed
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id).maxVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id);
|
||||||
|
motor.maxVelocity = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The motor's maximum rotational force.
|
||||||
|
/// </summary>
|
||||||
|
public float Torque
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id).maxForce;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id);
|
||||||
|
motor.maxForce = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The motor's direction.
|
||||||
|
/// </summary>
|
||||||
|
public bool Reverse
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id).reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id);
|
||||||
|
motor.reverse = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
90
GamecraftModdingAPI/Blocks/Piston.cs
Normal file
90
GamecraftModdingAPI/Blocks/Piston.cs
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using RobocraftX.Blocks;
|
||||||
|
using Svelto.ECS;
|
||||||
|
using Unity.Mathematics;
|
||||||
|
|
||||||
|
using GamecraftModdingAPI.Utility;
|
||||||
|
|
||||||
|
namespace GamecraftModdingAPI.Blocks
|
||||||
|
{
|
||||||
|
public class Piston : Block
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Places a new piston.
|
||||||
|
/// Any valid piston type is accepted.
|
||||||
|
/// This re-implements Block.PlaceNew(...)
|
||||||
|
/// </summary>
|
||||||
|
public static new Piston 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 (!(block == BlockIDs.ServoPiston || block == BlockIDs.StepperPiston || block == BlockIDs.PneumaticPiston))
|
||||||
|
{
|
||||||
|
throw new BlockTypeException($"Block is not a {typeof(Piston).Name} block");
|
||||||
|
}
|
||||||
|
if (PlacementEngine.IsInGame && GameState.IsBuildMode())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
EGID id = PlacementEngine.PlaceBlock(block, color, darkness,
|
||||||
|
position, uscale, scale, player, rotation);
|
||||||
|
Sync();
|
||||||
|
return new Piston(id);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logging.MetaDebugLog(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Piston(EGID id) : base(id)
|
||||||
|
{
|
||||||
|
if (!BlockEngine.GetBlockInfoExists<PistonReadOnlyStruct>(this.Id))
|
||||||
|
{
|
||||||
|
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Piston(uint id) : base(id)
|
||||||
|
{
|
||||||
|
if (!BlockEngine.GetBlockInfoExists<PistonReadOnlyStruct>(this.Id))
|
||||||
|
{
|
||||||
|
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom piston properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The piston's max extension distance.
|
||||||
|
/// </summary>
|
||||||
|
public float MaximumExtension
|
||||||
|
{
|
||||||
|
get => BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(Id).maxDeviation;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ref PistonReadOnlyStruct piston = ref BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(Id);
|
||||||
|
piston.maxDeviation = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The piston's max extension force.
|
||||||
|
/// </summary>
|
||||||
|
public float MaximumForce
|
||||||
|
{
|
||||||
|
get => BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(Id).maxForce;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ref PistonReadOnlyStruct piston = ref BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(Id);
|
||||||
|
piston.maxForce = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
118
GamecraftModdingAPI/Blocks/Servo.cs
Normal file
118
GamecraftModdingAPI/Blocks/Servo.cs
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using RobocraftX.Blocks;
|
||||||
|
using Svelto.ECS;
|
||||||
|
using Unity.Mathematics;
|
||||||
|
|
||||||
|
using GamecraftModdingAPI.Utility;
|
||||||
|
|
||||||
|
namespace GamecraftModdingAPI.Blocks
|
||||||
|
{
|
||||||
|
public class Servo : Block
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Places a new servo.
|
||||||
|
/// Any valid servo type is accepted.
|
||||||
|
/// This re-implements Block.PlaceNew(...)
|
||||||
|
/// </summary>
|
||||||
|
public static new Servo 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 (!(block == BlockIDs.ServoAxle || block == BlockIDs.ServoHinge || block == BlockIDs.ServoPiston))
|
||||||
|
{
|
||||||
|
throw new BlockTypeException($"Block is not a {typeof(Servo).Name} block");
|
||||||
|
}
|
||||||
|
if (PlacementEngine.IsInGame && GameState.IsBuildMode())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
EGID id = PlacementEngine.PlaceBlock(block, color, darkness,
|
||||||
|
position, uscale, scale, player, rotation);
|
||||||
|
Sync();
|
||||||
|
return new Servo(id);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logging.MetaDebugLog(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Servo(EGID id) : base(id)
|
||||||
|
{
|
||||||
|
if (!BlockEngine.GetBlockInfoExists<ServoReadOnlyStruct>(this.Id))
|
||||||
|
{
|
||||||
|
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Servo(uint id) : base(id)
|
||||||
|
{
|
||||||
|
if (!BlockEngine.GetBlockInfoExists<ServoReadOnlyStruct>(this.Id))
|
||||||
|
{
|
||||||
|
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom servo properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The servo's minimum angle.
|
||||||
|
/// </summary>
|
||||||
|
public float MinimumAngle
|
||||||
|
{
|
||||||
|
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id).minDeviation;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id);
|
||||||
|
servo.minDeviation = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The servo's maximum angle.
|
||||||
|
/// </summary>
|
||||||
|
public float MaximumAngle
|
||||||
|
{
|
||||||
|
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id).maxDeviation;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id);
|
||||||
|
servo.maxDeviation = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The servo's maximum force.
|
||||||
|
/// </summary>
|
||||||
|
public float MaximumForce
|
||||||
|
{
|
||||||
|
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id).maxForce;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id);
|
||||||
|
servo.maxForce = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The servo's direction.
|
||||||
|
/// </summary>
|
||||||
|
public bool Reverse
|
||||||
|
{
|
||||||
|
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id).reverse;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id);
|
||||||
|
servo.reverse = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,11 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SignalEngine : IApiEngine
|
public class SignalEngine : IApiEngine
|
||||||
{
|
{
|
||||||
|
public const float POSITIVE_HIGH = 1.0f;
|
||||||
|
public const float NEGATIVE_HIGH = -1.0f;
|
||||||
|
public const float HIGH = 1.0f;
|
||||||
|
public const float ZERO = 0.0f;
|
||||||
|
|
||||||
public string Name { get; } = "GamecraftModdingAPISignalGameEngine";
|
public string Name { get; } = "GamecraftModdingAPISignalGameEngine";
|
||||||
|
|
||||||
public EntitiesDB entitiesDB { set; private get; }
|
public EntitiesDB entitiesDB { set; private get; }
|
||||||
|
@ -58,13 +63,13 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
channelData.valueAsFloat += signal;
|
channelData.valueAsFloat += signal;
|
||||||
if (clamp)
|
if (clamp)
|
||||||
{
|
{
|
||||||
if (channelData.valueAsFloat > Signals.POSITIVE_HIGH)
|
if (channelData.valueAsFloat > POSITIVE_HIGH)
|
||||||
{
|
{
|
||||||
channelData.valueAsFloat = Signals.POSITIVE_HIGH;
|
channelData.valueAsFloat = POSITIVE_HIGH;
|
||||||
}
|
}
|
||||||
else if (channelData.valueAsFloat < Signals.NEGATIVE_HIGH)
|
else if (channelData.valueAsFloat < NEGATIVE_HIGH)
|
||||||
{
|
{
|
||||||
channelData.valueAsFloat = Signals.NEGATIVE_HIGH;
|
channelData.valueAsFloat = NEGATIVE_HIGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return channelData.valueAsFloat;
|
return channelData.valueAsFloat;
|
||||||
|
@ -106,6 +111,60 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
return signals;
|
return signals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EGID[] GetSignalInputs(EGID blockID)
|
||||||
|
{
|
||||||
|
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(blockID);
|
||||||
|
EGID[] inputs = new EGID[ports.inputCount];
|
||||||
|
for (uint i = 0; i < ports.inputCount; i++)
|
||||||
|
{
|
||||||
|
inputs[i] = new EGID(i + ports.firstInputID, NamedExclusiveGroup<InputPortsGroup>.Group);
|
||||||
|
}
|
||||||
|
return inputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EGID[] GetSignalOutputs(EGID blockID)
|
||||||
|
{
|
||||||
|
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(blockID);
|
||||||
|
EGID[] outputs = new EGID[ports.outputCount];
|
||||||
|
for (uint i = 0; i < ports.outputCount; i++)
|
||||||
|
{
|
||||||
|
outputs[i] = new EGID(i + ports.firstOutputID, NamedExclusiveGroup<OutputPortsGroup>.Group);
|
||||||
|
}
|
||||||
|
return outputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref WireEntityStruct MatchPortToWire(EGID portID, EGID blockID, out bool exists)
|
||||||
|
{
|
||||||
|
ref PortEntityStruct port = ref entitiesDB.QueryEntity<PortEntityStruct>(portID);
|
||||||
|
WireEntityStruct[] wires = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<WiresGroup>.Group).ToFastAccess(out uint count);
|
||||||
|
for (uint i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if ((wires[i].destinationPortUsage == port.usage && wires[i].destinationBlockEGID == blockID)
|
||||||
|
|| (wires[i].sourcePortUsage == port.usage && wires[i].sourceBlockEGID == blockID))
|
||||||
|
{
|
||||||
|
exists = true;
|
||||||
|
return ref wires[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exists = false;
|
||||||
|
WireEntityStruct[] defRef = new WireEntityStruct[1];
|
||||||
|
return ref defRef[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref ChannelDataStruct GetChannelDataStruct(EGID portID, out bool exists)
|
||||||
|
{
|
||||||
|
ref PortEntityStruct port = ref entitiesDB.QueryEntity<PortEntityStruct>(portID);
|
||||||
|
ChannelDataStruct[] channels = entitiesDB.QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<ChannelDataGroup>.Group).ToFastAccess(out uint count);
|
||||||
|
if (port.firstChannelIndexCachedInSim < count)
|
||||||
|
{
|
||||||
|
exists = true;
|
||||||
|
return ref channels[port.firstChannelIndexCachedInSim];
|
||||||
|
}
|
||||||
|
exists = false;
|
||||||
|
ChannelDataStruct[] defRef = new ChannelDataStruct[1];
|
||||||
|
return ref defRef[0];
|
||||||
|
}
|
||||||
|
|
||||||
public EGID[] GetElectricBlocks()
|
public EGID[] GetElectricBlocks()
|
||||||
{
|
{
|
||||||
uint count = entitiesDB.Count<BlockPortsStruct>(BlockIdentifiers.OWNED_BLOCKS) + entitiesDB.Count<BlockPortsStruct>(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS);
|
uint count = entitiesDB.Count<BlockPortsStruct>(BlockIdentifiers.OWNED_BLOCKS) + entitiesDB.Count<BlockPortsStruct>(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS);
|
||||||
|
|
131
GamecraftModdingAPI/Blocks/SignalingBlock.cs
Normal file
131
GamecraftModdingAPI/Blocks/SignalingBlock.cs
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Gamecraft.Wires;
|
||||||
|
using Svelto.ECS;
|
||||||
|
using Unity.Mathematics;
|
||||||
|
|
||||||
|
using GamecraftModdingAPI;
|
||||||
|
using GamecraftModdingAPI.Utility;
|
||||||
|
|
||||||
|
namespace GamecraftModdingAPI.Blocks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Common implementation for blocks that support wiring.
|
||||||
|
/// </summary>
|
||||||
|
public class SignalingBlock : Block
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Places a new signaling block.
|
||||||
|
/// Any valid functional block type with IO ports will work.
|
||||||
|
/// This re-implements Block.PlaceNew(...)
|
||||||
|
/// </summary>
|
||||||
|
public static new SignalingBlock 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
|
||||||
|
{
|
||||||
|
EGID id = PlacementEngine.PlaceBlock(block, color, darkness,
|
||||||
|
position, uscale, scale, player, rotation);
|
||||||
|
Sync();
|
||||||
|
return new SignalingBlock(id);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logging.MetaDebugLog(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SignalingBlock(EGID id) : base(id)
|
||||||
|
{
|
||||||
|
if (!BlockEngine.GetBlockInfoExists<BlockPortsStruct>(this.Id))
|
||||||
|
{
|
||||||
|
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SignalingBlock(uint id) : base(id)
|
||||||
|
{
|
||||||
|
if (!BlockEngine.GetBlockInfoExists<BlockPortsStruct>(this.Id))
|
||||||
|
{
|
||||||
|
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ref BlockPortsStruct GetBlockPortsStruct()
|
||||||
|
{
|
||||||
|
return ref BlockEngine.GetBlockInfo<BlockPortsStruct>(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates the input port identifiers.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The input identifiers.</returns>
|
||||||
|
protected EGID[] GetInputIds()
|
||||||
|
{
|
||||||
|
return SignalEngine.GetSignalInputs(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates the output port identifiers.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The output identifiers.</returns>
|
||||||
|
protected EGID[] GetOutputIds()
|
||||||
|
{
|
||||||
|
return SignalEngine.GetSignalOutputs(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the port struct.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The port struct.</returns>
|
||||||
|
/// <param name="portId">Port identifier.</param>
|
||||||
|
protected ref PortEntityStruct GetPortStruct(EGID portId)
|
||||||
|
{
|
||||||
|
return ref BlockEngine.GetBlockInfo<PortEntityStruct>(portId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the connected wire.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The connected wire.</returns>
|
||||||
|
/// <param name="portId">Port identifier.</param>
|
||||||
|
/// <param name="connected">Whether the port has a wire connected to it.</param>
|
||||||
|
protected ref WireEntityStruct GetConnectedWire(EGID portId, out bool connected)
|
||||||
|
{
|
||||||
|
return ref SignalEngine.MatchPortToWire(portId, Id, out connected);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// [EXPERIMENTAL] Gets the channel data.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The channel data.</returns>
|
||||||
|
/// <param name="portId">Port identifier.</param>
|
||||||
|
/// <param name="exists">Whether the channel actually exists.</param>
|
||||||
|
protected ref ChannelDataStruct GetChannelData(EGID portId, out bool exists)
|
||||||
|
{
|
||||||
|
return ref SignalEngine.GetChannelDataStruct(portId, out exists);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The input port count.
|
||||||
|
/// </summary>
|
||||||
|
public uint InputCount
|
||||||
|
{
|
||||||
|
get => GetBlockPortsStruct().inputCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The output port count.
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputCount
|
||||||
|
{
|
||||||
|
get => GetBlockPortsStruct().outputCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,177 +0,0 @@
|
||||||
using Svelto.ECS;
|
|
||||||
|
|
||||||
using GamecraftModdingAPI.Utility;
|
|
||||||
|
|
||||||
namespace GamecraftModdingAPI.Blocks
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// [EXPERIMENTAL] Common block signal operations
|
|
||||||
/// The functionality in this class only works when in a game.
|
|
||||||
/// </summary>
|
|
||||||
public static class Signals
|
|
||||||
{
|
|
||||||
// Signal constants
|
|
||||||
public static readonly float HIGH = 1.0f;
|
|
||||||
public static readonly float POSITIVE_HIGH = HIGH;
|
|
||||||
public static readonly float NEGATIVE_HIGH = -1.0f;
|
|
||||||
public static readonly float LOW = 0.0f;
|
|
||||||
|
|
||||||
private static SignalEngine signalEngine = new SignalEngine();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the electric block's (first) signal value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="blockID">The block's id.</param>
|
|
||||||
/// <param name="signal">The signal value (-1 to 1; not enforced).</param>
|
|
||||||
/// <param name="input">Whether to retrieve input IDs (true) or output IDs (false).</param>
|
|
||||||
/// <param name="owned">Whether the block is in the owned group (true) or functional group (false)</param>
|
|
||||||
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 && GameState.IsSimulationMode())
|
|
||||||
{
|
|
||||||
signalEngine.SetSignal(egid, signal, out uint _, input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetSignalByBlock(EGID blockID, float signal, bool input = true)
|
|
||||||
{
|
|
||||||
if (signalEngine.IsInGame && GameState.IsSimulationMode())
|
|
||||||
{
|
|
||||||
signalEngine.SetSignal(blockID, signal, out uint _, input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the signal's value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="signalID">The channel cluster's id.</param>
|
|
||||||
/// <param name="signal">The signal value (-1 to 1; not enforced).</param>
|
|
||||||
/// <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 && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
|
|
||||||
{
|
|
||||||
signalEngine.SetSignal(signalID, signal, input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add a value to an electric block's signal.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="blockID">The block's id.</param>
|
|
||||||
/// <param name="signal">The signal value to add.</param>
|
|
||||||
/// <param name="clamp">Whether to clamp the resulting signal value between -1 and 1.</param>
|
|
||||||
/// <param name="input">Whether to retrieve input IDs (true) or output IDs (false).</param>
|
|
||||||
/// <param name="owned">Whether the block is in the owned group (true) or functional group (false)</param>
|
|
||||||
/// <returns>The signal's new value.</returns>
|
|
||||||
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 && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
|
|
||||||
{
|
|
||||||
return signalEngine.AddSignal(egid, signal, out uint _, clamp, input);
|
|
||||||
}
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float AddSignalByBlock(EGID blockID, float signal, bool clamp = true, bool input = true)
|
|
||||||
{
|
|
||||||
if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
|
|
||||||
{
|
|
||||||
return signalEngine.AddSignal(blockID, signal, out uint _, clamp, input);
|
|
||||||
}
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add a value to a conductive cluster channel.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="signalID">The channel cluster's id.</param>
|
|
||||||
/// <param name="signal">The signal value to add.</param>
|
|
||||||
/// <param name="clamp">Whether to clamp the resulting signal value between -1 and 1.</param>
|
|
||||||
/// <param name="input">Whether to retrieve input IDs (true) or output IDs (false).</param>
|
|
||||||
/// <returns>The signal's new value.</returns>
|
|
||||||
public static float AddSignalByID(uint signalID, float signal, bool clamp = true, bool input = true)
|
|
||||||
{
|
|
||||||
if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
|
|
||||||
{
|
|
||||||
return signalEngine.AddSignal(signalID, signal, clamp, input);
|
|
||||||
}
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a electric block's signal's (first) value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="blockID">The block's id.</param>
|
|
||||||
/// <param name="input">Whether to retrieve input IDs (true) or output IDs (false).</param>
|
|
||||||
/// <param name="owned">Whether the block is in the owned group (true) or functional group (false)</param>
|
|
||||||
/// <returns>The signal's value.</returns>
|
|
||||||
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 && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
|
|
||||||
{
|
|
||||||
return signalEngine.GetSignal(egid, out uint _, input);
|
|
||||||
}
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float GetSignalByBlock(EGID blockID, bool input = true)
|
|
||||||
{
|
|
||||||
if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
|
|
||||||
{
|
|
||||||
return signalEngine.GetSignal(blockID, out uint _, input);
|
|
||||||
}
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a signal's value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="signalID">The signal's id.</param>
|
|
||||||
/// <param name="input">Whether to retrieve input IDs (true) or output IDs (false).</param>
|
|
||||||
/// <returns>The signal's value.</returns>
|
|
||||||
public static float GetSignalByID(uint signalID, bool input = true)
|
|
||||||
{
|
|
||||||
if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode())
|
|
||||||
{
|
|
||||||
return signalEngine.GetSignal(signalID, input);
|
|
||||||
}
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the ID of every electric block in the game world.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The block IDs.</returns>
|
|
||||||
public static EGID[] GetElectricBlocks()
|
|
||||||
{
|
|
||||||
return signalEngine.GetElectricBlocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the unique identifiers for the input wires connected to an electric block.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="blockID">The block's id.</param>
|
|
||||||
/// <param name="input">Whether to retrieve input IDs (true) or output IDs (false).</param>
|
|
||||||
/// <param name="owned">Whether the block is in the owned group (true) or functional group (false)</param>
|
|
||||||
/// <returns>The unique IDs.</returns>
|
|
||||||
public static uint[] GetSignalIDs(uint blockID, bool input = true, bool owned = true)
|
|
||||||
{
|
|
||||||
EGID egid = new EGID(blockID, owned ? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS);
|
|
||||||
return signalEngine.GetSignalIDs(egid, input);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static uint[] GetSignalIDs(EGID blockID, bool input = true, bool owned = true)
|
|
||||||
{
|
|
||||||
return signalEngine.GetSignalIDs(blockID, input);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Init()
|
|
||||||
{
|
|
||||||
GameEngineManager.AddGameEngine(signalEngine);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
namespace GamecraftModdingAPI.Blocks
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Common tweakable stats operations.
|
|
||||||
/// The functionality of this class works best in build mode.
|
|
||||||
/// </summary>
|
|
||||||
public static class Tweakable
|
|
||||||
{
|
|
||||||
private static TweakableEngine tweakableEngine = new TweakableEngine();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the tweakable stat's value using a dynamic variable type.
|
|
||||||
/// This is similar to GetStat<T> but without strong type enforcement.
|
|
||||||
/// This should be used in dynamically-typed languages like Python.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The stat's value.</returns>
|
|
||||||
/// <param name="blockID">The block's id.</param>
|
|
||||||
/// <param name="stat">The stat's enumerated id.</param>
|
|
||||||
public static dynamic GetStatD(uint blockID, TweakableStat stat)
|
|
||||||
{
|
|
||||||
return tweakableEngine.GetStatDynamic(blockID, stat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the tweakable stat's value.
|
|
||||||
/// If T is not the same type as the stat, an InvalidCastException will be thrown.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The stat's value.</returns>
|
|
||||||
/// <param name="blockID">The block's id.</param>
|
|
||||||
/// <param name="stat">The stat's enumerated id.</param>
|
|
||||||
/// <typeparam name="T">The stat's type.</typeparam>
|
|
||||||
public static T GetStat<T>(uint blockID, TweakableStat stat)
|
|
||||||
{
|
|
||||||
return tweakableEngine.GetStatAny<T>(blockID, stat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the tweakable stat's value using dynamically-typed variables.
|
|
||||||
/// This is similar to SetStat<T> but without strong type enforcement.
|
|
||||||
/// This should be used in dynamically-typed languages like Python.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The stat's new value.</returns>
|
|
||||||
/// <param name="blockID">The block's id.</param>
|
|
||||||
/// <param name="stat">The stat's enumerated id.</param>
|
|
||||||
/// <param name="value">The stat's new value.</param>
|
|
||||||
public static dynamic SetStatD(uint blockID, TweakableStat stat, dynamic value)
|
|
||||||
{
|
|
||||||
return tweakableEngine.SetStatDynamic(blockID, stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the tweakable stat's value.
|
|
||||||
/// If T is not the stat's actual type, an InvalidCastException will be thrown.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The stat's new value.</returns>
|
|
||||||
/// <param name="blockID">The block's id.</param>
|
|
||||||
/// <param name="stat">The stat's enumerated id.</param>
|
|
||||||
/// <param name="value">The stat's new value.</param>
|
|
||||||
/// <typeparam name="T">The stat's type.</typeparam>
|
|
||||||
public static T SetStat<T>(uint blockID, TweakableStat stat, T value)
|
|
||||||
{
|
|
||||||
return tweakableEngine.SetStatAny<T>(blockID, stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add another value to the tweakable stat's value using dynamically-typed variables.
|
|
||||||
/// This is similar to AddStat<T> but without strong type enforcement.
|
|
||||||
/// This should be used in dynamically-typed languages like Python.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The stat's new value.</returns>
|
|
||||||
/// <param name="blockID">The block's id.</param>
|
|
||||||
/// <param name="stat">The stat's enumerated id.</param>
|
|
||||||
/// <param name="value">The value to be added to the stat.</param>
|
|
||||||
public static dynamic AddStatD(uint blockID, TweakableStat stat, dynamic value)
|
|
||||||
{
|
|
||||||
return tweakableEngine.AddStatDynamic(blockID, stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add another value to the tweakable stat's value.
|
|
||||||
/// If T is not the stat's actual type, an InvalidCastException will be thrown.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The stat's new value.</returns>
|
|
||||||
/// <param name="blockID">The block's id.</param>
|
|
||||||
/// <param name="stat">The stat's enumerated id.</param>
|
|
||||||
/// <param name="value">The value to be added to the stat.</param>
|
|
||||||
/// <typeparam name="T">The stat's type.</typeparam>
|
|
||||||
public static T AddStat<T>(uint blockID, TweakableStat stat, T value)
|
|
||||||
{
|
|
||||||
return tweakableEngine.AddStatAny<T>(blockID, stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Init()
|
|
||||||
{
|
|
||||||
GamecraftModdingAPI.Utility.GameEngineManager.AddGameEngine(tweakableEngine);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,452 +0,0 @@
|
||||||
using RobocraftX.Blocks;
|
|
||||||
using Gamecraft.Wires;
|
|
||||||
using Svelto.ECS;
|
|
||||||
|
|
||||||
using GamecraftModdingAPI.Engines;
|
|
||||||
|
|
||||||
|
|
||||||
namespace GamecraftModdingAPI.Blocks
|
|
||||||
{
|
|
||||||
public class TweakableEngine : IApiEngine
|
|
||||||
{
|
|
||||||
public string Name { get; } = "GamecraftModdingAPITweakableGameEngine";
|
|
||||||
|
|
||||||
public EntitiesDB entitiesDB { set; private get; }
|
|
||||||
|
|
||||||
public bool isRemovable => false;
|
|
||||||
|
|
||||||
public bool IsInGame = false;
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
IsInGame = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
|
||||||
IsInGame = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementations for Tweakable static class
|
|
||||||
|
|
||||||
public T GetStatAny<T>(EGID blockID, TweakableStat stat)
|
|
||||||
{
|
|
||||||
switch (stat)
|
|
||||||
{
|
|
||||||
case TweakableStat.TopSpeed:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return (T)(object)entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxVelocity;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Torque:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return (T)(object)entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxForce;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxExtension:
|
|
||||||
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return (T)(object)entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID).maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MinAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return (T)(object)entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).minDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return (T)(object)entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Reverse:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return (T)(object)entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).reverse;
|
|
||||||
}
|
|
||||||
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return (T)(object)entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).reverse;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.StartValue:
|
|
||||||
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
|
||||||
{
|
|
||||||
return (T)(object)entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID).startValue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return default(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T GetStatAny<T>(uint blockID, TweakableStat stat)
|
|
||||||
{
|
|
||||||
return GetStatAny<T>(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat);
|
|
||||||
}
|
|
||||||
|
|
||||||
public dynamic GetStatDynamic(EGID blockID, TweakableStat stat)
|
|
||||||
{
|
|
||||||
switch (stat)
|
|
||||||
{
|
|
||||||
case TweakableStat.TopSpeed:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxVelocity;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Torque:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxForce;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxExtension:
|
|
||||||
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID).maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MinAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).minDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Reverse:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).reverse;
|
|
||||||
}
|
|
||||||
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
return entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).reverse;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.StartValue:
|
|
||||||
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
|
||||||
{
|
|
||||||
return entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID).startValue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public dynamic GetStatDynamic(uint blockID, TweakableStat stat)
|
|
||||||
{
|
|
||||||
return GetStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T SetStatAny<T>(EGID blockID, TweakableStat stat, T value)
|
|
||||||
{
|
|
||||||
switch (stat)
|
|
||||||
{
|
|
||||||
case TweakableStat.TopSpeed:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxVelocity = (float)(object)value;
|
|
||||||
return (T)(object)refStruct.maxVelocity;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Torque:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxForce = (float)(object)value;
|
|
||||||
return (T)(object)refStruct.maxForce;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxExtension:
|
|
||||||
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxDeviation = (float)(object)value;
|
|
||||||
return (T)(object)refStruct.maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MinAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.minDeviation = (float)(object)value;
|
|
||||||
return (T)(object)refStruct.minDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxDeviation = (float)(object)value;
|
|
||||||
return (T)(object)refStruct.maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Reverse:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.reverse = (bool)(object)value;
|
|
||||||
return (T)(object)refStruct.reverse;
|
|
||||||
}
|
|
||||||
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.reverse = (bool)(object)value;
|
|
||||||
return (T)(object)refStruct.reverse;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.StartValue:
|
|
||||||
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
|
|
||||||
refStruct.startValue = (float)(object)value;
|
|
||||||
return (T)(object)refStruct.startValue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return default(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T SetStatAny<T>(uint blockID, TweakableStat stat, T value)
|
|
||||||
{
|
|
||||||
return SetStatAny<T>(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public dynamic SetStatDynamic(EGID blockID, TweakableStat stat, dynamic value)
|
|
||||||
{
|
|
||||||
switch (stat)
|
|
||||||
{
|
|
||||||
case TweakableStat.TopSpeed:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxVelocity = value;
|
|
||||||
return refStruct.maxVelocity;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Torque:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxForce = value;
|
|
||||||
return refStruct.maxForce;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxExtension:
|
|
||||||
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxDeviation = value;
|
|
||||||
return refStruct.maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MinAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.minDeviation = value;
|
|
||||||
return refStruct.minDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxDeviation = value;
|
|
||||||
return refStruct.maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Reverse:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.reverse = value;
|
|
||||||
return refStruct.reverse;
|
|
||||||
}
|
|
||||||
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.reverse = value;
|
|
||||||
return refStruct.reverse;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.StartValue:
|
|
||||||
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
|
|
||||||
refStruct.startValue = value;
|
|
||||||
return refStruct.startValue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public dynamic SetStatDynamic(uint blockID, TweakableStat stat, dynamic value)
|
|
||||||
{
|
|
||||||
return SetStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T AddStatAny<T>(EGID blockID, TweakableStat stat, T value)
|
|
||||||
{
|
|
||||||
switch (stat)
|
|
||||||
{
|
|
||||||
case TweakableStat.TopSpeed:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxVelocity += (float)(object)value;
|
|
||||||
return (T)(object)refStruct.maxVelocity;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Torque:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxForce += (float)(object)value;
|
|
||||||
return (T)(object)refStruct.maxForce;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxExtension:
|
|
||||||
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxDeviation += (float)(object)value;
|
|
||||||
return (T)(object)refStruct.maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MinAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.minDeviation += (float)(object)value;
|
|
||||||
return (T)(object)refStruct.minDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxDeviation += (float)(object)value;
|
|
||||||
return (T)(object)refStruct.maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Reverse:
|
|
||||||
// '+' is associated with logical OR in some fields, so it technically isn't invalid to "add" booleans
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.reverse = refStruct.reverse || (bool)(object)value;
|
|
||||||
return (T)(object)refStruct.reverse;
|
|
||||||
}
|
|
||||||
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.reverse = refStruct.reverse || (bool)(object)value;
|
|
||||||
return (T)(object)refStruct.reverse;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.StartValue:
|
|
||||||
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
|
|
||||||
refStruct.startValue += (float)(object)value;
|
|
||||||
return (T)(object)refStruct.startValue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return default(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T AddStatAny<T>(uint blockID, TweakableStat stat, T value)
|
|
||||||
{
|
|
||||||
return AddStatAny<T>(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public dynamic AddStatDynamic(EGID blockID, TweakableStat stat, dynamic value)
|
|
||||||
{
|
|
||||||
switch (stat)
|
|
||||||
{
|
|
||||||
case TweakableStat.TopSpeed:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxVelocity += value;
|
|
||||||
return refStruct.maxVelocity;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Torque:
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxForce += value;
|
|
||||||
return refStruct.maxForce;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxExtension:
|
|
||||||
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxDeviation += value;
|
|
||||||
return refStruct.maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MinAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.minDeviation += value;
|
|
||||||
return refStruct.minDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.MaxAngle:
|
|
||||||
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.maxDeviation += value;
|
|
||||||
return refStruct.maxDeviation;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.Reverse:
|
|
||||||
// '+' is associated with logical OR in some fields, so it technically isn't invalid to "add" booleans
|
|
||||||
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
|
||||||
refStruct.reverse = refStruct.reverse || value;
|
|
||||||
return refStruct.reverse;
|
|
||||||
}
|
|
||||||
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
|
||||||
refStruct.reverse = refStruct.reverse || value;
|
|
||||||
return refStruct.reverse;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TweakableStat.StartValue:
|
|
||||||
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
|
||||||
{
|
|
||||||
ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
|
|
||||||
refStruct.startValue += value;
|
|
||||||
return refStruct.startValue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public dynamic AddStatDynamic(uint blockID, TweakableStat stat, dynamic value)
|
|
||||||
{
|
|
||||||
return AddStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
namespace GamecraftModdingAPI.Blocks
|
|
||||||
{
|
|
||||||
public enum TweakableStat
|
|
||||||
{
|
|
||||||
TopSpeed, // MotorReadOnlyStruct
|
|
||||||
Torque, // MotorReadOnlyStruct
|
|
||||||
MaxExtension, // PistonReadOnlyStruct
|
|
||||||
MinAngle, // ServoReadOnlyStruct
|
|
||||||
MaxAngle, // ServoReadOnlyStruct
|
|
||||||
Reverse, // MotorReadOnlyStruct or ServoReadOnlyStruct
|
|
||||||
StartValue, // SignalGeneratorEntityStruct
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -63,8 +63,6 @@ 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.Signals.Init();
|
|
||||||
Blocks.Tweakable.Init();
|
|
||||||
// init inventory
|
// init inventory
|
||||||
Inventory.Hotbar.Init();
|
Inventory.Hotbar.Init();
|
||||||
// init input
|
// init input
|
||||||
|
|
|
@ -146,35 +146,6 @@ namespace GamecraftModdingAPI.Tests
|
||||||
.Action((float x, float y, float z) => { Block.PlaceNew(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
|
|
||||||
CommandBuilder.Builder()
|
|
||||||
.Name("RandomizeSignalsInputs")
|
|
||||||
.Description("Do the thing")
|
|
||||||
.Action(() => {
|
|
||||||
if (!GameState.IsSimulationMode())
|
|
||||||
{
|
|
||||||
Logging.CommandLogError("You must be in simulation mode for this to work!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Tasks.Repeatable task = new Tasks.Repeatable(
|
|
||||||
() => {
|
|
||||||
uint count = 0;
|
|
||||||
EGID[] eBlocks = Blocks.Signals.GetElectricBlocks();
|
|
||||||
for (uint i = 0u; i < eBlocks.Length; i++)
|
|
||||||
{
|
|
||||||
uint[] ids = Blocks.Signals.GetSignalIDs(eBlocks[i]);
|
|
||||||
for (uint j = 0u; j < ids.Length; j++)
|
|
||||||
{
|
|
||||||
Blocks.Signals.SetSignalByID(ids[j], (float)random.NextDouble());
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Logging.MetaDebugLog($"Did the thing on {count} inputs");
|
|
||||||
},
|
|
||||||
() => { return GameState.IsSimulationMode(); });
|
|
||||||
Tasks.Scheduler.Schedule(task);
|
|
||||||
}).Build();
|
|
||||||
|
|
||||||
CommandBuilder.Builder("getBlock")
|
CommandBuilder.Builder("getBlock")
|
||||||
.Action(() => uREPL.Log.Output(new Player(Players.PlayerType.Local).GetBlockLookedAt()+"")).Build();
|
.Action(() => uREPL.Log.Output(new Player(Players.PlayerType.Local).GetBlockLookedAt()+"")).Build();
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ PROJECT_NAME = "GamecraftModdingAPI"
|
||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "v1.0.0"
|
PROJECT_NUMBER = "v1.1.0"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|
Loading…
Reference in a new issue