Merge branch 'master' of https://git.exmods.org/modtainers/GamecraftModdingAPI
This commit is contained in:
commit
95574a50f8
15 changed files with 419 additions and 63 deletions
|
@ -171,7 +171,7 @@ namespace GamecraftModdingAPI
|
||||||
egid = new EGID(id, group.Value);
|
egid = new EGID(id, group.Value);
|
||||||
if (typeToGroup.TryGetValue(type, out var gr)
|
if (typeToGroup.TryGetValue(type, out var gr)
|
||||||
&& gr.All(egs => egs != group.Value)) //If this subclass has a specific group, then use that - so Block should still work
|
&& gr.All(egs => egs != group.Value)) //If this subclass has a specific group, then use that - so Block should still work
|
||||||
throw new BlockTypeException($"Incompatible block type! Type {type.Name} belongs to group {gr.Select(g => g.ToString()).Aggregate((a, b) => a + ", " + b)} instead of {group.Value}");
|
throw new BlockTypeException($"Incompatible block type! Type {type.Name} belongs to group {gr.Select(g => ((uint)g).ToString()).Aggregate((a, b) => a + ", " + b)} instead of {(uint)group.Value}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initializers.TryGetValue(type, out var func))
|
if (initializers.TryGetValue(type, out var func))
|
||||||
|
@ -213,7 +213,7 @@ namespace GamecraftModdingAPI
|
||||||
throw new BlockTypeException("The block has the wrong group! The type is " + GetType() +
|
throw new BlockTypeException("The block has the wrong group! The type is " + GetType() +
|
||||||
" while the group is " + id.groupID);
|
" while the group is " + id.groupID);
|
||||||
}
|
}
|
||||||
else if (type != typeof(Block))
|
else if (type != typeof(Block) && !typeof(CustomBlock).IsAssignableFrom(type))
|
||||||
Logging.LogWarning($"Unknown block type! Add {type} to the dictionary.");
|
Logging.LogWarning($"Unknown block type! Add {type} to the dictionary.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,7 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
for (int i = 0; i < joints.count; i++)
|
for (int i = 0; i < joints.count; i++)
|
||||||
{
|
{
|
||||||
ref var joint = ref joints.buffer[i];
|
ref var joint = ref joints.buffer[i];
|
||||||
if (joint.jointState == JointState.Broken) continue;
|
if (joint.isBroken) continue;
|
||||||
if (joint.connectedEntityA == id) list.Add(new SimBody(joint.connectedEntityB));
|
if (joint.connectedEntityA == id) list.Add(new SimBody(joint.connectedEntityB));
|
||||||
else if (joint.connectedEntityB == id) list.Add(new SimBody(joint.connectedEntityA));
|
else if (joint.connectedEntityB == id) list.Add(new SimBody(joint.connectedEntityA));
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,9 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
GlassConeSegment,
|
GlassConeSegment,
|
||||||
GlassCylinder,
|
GlassCylinder,
|
||||||
GlassSphere,
|
GlassSphere,
|
||||||
Lever, //63 - two IDs skipped
|
Lever, //63
|
||||||
PlayerSpawn = 66, //Crashes without special handling
|
WoodenSlatsDoor = 65,
|
||||||
|
PlayerSpawn, //Crashes without special handling
|
||||||
SmallSpawn,
|
SmallSpawn,
|
||||||
MediumSpawn,
|
MediumSpawn,
|
||||||
LargeSpawn,
|
LargeSpawn,
|
||||||
|
@ -86,10 +87,17 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
DampedSpring,
|
DampedSpring,
|
||||||
ServoPiston,
|
ServoPiston,
|
||||||
StepperPiston,
|
StepperPiston,
|
||||||
PneumaticPiston,
|
PneumaticPiston, //80
|
||||||
PneumaticHinge,
|
PneumaticHinge,
|
||||||
PneumaticAxle, //82
|
PneumaticAxle,
|
||||||
PilotSeat = 90, //Might crash
|
WindowedDoor,
|
||||||
|
Bench,
|
||||||
|
Chair,
|
||||||
|
Stool,
|
||||||
|
DampedHingeSpring,
|
||||||
|
PlainGlassDoor,
|
||||||
|
PlainWoodenDoor,
|
||||||
|
PilotSeat, //Might crash
|
||||||
PassengerSeat,
|
PassengerSeat,
|
||||||
PilotControls,
|
PilotControls,
|
||||||
GrassCube,
|
GrassCube,
|
||||||
|
@ -148,8 +156,9 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
WoodCylinder,
|
WoodCylinder,
|
||||||
WoodHemisphere,
|
WoodHemisphere,
|
||||||
WoodSphere,
|
WoodSphere,
|
||||||
BrickCube, //149
|
BrickCube,
|
||||||
BrickSlicedCube = 151,
|
DampedAxleSpring, //150
|
||||||
|
BrickSlicedCube,
|
||||||
BrickSlope,
|
BrickSlope,
|
||||||
BrickCorner,
|
BrickCorner,
|
||||||
ConcreteCube,
|
ConcreteCube,
|
||||||
|
@ -355,6 +364,7 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
HexNetCylinder = 797,
|
HexNetCylinder = 797,
|
||||||
HexNetHemisphere,
|
HexNetHemisphere,
|
||||||
HexNetSphere,
|
HexNetSphere,
|
||||||
HexNetTubeCorner //800
|
HexNetTubeCorner, //800
|
||||||
|
CenterOfMassBlock = 1346
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using Gamecraft.Wires;
|
using Gamecraft.Wires;
|
||||||
|
using Unity.Mathematics;
|
||||||
|
|
||||||
using GamecraftModdingAPI;
|
using GamecraftModdingAPI;
|
||||||
using GamecraftModdingAPI.Tests;
|
using GamecraftModdingAPI.Tests;
|
||||||
|
@ -60,7 +61,7 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
Assert.Errorless(() => { b = newBlock.Specialise<Piston>(); }, "Block.Specialize<Piston>() raised an exception: ", "Block.Specialize<Piston>() completed without issue.");
|
Assert.Errorless(() => { b = newBlock.Specialise<Piston>(); }, "Block.Specialize<Piston>() raised an exception: ", "Block.Specialize<Piston>() completed without issue.");
|
||||||
if (!Assert.NotNull(b, "Block.Specialize<Piston>() returned null, possibly because it failed silently.", "Specialized Piston is not null.")) return;
|
if (!Assert.NotNull(b, "Block.Specialize<Piston>() returned null, possibly because it failed silently.", "Specialized Piston is not null.")) return;
|
||||||
if (!Assert.CloseTo(b.MaximumExtension, 1.01f, $"Piston.MaximumExtension {b.MaximumExtension} does not equal default value, possibly because it failed silently.", "Piston.MaximumExtension is close enough to default.")) return;
|
if (!Assert.CloseTo(b.MaximumExtension, 1.01f, $"Piston.MaximumExtension {b.MaximumExtension} does not equal default value, possibly because it failed silently.", "Piston.MaximumExtension is close enough to default.")) return;
|
||||||
if (!Assert.CloseTo(b.MaximumForce, 750f, $"Piston.MaximumForce {b.MaximumForce} does not equal default value, possibly because it failed silently.", "Piston.MaximumForce is close enough to default.")) return;
|
if (!Assert.CloseTo(b.MaximumForce, 1.0f, $"Piston.MaximumForce {b.MaximumForce} does not equal default value, possibly because it failed silently.", "Piston.MaximumForce is close enough to default.")) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[APITestCase(TestType.EditMode)]
|
[APITestCase(TestType.EditMode)]
|
||||||
|
@ -72,7 +73,19 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
if (!Assert.NotNull(b, "Block.Specialize<Servo>() returned null, possibly because it failed silently.", "Specialized Servo is not null.")) return;
|
if (!Assert.NotNull(b, "Block.Specialize<Servo>() returned null, possibly because it failed silently.", "Specialized Servo is not null.")) return;
|
||||||
if (!Assert.CloseTo(b.MaximumAngle, 180f, $"Servo.MaximumAngle {b.MaximumAngle} does not equal default value, possibly because it failed silently.", "Servo.MaximumAngle is close enough to default.")) return;
|
if (!Assert.CloseTo(b.MaximumAngle, 180f, $"Servo.MaximumAngle {b.MaximumAngle} does not equal default value, possibly because it failed silently.", "Servo.MaximumAngle is close enough to default.")) return;
|
||||||
if (!Assert.CloseTo(b.MinimumAngle, -180f, $"Servo.MinimumAngle {b.MinimumAngle} does not equal default value, possibly because it failed silently.", "Servo.MinimumAngle is close enough to default.")) return;
|
if (!Assert.CloseTo(b.MinimumAngle, -180f, $"Servo.MinimumAngle {b.MinimumAngle} does not equal default value, possibly because it failed silently.", "Servo.MinimumAngle is close enough to default.")) return;
|
||||||
if (!Assert.CloseTo(b.MaximumForce, 750f, $"Servo.MaximumForce {b.MaximumForce} does not equal default value, possibly because it failed silently.", "Servo.MaximumForce is close enough to default.")) return;
|
if (!Assert.CloseTo(b.MaximumForce, 60f, $"Servo.MaximumForce {b.MaximumForce} does not equal default value, possibly because it failed silently.", "Servo.MaximumForce is close enough to default.")) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[APITestCase(TestType.EditMode)]
|
||||||
|
public static void TestDampedSpring()
|
||||||
|
{
|
||||||
|
Block newBlock = Block.PlaceNew(BlockIDs.DampedSpring, Unity.Mathematics.float3.zero + 1);
|
||||||
|
DampedSpring b = null; // Note: the assignment operation is a lambda, which slightly confuses the compiler
|
||||||
|
Assert.Errorless(() => { b = newBlock.Specialise<DampedSpring>(); }, "Block.Specialize<Servo>() raised an exception: ", "Block.Specialize<DampedSpring>() completed without issue.");
|
||||||
|
if (!Assert.NotNull(b, "Block.Specialize<DampedSpring>() returned null, possibly because it failed silently.", "Specialized DampedSpring is not null.")) return;
|
||||||
|
if (!Assert.CloseTo(b.Stiffness, 1.0f, $"DampedSpring.Stiffness {b.Stiffness} does not equal default value, possibly because it failed silently.", "DampedSpring.Stiffness is close enough to default.")) return;
|
||||||
|
if (!Assert.CloseTo(b.Damping, 0.1f, $"DampedSpring.Damping {b.Damping} does not equal default value, possibly because it failed silently.", "DampedSpring.Damping is close enough to default.")) return;
|
||||||
|
if (!Assert.CloseTo(b.MaxExtension, 0.3f, $"DampedSpring.MaxExtension {b.MaxExtension} does not equal default value, possibly because it failed silently.", "DampedSpring.MaxExtension is close enough to default.")) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[APITestCase(TestType.Game)]
|
[APITestCase(TestType.Game)]
|
||||||
|
@ -119,6 +132,13 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
if (!Assert.Errorless(() => { newWire = b.Connect(0, target, 0);})) return;
|
if (!Assert.Errorless(() => { newWire = b.Connect(0, target, 0);})) return;
|
||||||
if (!Assert.NotNull(newWire, "SignalingBlock.Connect(...) returned null, possible because it failed silently.", "SignalingBlock.Connect(...) returned a non-null value.")) return;
|
if (!Assert.NotNull(newWire, "SignalingBlock.Connect(...) returned null, possible because it failed silently.", "SignalingBlock.Connect(...) returned a non-null value.")) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[APITestCase(TestType.EditMode)]
|
||||||
|
public static void TestSpecialiseError()
|
||||||
|
{
|
||||||
|
Block newBlock = Block.PlaceNew(BlockIDs.Bench, new float3(1, 1, 1));
|
||||||
|
if (Assert.Errorful<BlockTypeException>(() => newBlock.Specialise<MusicBlock>(), "Block.Specialise<MusicBlock>() was expected to error on a bench block.", "Block.Specialise<MusicBlock>() errored as expected for a bench block.")) return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
173
GamecraftModdingAPI/Blocks/CustomBlock.cs
Normal file
173
GamecraftModdingAPI/Blocks/CustomBlock.cs
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
using DataLoader;
|
||||||
|
using RobocraftX.Blocks;
|
||||||
|
using RobocraftX.Rendering;
|
||||||
|
using Svelto.ECS;
|
||||||
|
using Svelto.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
|
using Material = UnityEngine.Material;
|
||||||
|
|
||||||
|
using GamecraftModdingAPI.Utility;
|
||||||
|
|
||||||
|
namespace GamecraftModdingAPI.Blocks
|
||||||
|
{
|
||||||
|
public class CustomBlock : Block
|
||||||
|
{
|
||||||
|
private static ushort nextID = 500;
|
||||||
|
/// <summary>
|
||||||
|
/// Key: Prefab path
|
||||||
|
/// </summary>
|
||||||
|
private static Dictionary<string, Type> _customBlocks = new Dictionary<string, Type>();
|
||||||
|
|
||||||
|
private static bool _canRegister = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register a custom block type. Call it as soon as possible (in OnApplicationStart()).<br />
|
||||||
|
/// You need a Unity project with Addressables and Havok installed and need a prefab added as an addressable asset.
|
||||||
|
/// Build the addressables and the project and copy the catalog.json from StreamingAssets, you'll need to reference this file.
|
||||||
|
/// Also copy the asset files from the subfolder to the same path in the game.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The custom block type</typeparam>
|
||||||
|
public static void RegisterCustomBlock<T>() where T : CustomBlock
|
||||||
|
{
|
||||||
|
if (!_canRegister)
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
"It's too late to register custom blocks. Register it before the game starts loading.");
|
||||||
|
var type = typeof(T);
|
||||||
|
var attr = type.GetCustomAttribute<CustomBlockAttribute>();
|
||||||
|
if (attr == null)
|
||||||
|
throw new ArgumentException("The custom block type is missing the CustomBlock annotation");
|
||||||
|
string typeName = type.FullName ??
|
||||||
|
throw new ArgumentException("The given block type doesn't have a concrete full name.");
|
||||||
|
if (!File.Exists(attr.Catalog))
|
||||||
|
throw new FileNotFoundException("The specified catalog cannot be found for " + typeName);
|
||||||
|
_customBlocks.Add(attr.AssetPath, type);
|
||||||
|
Logging.MetaDebugLog("Registered custom block type " + typeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomBlock(EGID id) : base(id)
|
||||||
|
{
|
||||||
|
/*if (id.groupID != Group)
|
||||||
|
throw new BlockTypeException("The block is not a custom block! It has a group of " + id.groupID);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomBlock(uint id) : base(id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//public static ExclusiveGroup Group { get; } = new ExclusiveGroup("Custom block");
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
public static class MaterialCopyPatch
|
||||||
|
{
|
||||||
|
private static Material[] materials;
|
||||||
|
|
||||||
|
public static void Prefix(List<PrefabData> prefabData, IList<GameObject> prefabs)
|
||||||
|
{
|
||||||
|
for (var index = 0; index < prefabs.Count; index++)
|
||||||
|
{
|
||||||
|
if (prefabData[index].prefabName == "ConsoleBlock")
|
||||||
|
materials = prefabs[index].GetComponentsInChildren<MeshRenderer>()[0].sharedMaterials;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var index = 0; index < prefabs.Count; index++)
|
||||||
|
{
|
||||||
|
if (_customBlocks.ContainsKey(prefabData[index].prefabName)) //This is a custom block
|
||||||
|
prefabs[index].GetComponentsInChildren<MeshRenderer>()[0].sharedMaterials = materials;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodBase TargetMethod()
|
||||||
|
{ //General block registration
|
||||||
|
return AccessTools.Method("RobocraftX.Rendering.ECSGPUIResourceManager:InitPreRegisteredPrefabs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
public static class CubeRegistrationPatch
|
||||||
|
{
|
||||||
|
public static void Prefix(IDataDB dataDB)
|
||||||
|
{
|
||||||
|
//var abd = dataDB.GetValue<CubeListData>((int) BlockIDs.AluminiumCube);
|
||||||
|
foreach (var (key, type) in _customBlocks)
|
||||||
|
{
|
||||||
|
var attr = type.GetCustomAttribute<CustomBlockAttribute>();
|
||||||
|
var cld = new CubeListData
|
||||||
|
{ //"Assets/Prefabs/Cube.prefab" - "CTR_CommandBlock" - "strConsoleBlock"
|
||||||
|
cubeType = attr.Type,
|
||||||
|
//cubeCategory = (CubeCategory) 1000,
|
||||||
|
cubeCategory = attr.Category,
|
||||||
|
inventoryCategory = attr.InventoryCategory,
|
||||||
|
ID = nextID++,
|
||||||
|
Path = attr.AssetPath, //Index out of range exception: Asset failed to load (wrong path)
|
||||||
|
SpriteName = attr.SpriteName,
|
||||||
|
CubeNameKey = attr.NameKey,
|
||||||
|
CubeDescriptionKey = attr.DescKey,
|
||||||
|
SelectableFaces = new[] {0, 1, 2, 3, 4, 5},
|
||||||
|
GridScale = new[] {5, 5, 5},
|
||||||
|
Mass = attr.Mass,
|
||||||
|
Material = attr.Material,
|
||||||
|
scalingPermission = attr.ScalingPermission,
|
||||||
|
SortIndex = attr.SortIndex,
|
||||||
|
DefaultColour = attr.DefaultColor.Index,
|
||||||
|
Volume = attr.Volume,
|
||||||
|
EdgeConnectingFaces = new[] {0, 1, 2, 3, 4, 5},
|
||||||
|
PointDataVolumeMultiplier = 1f
|
||||||
|
};
|
||||||
|
dataDB.GetValues<CubeListData>().Add(cld.ID.ToString(), cld); //The registration needs to happen after the ID has been set
|
||||||
|
dataDB.GetFasterValues<CubeListData>().Add(cld.ID, cld); //So can't use the builtin method to create a CubeListData
|
||||||
|
}
|
||||||
|
|
||||||
|
_canRegister = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodBase TargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method("RobocraftX.CR.MainGame.MainGameCompositionRoot:Init");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*[HarmonyPatch] - The block has no collision even in simulation if using a custom category
|
||||||
|
private static class FactorySetupPatch
|
||||||
|
{
|
||||||
|
public static void Prefix(BlockEntityFactory __instance)
|
||||||
|
{
|
||||||
|
var builders = (Dictionary<CubeCategory, IBlockBuilder>)
|
||||||
|
AccessTools.Field(__instance.GetType(), "_blockBuilders").GetValue(__instance);
|
||||||
|
builders.Add((CubeCategory) 1000, new BlockBuilder<StandardBlockEntityDescriptor>(Group));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodBase TargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method(typeof(BlockEntityFactory), "ParseDataDB");
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
internal static IEnumerator Prepare()
|
||||||
|
{ //Should be pretty quick
|
||||||
|
foreach (var type in _customBlocks.Values)
|
||||||
|
{
|
||||||
|
var attr = type.GetCustomAttribute<CustomBlockAttribute>();
|
||||||
|
Logging.Log("Loading custom block catalog " + attr.Catalog);
|
||||||
|
var res = Addressables.LoadContentCatalogAsync(attr.Catalog);
|
||||||
|
while (!res.IsDone) yield return Yield.It;
|
||||||
|
Logging.Log("Loaded custom block catalog: " + res.Result.LocatorId);
|
||||||
|
Addressables.AddResourceLocator(res.Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*internal static void OnBlockFactoryObtained(BlockEntityFactory factory)
|
||||||
|
{
|
||||||
|
var builders = (Dictionary<CubeCategory, IBlockBuilder>)
|
||||||
|
AccessTools.Field(factory.GetType(), "_blockBuilders").GetValue(factory);
|
||||||
|
builders.Add((CubeCategory) 1000, new BlockBuilder<StandardBlockEntityDescriptor>(Group));
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
85
GamecraftModdingAPI/Blocks/CustomBlockAttribute.cs
Normal file
85
GamecraftModdingAPI/Blocks/CustomBlockAttribute.cs
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
using System;
|
||||||
|
using DataLoader;
|
||||||
|
|
||||||
|
namespace GamecraftModdingAPI.Blocks
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
public class CustomBlockAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Custom block attribute necessary for configuration.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="catalog">File path to the catalog.json that holds asset references for the custom block</param>
|
||||||
|
/// <param name="assetPath">The path/address to the block's prefab specified in Unity</param>
|
||||||
|
/// <param name="nameKey">The translation key for the block's name</param>
|
||||||
|
/// <param name="spriteName">The path to the inventory sprite for the block, console block by default</param>
|
||||||
|
/// <param name="descKey">The translation key for the block's description</param>
|
||||||
|
public CustomBlockAttribute(string catalog, string assetPath, string nameKey,
|
||||||
|
string spriteName = "CTR_CommandBlock", string descKey = "")
|
||||||
|
{
|
||||||
|
Catalog = catalog;
|
||||||
|
AssetPath = assetPath;
|
||||||
|
SpriteName = spriteName;
|
||||||
|
NameKey = nameKey;
|
||||||
|
DescKey = descKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The location of the catalog.json file used to find assets for this block.
|
||||||
|
/// </summary>
|
||||||
|
public string Catalog { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// The asset path/address for the block's prefab.
|
||||||
|
/// </summary>
|
||||||
|
public string AssetPath { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the sprite used in the inventory.
|
||||||
|
/// </summary>
|
||||||
|
public string SpriteName { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// The translation key for the block's name.
|
||||||
|
/// </summary>
|
||||||
|
public string NameKey { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// The translation key for the block's description.
|
||||||
|
/// </summary>
|
||||||
|
public string DescKey { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The block's type - block, joint, light.
|
||||||
|
/// </summary>
|
||||||
|
public CubeType Type { get; set; } = CubeType.Block;
|
||||||
|
/// <summary>
|
||||||
|
/// The block's category, so it's treated as a pre-existing functional block.
|
||||||
|
/// </summary>
|
||||||
|
public CubeCategory Category { get; set; } = CubeCategory.General;
|
||||||
|
/// <summary>
|
||||||
|
/// The block's inventory category.
|
||||||
|
/// </summary>
|
||||||
|
public InventoryCategory InventoryCategory { get; set; } = InventoryCategory.Shapes;
|
||||||
|
/// <summary>
|
||||||
|
/// The block's mass.
|
||||||
|
/// </summary>
|
||||||
|
public float Mass { get; set; } = 1f;
|
||||||
|
/// <summary>
|
||||||
|
/// The key of the material properties this block should use.
|
||||||
|
/// </summary>
|
||||||
|
public string Material { get; set; } = "Aluminium";
|
||||||
|
/// <summary>
|
||||||
|
/// The scaling permission determining what scaling is allowed on this block.
|
||||||
|
/// </summary>
|
||||||
|
public ScalingPermission ScalingPermission { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The sort index in the inventory.
|
||||||
|
/// </summary>
|
||||||
|
public int SortIndex { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The default color of the block when placed.
|
||||||
|
/// </summary>
|
||||||
|
public BlockColor DefaultColor { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The volume of the block.
|
||||||
|
/// </summary>
|
||||||
|
public float Volume { get; set; } = 1f;
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,10 +19,10 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MaxForce
|
public float MaxForce
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (DampedSpringReadOnlyStruct dsrs) => dsrs.maxForce);
|
get => BlockEngine.GetBlockInfo(this, (DampedSpringReadOnlyStruct dsrs) => dsrs.springFrequency);
|
||||||
|
|
||||||
set => BlockEngine.SetBlockInfo(this,
|
set => BlockEngine.SetBlockInfo(this,
|
||||||
(ref DampedSpringReadOnlyStruct dsrs, float val) => dsrs.maxForce = val, value);
|
(ref DampedSpringReadOnlyStruct dsrs, float val) => dsrs.springFrequency = val, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -39,10 +39,21 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float Damping
|
public float Damping
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (LinearJointForcesReadOnlyStruct ljf) => ljf.dampingForceMagnitude);
|
get => BlockEngine.GetBlockInfo(this, (DampedSpringReadOnlyStruct ljf) => ljf.springDamping);
|
||||||
|
|
||||||
set => BlockEngine.SetBlockInfo(this,
|
set => BlockEngine.SetBlockInfo(this,
|
||||||
(ref LinearJointForcesReadOnlyStruct ljf, float val) => ljf.dampingForceMagnitude = val, value);
|
(ref DampedSpringReadOnlyStruct ljf, float val) => ljf.springDamping = val, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The spring's maximum extension.
|
||||||
|
/// </summary>
|
||||||
|
public float MaxExtension
|
||||||
|
{
|
||||||
|
get => BlockEngine.GetBlockInfo(this, (DampedSpringReadOnlyStruct ljf) => ljf.maxExtent);
|
||||||
|
|
||||||
|
set => BlockEngine.SetBlockInfo(this,
|
||||||
|
(ref DampedSpringReadOnlyStruct ljf, float val) => ljf.maxExtent = val, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -40,11 +40,11 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MaximumForce
|
public float MaximumForce
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (PistonReadOnlyStruct st) => st.maxForce);
|
get => BlockEngine.GetBlockInfo(this, (PistonReadOnlyStruct st) => st.pistonVelocity);
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref PistonReadOnlyStruct st, float val) => st.maxForce = val, value);
|
BlockEngine.SetBlockInfo(this, (ref PistonReadOnlyStruct st, float val) => st.pistonVelocity = val, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,11 +52,11 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MaximumForce
|
public float MaximumForce
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.maxForce);
|
get => BlockEngine.GetBlockInfo(this, (ServoReadOnlyStruct st) => st.servoVelocity);
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, float val) => st.maxForce = val, value);
|
BlockEngine.SetBlockInfo(this, (ref ServoReadOnlyStruct st, float val) => st.servoVelocity = val, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,8 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) =>
|
BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) =>
|
||||||
{
|
{
|
||||||
tbds.textCurrent.Set(val);
|
tbds.textCurrent.Set(val);
|
||||||
tbds.textStored.Set(val);
|
tbds.textStored.Set(val, true);
|
||||||
}, value);
|
}, value);
|
||||||
BlockEngine.SetBlockInfo(this,
|
|
||||||
(ref TextBlockNetworkDataStruct st, string val) => st.newTextBlockStringContent.Set(val), value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,8 +52,6 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
if (value == null) value = "";
|
if (value == null) value = "";
|
||||||
BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) =>
|
BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) =>
|
||||||
tbds.textBlockID.Set(val), value);
|
tbds.textBlockID.Set(val), value);
|
||||||
BlockEngine.SetBlockInfo(this,
|
|
||||||
(ref TextBlockNetworkDataStruct st, string val) => st.newTextBlockID.Set(val), value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,9 +79,13 @@
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\DDNA.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\DDNA.dll</HintPath>
|
||||||
<HintPath>..\..\ref\Gamecraft_Data\Managed\DDNA.dll</HintPath>
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\DDNA.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="FMOD">
|
<Reference Include="FMODUnity">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\FMOD.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\FMODUnity.dll</HintPath>
|
||||||
<HintPath>..\..\ref\Gamecraft_Data\Managed\FMOD.dll</HintPath>
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\FMODUnity.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Facepunch.Steamworks.Win64">
|
||||||
|
<HintPath>..\ref\Gamecraft_Data\Managed\Facepunch.Steamworks.Win64.dll</HintPath>
|
||||||
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\Facepunch.Steamworks.Win64.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="FullGame">
|
<Reference Include="FullGame">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\FullGame.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\FullGame.dll</HintPath>
|
||||||
|
@ -267,6 +271,10 @@
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Gamecraft.Music.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\Gamecraft.Music.dll</HintPath>
|
||||||
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Music.dll</HintPath>
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Music.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Gamecraft.NetStrings">
|
||||||
|
<HintPath>..\ref\Gamecraft_Data\Managed\Gamecraft.NetStrings.dll</HintPath>
|
||||||
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.NetStrings.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Gamecraft.PerformanceWarnings">
|
<Reference Include="Gamecraft.PerformanceWarnings">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Gamecraft.PerformanceWarnings.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\Gamecraft.PerformanceWarnings.dll</HintPath>
|
||||||
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.PerformanceWarnings.dll</HintPath>
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.PerformanceWarnings.dll</HintPath>
|
||||||
|
@ -287,6 +295,10 @@
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Gamecraft.Projectiles.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\Gamecraft.Projectiles.dll</HintPath>
|
||||||
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Projectiles.dll</HintPath>
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Projectiles.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Gamecraft.Serialization">
|
||||||
|
<HintPath>..\ref\Gamecraft_Data\Managed\Gamecraft.Serialization.dll</HintPath>
|
||||||
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Serialization.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Gamecraft.Tweaks">
|
<Reference Include="Gamecraft.Tweaks">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Gamecraft.Tweaks.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\Gamecraft.Tweaks.dll</HintPath>
|
||||||
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Tweaks.dll</HintPath>
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Tweaks.dll</HintPath>
|
||||||
|
@ -475,6 +487,10 @@
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll</HintPath>
|
||||||
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll</HintPath>
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="RobocraftX.Multiplayer.Serializers">
|
||||||
|
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.Serializers.dll</HintPath>
|
||||||
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.Serializers.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="RobocraftX.MultiplayerInput">
|
<Reference Include="RobocraftX.MultiplayerInput">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.MultiplayerInput.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.MultiplayerInput.dll</HintPath>
|
||||||
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.MultiplayerInput.dll</HintPath>
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.MultiplayerInput.dll</HintPath>
|
||||||
|
@ -519,10 +535,6 @@
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.SaveGameDialog.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.SaveGameDialog.dll</HintPath>
|
||||||
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.SaveGameDialog.dll</HintPath>
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.SaveGameDialog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.Serializers">
|
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Serializers.dll</HintPath>
|
|
||||||
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Serializers.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="RobocraftX.Services">
|
<Reference Include="RobocraftX.Services">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Services.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Services.dll</HintPath>
|
||||||
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Services.dll</HintPath>
|
<HintPath>..\..\ref\Gamecraft_Data\Managed\RobocraftX.Services.dll</HintPath>
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using GamecraftModdingAPI.Blocks;
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
|
using RobocraftX.Schedulers;
|
||||||
using RobocraftX.Services;
|
using RobocraftX.Services;
|
||||||
using Svelto.Context;
|
using Svelto.Context;
|
||||||
|
using Svelto.Tasks.ExtraLean;
|
||||||
|
|
||||||
|
using GamecraftModdingAPI.Blocks;
|
||||||
using GamecraftModdingAPI.Utility;
|
using GamecraftModdingAPI.Utility;
|
||||||
using GamecraftModdingAPI.Events;
|
using GamecraftModdingAPI.Events;
|
||||||
using GamecraftModdingAPI.Tasks;
|
using GamecraftModdingAPI.Tasks;
|
||||||
|
@ -89,6 +91,7 @@ namespace GamecraftModdingAPI
|
||||||
AsyncUtils.Init();
|
AsyncUtils.Init();
|
||||||
GamecraftModdingAPI.App.Client.Init();
|
GamecraftModdingAPI.App.Client.Init();
|
||||||
GamecraftModdingAPI.App.Game.Init();
|
GamecraftModdingAPI.App.Game.Init();
|
||||||
|
CustomBlock.Prepare().RunOn(ExtraLean.UIScheduler);
|
||||||
// init UI
|
// init UI
|
||||||
Interface.IMGUI.Constants.Init();
|
Interface.IMGUI.Constants.Init();
|
||||||
Interface.IMGUI.IMGUIManager.Init();
|
Interface.IMGUI.IMGUIManager.Init();
|
||||||
|
|
|
@ -119,6 +119,25 @@ namespace GamecraftModdingAPI.Tests
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool Errorful<T>(Action tryThis, string err = null, string success = null) where T : Exception
|
||||||
|
{
|
||||||
|
if (err == null) err = $"{tryThis} was expected to error but completed without errors.";
|
||||||
|
if (success == null) success = $"{tryThis} completed with an expected error.";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tryThis();
|
||||||
|
}
|
||||||
|
catch (T e)
|
||||||
|
{
|
||||||
|
TestRoot.TestsPassed = true;
|
||||||
|
Log(PASS + success + " " + e.GetType().Name + ": " + e.Message);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Log(FAIL + err);
|
||||||
|
TestRoot.TestsPassed = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool CloseTo(float a, float b, string err = null, string success = null, float delta = float.Epsilon)
|
public static bool CloseTo(float a, float b, string err = null, string success = null, float delta = float.Epsilon)
|
||||||
{
|
{
|
||||||
if (err == null) err = $"{a} is not within {delta} of {b}.";
|
if (err == null) err = $"{a} is not within {delta} of {b}.";
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
|
@ -17,6 +18,9 @@ using RobocraftX.SimulationModeState;
|
||||||
using RobocraftX.FrontEnd;
|
using RobocraftX.FrontEnd;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using RobocraftX.Schedulers;
|
||||||
|
using Svelto.Tasks.ExtraLean;
|
||||||
|
using uREPL;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
using GamecraftModdingAPI.Commands;
|
||||||
using GamecraftModdingAPI.Events;
|
using GamecraftModdingAPI.Events;
|
||||||
|
@ -296,6 +300,13 @@ namespace GamecraftModdingAPI.Tests
|
||||||
.BlockGroup = group;
|
.BlockGroup = group;
|
||||||
}).Build();
|
}).Build();
|
||||||
|
|
||||||
|
CommandBuilder.Builder("placeCustomBlock", "Places a custom block, needs a custom catalog and assets.")
|
||||||
|
.Action((float x, float y, float z) =>
|
||||||
|
{
|
||||||
|
Logging.CommandLog("Block placed: " +
|
||||||
|
Block.PlaceNew<TestBlock>((BlockIDs) 500, new float3(0, 0, 0)));
|
||||||
|
}).Build();
|
||||||
|
|
||||||
GameClient.SetDebugInfo("InstalledMods", InstalledMods);
|
GameClient.SetDebugInfo("InstalledMods", InstalledMods);
|
||||||
Block.Placed += (sender, args) =>
|
Block.Placed += (sender, args) =>
|
||||||
Logging.MetaDebugLog("Placed block " + args.Type + " with ID " + args.ID);
|
Logging.MetaDebugLog("Placed block " + args.Type + " with ID " + args.ID);
|
||||||
|
@ -356,7 +367,7 @@ namespace GamecraftModdingAPI.Tests
|
||||||
Logging.Log("Compatible GamecraftScripting detected");
|
Logging.Log("Compatible GamecraftScripting detected");
|
||||||
}
|
}
|
||||||
// Interface test
|
// Interface test
|
||||||
/*Interface.IMGUI.Group uiGroup = new Group(new Rect(20, 20, 200, 500), "GamecraftModdingAPI_UITestGroup", true);
|
Interface.IMGUI.Group uiGroup = new Group(new Rect(20, 20, 200, 500), "GamecraftModdingAPI_UITestGroup", true);
|
||||||
Interface.IMGUI.Button button = new Button("TEST");
|
Interface.IMGUI.Button button = new Button("TEST");
|
||||||
button.OnClick += (b, __) => { Logging.MetaDebugLog($"Click on {((Interface.IMGUI.Button)b).Name}");};
|
button.OnClick += (b, __) => { Logging.MetaDebugLog($"Click on {((Interface.IMGUI.Button)b).Name}");};
|
||||||
Interface.IMGUI.Button button2 = new Button("TEST2");
|
Interface.IMGUI.Button button2 = new Button("TEST2");
|
||||||
|
@ -380,7 +391,27 @@ namespace GamecraftModdingAPI.Tests
|
||||||
uiImg.Enabled = true;
|
uiImg.Enabled = true;
|
||||||
Logging.MetaDebugLog($"Got blue bg asset {handle.Result}");
|
Logging.MetaDebugLog($"Got blue bg asset {handle.Result}");
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
|
|
||||||
|
CommandBuilder.Builder("enableCompletions")
|
||||||
|
.Action(() =>
|
||||||
|
{
|
||||||
|
var p = Window.selected.main.parameters;
|
||||||
|
p.useCommandCompletion = true;
|
||||||
|
p.useMonoCompletion = true;
|
||||||
|
p.useGlobalClassCompletion = true;
|
||||||
|
Log.Output("Submitted: " + Window.selected.submittedCode);
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CustomBlock.RegisterCustomBlock<TestBlock>();
|
||||||
|
Logging.MetaDebugLog("Registered test custom block");
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
Logging.MetaDebugLog("Test custom block catalog not found");
|
||||||
|
}
|
||||||
#if TEST
|
#if TEST
|
||||||
TestRoot.RunTests();
|
TestRoot.RunTests();
|
||||||
#endif
|
#endif
|
||||||
|
@ -443,6 +474,18 @@ namespace GamecraftModdingAPI.Tests
|
||||||
return ((Action) MinimumSpecsCheck.CheckRequirementsMet).Method;
|
return ((Action) MinimumSpecsCheck.CheckRequirementsMet).Method;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CustomBlock("customCatalog.json", "Assets/Prefabs/Cube.prefab", "strAluminiumCube", SortIndex = 12)]
|
||||||
|
public class TestBlock : CustomBlock
|
||||||
|
{
|
||||||
|
public TestBlock(EGID id) : base(id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestBlock(uint id) : base(id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,38 +43,22 @@ namespace GamecraftModdingAPI.Utility
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
sound.getParameterValue(key, out float val, out float finalVal);
|
sound.getParameterByName(key, out float val, out float finalVal);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
set => sound.setParameterValue(key, value);
|
set => sound.setParameterByName(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float this[int index]
|
public float this[PARAMETER_ID index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
sound.getParameterValueByIndex(index, out float val, out float finalVal);
|
sound.getParameterByID(index, out float val, out float finalVal);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
set => sound.setParameterValueByIndex(index, value);
|
set => sound.setParameterByID(index, value);
|
||||||
}
|
|
||||||
|
|
||||||
public string[] Parameters
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
sound.getParameterCount(out int count);
|
|
||||||
string[] parameters = new string[count];
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
sound.getParameterByIndex(i, out ParameterInstance param);
|
|
||||||
param.getDescription(out PARAMETER_DESCRIPTION desc);
|
|
||||||
parameters[i] = desc.name;
|
|
||||||
}
|
|
||||||
return parameters;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float3 Position
|
public float3 Position
|
||||||
|
|
Loading…
Reference in a new issue