Add Tweakable stat support
This commit is contained in:
parent
7ac5120ef5
commit
fd98879ccd
6 changed files with 576 additions and 2 deletions
102
GamecraftModdingAPI/Blocks/Tweakable.cs
Normal file
102
GamecraftModdingAPI/Blocks/Tweakable.cs
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Svelto.ECS;
|
||||||
|
|
||||||
|
namespace GamecraftModdingAPI.Blocks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Common tweakable stats operations.
|
||||||
|
/// The functionality of this class works best in build mode.
|
||||||
|
/// </summary>
|
||||||
|
public static class Tweakable
|
||||||
|
{
|
||||||
|
private static TweakableEngine tweakableEngine = new TweakableEngine();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the tweakable stat's value using a dynamic variable type.
|
||||||
|
/// This is similar to GetStat<T> but without strong type enforcement.
|
||||||
|
/// This should be used in dynamically-typed languages like Python.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The stat's value.</returns>
|
||||||
|
/// <param name="blockID">The block's id.</param>
|
||||||
|
/// <param name="stat">The stat's enumerated id.</param>
|
||||||
|
public static dynamic GetStatD(uint blockID, TweakableStat stat)
|
||||||
|
{
|
||||||
|
return tweakableEngine.GetStatDynamic(blockID, stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the tweakable stat's value.
|
||||||
|
/// If T is not the same type as the stat, an InvalidCastException will be thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The stat's value.</returns>
|
||||||
|
/// <param name="blockID">The block's id.</param>
|
||||||
|
/// <param name="stat">The stat's enumerated id.</param>
|
||||||
|
/// <typeparam name="T">The stat's type.</typeparam>
|
||||||
|
public static T GetStat<T>(uint blockID, TweakableStat stat)
|
||||||
|
{
|
||||||
|
return tweakableEngine.GetStatAny<T>(blockID, stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the tweakable stat's value using dynamically-typed variables.
|
||||||
|
/// This is similar to SetStat<T> but without strong type enforcement.
|
||||||
|
/// This should be used in dynamically-typed languages like Python.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The stat's new value.</returns>
|
||||||
|
/// <param name="blockID">The block's id.</param>
|
||||||
|
/// <param name="stat">The stat's enumerated id.</param>
|
||||||
|
/// <param name="value">The stat's new value.</param>
|
||||||
|
public static dynamic SetStatD(uint blockID, TweakableStat stat, dynamic value)
|
||||||
|
{
|
||||||
|
return tweakableEngine.SetStatDynamic(blockID, stat, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the tweakable stat's value.
|
||||||
|
/// If T is not the stat's actual type, an InvalidCastException will be thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The stat's new value.</returns>
|
||||||
|
/// <param name="blockID">The block's id.</param>
|
||||||
|
/// <param name="stat">The stat's enumerated id.</param>
|
||||||
|
/// <param name="value">The stat's new value.</param>
|
||||||
|
/// <typeparam name="T">The stat's type.</typeparam>
|
||||||
|
public static T SetStat<T>(uint blockID, TweakableStat stat, T value)
|
||||||
|
{
|
||||||
|
return tweakableEngine.SetStatAny<T>(blockID, stat, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add another value to the tweakable stat's value using dynamically-typed variables.
|
||||||
|
/// This is similar to AddStat<T> but without strong type enforcement.
|
||||||
|
/// This should be used in dynamically-typed languages like Python.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The stat's new value.</returns>
|
||||||
|
/// <param name="blockID">The block's id.</param>
|
||||||
|
/// <param name="stat">The stat's enumerated id.</param>
|
||||||
|
/// <param name="value">The value to be added to the stat.</param>
|
||||||
|
public static dynamic AddStatD(uint blockID, TweakableStat stat, dynamic value)
|
||||||
|
{
|
||||||
|
return tweakableEngine.AddStatDynamic(blockID, stat, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add another value to the tweakable stat's value.
|
||||||
|
/// If T is not the stat's actual type, an InvalidCastException will be thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The stat's new value.</returns>
|
||||||
|
/// <param name="blockID">The block's id.</param>
|
||||||
|
/// <param name="stat">The stat's enumerated id.</param>
|
||||||
|
/// <param name="value">The value to be added to the stat.</param>
|
||||||
|
/// <typeparam name="T">The stat's type.</typeparam>
|
||||||
|
public static T AddStat<T>(uint blockID, TweakableStat stat, T value)
|
||||||
|
{
|
||||||
|
return tweakableEngine.AddStatAny<T>(blockID, stat, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
GamecraftModdingAPI.Utility.GameEngineManager.AddGameEngine(tweakableEngine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
452
GamecraftModdingAPI/Blocks/TweakableEngine.cs
Normal file
452
GamecraftModdingAPI/Blocks/TweakableEngine.cs
Normal file
|
@ -0,0 +1,452 @@
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
using RobocraftX.Blocks;
|
||||||
|
using Gamecraft.Wires;
|
||||||
|
|
||||||
|
using GamecraftModdingAPI.Utility;
|
||||||
|
using Svelto.ECS;
|
||||||
|
|
||||||
|
namespace GamecraftModdingAPI.Blocks
|
||||||
|
{
|
||||||
|
public class TweakableEngine : IApiEngine
|
||||||
|
{
|
||||||
|
public string Name { get; } = "GamecraftModdingAPITweakableGameEngine";
|
||||||
|
|
||||||
|
public IEntitiesDB entitiesDB { set; private get; }
|
||||||
|
|
||||||
|
public bool IsInGame = false;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
IsInGame = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Ready()
|
||||||
|
{
|
||||||
|
IsInGame = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementations for Tweakable static class
|
||||||
|
|
||||||
|
public T GetStatAny<T>(EGID blockID, TweakableStat stat)
|
||||||
|
{
|
||||||
|
switch (stat)
|
||||||
|
{
|
||||||
|
case TweakableStat.TopSpeed:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return (T)(object)entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxVelocity;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Torque:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return (T)(object)entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxForce;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxExtension:
|
||||||
|
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return (T)(object)entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID).maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MinAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return (T)(object)entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).minDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return (T)(object)entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Reverse:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return (T)(object)entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).reverse;
|
||||||
|
}
|
||||||
|
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return (T)(object)entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).reverse;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.StartValue:
|
||||||
|
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
||||||
|
{
|
||||||
|
return (T)(object)entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID).startValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetStatAny<T>(uint blockID, TweakableStat stat)
|
||||||
|
{
|
||||||
|
return GetStatAny<T>(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public dynamic GetStatDynamic(EGID blockID, TweakableStat stat)
|
||||||
|
{
|
||||||
|
switch (stat)
|
||||||
|
{
|
||||||
|
case TweakableStat.TopSpeed:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxVelocity;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Torque:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxForce;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxExtension:
|
||||||
|
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID).maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MinAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).minDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Reverse:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).reverse;
|
||||||
|
}
|
||||||
|
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
return entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).reverse;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.StartValue:
|
||||||
|
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
||||||
|
{
|
||||||
|
return entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID).startValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public dynamic GetStatDynamic(uint blockID, TweakableStat stat)
|
||||||
|
{
|
||||||
|
return GetStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T SetStatAny<T>(EGID blockID, TweakableStat stat, T value)
|
||||||
|
{
|
||||||
|
switch (stat)
|
||||||
|
{
|
||||||
|
case TweakableStat.TopSpeed:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxVelocity = (float)(object)value;
|
||||||
|
return (T)(object)refStruct.maxVelocity;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Torque:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxForce = (float)(object)value;
|
||||||
|
return (T)(object)refStruct.maxForce;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxExtension:
|
||||||
|
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxDeviation = (float)(object)value;
|
||||||
|
return (T)(object)refStruct.maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MinAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.minDeviation = (float)(object)value;
|
||||||
|
return (T)(object)refStruct.minDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxDeviation = (float)(object)value;
|
||||||
|
return (T)(object)refStruct.maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Reverse:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.reverse = (bool)(object)value;
|
||||||
|
return (T)(object)refStruct.reverse;
|
||||||
|
}
|
||||||
|
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.reverse = (bool)(object)value;
|
||||||
|
return (T)(object)refStruct.reverse;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.StartValue:
|
||||||
|
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
|
||||||
|
refStruct.startValue = (float)(object)value;
|
||||||
|
return (T)(object)refStruct.startValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T SetStatAny<T>(uint blockID, TweakableStat stat, T value)
|
||||||
|
{
|
||||||
|
return SetStatAny<T>(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public dynamic SetStatDynamic(EGID blockID, TweakableStat stat, dynamic value)
|
||||||
|
{
|
||||||
|
switch (stat)
|
||||||
|
{
|
||||||
|
case TweakableStat.TopSpeed:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxVelocity = value;
|
||||||
|
return refStruct.maxVelocity;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Torque:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxForce = value;
|
||||||
|
return refStruct.maxForce;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxExtension:
|
||||||
|
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxDeviation = value;
|
||||||
|
return refStruct.maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MinAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.minDeviation = value;
|
||||||
|
return refStruct.minDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxDeviation = value;
|
||||||
|
return refStruct.maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Reverse:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.reverse = value;
|
||||||
|
return refStruct.reverse;
|
||||||
|
}
|
||||||
|
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.reverse = value;
|
||||||
|
return refStruct.reverse;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.StartValue:
|
||||||
|
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
|
||||||
|
refStruct.startValue = value;
|
||||||
|
return refStruct.startValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public dynamic SetStatDynamic(uint blockID, TweakableStat stat, dynamic value)
|
||||||
|
{
|
||||||
|
return SetStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T AddStatAny<T>(EGID blockID, TweakableStat stat, T value)
|
||||||
|
{
|
||||||
|
switch (stat)
|
||||||
|
{
|
||||||
|
case TweakableStat.TopSpeed:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxVelocity += (float)(object)value;
|
||||||
|
return (T)(object)refStruct.maxVelocity;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Torque:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxForce += (float)(object)value;
|
||||||
|
return (T)(object)refStruct.maxForce;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxExtension:
|
||||||
|
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxDeviation += (float)(object)value;
|
||||||
|
return (T)(object)refStruct.maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MinAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.minDeviation += (float)(object)value;
|
||||||
|
return (T)(object)refStruct.minDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxDeviation += (float)(object)value;
|
||||||
|
return (T)(object)refStruct.maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Reverse:
|
||||||
|
// '+' is associated with logical OR in some fields, so it technically isn't invalid to "add" booleans
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.reverse = refStruct.reverse || (bool)(object)value;
|
||||||
|
return (T)(object)refStruct.reverse;
|
||||||
|
}
|
||||||
|
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.reverse = refStruct.reverse || (bool)(object)value;
|
||||||
|
return (T)(object)refStruct.reverse;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.StartValue:
|
||||||
|
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
|
||||||
|
refStruct.startValue += (float)(object)value;
|
||||||
|
return (T)(object)refStruct.startValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T AddStatAny<T>(uint blockID, TweakableStat stat, T value)
|
||||||
|
{
|
||||||
|
return AddStatAny<T>(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public dynamic AddStatDynamic(EGID blockID, TweakableStat stat, dynamic value)
|
||||||
|
{
|
||||||
|
switch (stat)
|
||||||
|
{
|
||||||
|
case TweakableStat.TopSpeed:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxVelocity += value;
|
||||||
|
return refStruct.maxVelocity;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Torque:
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxForce += value;
|
||||||
|
return refStruct.maxForce;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxExtension:
|
||||||
|
if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxDeviation += value;
|
||||||
|
return refStruct.maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MinAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.minDeviation += value;
|
||||||
|
return refStruct.minDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.MaxAngle:
|
||||||
|
if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.maxDeviation += value;
|
||||||
|
return refStruct.maxDeviation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.Reverse:
|
||||||
|
// '+' is associated with logical OR in some fields, so it technically isn't invalid to "add" booleans
|
||||||
|
if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
|
||||||
|
refStruct.reverse = refStruct.reverse || value;
|
||||||
|
return refStruct.reverse;
|
||||||
|
}
|
||||||
|
else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
|
||||||
|
refStruct.reverse = refStruct.reverse || value;
|
||||||
|
return refStruct.reverse;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TweakableStat.StartValue:
|
||||||
|
if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
|
||||||
|
{
|
||||||
|
ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
|
||||||
|
refStruct.startValue += value;
|
||||||
|
return refStruct.startValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public dynamic AddStatDynamic(uint blockID, TweakableStat stat, dynamic value)
|
||||||
|
{
|
||||||
|
return AddStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
GamecraftModdingAPI/Blocks/TweakableStat.cs
Normal file
14
GamecraftModdingAPI/Blocks/TweakableStat.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
namespace GamecraftModdingAPI.Blocks
|
||||||
|
{
|
||||||
|
public enum TweakableStat
|
||||||
|
{
|
||||||
|
TopSpeed, // MotorReadOnlyStruct
|
||||||
|
Torque, // MotorReadOnlyStruct
|
||||||
|
MaxExtension, // PistonReadOnlyStruct
|
||||||
|
MinAngle, // ServoReadOnlyStruct
|
||||||
|
MaxAngle, // ServoReadOnlyStruct
|
||||||
|
Reverse, // MotorReadOnlyStruct or ServoReadOnlyStruct
|
||||||
|
StartValue, // SignalGeneratorEntityStruct
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,12 +3,16 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net472</TargetFramework>
|
<TargetFramework>net472</TargetFramework>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
<Version>0.1.3.0</Version>
|
<Version>0.1.4.0</Version>
|
||||||
<Authors>Exmods</Authors>
|
<Authors>Exmods</Authors>
|
||||||
<PackageLicenseExpression>GNU General Public Licence 3+</PackageLicenseExpression>
|
<PackageLicenseExpression>GNU General Public Licence 3+</PackageLicenseExpression>
|
||||||
<PackageProjectUrl>https://git.exmods.org/modtainers/GamecraftModdingAPI</PackageProjectUrl>
|
<PackageProjectUrl>https://git.exmods.org/modtainers/GamecraftModdingAPI</PackageProjectUrl>
|
||||||
<NeutralLanguage>en-CA</NeutralLanguage>
|
<NeutralLanguage>en-CA</NeutralLanguage>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Lib.Harmony" Version="1.2.0.1" />
|
<PackageReference Include="Lib.Harmony" Version="1.2.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -543,6 +547,7 @@
|
||||||
<Reference Include="VisualProfiler">
|
<Reference Include="VisualProfiler">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\VisualProfiler.dll</HintPath>
|
<HintPath>..\ref\Gamecraft_Data\Managed\VisualProfiler.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!--End Dependencies-->
|
<!--End Dependencies-->
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ namespace GamecraftModdingAPI
|
||||||
Blocks.Rotation.Init();
|
Blocks.Rotation.Init();
|
||||||
Blocks.Signals.Init();
|
Blocks.Signals.Init();
|
||||||
Blocks.Placement.Init();
|
Blocks.Placement.Init();
|
||||||
|
Blocks.Tweakable.Init();
|
||||||
Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized");
|
Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ PROJECT_NAME = "GamecraftModdingAPI"
|
||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "v0.1.3.0"
|
PROJECT_NUMBER = "v0.1.4.0"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|
Loading…
Reference in a new issue