Merge branch 'feature-ecs_object_base'
This commit is contained in:
commit
aa12b848d0
27 changed files with 526 additions and 516 deletions
|
@ -27,7 +27,7 @@ def buildReferencesXml(path):
|
||||||
return "<!--Start Dependencies-->\n <ItemGroup>\n" + "".join(result) + " </ItemGroup>\n<!--End Dependencies-->"
|
return "<!--Start Dependencies-->\n <ItemGroup>\n" + "".join(result) + " </ItemGroup>\n<!--End Dependencies-->"
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="Generate GamecraftModdingAPI.csproj")
|
parser = argparse.ArgumentParser(description="Generate TechbloxModdingAPI.csproj")
|
||||||
# TODO (maybe?): add params for custom csproj read and write locations
|
# TODO (maybe?): add params for custom csproj read and write locations
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
@ -35,8 +35,8 @@ if __name__ == "__main__":
|
||||||
asmXml = buildReferencesXml("../ref/TechbloxPreview_Data/Managed")
|
asmXml = buildReferencesXml("../ref/TechbloxPreview_Data/Managed")
|
||||||
# print(asmXml)
|
# print(asmXml)
|
||||||
|
|
||||||
with open("../GamecraftModdingAPI/GamecraftModdingAPI.csproj", "r") as xmlFile:
|
with open("../TechbloxModdingAPI/TechbloxModdingAPI.csproj", "r") as xmlFile:
|
||||||
print("Parsing GamecraftModdingAPI.csproj")
|
print("Parsing TechbloxModdingAPI.csproj")
|
||||||
fileStr = xmlFile.read()
|
fileStr = xmlFile.read()
|
||||||
# print(fileStr)
|
# print(fileStr)
|
||||||
depsStart = re.search(r"\<!--\s*Start\s+Dependencies\s*--\>", fileStr)
|
depsStart = re.search(r"\<!--\s*Start\s+Dependencies\s*--\>", fileStr)
|
||||||
|
@ -45,7 +45,7 @@ if __name__ == "__main__":
|
||||||
print("Unable to find dependency XML comments, aborting!")
|
print("Unable to find dependency XML comments, aborting!")
|
||||||
exit(1)
|
exit(1)
|
||||||
newFileStr = fileStr[:depsStart.start()] + "\n" + asmXml + "\n" + fileStr[depsEnd.end() + 1:]
|
newFileStr = fileStr[:depsStart.start()] + "\n" + asmXml + "\n" + fileStr[depsEnd.end() + 1:]
|
||||||
with open("../GamecraftModdingAPI/GamecraftModdingAPI.csproj", "w") as xmlFile:
|
with open("../TechbloxModdingAPI/TechbloxModdingAPI.csproj", "w") as xmlFile:
|
||||||
print("Writing Assembly references")
|
print("Writing Assembly references")
|
||||||
xmlFile.write(newFileStr)
|
xmlFile.write(newFileStr)
|
||||||
# print(newFileStr)
|
# print(newFileStr)
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace TechbloxModdingAPI
|
||||||
/// A single (perhaps scaled) block. Properties may return default values if the block is removed and then setting them is ignored.
|
/// A single (perhaps scaled) block. Properties may return default values if the block is removed and then setting them is ignored.
|
||||||
/// For specific block type operations, use the specialised block classes in the TechbloxModdingAPI.Blocks namespace.
|
/// For specific block type operations, use the specialised block classes in the TechbloxModdingAPI.Blocks namespace.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Block : IEquatable<Block>, IEquatable<EGID>
|
public class Block : EcsObjectBase, IEquatable<Block>, IEquatable<EGID>
|
||||||
{
|
{
|
||||||
protected static readonly PlacementEngine PlacementEngine = new PlacementEngine();
|
protected static readonly PlacementEngine PlacementEngine = new PlacementEngine();
|
||||||
protected static readonly MovementEngine MovementEngine = new MovementEngine();
|
protected static readonly MovementEngine MovementEngine = new MovementEngine();
|
||||||
|
@ -78,8 +78,7 @@ namespace TechbloxModdingAPI
|
||||||
var initializer = PlacementEngine.PlaceBlock(block, position, player, autoWire);
|
var initializer = PlacementEngine.PlaceBlock(block, position, player, autoWire);
|
||||||
var egid = initializer.EGID;
|
var egid = initializer.EGID;
|
||||||
var bl = New<T>(egid.entityID, egid.groupID);
|
var bl = New<T>(egid.entityID, egid.groupID);
|
||||||
bl.InitData.Group = BlockEngine.InitGroup(initializer);
|
bl.InitData = initializer;
|
||||||
bl.InitData.Reference = initializer.reference;
|
|
||||||
Placed += bl.OnPlacedInit;
|
Placed += bl.OnPlacedInit;
|
||||||
return bl;
|
return bl;
|
||||||
}
|
}
|
||||||
|
@ -241,13 +240,12 @@ namespace TechbloxModdingAPI
|
||||||
throw new BlockException("Blocks can only be placed in build mode.");
|
throw new BlockException("Blocks can only be placed in build mode.");
|
||||||
var initializer = PlacementEngine.PlaceBlock(type, position, player, autoWire);
|
var initializer = PlacementEngine.PlaceBlock(type, position, player, autoWire);
|
||||||
Id = initializer.EGID;
|
Id = initializer.EGID;
|
||||||
InitData.Group = BlockEngine.InitGroup(initializer);
|
InitData = initializer;
|
||||||
Placed += OnPlacedInit;
|
Placed += OnPlacedInit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EGID Id { get; }
|
public override EGID Id { get; }
|
||||||
|
|
||||||
internal BlockEngine.BlockInitData InitData;
|
|
||||||
private EGID copiedFrom;
|
private EGID copiedFrom;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -256,10 +254,10 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float3 Position
|
public float3 Position
|
||||||
{
|
{
|
||||||
get => MovementEngine.GetPosition(Id, InitData);
|
get => MovementEngine.GetPosition(this);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
MovementEngine.MoveBlock(Id, InitData, value);
|
MovementEngine.MoveBlock(this, value);
|
||||||
if (blockGroup != null)
|
if (blockGroup != null)
|
||||||
blockGroup.PosAndRotCalculated = false;
|
blockGroup.PosAndRotCalculated = false;
|
||||||
BlockEngine.UpdateDisplayedBlock(Id);
|
BlockEngine.UpdateDisplayedBlock(Id);
|
||||||
|
@ -271,10 +269,10 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float3 Rotation
|
public float3 Rotation
|
||||||
{
|
{
|
||||||
get => RotationEngine.GetRotation(Id, InitData);
|
get => RotationEngine.GetRotation(this);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
RotationEngine.RotateBlock(Id, InitData, value);
|
RotationEngine.RotateBlock(this, value);
|
||||||
if (blockGroup != null)
|
if (blockGroup != null)
|
||||||
blockGroup.PosAndRotCalculated = false;
|
blockGroup.PosAndRotCalculated = false;
|
||||||
BlockEngine.UpdateDisplayedBlock(Id);
|
BlockEngine.UpdateDisplayedBlock(Id);
|
||||||
|
@ -287,14 +285,14 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float3 Scale
|
public float3 Scale
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (ScalingEntityStruct st) => st.scale);
|
get => BlockEngine.GetBlockInfo<ScalingEntityStruct>(this).scale;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
int uscale = UniformScale;
|
int uscale = UniformScale;
|
||||||
if (value.x < 4e-5) value.x = uscale;
|
if (value.x < 4e-5) value.x = uscale;
|
||||||
if (value.y < 4e-5) value.y = uscale;
|
if (value.y < 4e-5) value.y = uscale;
|
||||||
if (value.z < 4e-5) value.z = uscale;
|
if (value.z < 4e-5) value.z = uscale;
|
||||||
BlockEngine.SetBlockInfo(this, (ref ScalingEntityStruct st, float3 val) => st.scale = val, value);
|
BlockEngine.GetBlockInfo<ScalingEntityStruct>(this).scale = value;
|
||||||
if (!Exists) return; //UpdateCollision needs the block to exist
|
if (!Exists) return; //UpdateCollision needs the block to exist
|
||||||
ScalingEngine.UpdateCollision(Id);
|
ScalingEngine.UpdateCollision(Id);
|
||||||
BlockEngine.UpdateDisplayedBlock(Id);
|
BlockEngine.UpdateDisplayedBlock(Id);
|
||||||
|
@ -307,12 +305,11 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int UniformScale
|
public int UniformScale
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (UniformBlockScaleEntityStruct st) => st.scaleFactor);
|
get => BlockEngine.GetBlockInfo<UniformBlockScaleEntityStruct>(this).scaleFactor;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value < 1) value = 1;
|
if (value < 1) value = 1;
|
||||||
BlockEngine.SetBlockInfo(this, (ref UniformBlockScaleEntityStruct st, int val) => st.scaleFactor = val,
|
BlockEngine.GetBlockInfo<UniformBlockScaleEntityStruct>(this).scaleFactor = value;
|
||||||
value);
|
|
||||||
Scale = new float3(value, value, value);
|
Scale = new float3(value, value, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,16 +319,12 @@ namespace TechbloxModdingAPI
|
||||||
*/
|
*/
|
||||||
public bool Flipped
|
public bool Flipped
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (ScalingEntityStruct st) => st.scale.x < 0);
|
get => BlockEngine.GetBlockInfo<ScalingEntityStruct>(this).scale.x < 0;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ScalingEntityStruct st, bool val) =>
|
var st = BlockEngine.GetBlockInfo<ScalingEntityStruct>(this);
|
||||||
st.scale.x = math.abs(st.scale.x) * (val ? -1 : 1), value);
|
st.scale.x = math.abs(st.scale.x) * (value ? -1 : 1);
|
||||||
BlockEngine.SetBlockInfo(this, (ref GFXPrefabEntityStructGPUI st, bool val) =>
|
BlockEngine.UpdatePrefab(this, (ushort) Type, (byte) Material, value);
|
||||||
{
|
|
||||||
uint prefabId = PrefabsID.GetOrCreatePrefabID((ushort) Type, (byte) Material, 0, value);
|
|
||||||
st.prefabID = prefabId;
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +335,8 @@ namespace TechbloxModdingAPI
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (DBEntityStruct st) => (BlockIDs) st.DBID, BlockIDs.Invalid);
|
var opt = BlockEngine.GetBlockInfoOptional<DBEntityStruct>(this);
|
||||||
|
return opt ? (BlockIDs) opt.Get().DBID : BlockIDs.Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,18 +347,16 @@ namespace TechbloxModdingAPI
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
byte index = BlockEngine.GetBlockInfo(this, (ColourParameterEntityStruct st) => st.indexInPalette,
|
var opt = BlockEngine.GetBlockInfoOptional<ColourParameterEntityStruct>(this);
|
||||||
byte.MaxValue);
|
return new BlockColor(opt ? opt.Get().indexInPalette : byte.MaxValue);
|
||||||
return new BlockColor(index);
|
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, BlockColor val) =>
|
//TODO: Check if setting to 255 works
|
||||||
{ //TODO: Check if setting to 255 works
|
var color = BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(this);
|
||||||
color.indexInPalette = val.Index;
|
color.indexInPalette = value.Index;
|
||||||
color.hasNetworkChange = true;
|
color.hasNetworkChange = true;
|
||||||
color.paletteColour = BlockEngine.ConvertBlockColor(color.indexInPalette);
|
color.paletteColour = BlockEngine.ConvertBlockColor(color.indexInPalette);
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,14 +365,12 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float4 CustomColor
|
public float4 CustomColor
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (ColourParameterEntityStruct st) => st.paletteColour);
|
get => BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(this).paletteColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, float4 val) =>
|
ref var color = ref BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(this);
|
||||||
{
|
color.paletteColour = value;
|
||||||
color.paletteColour = val;
|
color.hasNetworkChange = true;
|
||||||
color.hasNetworkChange = true;
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,9 +379,16 @@ namespace TechbloxModdingAPI
|
||||||
*/
|
*/
|
||||||
public BlockMaterial Material
|
public BlockMaterial Material
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (CubeMaterialStruct cmst) => (BlockMaterial) cmst.materialId, BlockMaterial.Default);
|
get
|
||||||
set => BlockEngine.SetBlockInfo(this,
|
{
|
||||||
(ref CubeMaterialStruct cmst, BlockMaterial val) => cmst.materialId = (byte) val, value);
|
var opt = BlockEngine.GetBlockInfoOptional<CubeMaterialStruct>(this);
|
||||||
|
return opt ? (BlockMaterial) opt.Get().materialId : BlockMaterial.Default;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
BlockEngine.GetBlockInfo<CubeMaterialStruct>(this).materialId = (byte) value;
|
||||||
|
BlockEngine.UpdatePrefab(this, (ushort) Type, (byte) value, Flipped); //TODO: Test default
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -400,13 +397,11 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Label
|
public string Label
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfoViewStruct(this, (TextLabelEntityViewStruct st) => st.textLabelComponent?.text);
|
get => BlockEngine.GetBlockInfoViewComponent<TextLabelEntityViewStruct>(this).textLabelComponent?.text;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfoViewStruct(this, (ref TextLabelEntityViewStruct text, string val) =>
|
var comp = BlockEngine.GetBlockInfoViewComponent<TextLabelEntityViewStruct>(this).textLabelComponent;
|
||||||
{
|
if (comp != null) comp.text = value;
|
||||||
if (text.textLabelComponent != null) text.textLabelComponent.text = val;
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,9 +419,8 @@ namespace TechbloxModdingAPI
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (blockGroup != null) return blockGroup;
|
if (blockGroup != null) return blockGroup;
|
||||||
return blockGroup = BlockEngine.GetBlockInfo(this,
|
var bgec = BlockEngine.GetBlockInfo<BlockGroupEntityComponent>(this);
|
||||||
(BlockGroupEntityComponent bgec) =>
|
return blockGroup = bgec.currentBlockGroup == -1 ? null : new BlockGroup(bgec.currentBlockGroup, this);
|
||||||
bgec.currentBlockGroup == -1 ? null : new BlockGroup(bgec.currentBlockGroup, this));
|
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
@ -437,9 +431,7 @@ namespace TechbloxModdingAPI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
blockGroup?.RemoveInternal(this);
|
blockGroup?.RemoveInternal(this);
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<BlockGroupEntityComponent>(this).currentBlockGroup = (int?) value?.Id.entityID ?? -1;
|
||||||
(ref BlockGroupEntityComponent bgec, BlockGroup val) => bgec.currentBlockGroup = val?.Id ?? -1,
|
|
||||||
value);
|
|
||||||
value?.AddInternal(this);
|
value?.AddInternal(this);
|
||||||
blockGroup = value;
|
blockGroup = value;
|
||||||
}
|
}
|
||||||
|
@ -469,10 +461,10 @@ namespace TechbloxModdingAPI
|
||||||
/// <returns>The SimBody of the chunk or null if the block doesn't exist or not in simulation mode.</returns>
|
/// <returns>The SimBody of the chunk or null if the block doesn't exist or not in simulation mode.</returns>
|
||||||
public SimBody GetSimBody()
|
public SimBody GetSimBody()
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this,
|
var st = BlockEngine.GetBlockInfo<GridConnectionsEntityStruct>(this);
|
||||||
(GridConnectionsEntityStruct st) => st.machineRigidBodyId != uint.MaxValue
|
return st.machineRigidBodyId != uint.MaxValue
|
||||||
? new SimBody(st.machineRigidBodyId, st.clusterId)
|
? new SimBody(st.machineRigidBodyId, st.clusterId)
|
||||||
: null);
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -558,7 +550,7 @@ namespace TechbloxModdingAPI
|
||||||
|
|
||||||
//Lets improve that using delegates
|
//Lets improve that using delegates
|
||||||
var block = New<T>(Id.entityID, Id.groupID);
|
var block = New<T>(Id.entityID, Id.groupID);
|
||||||
if (this.InitData.Group != null)
|
if (this.InitData.Valid)
|
||||||
{
|
{
|
||||||
block.InitData = this.InitData;
|
block.InitData = this.InitData;
|
||||||
Placed += block.OnPlacedInit; //Reset InitData of new object
|
Placed += block.OnPlacedInit; //Reset InitData of new object
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Gamecraft.Blocks.BlockGroups;
|
using Gamecraft.Blocks.BlockGroups;
|
||||||
|
using Svelto.ECS;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using TechbloxModdingAPI.Blocks;
|
using TechbloxModdingAPI.Blocks;
|
||||||
|
@ -13,10 +14,10 @@ namespace TechbloxModdingAPI
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A group of blocks that can be selected together. The placed version of blueprints. Dispose after usage.
|
/// A group of blocks that can be selected together. The placed version of blueprints. Dispose after usage.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BlockGroup : ICollection<Block>, IDisposable
|
public class BlockGroup : EcsObjectBase, ICollection<Block>, IDisposable
|
||||||
{
|
{
|
||||||
internal static BlueprintEngine _engine = new BlueprintEngine();
|
internal static BlueprintEngine _engine = new BlueprintEngine();
|
||||||
public int Id { get; }
|
public override EGID Id { get; }
|
||||||
private readonly Block sourceBlock;
|
private readonly Block sourceBlock;
|
||||||
private readonly List<Block> blocks;
|
private readonly List<Block> blocks;
|
||||||
private float3 position, rotation;
|
private float3 position, rotation;
|
||||||
|
@ -26,7 +27,7 @@ namespace TechbloxModdingAPI
|
||||||
{
|
{
|
||||||
if (id == BlockGroupUtility.GROUP_UNASSIGNED)
|
if (id == BlockGroupUtility.GROUP_UNASSIGNED)
|
||||||
throw new BlockException("Cannot create a block group for blocks without a group!");
|
throw new BlockException("Cannot create a block group for blocks without a group!");
|
||||||
Id = id;
|
Id = new EGID((uint) id, BlockGroupExclusiveGroups.BlockGroupEntityGroup);
|
||||||
sourceBlock = block;
|
sourceBlock = block;
|
||||||
blocks = new List<Block>(GetBlocks());
|
blocks = new List<Block>(GetBlocks());
|
||||||
Block.Removed += OnBlockRemoved;
|
Block.Removed += OnBlockRemoved;
|
||||||
|
@ -168,7 +169,7 @@ namespace TechbloxModdingAPI
|
||||||
internal void AddInternal(Block item)
|
internal void AddInternal(Block item)
|
||||||
{
|
{
|
||||||
blocks.Add(item);
|
blocks.Add(item);
|
||||||
_engine.AddBlockToGroup(item.Id, Id);
|
_engine.AddBlockToGroup(item.Id, (int) Id.entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -9,6 +9,7 @@ using RobocraftX.Blocks;
|
||||||
using RobocraftX.Common;
|
using RobocraftX.Common;
|
||||||
using RobocraftX.Physics;
|
using RobocraftX.Physics;
|
||||||
using RobocraftX.Rendering;
|
using RobocraftX.Rendering;
|
||||||
|
using RobocraftX.Rendering.GPUI;
|
||||||
using Svelto.ECS.EntityStructs;
|
using Svelto.ECS.EntityStructs;
|
||||||
|
|
||||||
using Svelto.DataStructures;
|
using Svelto.DataStructures;
|
||||||
|
@ -16,6 +17,7 @@ using Svelto.ECS;
|
||||||
using Svelto.ECS.Hybrid;
|
using Svelto.ECS.Hybrid;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using TechbloxModdingAPI.Engines;
|
using TechbloxModdingAPI.Engines;
|
||||||
|
using TechbloxModdingAPI.Utility;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Blocks
|
namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
|
@ -68,76 +70,24 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
: entitiesDB.QueryEntity<PaletteEntryEntityStruct>(index,
|
: entitiesDB.QueryEntity<PaletteEntryEntityStruct>(index,
|
||||||
CommonExclusiveGroups.COLOUR_PALETTE_GROUP).Colour;
|
CommonExclusiveGroups.COLOUR_PALETTE_GROUP).Colour;
|
||||||
|
|
||||||
public ref T GetBlockInfo<T>(EGID blockID) where T : unmanaged, IEntityComponent
|
public OptionalRef<T> GetBlockInfoOptional<T>(Block block) where T : unmanaged, IEntityComponent
|
||||||
{
|
{
|
||||||
if (entitiesDB.Exists<T>(blockID))
|
return entitiesDB.QueryEntityOptional<T>(block);
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
public ref T GetBlockInfoViewStruct<T>(EGID blockID) where T : struct, INeedEGID, IEntityViewComponent
|
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public U GetBlockInfo<T, U>(Block block, Func<T, U> getter,
|
public ref T GetBlockInfo<T>(Block block) where T : unmanaged, IEntityComponent
|
||||||
U def = default) where T : unmanaged, IEntityComponent
|
|
||||||
{
|
{
|
||||||
if (entitiesDB.Exists<T>(block.Id))
|
return ref entitiesDB.QueryEntityOrDefault<T>(block);
|
||||||
return getter(entitiesDB.QueryEntity<T>(block.Id));
|
|
||||||
return GetBlockInitInfo(block, getter, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
public U GetBlockInfoViewStruct<T, U>(Block block, Func<T, U> getter,
|
|
||||||
U def = default) where T : struct, IEntityViewComponent
|
|
||||||
{
|
|
||||||
if (entitiesDB.Exists<T>(block.Id))
|
|
||||||
return getter(entitiesDB.QueryEntity<T>(block.Id));
|
|
||||||
return GetBlockInitInfo(block, getter, def);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private U GetBlockInitInfo<T, U>(Block block, Func<T, U> getter, U def) where T : struct, IEntityComponent
|
internal ref T GetBlockInfo<T>(EcsObjectBase obj) where T : unmanaged, IEntityComponent
|
||||||
{
|
{
|
||||||
if (block.InitData.Group == null) return def;
|
return ref entitiesDB.QueryEntityOrDefault<T>(obj);
|
||||||
var initializer = new EntityInitializer(block.Id, block.InitData.Group, block.InitData.Reference);
|
|
||||||
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 ref T GetBlockInfoViewComponent<T>(Block block) where T : struct, IEntityViewComponent
|
||||||
|
|
||||||
public void SetBlockInfoViewStruct<T, U>(Block block, Setter<T, U> setter, U value) where T : struct, IEntityViewComponent
|
|
||||||
{
|
{
|
||||||
if (entitiesDB.Exists<T>(block.Id))
|
return ref entitiesDB.QueryEntityOrDefault<T>(block);
|
||||||
setter(ref entitiesDB.QueryEntity<T>(block.Id), value);
|
|
||||||
else
|
|
||||||
SetBlockInitInfo(block, setter, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetBlockInfo<T, U>(Block block, Setter<T, U> setter, U value) where T : unmanaged, IEntityComponent
|
|
||||||
{
|
|
||||||
if (entitiesDB.Exists<T>(block.Id))
|
|
||||||
setter(ref entitiesDB.QueryEntity<T>(block.Id), value);
|
|
||||||
else
|
|
||||||
SetBlockInitInfo(block, setter, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetBlockInitInfo<T, U>(Block block, Setter<T, U> setter, U value)
|
|
||||||
where T : struct, IEntityComponent
|
|
||||||
{
|
|
||||||
if (block.InitData.Group != null)
|
|
||||||
{
|
|
||||||
var initializer = new EntityInitializer(block.Id, block.InitData.Group, block.InitData.Reference);
|
|
||||||
T component = initializer.Has<T>() ? initializer.Get<T>() : default;
|
|
||||||
ref T structRef = ref component;
|
|
||||||
setter(ref structRef, value);
|
|
||||||
initializer.Init(structRef);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateDisplayedBlock(EGID id)
|
public void UpdateDisplayedBlock(EGID id)
|
||||||
|
@ -149,21 +99,18 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
entitiesDB.QueryEntity<RenderingDataStruct>(id).matrix = float4x4.TRS(pos.position, rot.rotation, scale.scale);
|
entitiesDB.QueryEntity<RenderingDataStruct>(id).matrix = float4x4.TRS(pos.position, rot.rotation, scale.scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void UpdatePrefab(Block block, ushort type, byte material, bool flipped)
|
||||||
|
{
|
||||||
|
uint pid = PrefabsID.GetOrCreatePrefabID(type, material, 0, flipped);
|
||||||
|
entitiesDB.QueryEntityOrDefault<GFXPrefabEntityStructGPUI>(block).prefabID = pid;
|
||||||
|
entitiesDB.QueryEntityOrDefault<PhysicsPrefabEntityStruct>(block) = new PhysicsPrefabEntityStruct(pid);
|
||||||
|
}
|
||||||
|
|
||||||
public bool BlockExists(EGID blockID)
|
public bool BlockExists(EGID blockID)
|
||||||
{
|
{
|
||||||
return entitiesDB.Exists<DBEntityStruct>(blockID);
|
return entitiesDB.Exists<DBEntityStruct>(blockID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GetBlockInfoExists<T>(Block block) where T : struct, IEntityComponent
|
|
||||||
{
|
|
||||||
if (entitiesDB.Exists<T>(block.Id))
|
|
||||||
return true;
|
|
||||||
if (block.InitData.Group == null)
|
|
||||||
return false;
|
|
||||||
var init = new EntityInitializer(block.Id, block.InitData.Group, block.InitData.Reference);
|
|
||||||
return init.Has<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SimBody[] GetSimBodiesFromID(byte id)
|
public SimBody[] GetSimBodiesFromID(byte id)
|
||||||
{
|
{
|
||||||
var ret = new FasterList<SimBody>(4);
|
var ret = new FasterList<SimBody>(4);
|
||||||
|
|
|
@ -19,10 +19,9 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MaxForce
|
public float MaxForce
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (DampedSpringReadOnlyStruct dsrs) => dsrs.springFrequency);
|
get => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).springFrequency;
|
||||||
|
|
||||||
set => BlockEngine.SetBlockInfo(this,
|
set => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).springFrequency = value;
|
||||||
(ref DampedSpringReadOnlyStruct dsrs, float val) => dsrs.springFrequency = val, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -39,10 +38,9 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float Damping
|
public float Damping
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (DampedSpringReadOnlyStruct ljf) => ljf.springDamping);
|
get => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).springDamping;
|
||||||
|
|
||||||
set => BlockEngine.SetBlockInfo(this,
|
set => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).springDamping = value;
|
||||||
(ref DampedSpringReadOnlyStruct ljf, float val) => ljf.springDamping = val, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -50,10 +48,9 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MaxExtension
|
public float MaxExtension
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (DampedSpringReadOnlyStruct ljf) => ljf.maxExtent);
|
get => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).maxExtent;
|
||||||
|
|
||||||
set => BlockEngine.SetBlockInfo(this,
|
set => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).maxExtent = value;
|
||||||
(ref DampedSpringReadOnlyStruct ljf, float val) => ljf.maxExtent = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,12 +28,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (MotorReadOnlyStruct st) => st.maxVelocity);
|
return BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(this).maxVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref MotorReadOnlyStruct st, float val) => st.maxVelocity = val, value);
|
BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(this).maxVelocity = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,12 +44,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (MotorReadOnlyStruct st) => st.maxForce);
|
return BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(this).maxForce;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref MotorReadOnlyStruct st, float val) => st.maxForce = val, value);
|
BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(this).maxForce = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,12 +60,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (MotorReadOnlyStruct st) => st.reverse);
|
return BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(this).reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref MotorReadOnlyStruct st, bool val) => st.reverse = val, value);
|
BlockEngine.GetBlockInfo<MotorReadOnlyStruct>(this).reverse = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,21 +34,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
// implementations for Movement static class
|
// implementations for Movement static class
|
||||||
|
|
||||||
internal float3 MoveBlock(EGID blockID, BlockEngine.BlockInitData data, float3 vector)
|
internal float3 MoveBlock(Block block, float3 vector)
|
||||||
{
|
{
|
||||||
if (!entitiesDB.Exists<PositionEntityStruct>(blockID))
|
ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntityOrDefault<PositionEntityStruct>(block);
|
||||||
{
|
ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntityOrDefault<GridRotationStruct>(block);
|
||||||
if (data.Group == null) return float3.zero;
|
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntityOrDefault<LocalTransformEntityStruct>(block);
|
||||||
var init = new EntityInitializer(blockID, data.Group, data.Reference);
|
ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntityOrDefault<UECSPhysicsEntityStruct>(block);
|
||||||
init.GetOrCreate<PositionEntityStruct>().position = vector;
|
|
||||||
init.GetOrCreate<GridRotationStruct>().position = vector;
|
|
||||||
init.GetOrCreate<LocalTransformEntityStruct>().position = vector;
|
|
||||||
return vector;
|
|
||||||
}
|
|
||||||
ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID);
|
|
||||||
ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity<GridRotationStruct>(blockID);
|
|
||||||
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity<LocalTransformEntityStruct>(blockID);
|
|
||||||
ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(blockID);
|
|
||||||
// main (persistent) position
|
// main (persistent) position
|
||||||
posStruct.position = vector;
|
posStruct.position = vector;
|
||||||
// placement grid position
|
// placement grid position
|
||||||
|
@ -56,24 +47,21 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
// rendered position
|
// rendered position
|
||||||
transStruct.position = vector;
|
transStruct.position = vector;
|
||||||
// collision position
|
// collision position
|
||||||
FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation
|
if (phyStruct.ID != EGID.Empty)
|
||||||
{
|
{ //It exists
|
||||||
Value = posStruct.position
|
FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation
|
||||||
});
|
{
|
||||||
entitiesDB.QueryEntity<GridConnectionsEntityStruct>(blockID).isProcessed = false;
|
Value = posStruct.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
entitiesDB.QueryEntityOrDefault<GridConnectionsEntityStruct>(block).isProcessed = false;
|
||||||
return posStruct.position;
|
return posStruct.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal float3 GetPosition(EGID blockID, BlockEngine.BlockInitData data)
|
internal float3 GetPosition(Block block)
|
||||||
{
|
{
|
||||||
if (!entitiesDB.Exists<PositionEntityStruct>(blockID))
|
return entitiesDB.QueryEntityOrDefault<PositionEntityStruct>(block).position;
|
||||||
{
|
|
||||||
if (data.Group == null) return float3.zero;
|
|
||||||
var init = new EntityInitializer(blockID, data.Group, data.Reference);
|
|
||||||
return init.Has<PositionEntityStruct>() ? init.Get<PositionEntityStruct>().position : float3.zero;
|
|
||||||
}
|
|
||||||
ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID);
|
|
||||||
return posStruct.position;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,13 +28,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (MusicBlockDataEntityStruct st) => st.trackIndx);
|
return BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).trackIndx;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).trackIndx = value;
|
||||||
(ref MusicBlockDataEntityStruct msdes, byte val) => msdes.trackIndx = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,24 +41,22 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this,
|
var msdes = BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this);
|
||||||
(MusicBlockDataEntityStruct msdes) => msdes.fmod2DEventPaths.Get<Guid>(msdes.trackIndx));
|
return msdes.fmod2DEventPaths.Get<Guid>(msdes.trackIndx);
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref MusicBlockDataEntityStruct msdes, Guid val) =>
|
ref var msdes = ref BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this);
|
||||||
|
for (byte i = 0; i < msdes.fmod2DEventPaths.Count<Guid>(); i++)
|
||||||
{
|
{
|
||||||
for (byte i = 0; i < msdes.fmod2DEventPaths.Count<Guid>(); i++)
|
Guid track = msdes.fmod2DEventPaths.Get<Guid>(i);
|
||||||
|
if (track == value)
|
||||||
{
|
{
|
||||||
Guid track = msdes.fmod2DEventPaths.Get<Guid>(i);
|
msdes.trackIndx = i;
|
||||||
if (track == val)
|
break;
|
||||||
{
|
|
||||||
msdes.trackIndx = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, value);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,15 +64,13 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (MusicBlockDataEntityStruct msdes) =>
|
var msdes = BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this);
|
||||||
|
Guid[] tracks = new Guid[msdes.fmod2DEventPaths.Count<Guid>()];
|
||||||
|
for (byte i = 0; i < tracks.Length; i++)
|
||||||
{
|
{
|
||||||
Guid[] tracks = new Guid[msdes.fmod2DEventPaths.Count<Guid>()];
|
tracks[i] = msdes.fmod2DEventPaths.Get<Guid>(i);
|
||||||
for (byte i = 0; i < tracks.Length; i++)
|
}
|
||||||
{
|
return tracks;
|
||||||
tracks[i] = msdes.fmod2DEventPaths.Get<Guid>(i);
|
|
||||||
}
|
|
||||||
return tracks;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,13 +78,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (MusicBlockDataEntityStruct msdes) => msdes.tweakableVolume);
|
return BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).tweakableVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).tweakableVolume = value;
|
||||||
(ref MusicBlockDataEntityStruct msdes, float val) => msdes.tweakableVolume = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,14 +92,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
//Assert.Log("Block exists: " + Exists);
|
//Assert.Log("Block exists: " + Exists);
|
||||||
return BlockEngine.GetBlockInfo(this,
|
return (ChannelType) BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).channelType;
|
||||||
(MusicBlockDataEntityStruct msdes) => (ChannelType) msdes.channelType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).channelType = (byte) value;
|
||||||
(ref MusicBlockDataEntityStruct msdes, ChannelType val) => msdes.channelType = (byte) val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,33 +105,31 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this,
|
return BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).isPlaying;
|
||||||
(MusicBlockDataEntityStruct msdes) => msdes.isPlaying);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref MusicBlockDataEntityStruct msdes, bool val) =>
|
ref var msdes = ref BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this);
|
||||||
|
if (msdes.isPlaying == value) return;
|
||||||
|
if (value)
|
||||||
{
|
{
|
||||||
if (msdes.isPlaying == val) return;
|
// start playing
|
||||||
if (val)
|
EventInstance inst = RuntimeManager.CreateInstance(msdes.fmod2DEventPaths.Get<Guid>(msdes.trackIndx));
|
||||||
{
|
inst.setVolume(msdes.tweakableVolume / 100f);
|
||||||
// start playing
|
inst.start();
|
||||||
EventInstance inst = RuntimeManager.CreateInstance(msdes.fmod2DEventPaths.Get<Guid>(msdes.trackIndx));
|
msdes.eventHandle = inst.handle;
|
||||||
inst.setVolume(msdes.tweakableVolume / 100f);
|
}
|
||||||
inst.start();
|
else
|
||||||
msdes.eventHandle = inst.handle;
|
{
|
||||||
}
|
// stop playing
|
||||||
else
|
EventInstance inst = default(EventInstance);
|
||||||
{
|
inst.handle = msdes.eventHandle;
|
||||||
// stop playing
|
inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
|
||||||
EventInstance inst = default(EventInstance);
|
inst.release();
|
||||||
inst.handle = msdes.eventHandle;
|
}
|
||||||
inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
|
|
||||||
inst.release();
|
msdes.isPlaying = value;
|
||||||
}
|
|
||||||
msdes.isPlaying = val;
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,14 +16,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
public char Identifier
|
public char Identifier
|
||||||
{
|
{
|
||||||
get => (char) BlockEngine.GetBlockInfo(this, (ObjectIdEntityStruct st) => st.objectId + 'A');
|
get => (char) (BlockEngine.GetBlockInfo<ObjectIdEntityStruct>(this).objectId + 'A');
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ObjectIdEntityStruct st, char val) =>
|
BlockEngine.GetBlockInfo<ObjectIdEntityStruct>(this).objectId = (byte) (value - 'A');
|
||||||
{
|
Label = value + ""; //The label isn't updated automatically
|
||||||
st.objectId = (byte) (val - 'A');
|
|
||||||
Label = val + ""; //The label isn't updated automatically
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +29,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte SimID
|
public byte SimID
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (ObjectIdEntityStruct st) => st.simObjectId);
|
get => BlockEngine.GetBlockInfo<ObjectIdEntityStruct>(this).simObjectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -26,12 +26,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MaximumExtension
|
public float MaximumExtension
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (PistonReadOnlyStruct st) => st.maxDeviation);
|
get => BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(this).maxDeviation;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref PistonReadOnlyStruct st, float val) => st.maxDeviation = val,
|
BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(this).maxDeviation = value;
|
||||||
value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,11 +39,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MaximumForce
|
public float MaximumForce
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (PistonReadOnlyStruct st) => st.pistonVelocity);
|
get => BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(this).pistonVelocity;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref PistonReadOnlyStruct st, float val) => st.pistonVelocity = val, value);
|
BlockEngine.GetBlockInfo<PistonReadOnlyStruct>(this).pistonVelocity = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,55 +34,38 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
// implementations for Rotation static class
|
// implementations for Rotation static class
|
||||||
|
|
||||||
internal float3 RotateBlock(EGID blockID, BlockEngine.BlockInitData data, Vector3 vector)
|
internal float3 RotateBlock(Block block, Vector3 vector)
|
||||||
{
|
{
|
||||||
if (!entitiesDB.Exists<RotationEntityStruct>(blockID))
|
ref RotationEntityStruct rotStruct = ref this.entitiesDB.QueryEntityOrDefault<RotationEntityStruct>(block);
|
||||||
{
|
ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntityOrDefault<GridRotationStruct>(block);
|
||||||
if (data.Group == null) return float3.zero;
|
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntityOrDefault<LocalTransformEntityStruct>(block);
|
||||||
var init = new EntityInitializer(blockID, data.Group, data.Reference);
|
ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntityOrDefault<UECSPhysicsEntityStruct>(block);
|
||||||
init.GetOrCreate<RotationEntityStruct>().rotation = Quaternion.Euler(vector);
|
// main (persistent) rotation
|
||||||
init.GetOrCreate<GridRotationStruct>().rotation = Quaternion.Euler(vector);
|
|
||||||
init.GetOrCreate<LocalTransformEntityStruct>().rotation = Quaternion.Euler(vector);
|
|
||||||
return vector;
|
|
||||||
}
|
|
||||||
ref RotationEntityStruct rotStruct = ref this.entitiesDB.QueryEntity<RotationEntityStruct>(blockID);
|
|
||||||
ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity<GridRotationStruct>(blockID);
|
|
||||||
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity<LocalTransformEntityStruct>(blockID);
|
|
||||||
ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(blockID);
|
|
||||||
// main (persistent) position
|
|
||||||
Quaternion newRotation = rotStruct.rotation;
|
Quaternion newRotation = rotStruct.rotation;
|
||||||
newRotation.eulerAngles = vector;
|
newRotation.eulerAngles = vector;
|
||||||
rotStruct.rotation = newRotation;
|
rotStruct.rotation = newRotation;
|
||||||
// placement grid rotation
|
// placement grid rotation
|
||||||
Quaternion newGridRotation = gridStruct.rotation;
|
gridStruct.rotation = newRotation;
|
||||||
newGridRotation.eulerAngles = vector;
|
// rendered rotation
|
||||||
gridStruct.rotation = newGridRotation;
|
transStruct.rotation = newRotation;
|
||||||
// rendered position
|
// collision rotation
|
||||||
Quaternion newTransRotation = rotStruct.rotation;
|
if (phyStruct.ID != EGID.Empty)
|
||||||
newTransRotation.eulerAngles = vector;
|
{ //It exists
|
||||||
transStruct.rotation = newTransRotation;
|
FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity,
|
||||||
// collision position
|
new Unity.Transforms.Rotation
|
||||||
FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Unity.Transforms.Rotation
|
{
|
||||||
{
|
Value = rotStruct.rotation
|
||||||
Value = rotStruct.rotation
|
});
|
||||||
});
|
}
|
||||||
entitiesDB.QueryEntity<GridConnectionsEntityStruct>(blockID).isProcessed = false;
|
|
||||||
|
entitiesDB.QueryEntityOrDefault<GridConnectionsEntityStruct>(block).isProcessed = false;
|
||||||
return ((Quaternion)rotStruct.rotation).eulerAngles;
|
return ((Quaternion)rotStruct.rotation).eulerAngles;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal float3 GetRotation(EGID blockID, BlockEngine.BlockInitData data)
|
internal float3 GetRotation(Block block)
|
||||||
{
|
{
|
||||||
if (!entitiesDB.Exists<RotationEntityStruct>(blockID))
|
ref RotationEntityStruct rotStruct = ref entitiesDB.QueryEntityOrDefault<RotationEntityStruct>(block);
|
||||||
{
|
|
||||||
if (data.Group == null) return float3.zero;
|
|
||||||
var init = new EntityInitializer(blockID, data.Group, data.Reference);
|
|
||||||
return init.Has<RotationEntityStruct>()
|
|
||||||
? (float3) ((Quaternion) init.Get<RotationEntityStruct>().rotation).eulerAngles
|
|
||||||
: float3.zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
ref RotationEntityStruct rotStruct = ref entitiesDB.QueryEntity<RotationEntityStruct>(blockID);
|
|
||||||
return ((Quaternion) rotStruct.rotation).eulerAngles;
|
return ((Quaternion) rotStruct.rotation).eulerAngles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MinimumAngle
|
public float MinimumAngle
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.minDeviation);
|
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(this).minDeviation;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, float val) => st.minDeviation = val, value);
|
BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(this).minDeviation = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +39,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MaximumAngle
|
public float MaximumAngle
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.maxDeviation);
|
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(this).maxDeviation;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, float val) => st.maxDeviation = val, value);
|
BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(this).maxDeviation = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,11 +52,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MaximumForce
|
public float MaximumForce
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.servoVelocity);
|
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(this).servoVelocity;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, float val) => st.servoVelocity = val, value);
|
BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(this).servoVelocity = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,11 +65,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Reverse
|
public bool Reverse
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.reverse);
|
get => BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(this).reverse;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, bool val) => st.reverse = val, value);
|
BlockEngine.GetBlockInfo<ServoReadOnlyStruct>(this).reverse = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => obj.tweakableVolume);
|
return BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).tweakableVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).tweakableVolume = value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, float val) => obj.tweakableVolume = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,13 +35,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => obj.tweakablePitch);
|
return BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).tweakablePitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).tweakablePitch = value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, float val) => obj.tweakablePitch = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,13 +48,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => obj.is3D);
|
return BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).is3D;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).is3D = value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, bool val) => obj.is3D = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,13 +61,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => (ChannelType)obj.channelType);
|
return (ChannelType) BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).channelType;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).channelType = (byte) value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, ChannelType val) => obj.tweakableVolume = (byte) val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,13 +74,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => obj.soundEffectIndex);
|
return BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).soundEffectIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).soundEffectIndex = value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, byte val) => obj.soundEffectIndex = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,35 +88,36 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this,
|
var obj = BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this);
|
||||||
(SoundSfxBlockDataEntityStruct obj) => obj.is3D ? obj.fmod3DEventPaths.Get<Guid>(obj.soundEffectIndex) : obj.fmod2DEventPaths.Get<Guid>(obj.soundEffectIndex));
|
return obj.is3D
|
||||||
|
? obj.fmod3DEventPaths.Get<Guid>(obj.soundEffectIndex)
|
||||||
|
: obj.fmod2DEventPaths.Get<Guid>(obj.soundEffectIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref SoundSfxBlockDataEntityStruct obj, Guid val) =>
|
var obj = BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this);
|
||||||
|
for (byte i = 0; i < obj.fmod2DEventPaths.Count<Guid>(); i++)
|
||||||
{
|
{
|
||||||
for (byte i = 0; i < obj.fmod2DEventPaths.Count<Guid>(); i++)
|
Guid track = obj.fmod2DEventPaths.Get<Guid>(i);
|
||||||
|
if (track == value)
|
||||||
{
|
{
|
||||||
Guid track = obj.fmod2DEventPaths.Get<Guid>(i);
|
obj.soundEffectIndex = i;
|
||||||
if (track == val)
|
obj.is3D = false;
|
||||||
{
|
return;
|
||||||
obj.soundEffectIndex = i;
|
|
||||||
obj.is3D = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (byte i = 0; i < obj.fmod3DEventPaths.Count<Guid>(); i++)
|
}
|
||||||
|
|
||||||
|
for (byte i = 0; i < obj.fmod3DEventPaths.Count<Guid>(); i++)
|
||||||
|
{
|
||||||
|
Guid track = obj.fmod3DEventPaths.Get<Guid>(i);
|
||||||
|
if (track == value)
|
||||||
{
|
{
|
||||||
Guid track = obj.fmod3DEventPaths.Get<Guid>(i);
|
obj.soundEffectIndex = i;
|
||||||
if (track == val)
|
obj.is3D = true;
|
||||||
{
|
return;
|
||||||
obj.soundEffectIndex = i;
|
|
||||||
obj.is3D = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, value);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,31 +126,29 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) =>
|
var obj = BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this);
|
||||||
|
Guid[] tracks = new Guid[obj.fmod2DEventPaths.Count<Guid>()];
|
||||||
|
for (byte i = 0; i < tracks.Length; i++)
|
||||||
{
|
{
|
||||||
Guid[] tracks = new Guid[obj.fmod2DEventPaths.Count<Guid>()];
|
tracks[i] = obj.fmod2DEventPaths.Get<Guid>(i);
|
||||||
for (byte i = 0; i < tracks.Length; i++)
|
}
|
||||||
{
|
|
||||||
tracks[i] = obj.fmod2DEventPaths.Get<Guid>(i);
|
return tracks;
|
||||||
}
|
|
||||||
return tracks;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Guid[] Tracks3D
|
public Guid[] Tracks3D
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) =>
|
var obj = BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this);
|
||||||
|
Guid[] tracks = new Guid[obj.fmod3DEventPaths.Count<Guid>()];
|
||||||
|
for (byte i = 0; i < tracks.Length; i++)
|
||||||
{
|
{
|
||||||
Guid[] tracks = new Guid[obj.fmod3DEventPaths.Count<Guid>()];
|
tracks[i] = obj.fmod2DEventPaths.Get<Guid>(i);
|
||||||
for (byte i = 0; i < tracks.Length; i++)
|
}
|
||||||
{
|
|
||||||
tracks[i] = obj.fmod2DEventPaths.Get<Guid>(i);
|
return tracks;
|
||||||
}
|
|
||||||
return tracks;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,13 +156,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => obj.isLoopedBlock);
|
return BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).isLoopedBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).isLoopedBlock = value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, bool val) => obj.isLoopedBlock = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,33 +169,33 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this,
|
return BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).isPlaying;
|
||||||
(SoundSfxBlockDataEntityStruct obj) => obj.isPlaying);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref SoundSfxBlockDataEntityStruct obj, bool val) =>
|
var obj = BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this);
|
||||||
|
if (obj.isPlaying == value) return;
|
||||||
|
if (value)
|
||||||
{
|
{
|
||||||
if (obj.isPlaying == val) return;
|
// start playing
|
||||||
if (val)
|
EventInstance inst = RuntimeManager.CreateInstance(obj.is3D
|
||||||
{
|
? obj.fmod3DEventPaths.Get<Guid>(obj.soundEffectIndex)
|
||||||
// start playing
|
: obj.fmod2DEventPaths.Get<Guid>(obj.soundEffectIndex));
|
||||||
EventInstance inst = RuntimeManager.CreateInstance(obj.is3D ? obj.fmod3DEventPaths.Get<Guid>(obj.soundEffectIndex) : obj.fmod2DEventPaths.Get<Guid>(obj.soundEffectIndex));
|
inst.setVolume(obj.tweakableVolume / 100f);
|
||||||
inst.setVolume(obj.tweakableVolume / 100f);
|
inst.start();
|
||||||
inst.start();
|
obj.eventHandle = inst.handle;
|
||||||
obj.eventHandle = inst.handle;
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
// stop playing
|
||||||
// stop playing
|
EventInstance inst = default(EventInstance);
|
||||||
EventInstance inst = default(EventInstance);
|
inst.handle = obj.eventHandle;
|
||||||
inst.handle = obj.eventHandle;
|
inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
|
||||||
inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
|
inst.release();
|
||||||
inst.release();
|
}
|
||||||
}
|
|
||||||
obj.isPlaying = val;
|
obj.isPlaying = value;
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Svelto.ECS;
|
||||||
using Svelto.DataStructures;
|
using Svelto.DataStructures;
|
||||||
using Gamecraft.Wires;
|
using Gamecraft.Wires;
|
||||||
using TechbloxModdingAPI.Engines;
|
using TechbloxModdingAPI.Engines;
|
||||||
|
using TechbloxModdingAPI.Utility;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Blocks
|
namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
|
@ -87,8 +88,8 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
public ref PortEntityStruct GetPortByOffset(Block block, byte portNumber, bool input)
|
public ref PortEntityStruct GetPortByOffset(Block block, byte portNumber, bool input)
|
||||||
{
|
{
|
||||||
BlockPortsStruct bps = GetFromDbOrInitData<BlockPortsStruct>(block, block.Id, out bool exists);
|
var bps = entitiesDB.QueryEntityOptional<BlockPortsStruct>(block);
|
||||||
if (!exists)
|
if (!bps)
|
||||||
{
|
{
|
||||||
throw new BlockException("Block does not exist");
|
throw new BlockException("Block does not exist");
|
||||||
}
|
}
|
||||||
|
@ -208,8 +209,9 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
public EGID MatchBlockInputToPort(Block block, byte portUsage, out bool exists)
|
public EGID MatchBlockInputToPort(Block block, byte portUsage, out bool exists)
|
||||||
{
|
{
|
||||||
BlockPortsStruct ports = GetFromDbOrInitData<BlockPortsStruct>(block, block.Id, out exists);
|
var ports = entitiesDB.QueryEntityOptional<BlockPortsStruct>(block);
|
||||||
return new EGID(ports.firstInputID + portUsage, NamedExclusiveGroup<InputPortsGroup>.Group);
|
exists = ports;
|
||||||
|
return new EGID(ports.Get().firstInputID + portUsage, NamedExclusiveGroup<InputPortsGroup>.Group);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EGID MatchBlockInputToPort(EGID block, byte portUsage, out bool exists)
|
public EGID MatchBlockInputToPort(EGID block, byte portUsage, out bool exists)
|
||||||
|
@ -226,8 +228,9 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
public EGID MatchBlockOutputToPort(Block block, byte portUsage, out bool exists)
|
public EGID MatchBlockOutputToPort(Block block, byte portUsage, out bool exists)
|
||||||
{
|
{
|
||||||
BlockPortsStruct ports = GetFromDbOrInitData<BlockPortsStruct>(block, block.Id, out exists);
|
var ports = entitiesDB.QueryEntityOptional<BlockPortsStruct>(block);
|
||||||
return new EGID(ports.firstOutputID + portUsage, NamedExclusiveGroup<OutputPortsGroup>.Group);
|
exists = ports;
|
||||||
|
return new EGID(ports.Get().firstOutputID + portUsage, NamedExclusiveGroup<OutputPortsGroup>.Group);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EGID MatchBlockOutputToPort(EGID block, byte portUsage, out bool exists)
|
public EGID MatchBlockOutputToPort(EGID block, byte portUsage, out bool exists)
|
||||||
|
@ -385,29 +388,6 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
return results.ToArray();
|
return results.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ref T GetFromDbOrInitData<T>(Block block, EGID id, out bool exists) where T : unmanaged, IEntityComponent
|
|
||||||
{
|
|
||||||
T[] defRef = new T[1];
|
|
||||||
if (entitiesDB.Exists<T>(id))
|
|
||||||
{
|
|
||||||
exists = true;
|
|
||||||
return ref entitiesDB.QueryEntity<T>(id);
|
|
||||||
}
|
|
||||||
if (block == null || block.InitData.Group == null)
|
|
||||||
{
|
|
||||||
exists = false;
|
|
||||||
return ref defRef[0];
|
|
||||||
}
|
|
||||||
EntityInitializer initializer = new EntityInitializer(block.Id, block.InitData.Group, block.InitData.Reference);
|
|
||||||
if (initializer.Has<T>())
|
|
||||||
{
|
|
||||||
exists = true;
|
|
||||||
return ref initializer.Get<T>();
|
|
||||||
}
|
|
||||||
exists = false;
|
|
||||||
return ref defRef[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private EntityCollection<ChannelDataStruct> GetSignalStruct(uint signalID, out uint index, bool input = true)
|
private EntityCollection<ChannelDataStruct> GetSignalStruct(uint signalID, out uint index, bool input = true)
|
||||||
{
|
{
|
||||||
ExclusiveGroup group = input
|
ExclusiveGroup group = input
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint InputCount
|
public uint InputCount
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (BlockPortsStruct st) => st.inputCount);
|
get => BlockEngine.GetBlockInfo<BlockPortsStruct>(this).inputCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -75,7 +75,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint OutputCount
|
public uint OutputCount
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (BlockPortsStruct st) => st.outputCount);
|
get => BlockEngine.GetBlockInfo<BlockPortsStruct>(this).outputCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -109,7 +109,6 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// <returns>The localized port name.</returns>
|
/// <returns>The localized port name.</returns>
|
||||||
public string PortName(byte port, bool input)
|
public string PortName(byte port, bool input)
|
||||||
{
|
{
|
||||||
BlockPortsStruct bps = BlockEngine.GetBlockInfo(this, (BlockPortsStruct a) => a);
|
|
||||||
PortEntityStruct pes = SignalEngine.GetPortByOffset(this, port, input);
|
PortEntityStruct pes = SignalEngine.GetPortByOffset(this, port, input);
|
||||||
return pes.portNameLocalised;
|
return pes.portNameLocalised;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Lives
|
public uint Lives
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (SpawnPointStatsEntityStruct st) => st.lives);
|
get => BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(this).lives;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref SpawnPointStatsEntityStruct st, uint val) => st.lives = val, value);
|
BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(this).lives = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,11 +41,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Damageable
|
public bool Damageable
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (SpawnPointStatsEntityStruct st) => st.canTakeDamage);
|
get => BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(this).canTakeDamage;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref SpawnPointStatsEntityStruct st, bool val) => st.canTakeDamage = val, value);
|
BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(this).canTakeDamage = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,11 +54,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool GameOverEnabled
|
public bool GameOverEnabled
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (SpawnPointStatsEntityStruct st) => st.gameOverScreen);
|
get => BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(this).gameOverScreen;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref SpawnPointStatsEntityStruct st, bool val) => st.gameOverScreen = val, value);
|
BlockEngine.GetBlockInfo<SpawnPointStatsEntityStruct>(this).gameOverScreen = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,11 +67,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte Team
|
public byte Team
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (SpawnPointIdsEntityStruct st) => st.teamId);
|
get => BlockEngine.GetBlockInfo<SpawnPointIdsEntityStruct>(this).teamId;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref SpawnPointIdsEntityStruct st, byte val) => st.teamId = val, value);
|
BlockEngine.GetBlockInfo<SpawnPointIdsEntityStruct>(this).teamId = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,17 +26,15 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// The text block's current text.
|
/// The text block's current text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Text
|
public string Text
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (TextBlockDataStruct st) => st.textCurrent);
|
get => BlockEngine.GetBlockInfo<TextBlockDataStruct>(this).textCurrent;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == null) value = "";
|
if (value == null) value = "";
|
||||||
BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) =>
|
var tbds = BlockEngine.GetBlockInfo<TextBlockDataStruct>(this);
|
||||||
{
|
tbds.textCurrent.Set(value);
|
||||||
tbds.textCurrent.Set(val);
|
tbds.textStored.Set(value, true);
|
||||||
tbds.textStored.Set(val, true);
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,13 +43,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TextBlockId
|
public string TextBlockId
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (TextBlockDataStruct st) => st.textBlockID);
|
get => BlockEngine.GetBlockInfo<TextBlockDataStruct>(this).textBlockID;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == null) value = "";
|
if (value == null) value = "";
|
||||||
BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) =>
|
BlockEngine.GetBlockInfo<TextBlockDataStruct>(this).textBlockID.Set(value);
|
||||||
tbds.textBlockID.Set(val), value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float Start
|
public float Start
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (TimerBlockDataStruct st) => st.startTime);
|
get => BlockEngine.GetBlockInfo<TimerBlockDataStruct>(this).startTime;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref TimerBlockDataStruct tbds, float val) => tbds.startTime = val,
|
BlockEngine.GetBlockInfo<TimerBlockDataStruct>(this).startTime = value;
|
||||||
value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,12 +41,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float End
|
public float End
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (TimerBlockDataStruct st) => st.endTime);
|
get => BlockEngine.GetBlockInfo<TimerBlockDataStruct>(this).endTime;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref TimerBlockDataStruct tbds, float val) => tbds.endTime = val,
|
BlockEngine.GetBlockInfo<TimerBlockDataStruct>(this).endTime = value;
|
||||||
value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,12 +54,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool DisplayMilliseconds
|
public bool DisplayMilliseconds
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (TimerBlockDataStruct st) => st.outputFormatHasMS);
|
get => BlockEngine.GetBlockInfo<TimerBlockDataStruct>(this).outputFormatHasMS;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref TimerBlockDataStruct tbds, bool val) => tbds.outputFormatHasMS = val,
|
BlockEngine.GetBlockInfo<TimerBlockDataStruct>(this).outputFormatHasMS = value;
|
||||||
value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,12 +67,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int CurrentTime
|
public int CurrentTime
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (TimerBlockLabelCacheEntityStruct st) => st.timeLastRenderFrameMS);
|
get => BlockEngine.GetBlockInfo<TimerBlockLabelCacheEntityStruct>(this).timeLastRenderFrameMS;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref TimerBlockLabelCacheEntityStruct tbds, int val) => tbds.timeLastRenderFrameMS = val,
|
BlockEngine.GetBlockInfo<TimerBlockLabelCacheEntityStruct>(this).timeLastRenderFrameMS = value;
|
||||||
value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ namespace TechbloxModdingAPI
|
||||||
/// Represnts a cluster of blocks in time running mode, meaning blocks that are connected either directly or via joints.
|
/// Represnts a cluster of blocks in time running mode, meaning blocks that are connected either directly or via joints.
|
||||||
/// Only exists if a cluster destruction manager is present. Static blocks like grass and dirt aren't part of a cluster.
|
/// Only exists if a cluster destruction manager is present. Static blocks like grass and dirt aren't part of a cluster.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Cluster
|
public class Cluster : EcsObjectBase
|
||||||
{
|
{
|
||||||
public EGID Id { get; }
|
public override EGID Id { get; }
|
||||||
|
|
||||||
public Cluster(EGID id)
|
public Cluster(EGID id)
|
||||||
{
|
{
|
||||||
|
@ -23,20 +23,20 @@ namespace TechbloxModdingAPI
|
||||||
|
|
||||||
public float InitialHealth
|
public float InitialHealth
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).initialHealth;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).initialHealth = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float CurrentHealth
|
public float CurrentHealth
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).currentHealth;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).currentHealth = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float HealthMultiplier
|
public float HealthMultiplier
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).healthMultiplier;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).healthMultiplier = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,33 +1,43 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
using Svelto.DataStructures;
|
using Svelto.DataStructures;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Svelto.ECS.Internal;
|
using Svelto.ECS.Internal;
|
||||||
|
using TechbloxModdingAPI.Blocks;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Blocks
|
namespace TechbloxModdingAPI
|
||||||
{
|
{
|
||||||
public partial class BlockEngine
|
public abstract class EcsObjectBase
|
||||||
{
|
{
|
||||||
|
public abstract EGID Id { get; } //Abstract to support the 'place' Block constructor
|
||||||
|
|
||||||
|
protected internal EcsInitData InitData;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Holds information needed to construct a component initializer
|
/// Holds information needed to construct a component initializer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal struct BlockInitData
|
protected internal struct EcsInitData
|
||||||
{
|
{
|
||||||
public FasterDictionary<RefWrapperType, ITypeSafeDictionary> Group;
|
private FasterDictionary<RefWrapperType, ITypeSafeDictionary> group;
|
||||||
public EntityReference Reference;
|
private EntityReference reference;
|
||||||
|
|
||||||
|
public static implicit operator EcsInitData(EntityInitializer initializer) => new EcsInitData
|
||||||
|
{group = GetInitGroup(initializer), reference = initializer.reference};
|
||||||
|
|
||||||
|
public EntityInitializer Initializer(EGID id) => new EntityInitializer(id, group, reference);
|
||||||
|
public bool Valid => group != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal delegate FasterDictionary<RefWrapperType, ITypeSafeDictionary> GetInitGroup(
|
private delegate FasterDictionary<RefWrapperType, ITypeSafeDictionary> GetInitGroupFunc(
|
||||||
EntityInitializer initializer);
|
EntityInitializer initializer);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Accesses the group field of the initializer
|
/// Accesses the group field of the initializer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal GetInitGroup InitGroup = CreateAccessor<GetInitGroup>("_group");
|
private static GetInitGroupFunc GetInitGroup = CreateAccessor<GetInitGroupFunc>("_group");
|
||||||
|
|
||||||
//https://stackoverflow.com/questions/55878525/unit-testing-ref-structs-with-private-fields-via-reflection
|
//https://stackoverflow.com/questions/55878525/unit-testing-ref-structs-with-private-fields-via-reflection
|
||||||
internal static TDelegate CreateAccessor<TDelegate>(string memberName) where TDelegate : Delegate
|
private static TDelegate CreateAccessor<TDelegate>(string memberName) where TDelegate : Delegate
|
||||||
{
|
{
|
||||||
var invokeMethod = typeof(TDelegate).GetMethod("Invoke");
|
var invokeMethod = typeof(TDelegate).GetMethod("Invoke");
|
||||||
if (invokeMethod == null)
|
if (invokeMethod == null)
|
|
@ -1,4 +1,5 @@
|
||||||
using RobocraftX.Physics;
|
using RobocraftX.Physics;
|
||||||
|
using Svelto.ECS;
|
||||||
using Svelto.ECS.EntityStructs;
|
using Svelto.ECS.EntityStructs;
|
||||||
using Techblox.FlyCam;
|
using Techblox.FlyCam;
|
||||||
using TechbloxModdingAPI.Players;
|
using TechbloxModdingAPI.Players;
|
||||||
|
@ -8,13 +9,13 @@ using UnityEngine;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI
|
namespace TechbloxModdingAPI
|
||||||
{
|
{
|
||||||
public class FlyCam
|
public class FlyCam : EcsObjectBase
|
||||||
{
|
{
|
||||||
private static FlyCamEngine Engine = new FlyCamEngine();
|
private static FlyCamEngine Engine = new FlyCamEngine();
|
||||||
|
|
||||||
public uint Id { get; }
|
public override EGID Id { get; }
|
||||||
|
|
||||||
public FlyCam(uint id) => Id = id;
|
public FlyCam(uint id) => Id = new EGID(id, Techblox.FlyCam.FlyCam.Group);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The local player's camera.
|
/// The local player's camera.
|
||||||
|
@ -26,11 +27,11 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float3 Position
|
public float3 Position
|
||||||
{
|
{
|
||||||
get => Engine.GetComponent<PositionEntityStruct>(Id).Get().position;
|
get => Engine.GetComponent<PositionEntityStruct>(this).position;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Engine.GetComponent<PositionEntityStruct>(Id).Get().position = value;
|
Engine.GetComponent<PositionEntityStruct>(this).position = value;
|
||||||
Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().position = value;
|
Engine.GetComponent<RigidBodyEntityStruct>(this).position = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +40,11 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float3 Rotation
|
public float3 Rotation
|
||||||
{
|
{
|
||||||
get => ((Quaternion) Engine.GetComponent<RotationEntityStruct>(Id).Get().rotation).eulerAngles;
|
get => ((Quaternion) Engine.GetComponent<RotationEntityStruct>(this).rotation).eulerAngles;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Engine.GetComponent<RotationEntityStruct>(Id).Get().rotation = Quaternion.Euler(value);
|
Engine.GetComponent<RotationEntityStruct>(this).rotation = Quaternion.Euler(value);
|
||||||
Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().rotation = Quaternion.Euler(value);
|
Engine.GetComponent<RigidBodyEntityStruct>(this).rotation = Quaternion.Euler(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +53,8 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float3 MovementDirection
|
public float3 MovementDirection
|
||||||
{
|
{
|
||||||
get => Engine.GetComponent<FlyCamMovementComponent>(Id).Get().movementDirection;
|
get => Engine.GetComponent<FlyCamMovementComponent>(this).movementDirection;
|
||||||
set => Engine.GetComponent<FlyCamMovementComponent>(Id).Get().movementDirection = value;
|
set => Engine.GetComponent<FlyCamMovementComponent>(this).movementDirection = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -61,8 +62,8 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Sprinting
|
public bool Sprinting
|
||||||
{
|
{
|
||||||
get => Engine.GetComponent<FlyCamMovementComponent>(Id).Get().sprinting;
|
get => Engine.GetComponent<FlyCamMovementComponent>(this).sprinting;
|
||||||
set => Engine.GetComponent<FlyCamMovementComponent>(Id).Get().sprinting = value;
|
set => Engine.GetComponent<FlyCamMovementComponent>(this).sprinting = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -70,8 +71,8 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float Speed
|
public float Speed
|
||||||
{
|
{
|
||||||
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().speed;
|
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).speed;
|
||||||
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().speed = value;
|
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).speed = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -79,8 +80,8 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float SpeedSprintMultiplier
|
public float SpeedSprintMultiplier
|
||||||
{
|
{
|
||||||
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().speedSprintMultiplier;
|
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).speedSprintMultiplier;
|
||||||
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().speedSprintMultiplier = value;
|
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).speedSprintMultiplier = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -88,8 +89,8 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float Acceleration
|
public float Acceleration
|
||||||
{
|
{
|
||||||
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().acceleration;
|
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).acceleration;
|
||||||
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().acceleration = value;
|
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).acceleration = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -97,8 +98,8 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float3 Velocity
|
public float3 Velocity
|
||||||
{
|
{
|
||||||
get => Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().velocity;
|
get => Engine.GetComponent<RigidBodyEntityStruct>(this).velocity;
|
||||||
set => Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().velocity = value;
|
set => Engine.GetComponent<RigidBodyEntityStruct>(this).velocity = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -106,8 +107,8 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float3 AngularVelocity
|
public float3 AngularVelocity
|
||||||
{
|
{
|
||||||
get => Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().angularVelocity;
|
get => Engine.GetComponent<RigidBodyEntityStruct>(this).angularVelocity;
|
||||||
set => Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().angularVelocity = value;
|
set => Engine.GetComponent<RigidBodyEntityStruct>(this).angularVelocity = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Techblox.FlyCam;
|
using Techblox.FlyCam;
|
||||||
using TechbloxModdingAPI.Engines;
|
using TechbloxModdingAPI.Engines;
|
||||||
|
using TechbloxModdingAPI.Utility;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Players
|
namespace TechbloxModdingAPI.Players
|
||||||
{
|
{
|
||||||
|
@ -18,11 +19,9 @@ namespace TechbloxModdingAPI.Players
|
||||||
public string Name => "TechbloxModdingAPIFlyCamEngine";
|
public string Name => "TechbloxModdingAPIFlyCamEngine";
|
||||||
public bool isRemovable => false;
|
public bool isRemovable => false;
|
||||||
|
|
||||||
public OptionalRef<T> GetComponent<T>(uint id) where T : unmanaged, IEntityComponent
|
public ref T GetComponent<T>(FlyCam cam) where T : unmanaged, IEntityComponent
|
||||||
{
|
{
|
||||||
if (entitiesDB.TryQueryEntitiesAndIndex<T>(id, Techblox.FlyCam.FlyCam.Group, out uint index, out var array))
|
return ref entitiesDB.QueryEntityOrDefault<T>(cam);
|
||||||
return new OptionalRef<T>(array, index);
|
|
||||||
return new OptionalRef<T>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,9 +12,9 @@ namespace TechbloxModdingAPI
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A rigid body (like a chunk of connected blocks) during simulation.
|
/// A rigid body (like a chunk of connected blocks) during simulation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SimBody : IEquatable<SimBody>, IEquatable<EGID>
|
public class SimBody : EcsObjectBase, IEquatable<SimBody>, IEquatable<EGID>
|
||||||
{
|
{
|
||||||
public EGID Id { get; }
|
public override EGID Id { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The cluster this chunk belongs to, or null if no cluster destruction manager present or the chunk doesn't exist.
|
/// The cluster this chunk belongs to, or null if no cluster destruction manager present or the chunk doesn't exist.
|
||||||
|
@ -92,26 +92,26 @@ namespace TechbloxModdingAPI
|
||||||
|
|
||||||
public float InitialHealth
|
public float InitialHealth
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).initialHealth;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).initialHealth = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float CurrentHealth
|
public float CurrentHealth
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).currentHealth;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).currentHealth = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float HealthMultiplier
|
public float HealthMultiplier
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).healthMultiplier;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).healthMultiplier = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the body can be moved or static.
|
/// Whether the body can be moved or static.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Static => Block.BlockEngine.GetBlockInfo<MassEntityStruct>(Id).isStatic; //Setting it doesn't have any effect
|
public bool Static => Block.BlockEngine.GetBlockInfo<MassEntityStruct>(this).isStatic; //Setting it doesn't have any effect
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The rigid bodies connected to this one via functional joints (broken ones don't count).
|
/// The rigid bodies connected to this one via functional joints (broken ones don't count).
|
||||||
|
@ -132,7 +132,7 @@ namespace TechbloxModdingAPI
|
||||||
|
|
||||||
private ref RigidBodyEntityStruct GetStruct()
|
private ref RigidBodyEntityStruct GetStruct()
|
||||||
{
|
{
|
||||||
return ref Block.BlockEngine.GetBlockInfo<RigidBodyEntityStruct>(Id);
|
return ref Block.BlockEngine.GetBlockInfo<RigidBodyEntityStruct>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
@ -487,9 +487,9 @@
|
||||||
<HintPath>..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.dll</HintPath>
|
<HintPath>..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.dll</HintPath>
|
||||||
<HintPath>..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.dll</HintPath>
|
<HintPath>..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.Inventory.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.GUI.RemoveBlock">
|
<Reference Include="RobocraftX.GUI.PauseMenu">
|
||||||
<HintPath>..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.RemoveBlock.dll</HintPath>
|
<HintPath>..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.PauseMenu.dll</HintPath>
|
||||||
<HintPath>..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.RemoveBlock.dll</HintPath>
|
<HintPath>..\..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.PauseMenu.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.GUI.ScaleGhost">
|
<Reference Include="RobocraftX.GUI.ScaleGhost">
|
||||||
<HintPath>..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.ScaleGhost.dll</HintPath>
|
<HintPath>..\ref\TechbloxPreview_Data\Managed\RobocraftX.GUI.ScaleGhost.dll</HintPath>
|
||||||
|
@ -655,9 +655,9 @@
|
||||||
<HintPath>..\ref\TechbloxPreview_Data\Managed\Techblox.InputCapture.dll</HintPath>
|
<HintPath>..\ref\TechbloxPreview_Data\Managed\Techblox.InputCapture.dll</HintPath>
|
||||||
<HintPath>..\..\ref\TechbloxPreview_Data\Managed\Techblox.InputCapture.dll</HintPath>
|
<HintPath>..\..\ref\TechbloxPreview_Data\Managed\Techblox.InputCapture.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Techblox.MouseCursor">
|
<Reference Include="Techblox.Pointer">
|
||||||
<HintPath>..\ref\TechbloxPreview_Data\Managed\Techblox.MouseCursor.dll</HintPath>
|
<HintPath>..\ref\TechbloxPreview_Data\Managed\Techblox.Pointer.dll</HintPath>
|
||||||
<HintPath>..\..\ref\TechbloxPreview_Data\Managed\Techblox.MouseCursor.dll</HintPath>
|
<HintPath>..\..\ref\TechbloxPreview_Data\Managed\Techblox.Pointer.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Techblox.SwitchAnimation">
|
<Reference Include="Techblox.SwitchAnimation">
|
||||||
<HintPath>..\ref\TechbloxPreview_Data\Managed\Techblox.SwitchAnimation.dll</HintPath>
|
<HintPath>..\ref\TechbloxPreview_Data\Managed\Techblox.SwitchAnimation.dll</HintPath>
|
||||||
|
|
55
TechbloxModdingAPI/Utility/ManagedApiExtensions.cs
Normal file
55
TechbloxModdingAPI/Utility/ManagedApiExtensions.cs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
using Svelto.ECS;
|
||||||
|
using Svelto.ECS.Hybrid;
|
||||||
|
using TechbloxModdingAPI.Blocks;
|
||||||
|
|
||||||
|
namespace TechbloxModdingAPI.Utility
|
||||||
|
{
|
||||||
|
public static class ManagedApiExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to query an entity and returns an optional that contains the result if succeeded.
|
||||||
|
/// <b>This overload does not take initializer data into account.</b>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entitiesDB">The entities DB</param>
|
||||||
|
/// <param name="egid">The EGID to query</param>
|
||||||
|
/// <typeparam name="T">The component type to query</typeparam>
|
||||||
|
/// <returns>An optional that contains the result on success or is empty if not found</returns>
|
||||||
|
public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EGID egid)
|
||||||
|
where T : struct, IEntityViewComponent
|
||||||
|
{
|
||||||
|
return entitiesDB.TryQueryEntitiesAndIndex<T>(egid, out uint index, out var array)
|
||||||
|
? new OptionalRef<T>(array, index)
|
||||||
|
: new OptionalRef<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to query an entity and returns the result or a dummy value that can be modified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entitiesDB"></param>
|
||||||
|
/// <param name="obj"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EcsObjectBase obj)
|
||||||
|
where T : struct, IEntityViewComponent
|
||||||
|
{
|
||||||
|
var opt = QueryEntityOptional<T>(entitiesDB, obj.Id);
|
||||||
|
return opt ? opt : new OptionalRef<T>(obj, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to query an entity and returns the result or a dummy value that can be modified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entitiesDB"></param>
|
||||||
|
/// <param name="obj"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ref T QueryEntityOrDefault<T>(this EntitiesDB entitiesDB, EcsObjectBase obj)
|
||||||
|
where T : struct, IEntityViewComponent
|
||||||
|
{
|
||||||
|
var opt = QueryEntityOptional<T>(entitiesDB, obj.Id);
|
||||||
|
if (opt) return ref opt.Get();
|
||||||
|
if (obj.InitData.Valid) return ref obj.InitData.Initializer(obj.Id).GetOrCreate<T>();
|
||||||
|
return ref opt.Get(); //Default value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
TechbloxModdingAPI/Utility/NativeApiExtensions.cs
Normal file
53
TechbloxModdingAPI/Utility/NativeApiExtensions.cs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
using Svelto.ECS;
|
||||||
|
|
||||||
|
namespace TechbloxModdingAPI.Utility
|
||||||
|
{
|
||||||
|
public static class NativeApiExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to query an entity and returns an optional that contains the result if succeeded.
|
||||||
|
/// <b>This overload does not take initializer data into account.</b>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entitiesDB">The entities DB</param>
|
||||||
|
/// <param name="egid">The EGID to query</param>
|
||||||
|
/// <typeparam name="T">The component type to query</typeparam>
|
||||||
|
/// <returns>An optional that contains the result on success or is empty if not found</returns>
|
||||||
|
public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EGID egid)
|
||||||
|
where T : unmanaged, IEntityComponent
|
||||||
|
{
|
||||||
|
return entitiesDB.TryQueryEntitiesAndIndex<T>(egid, out uint index, out var array)
|
||||||
|
? new OptionalRef<T>(array, index)
|
||||||
|
: new OptionalRef<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to query an entity and returns the result or a dummy value that can be modified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entitiesDB"></param>
|
||||||
|
/// <param name="obj"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EcsObjectBase obj)
|
||||||
|
where T : unmanaged, IEntityComponent
|
||||||
|
{
|
||||||
|
var opt = QueryEntityOptional<T>(entitiesDB, obj.Id);
|
||||||
|
return opt ? opt : new OptionalRef<T>(obj, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to query an entity and returns the result or a dummy value that can be modified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entitiesDB"></param>
|
||||||
|
/// <param name="obj"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ref T QueryEntityOrDefault<T>(this EntitiesDB entitiesDB, EcsObjectBase obj)
|
||||||
|
where T : unmanaged, IEntityComponent
|
||||||
|
{
|
||||||
|
var opt = QueryEntityOptional<T>(entitiesDB, obj.Id);
|
||||||
|
if (opt) return ref opt.Get();
|
||||||
|
if (obj.InitData.Valid) return ref obj.InitData.Initializer(obj.Id).GetOrCreate<T>();
|
||||||
|
return ref opt.Get(); //Default value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,60 +1,93 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Runtime.InteropServices;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using TechbloxModdingAPI.Blocks;
|
|
||||||
using Svelto.DataStructures;
|
using Svelto.DataStructures;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI
|
namespace TechbloxModdingAPI.Utility
|
||||||
{
|
{
|
||||||
public struct OptionalRef<T> where T : unmanaged
|
public ref struct OptionalRef<T> where T : struct, IEntityComponent
|
||||||
{
|
{
|
||||||
private bool exists;
|
private readonly State state;
|
||||||
|
private readonly uint index;
|
||||||
private NB<T> array;
|
private NB<T> array;
|
||||||
private uint index;
|
private MB<T> managedArray;
|
||||||
|
private readonly EntityInitializer initializer;
|
||||||
|
//The possible fields are: (index && (array || managedArray)) || initializer
|
||||||
|
|
||||||
public OptionalRef(NB<T> array, uint index)
|
public OptionalRef(NB<T> array, uint index)
|
||||||
{
|
{
|
||||||
exists = true;
|
state = State.Native;
|
||||||
this.array = array;
|
this.array = array;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
initializer = default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OptionalRef(ref T value)
|
public OptionalRef(MB<T> array, uint index)
|
||||||
{
|
{
|
||||||
exists = true;
|
state = State.Managed;
|
||||||
|
managedArray = array;
|
||||||
|
this.index = index;
|
||||||
|
initializer = default;
|
||||||
|
this.array = default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wraps the initializer data, if present.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The object with the initializer</param>
|
||||||
|
/// <param name="unmanaged">Whether the struct is unmanaged</param>
|
||||||
|
public OptionalRef(EcsObjectBase obj, bool unmanaged)
|
||||||
|
{
|
||||||
|
if (obj.InitData.Valid)
|
||||||
|
{
|
||||||
|
initializer = obj.InitData.Initializer(obj.Id);
|
||||||
|
state = (unmanaged ? State.Native : State.Managed) | State.Initializer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initializer = default;
|
||||||
|
state = State.Empty;
|
||||||
|
}
|
||||||
array = default;
|
array = default;
|
||||||
index = default;
|
index = default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref T Get(T def = default)
|
/// <summary>
|
||||||
|
/// Returns the value or a default value if empty. Supports objects that are being initialized.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The value or the default value</returns>
|
||||||
|
public ref T Get()
|
||||||
{
|
{
|
||||||
if (exists)
|
if (state == State.Empty) return ref CompRefCache.Default;
|
||||||
return ref array[index];
|
if ((state & State.Initializer) != State.Empty) return ref initializer.GetOrCreate<T>();
|
||||||
return ref CompRefCache<T>._default;
|
if ((state & State.Native) != State.Empty) return ref array[index];
|
||||||
|
return ref managedArray[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Exists => exists;
|
public bool Exists => state != State.Empty;
|
||||||
|
|
||||||
public static implicit operator T(OptionalRef<T> opt) => opt.Get();
|
public static implicit operator T(OptionalRef<T> opt) => opt.Get();
|
||||||
|
|
||||||
public static implicit operator bool(OptionalRef<T> opt) => opt.exists;
|
public static implicit operator bool(OptionalRef<T> opt) => opt.state != State.Empty;
|
||||||
|
|
||||||
/*public delegate ref TR Mapper<TR>(ref T component) where TR : unmanaged;
|
|
||||||
public unsafe delegate TR* PMapper<TR>(T* component) where TR : unmanaged;
|
|
||||||
|
|
||||||
public unsafe OptionalRef<TR> Map<TR>(PMapper<TR> mapper) where TR : unmanaged =>
|
|
||||||
exists ? new OptionalRef<TR>(ref *mapper(pointer)) : new OptionalRef<TR>();*/
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an instance of a struct T that can be referenced.
|
/// Creates an instance of a struct T that can be referenced.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The struct type to cache</typeparam>
|
internal struct CompRefCache
|
||||||
private struct CompRefCache<T> where T : unmanaged
|
|
||||||
{
|
{
|
||||||
public static T _default;
|
public static T Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A byte that holds state in its bits.
|
||||||
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
|
private enum State : byte
|
||||||
|
{
|
||||||
|
Empty,
|
||||||
|
Native,
|
||||||
|
Managed,
|
||||||
|
Initializer = 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue