Add support for initializing blocks with properties
Newly created blocks use the initializer to set properties, allowing the user to set per-block properties
This commit is contained in:
parent
5bbb54c0c5
commit
3592c6f464
15 changed files with 301 additions and 338 deletions
|
@ -55,13 +55,7 @@ namespace GamecraftModdingAPI
|
|||
float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0,
|
||||
int uscale = 1, float3 scale = default, Player player = null)
|
||||
{
|
||||
if (PlacementEngine.IsInGame && GameState.IsBuildMode())
|
||||
{
|
||||
return new Block(PlacementEngine.PlaceBlock(block, color, darkness,
|
||||
position, uscale, scale, player, rotation));
|
||||
}
|
||||
|
||||
return null;
|
||||
return PlaceNew<Block>(block, position, rotation, color, darkness, uscale, scale, player);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -85,8 +79,10 @@ namespace GamecraftModdingAPI
|
|||
if (PlacementEngine.IsInGame && GameState.IsBuildMode())
|
||||
{
|
||||
var egid = PlacementEngine.PlaceBlock(block, color, darkness,
|
||||
position, uscale, scale, player, rotation);
|
||||
return New<T>(egid.entityID, egid.groupID);
|
||||
position, uscale, scale, player, rotation, out var initializer);
|
||||
var bl = New<T>(egid.entityID, egid.groupID);
|
||||
bl.InitData.Group = BlockEngine.InitGroup(initializer);
|
||||
return bl;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -205,6 +201,8 @@ namespace GamecraftModdingAPI
|
|||
|
||||
public EGID Id { get; }
|
||||
|
||||
internal BlockEngine.BlockInitData InitData;
|
||||
|
||||
/// <summary>
|
||||
/// The block's current position or zero if the block no longer exists.
|
||||
/// A block is 0.2 wide by default in terms of position.
|
||||
|
@ -236,12 +234,11 @@ namespace GamecraftModdingAPI
|
|||
/// </summary>
|
||||
public float3 Scale
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<ScalingEntityStruct>(Id).scale;
|
||||
get => BlockEngine.GetBlockInfo(this, (ScalingEntityStruct st) => st.scale);
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref ScalingEntityStruct st, float3 val) => st.scale = val, value);
|
||||
if (!Exists) return; //UpdateCollision needs the block to exist
|
||||
ref var scaling = ref BlockEngine.GetBlockInfo<ScalingEntityStruct>(Id);
|
||||
scaling.scale = value;
|
||||
ScalingEngine.UpdateCollision(Id);
|
||||
}
|
||||
}
|
||||
|
@ -252,11 +249,11 @@ namespace GamecraftModdingAPI
|
|||
/// </summary>
|
||||
public int UniformScale
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<UniformBlockScaleEntityStruct>(Id).scaleFactor;
|
||||
get => BlockEngine.GetBlockInfo(this, (UniformBlockScaleEntityStruct st) => st.scaleFactor);
|
||||
set
|
||||
{
|
||||
ref var scaleStruct = ref BlockEngine.GetBlockInfo<UniformBlockScaleEntityStruct>(Id);
|
||||
scaleStruct.scaleFactor = value;
|
||||
BlockEngine.SetBlockInfo(this, (ref UniformBlockScaleEntityStruct st, int val) => st.scaleFactor = val,
|
||||
value);
|
||||
Scale = new float3(value, value, value);
|
||||
}
|
||||
}
|
||||
|
@ -268,8 +265,7 @@ namespace GamecraftModdingAPI
|
|||
{
|
||||
get
|
||||
{
|
||||
var id = (BlockIDs) BlockEngine.GetBlockInfo<DBEntityStruct>(Id, out var exists).DBID;
|
||||
return exists ? id : BlockIDs.Invalid;
|
||||
return BlockEngine.GetBlockInfo(this, (DBEntityStruct st) => (BlockIDs) st.DBID, BlockIDs.Invalid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,17 +276,19 @@ namespace GamecraftModdingAPI
|
|||
{
|
||||
get
|
||||
{
|
||||
byte index = BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(Id, out var exists).indexInPalette;
|
||||
if (!exists) index = byte.MaxValue;
|
||||
byte index = BlockEngine.GetBlockInfo(this, (ColourParameterEntityStruct st) => st.indexInPalette,
|
||||
byte.MaxValue);
|
||||
return new BlockColor(index);
|
||||
}
|
||||
set
|
||||
{
|
||||
ref var color = ref BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(Id);
|
||||
color.indexInPalette = (byte)(value.Color + value.Darkness * 10);
|
||||
color.overridePaletteColour = false;
|
||||
color.needsUpdate = true;
|
||||
BlockEngine.SetBlockColorFromPalette(ref color);
|
||||
BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, BlockColor val) =>
|
||||
{
|
||||
color.indexInPalette = (byte) (val.Color + val.Darkness * 10);
|
||||
color.overridePaletteColour = false;
|
||||
color.needsUpdate = true;
|
||||
BlockEngine.SetBlockColorFromPalette(ref color);
|
||||
}, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,27 +297,31 @@ namespace GamecraftModdingAPI
|
|||
/// </summary>
|
||||
public float4 CustomColor
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(Id).overriddenColour;
|
||||
get => BlockEngine.GetBlockInfo(this, (ColourParameterEntityStruct st) => st.overriddenColour);
|
||||
set
|
||||
{
|
||||
ref var color = ref BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(Id);
|
||||
color.overriddenColour = value;
|
||||
color.overridePaletteColour = true;
|
||||
color.needsUpdate = true;
|
||||
BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, float4 val) =>
|
||||
{
|
||||
color.overriddenColour = val;
|
||||
color.overridePaletteColour = true;
|
||||
color.needsUpdate = true;
|
||||
}, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The short text displayed on the block if applicable, or null.
|
||||
/// The 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;
|
||||
get => BlockEngine.GetBlockInfo(this, (TextLabelEntityViewStruct st) => st.textLabelComponent?.text);
|
||||
set
|
||||
{
|
||||
ref var text = ref BlockEngine.GetBlockInfo<TextLabelEntityViewStruct>(Id);
|
||||
if (text.textLabelComponent != null) text.textLabelComponent.text = value;
|
||||
BlockEngine.SetBlockInfo(this, (ref TextLabelEntityViewStruct text, string val) =>
|
||||
{
|
||||
if (text.textLabelComponent != null) text.textLabelComponent.text = val;
|
||||
}, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,8 +348,8 @@ namespace GamecraftModdingAPI
|
|||
/// <returns>The SimBody of the cluster or null if the block doesn't exist.</returns>
|
||||
public SimBody GetSimBody()
|
||||
{
|
||||
uint id = BlockEngine.GetBlockInfo<GridConnectionsEntityStruct>(Id, out var exists).machineRigidBodyId;
|
||||
return exists ? new SimBody(id) : null;
|
||||
return BlockEngine.GetBlockInfo(this,
|
||||
(GridConnectionsEntityStruct st) => new SimBody(st.machineRigidBodyId));
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
@ -404,7 +406,9 @@ namespace GamecraftModdingAPI
|
|||
// So thanks to Microsoft, we've got this horrible implementation using reflection
|
||||
|
||||
//Lets improve that using delegates
|
||||
return New<T>(Id.entityID, Id.groupID);
|
||||
var block = New<T>(Id.entityID, Id.groupID);
|
||||
block.InitData = this.InitData;
|
||||
return block;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Gamecraft.Wires;
|
||||
|
@ -10,14 +11,13 @@ using Svelto.DataStructures;
|
|||
using Svelto.ECS;
|
||||
|
||||
using GamecraftModdingAPI.Engines;
|
||||
using GamecraftModdingAPI.Utility;
|
||||
|
||||
namespace GamecraftModdingAPI.Blocks
|
||||
{
|
||||
/// <summary>
|
||||
/// Engine for executing general block actions
|
||||
/// </summary>
|
||||
public class BlockEngine : IApiEngine
|
||||
public partial class BlockEngine : IApiEngine
|
||||
{
|
||||
public string Name { get; } = "GamecraftModdingAPIBlockGameEngine";
|
||||
|
||||
|
@ -61,66 +61,54 @@ namespace GamecraftModdingAPI.Blocks
|
|||
color.paletteColour = paletteEntry.Colour;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a struct of a block. Can be used to set properties.
|
||||
/// Returns a default value if not found.
|
||||
/// </summary>
|
||||
/// <param name="blockID">The block's ID</param>
|
||||
/// <typeparam name="T">The struct to query</typeparam>
|
||||
/// <returns>An editable reference to the struct</returns>
|
||||
public ref T GetBlockInfo<T>(EGID blockID) where T : struct, IEntityComponent
|
||||
{
|
||||
if (!Synced)
|
||||
{
|
||||
Sync();
|
||||
Synced = true;
|
||||
}
|
||||
if (entitiesDB.Exists<T>(blockID))
|
||||
return ref entitiesDB.QueryEntity<T>(blockID);
|
||||
T[] structHolder = new T[1]; //Create something that can be referenced
|
||||
return ref structHolder[0]; //Gets a default value automatically
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a struct of a block. Can be used to set properties.
|
||||
/// Returns a default value if not found.
|
||||
/// </summary>
|
||||
/// <param name="blockID">The block's ID</param>
|
||||
/// <param name="exists">Whether the specified struct exists for the block</param>
|
||||
/// <typeparam name="T">The struct to query</typeparam>
|
||||
/// <returns>An editable reference to the struct</returns>
|
||||
public ref T GetBlockInfo<T>(EGID blockID, out bool exists) where T : struct, IEntityComponent
|
||||
public U GetBlockInfo<T, U>(Block block, Func<T, U> getter,
|
||||
U def = default) where T : struct, IEntityComponent
|
||||
{
|
||||
if (!Synced)
|
||||
if (entitiesDB.Exists<T>(block.Id))
|
||||
return getter(entitiesDB.QueryEntity<T>(block.Id));
|
||||
if (block.InitData.Group == null) return def;
|
||||
var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group);
|
||||
if (initializer.Has<T>())
|
||||
return getter(initializer.Get<T>());
|
||||
return def;
|
||||
}
|
||||
|
||||
public delegate void Setter<T, U>(ref T component, U value) where T : struct, IEntityComponent;
|
||||
|
||||
public void SetBlockInfo<T, U>(Block block, Setter<T, U> setter, U value) where T : struct, IEntityComponent
|
||||
{
|
||||
if (entitiesDB.Exists<T>(block.Id))
|
||||
setter(ref entitiesDB.QueryEntity<T>(block.Id), value);
|
||||
if (block.InitData.Group != null)
|
||||
{
|
||||
Sync();
|
||||
Synced = true;
|
||||
var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group);
|
||||
ref T structRef = ref (new T[1])[0]; //A reference for a default value for struct
|
||||
setter(ref structRef, value);
|
||||
initializer.Init(structRef);
|
||||
}
|
||||
exists = entitiesDB.Exists<T>(blockID);
|
||||
if (exists)
|
||||
return ref entitiesDB.QueryEntity<T>(blockID);
|
||||
T[] structHolder = new T[1];
|
||||
return ref structHolder[0];
|
||||
}
|
||||
|
||||
public bool BlockExists(EGID id)
|
||||
public bool BlockExists(EGID blockID)
|
||||
{
|
||||
if (!Synced)
|
||||
{
|
||||
Sync();
|
||||
Synced = true;
|
||||
}
|
||||
return entitiesDB.Exists<DBEntityStruct>(id);
|
||||
return entitiesDB.Exists<DBEntityStruct>(blockID);
|
||||
}
|
||||
|
||||
public bool GetBlockInfoExists<T>(EGID blockID) where T : struct, IEntityComponent
|
||||
public bool GetBlockInfoExists<T>(Block block) where T : struct, IEntityComponent
|
||||
{
|
||||
if (!Synced)
|
||||
{
|
||||
Sync();
|
||||
Synced = true;
|
||||
}
|
||||
return entitiesDB.Exists<T>(blockID);
|
||||
if (entitiesDB.Exists<T>(block.Id))
|
||||
return true;
|
||||
if (block.InitData.Group == null)
|
||||
return false;
|
||||
var init = new EntityComponentInitializer(block.Id, block.InitData.Group);
|
||||
return init.Has<T>();
|
||||
}
|
||||
|
||||
public SimBody[] GetSimBodiesFromID(byte id)
|
||||
|
@ -183,17 +171,6 @@ namespace GamecraftModdingAPI.Blocks
|
|||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Synchronize newly created entity components with entities DB.
|
||||
/// This forces a partial game tick, so it may be slow.
|
||||
/// This also has the potential to make Gamecraft unstable.
|
||||
/// Use this sparingly.
|
||||
/// </summary>
|
||||
private static void Sync()
|
||||
{
|
||||
DeterministicStepCompositionRootPatch.SubmitEntitiesNow();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
public EntitiesDB GetEntitiesDB()
|
||||
{
|
||||
|
|
46
GamecraftModdingAPI/Blocks/BlockEngineInit.cs
Normal file
46
GamecraftModdingAPI/Blocks/BlockEngineInit.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
using Svelto.DataStructures;
|
||||
using Svelto.ECS;
|
||||
using Svelto.ECS.Internal;
|
||||
|
||||
namespace GamecraftModdingAPI.Blocks
|
||||
{
|
||||
public partial class BlockEngine
|
||||
{
|
||||
internal struct BlockInitData
|
||||
{
|
||||
public FasterDictionary<RefWrapper<Type>, ITypeSafeDictionary> Group;
|
||||
}
|
||||
|
||||
internal delegate FasterDictionary<RefWrapper<Type>, ITypeSafeDictionary> GetInitGroup(
|
||||
EntityComponentInitializer initializer);
|
||||
|
||||
internal GetInitGroup InitGroup = CreateAccessor<GetInitGroup>("_group");
|
||||
|
||||
//https://stackoverflow.com/questions/55878525/unit-testing-ref-structs-with-private-fields-via-reflection
|
||||
internal static TDelegate CreateAccessor<TDelegate>(string memberName) where TDelegate : Delegate
|
||||
{
|
||||
var invokeMethod = typeof(TDelegate).GetMethod("Invoke");
|
||||
if (invokeMethod == null)
|
||||
throw new InvalidOperationException($"{typeof(TDelegate)} signature could not be determined.");
|
||||
|
||||
var delegateParameters = invokeMethod.GetParameters();
|
||||
if (delegateParameters.Length != 1)
|
||||
throw new InvalidOperationException("Delegate must have a single parameter.");
|
||||
|
||||
var paramType = delegateParameters[0].ParameterType;
|
||||
|
||||
var objParam = Expression.Parameter(paramType, "obj");
|
||||
var memberExpr = Expression.PropertyOrField(objParam, memberName);
|
||||
Expression returnExpr = memberExpr;
|
||||
if (invokeMethod.ReturnType != memberExpr.Type)
|
||||
returnExpr = Expression.ConvertChecked(memberExpr, invokeMethod.ReturnType);
|
||||
|
||||
var lambda =
|
||||
Expression.Lambda<TDelegate>(returnExpr, $"Access{paramType.Name}_{memberName}", new[] {objParam});
|
||||
return lambda.Compile();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
using System;
|
||||
using GamecraftModdingAPI.Engines;
|
||||
using GamecraftModdingAPI.Utility;
|
||||
|
||||
using RobocraftX.Common;
|
||||
using Svelto.ECS;
|
||||
|
||||
using GamecraftModdingAPI.Engines;
|
||||
using GamecraftModdingAPI.Utility;
|
||||
|
||||
namespace GamecraftModdingAPI.Blocks
|
||||
{
|
||||
public class BlockEventsEngine : IReactionaryEngine<DBEntityStruct>
|
||||
|
@ -11,11 +13,18 @@ namespace GamecraftModdingAPI.Blocks
|
|||
public event EventHandler<BlockPlacedRemovedEventArgs> Placed;
|
||||
public event EventHandler<BlockPlacedRemovedEventArgs> Removed;
|
||||
|
||||
public BlockEventsEngine()
|
||||
{
|
||||
//Console.WriteLine("Creating BlockEventsEngine\n" + Environment.StackTrace);
|
||||
}
|
||||
|
||||
public void Ready()
|
||||
{
|
||||
//Console.WriteLine("BlockEventsEngine registered");
|
||||
}
|
||||
|
||||
public EntitiesDB entitiesDB { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
@ -23,17 +32,52 @@ namespace GamecraftModdingAPI.Blocks
|
|||
public string Name { get; } = "GamecraftModdingAPIBlockEventsEngine";
|
||||
public bool isRemovable { get; } = false;
|
||||
|
||||
private bool shouldAddRemove;
|
||||
public void Add(ref DBEntityStruct entityComponent, EGID egid)
|
||||
{
|
||||
ExceptionUtil.InvokeEvent(Placed, this, new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID});
|
||||
if (!(shouldAddRemove = !shouldAddRemove))
|
||||
return;
|
||||
ExceptionUtil.InvokeEvent(Placed, this,
|
||||
new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID});
|
||||
}
|
||||
|
||||
public void Remove(ref DBEntityStruct entityComponent, EGID egid)
|
||||
{
|
||||
ExceptionUtil.InvokeEvent(Removed, this, new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID});
|
||||
if (!(shouldAddRemove = !shouldAddRemove))
|
||||
return;
|
||||
ExceptionUtil.InvokeEvent(Removed, this,
|
||||
new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID});
|
||||
}
|
||||
}
|
||||
|
||||
/*[HarmonyPatch]
|
||||
public static class TestPatch
|
||||
{
|
||||
public static void Postfix(FasterDictionary<RefWrapper<Type>, FasterList<IEngine>> engines,
|
||||
ExclusiveGroupStruct? previousGroup, in PlatformProfiler profiler, EGID egid)
|
||||
{
|
||||
if (!engines.TryGetValue(new RefWrapper<Type>(TypeSafeDictionary<TValue>._type), out result))
|
||||
return;
|
||||
}
|
||||
public static MethodBase TargetMethod()
|
||||
{
|
||||
return AccessTools.Method("Svelto.ECS.Internal.TypeSafeDictionary:AddEntityComponentToEngines");
|
||||
}
|
||||
}*/
|
||||
|
||||
/*[HarmonyPatch]
|
||||
public static class TestPatch
|
||||
{
|
||||
public static void Postfix(EGID basePartEGID)
|
||||
{
|
||||
Console.WriteLine("Patched Add method: " + basePartEGID);
|
||||
}
|
||||
public static MethodBase TargetMethod()
|
||||
{
|
||||
return AccessTools.Method("RobocraftX.CR.MachineEditing.BuildBlockAdditionalPartEngine:Add");
|
||||
}
|
||||
}*/
|
||||
|
||||
public struct BlockPlacedRemovedEventArgs
|
||||
{
|
||||
public EGID ID;
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace GamecraftModdingAPI.Blocks
|
|||
public enum BlockIDs : ushort
|
||||
{
|
||||
/// <summary>
|
||||
/// A custom value for the API. Doesn't exist for Gamecraft.
|
||||
/// Called "nothing" in Gamecraft. (DBID.NOTHING)
|
||||
/// </summary>
|
||||
Invalid = ushort.MaxValue,
|
||||
AluminiumCube = 0,
|
||||
|
|
|
@ -14,18 +14,10 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
public ConsoleBlock(EGID id): base(id)
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<ConsoleBlockEntityStruct>(this.Id))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
}
|
||||
|
||||
public ConsoleBlock(uint id): base(new EGID(id, CommonExclusiveGroups.BUILD_CONSOLE_BLOCK_GROUP))
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<ConsoleBlockEntityStruct>(this.Id))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
}
|
||||
|
||||
// custom console block properties
|
||||
|
@ -34,43 +26,47 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<ConsoleBlockEntityStruct>(Id).commandName;
|
||||
return BlockEngine.GetBlockInfo(this, (ConsoleBlockEntityStruct st) => st.commandName);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
BlockEngine.GetBlockInfo<ConsoleBlockEntityStruct>(Id).commandName.Set(value);
|
||||
BlockEngine.SetBlockInfo(this, (ref ConsoleBlockEntityStruct st, string val) => st.commandName.Set(val),
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
public string Arg1
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<ConsoleBlockEntityStruct>(Id).arg1;
|
||||
get => BlockEngine.GetBlockInfo(this, (ConsoleBlockEntityStruct st) => st.arg1);
|
||||
|
||||
set
|
||||
{
|
||||
BlockEngine.GetBlockInfo<ConsoleBlockEntityStruct>(Id).arg1.Set(value);
|
||||
BlockEngine.SetBlockInfo(this, (ref ConsoleBlockEntityStruct st, string val) => st.arg1.Set(val),
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
public string Arg2
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<ConsoleBlockEntityStruct>(Id).arg2;
|
||||
get => BlockEngine.GetBlockInfo(this, (ConsoleBlockEntityStruct st) => st.arg2);
|
||||
|
||||
set
|
||||
{
|
||||
BlockEngine.GetBlockInfo<ConsoleBlockEntityStruct>(Id).arg2.Set(value);
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref ConsoleBlockEntityStruct st, string val) => st.arg2.Set(val),
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
public string Arg3
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<ConsoleBlockEntityStruct>(Id).arg3;
|
||||
get => BlockEngine.GetBlockInfo(this, (ConsoleBlockEntityStruct st) => st.arg3);
|
||||
|
||||
set
|
||||
{
|
||||
BlockEngine.GetBlockInfo<ConsoleBlockEntityStruct>(Id).arg3.Set(value);
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref ConsoleBlockEntityStruct st, string val) => st.arg3.Set(val),
|
||||
value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,18 +13,10 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
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(new EGID(id, CommonExclusiveGroups.BUILD_MOTOR_BLOCK_GROUP))
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<MotorReadOnlyStruct>(this.Id))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
}
|
||||
|
||||
// custom motor properties
|
||||
|
@ -36,13 +28,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id).maxVelocity;
|
||||
return BlockEngine.GetBlockInfo(this, (MotorReadOnlyStruct st) => st.maxVelocity);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id);
|
||||
motor.maxVelocity = value;
|
||||
BlockEngine.SetBlockInfo(this, (ref MotorReadOnlyStruct st, float val) => st.maxVelocity = val, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,13 +44,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id).maxForce;
|
||||
return BlockEngine.GetBlockInfo(this, (MotorReadOnlyStruct st) => st.maxForce);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id);
|
||||
motor.maxForce = value;
|
||||
BlockEngine.SetBlockInfo(this, (ref MotorReadOnlyStruct st, float val) => st.maxForce = val, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,13 +60,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id).reverse;
|
||||
return BlockEngine.GetBlockInfo(this, (MotorReadOnlyStruct st) => st.reverse);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
ref MotorReadOnlyStruct motor = ref BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(Id);
|
||||
motor.reverse = value;
|
||||
BlockEngine.SetBlockInfo(this, (ref MotorReadOnlyStruct st, bool val) => st.reverse = val, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,27 +8,22 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
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(new EGID(id, CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP))
|
||||
{
|
||||
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');
|
||||
get => (char) BlockEngine.GetBlockInfo(this, (ObjectIdEntityStruct st) => st.objectId + 'A');
|
||||
set
|
||||
{
|
||||
BlockEngine.GetBlockInfo<ObjectIdEntityStruct>(Id).objectId = (byte) (value - 'A');
|
||||
Label = value + ""; //The label isn't updated automatically
|
||||
BlockEngine.SetBlockInfo(this, (ref ObjectIdEntityStruct st, char val) =>
|
||||
{
|
||||
st.objectId = (byte) (val - 'A');
|
||||
Label = val + ""; //The label isn't updated automatically
|
||||
}, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +32,7 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public byte SimID
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<ObjectIdEntityStruct>(Id).simObjectId;
|
||||
get => BlockEngine.GetBlockInfo(this, (ObjectIdEntityStruct st) => st.simObjectId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -13,18 +13,10 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
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(new EGID(id, CommonExclusiveGroups.BUILD_PISTON_BLOCK_GROUP))
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<PistonReadOnlyStruct>(this.Id))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
}
|
||||
|
||||
// custom piston properties
|
||||
|
@ -33,13 +25,13 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// The piston's max extension distance.
|
||||
/// </summary>
|
||||
public float MaximumExtension
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(Id).maxDeviation;
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo(this, (PistonReadOnlyStruct st) => st.maxDeviation);
|
||||
|
||||
set
|
||||
{
|
||||
ref PistonReadOnlyStruct piston = ref BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(Id);
|
||||
piston.maxDeviation = value;
|
||||
BlockEngine.SetBlockInfo(this, (ref PistonReadOnlyStruct st, float val) => st.maxDeviation = val,
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,13 +39,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// The piston's max extension force.
|
||||
/// </summary>
|
||||
public float MaximumForce
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(Id).maxForce;
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo(this, (PistonReadOnlyStruct st) => st.maxForce);
|
||||
|
||||
set
|
||||
{
|
||||
ref PistonReadOnlyStruct piston = ref BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(Id);
|
||||
piston.maxForce = value;
|
||||
BlockEngine.SetBlockInfo(this, (ref PistonReadOnlyStruct st, float val) => st.maxForce = val, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,15 +40,16 @@ namespace GamecraftModdingAPI.Blocks
|
|||
private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine
|
||||
|
||||
public EGID PlaceBlock(BlockIDs block, BlockColors color, byte darkness, float3 position, int uscale,
|
||||
float3 scale, Player player, float3 rotation)
|
||||
float3 scale, Player player, float3 rotation, out EntityComponentInitializer initializer)
|
||||
{ //It appears that only the non-uniform scale has any visible effect, but if that's not given here it will be set to the uniform one
|
||||
if (darkness > 9)
|
||||
throw new Exception("That is too dark. Make sure to use 0-9 as darkness. (0 is default.)");
|
||||
return BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation,
|
||||
initializer = BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation,
|
||||
(player ?? new Player(PlayerType.Local)).Id);
|
||||
return initializer.EGID;
|
||||
}
|
||||
|
||||
private EGID BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot, uint playerId)
|
||||
private EntityComponentInitializer BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot, uint playerId)
|
||||
{
|
||||
if (_blockEntityFactory == null)
|
||||
throw new Exception("The factory is null.");
|
||||
|
@ -107,7 +108,7 @@ namespace GamecraftModdingAPI.Blocks
|
|||
pickedBlock.placedBlockEntityID = structInitializer.EGID;
|
||||
pickedBlock.placedBlockWasAPickedBlock = false;
|
||||
Block.BlockEngine.Synced = false; // Block entities will need to be submitted before properties can be used
|
||||
return structInitializer.EGID;
|
||||
return structInitializer;
|
||||
}
|
||||
|
||||
public string Name { get; } = "GamecraftModdingAPIPlacementGameEngine";
|
||||
|
|
|
@ -13,18 +13,10 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
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(new EGID(id, CommonExclusiveGroups.BUILD_SERVO_BLOCK_GROUP))
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<ServoReadOnlyStruct>(this.Id))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
}
|
||||
|
||||
// custom servo properties
|
||||
|
@ -33,13 +25,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// The servo's minimum angle.
|
||||
/// </summary>
|
||||
public float MinimumAngle
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id).minDeviation;
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.minDeviation);
|
||||
|
||||
set
|
||||
{
|
||||
ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id);
|
||||
servo.minDeviation = value;
|
||||
BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, float val) => st.minDeviation = val, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,13 +39,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public float MaximumAngle
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id).maxDeviation;
|
||||
get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.maxDeviation);
|
||||
|
||||
set
|
||||
{
|
||||
ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id);
|
||||
servo.maxDeviation = value;
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, float val) => st.maxDeviation = val, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -62,13 +52,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public float MaximumForce
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id).maxForce;
|
||||
get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.maxForce);
|
||||
|
||||
set
|
||||
{
|
||||
ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id);
|
||||
servo.maxForce = value;
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, float val) => st.maxForce = val, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -76,13 +65,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public bool Reverse
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id).reverse;
|
||||
get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.reverse);
|
||||
|
||||
set
|
||||
{
|
||||
ref ServoReadOnlyStruct servo = ref BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(Id);
|
||||
servo.reverse = value;
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, bool val) => st.reverse = val, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
public SignalingBlock(EGID id) : base(id)
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<BlockPortsStruct>(this.Id))
|
||||
if (!BlockEngine.GetBlockInfoExists<BlockPortsStruct>(this))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
|
@ -24,17 +24,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
|
||||
public SignalingBlock(uint id) : base(id)
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<BlockPortsStruct>(this.Id))
|
||||
if (!BlockEngine.GetBlockInfoExists<BlockPortsStruct>(this))
|
||||
{
|
||||
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>
|
||||
|
@ -53,16 +48,6 @@ namespace GamecraftModdingAPI.Blocks
|
|||
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>
|
||||
|
@ -89,16 +74,16 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// The input port count.
|
||||
/// </summary>
|
||||
public uint InputCount
|
||||
{
|
||||
get => GetBlockPortsStruct().inputCount;
|
||||
}
|
||||
{
|
||||
get => BlockEngine.GetBlockInfo(this, (BlockPortsStruct st) => st.inputCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The output port count.
|
||||
/// </summary>
|
||||
public uint OutputCount
|
||||
{
|
||||
get => GetBlockPortsStruct().outputCount;
|
||||
get => BlockEngine.GetBlockInfo(this, (BlockPortsStruct st) => st.outputCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,18 +15,10 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
public SpawnPoint(EGID id) : base(id)
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<SpawnPointStatsEntityStruct>(this.Id))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
}
|
||||
|
||||
public SpawnPoint(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_SPAWNPOINT_BLOCK_GROUP))
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<SpawnPointStatsEntityStruct>(this.Id))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
}
|
||||
|
||||
// custom spawn point properties
|
||||
|
@ -36,16 +28,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public uint Lives
|
||||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(Id).lives;
|
||||
}
|
||||
get => BlockEngine.GetBlockInfo(this, (SpawnPointStatsEntityStruct st) => st.lives);
|
||||
|
||||
set
|
||||
{
|
||||
ref SpawnPointStatsEntityStruct spses = ref BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(Id);
|
||||
spses.lives = value;
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref SpawnPointStatsEntityStruct st, uint val) => st.lives = val, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -53,16 +41,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public bool Damageable
|
||||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(Id).canTakeDamage;
|
||||
}
|
||||
get => BlockEngine.GetBlockInfo(this, (SpawnPointStatsEntityStruct st) => st.canTakeDamage);
|
||||
|
||||
set
|
||||
{
|
||||
ref SpawnPointStatsEntityStruct spses = ref BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(Id);
|
||||
spses.canTakeDamage = value;
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref SpawnPointStatsEntityStruct st, bool val) => st.canTakeDamage = val, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -70,16 +54,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public bool GameOverEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(Id).gameOverScreen;
|
||||
}
|
||||
get => BlockEngine.GetBlockInfo(this, (SpawnPointStatsEntityStruct st) => st.gameOverScreen);
|
||||
|
||||
set
|
||||
{
|
||||
ref SpawnPointStatsEntityStruct spses = ref BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(Id);
|
||||
spses.gameOverScreen = value;
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref SpawnPointStatsEntityStruct st, bool val) => st.gameOverScreen = val, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -87,16 +67,12 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public byte Team
|
||||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<SpawnPointIdsEntityStruct>(Id).teamId;
|
||||
}
|
||||
get => BlockEngine.GetBlockInfo(this, (SpawnPointIdsEntityStruct st) => st.teamId);
|
||||
|
||||
set
|
||||
{
|
||||
ref SpawnPointIdsEntityStruct spses = ref BlockEngine.GetBlockInfo<SpawnPointIdsEntityStruct>(Id);
|
||||
spses.teamId = value;
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref SpawnPointIdsEntityStruct st, byte val) => st.teamId = val, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,18 +14,10 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
public TextBlock(EGID id) : base(id)
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<TextBlockDataStruct>(this.Id))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
}
|
||||
|
||||
public TextBlock(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_TEXT_BLOCK_GROUP))
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<TextBlockDataStruct>(this.Id))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
}
|
||||
|
||||
// custom text block properties
|
||||
|
@ -35,35 +27,34 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public string Text
|
||||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<TextBlockDataStruct>(Id).textCurrent;
|
||||
}
|
||||
get => BlockEngine.GetBlockInfo(this, (TextBlockDataStruct st) => st.textCurrent);
|
||||
|
||||
set
|
||||
{
|
||||
ref TextBlockDataStruct tbds = ref BlockEngine.GetBlockInfo<TextBlockDataStruct>(Id);
|
||||
tbds.textCurrent.Set(value);
|
||||
tbds.textStored.Set(value);
|
||||
BlockEngine.GetBlockInfo<TextBlockNetworkDataStruct>(Id).newTextBlockStringContent.Set(value);
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) =>
|
||||
{
|
||||
tbds.textCurrent.Set(val);
|
||||
tbds.textStored.Set(val);
|
||||
}, value);
|
||||
BlockEngine.SetBlockInfo(this,
|
||||
(ref TextBlockNetworkDataStruct st, string val) => st.newTextBlockStringContent.Set(val), value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The text block's current text block ID (used in ChangeTextBlockCommand).
|
||||
/// The text block's current text block ID (used in ChangeTextBlockCommand).
|
||||
/// </summary>
|
||||
public string TextBlockId
|
||||
public string TextBlockId
|
||||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<TextBlockDataStruct>(Id).textBlockID;
|
||||
}
|
||||
get => BlockEngine.GetBlockInfo(this, (TextBlockDataStruct st) => st.textBlockID);
|
||||
|
||||
set
|
||||
{
|
||||
BlockEngine.GetBlockInfo<TextBlockDataStruct>(Id).textBlockID.Set(value);
|
||||
BlockEngine.GetBlockInfo<TextBlockNetworkDataStruct>(Id).newTextBlockID.Set(value);
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) =>
|
||||
tbds.textBlockID.Set(val), value);
|
||||
BlockEngine.SetBlockInfo(this,
|
||||
(ref TextBlockNetworkDataStruct st, string val) => st.newTextBlockID.Set(val), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,18 +15,10 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
public Timer(EGID id) : base(id)
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<TimerBlockDataStruct>(this.Id))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
}
|
||||
|
||||
public Timer(uint id) : base(new EGID(id, CommonExclusiveGroups.BUILD_TIMER_BLOCK_GROUP))
|
||||
{
|
||||
if (!BlockEngine.GetBlockInfoExists<TimerBlockDataStruct>(this.Id))
|
||||
{
|
||||
throw new BlockTypeException($"Block is not a {this.GetType().Name} block");
|
||||
}
|
||||
}
|
||||
|
||||
// custom timer properties
|
||||
|
@ -36,16 +28,13 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public float Start
|
||||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<TimerBlockDataStruct>(Id).startTime;
|
||||
}
|
||||
get => BlockEngine.GetBlockInfo(this, (TimerBlockDataStruct st) => st.startTime);
|
||||
|
||||
set
|
||||
{
|
||||
ref TimerBlockDataStruct tbds = ref BlockEngine.GetBlockInfo<TimerBlockDataStruct>(Id);
|
||||
tbds.startTime = value;
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref TimerBlockDataStruct tbds, float val) => tbds.startTime = val,
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -53,16 +42,13 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public float End
|
||||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<TimerBlockDataStruct>(Id).endTime;
|
||||
}
|
||||
get => BlockEngine.GetBlockInfo(this, (TimerBlockDataStruct st) => st.endTime);
|
||||
|
||||
set
|
||||
{
|
||||
ref TimerBlockDataStruct tbds = ref BlockEngine.GetBlockInfo<TimerBlockDataStruct>(Id);
|
||||
tbds.endTime = value;
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref TimerBlockDataStruct tbds, float val) => tbds.endTime = val,
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -70,16 +56,13 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public bool DisplayMilliseconds
|
||||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<TimerBlockDataStruct>(Id).outputFormatHasMS;
|
||||
}
|
||||
get => BlockEngine.GetBlockInfo(this, (TimerBlockDataStruct st) => st.outputFormatHasMS);
|
||||
|
||||
set
|
||||
{
|
||||
ref TimerBlockDataStruct tbds = ref BlockEngine.GetBlockInfo<TimerBlockDataStruct>(Id);
|
||||
tbds.outputFormatHasMS = value;
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref TimerBlockDataStruct tbds, bool val) => tbds.outputFormatHasMS = val,
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -87,16 +70,13 @@ namespace GamecraftModdingAPI.Blocks
|
|||
/// </summary>
|
||||
public int CurrentTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return BlockEngine.GetBlockInfo<TimerBlockLabelCacheEntityStruct>(Id).timeLastRenderFrameMS;
|
||||
}
|
||||
get => BlockEngine.GetBlockInfo(this, (TimerBlockLabelCacheEntityStruct st) => st.timeLastRenderFrameMS);
|
||||
|
||||
set
|
||||
{
|
||||
ref TimerBlockLabelCacheEntityStruct tblces = ref BlockEngine.GetBlockInfo<TimerBlockLabelCacheEntityStruct>(Id);
|
||||
tblces.timeLastRenderFrameMS = value;
|
||||
}
|
||||
set
|
||||
{
|
||||
BlockEngine.SetBlockInfo(this, (ref TimerBlockLabelCacheEntityStruct tbds, int val) => tbds.timeLastRenderFrameMS = val,
|
||||
value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue