using System; using System.Reflection; using RobocraftX.Blocks; using Gamecraft.Wires; using Svelto.ECS; using GamecraftModdingAPI.Utility; using GamecraftModdingAPI.Engines; namespace GamecraftModdingAPI.Blocks { public class TweakableEngine : IApiEngine { public string Name { get; } = "GamecraftModdingAPITweakableGameEngine"; public EntitiesDB entitiesDB { set; private get; } public bool isRemovable => false; public bool IsInGame = false; public void Dispose() { IsInGame = false; } public void Ready() { IsInGame = true; } // Implementations for Tweakable static class public T GetStatAny(EGID blockID, TweakableStat stat) { switch (stat) { case TweakableStat.TopSpeed: if (entitiesDB.Exists(blockID)) { return (T)(object)entitiesDB.QueryEntity(blockID).maxVelocity; } break; case TweakableStat.Torque: if (entitiesDB.Exists(blockID)) { return (T)(object)entitiesDB.QueryEntity(blockID).maxForce; } break; case TweakableStat.MaxExtension: if (entitiesDB.Exists(blockID)) { return (T)(object)entitiesDB.QueryEntity(blockID).maxDeviation; } break; case TweakableStat.MinAngle: if (entitiesDB.Exists(blockID)) { return (T)(object)entitiesDB.QueryEntity(blockID).minDeviation; } break; case TweakableStat.MaxAngle: if (entitiesDB.Exists(blockID)) { return (T)(object)entitiesDB.QueryEntity(blockID).maxDeviation; } break; case TweakableStat.Reverse: if (entitiesDB.Exists(blockID)) { return (T)(object)entitiesDB.QueryEntity(blockID).reverse; } else if (entitiesDB.Exists(blockID)) { return (T)(object)entitiesDB.QueryEntity(blockID).reverse; } break; case TweakableStat.StartValue: if (entitiesDB.Exists(blockID)) { return (T)(object)entitiesDB.QueryEntity(blockID).startValue; } break; } return default(T); } public T GetStatAny(uint blockID, TweakableStat stat) { return GetStatAny(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat); } public dynamic GetStatDynamic(EGID blockID, TweakableStat stat) { switch (stat) { case TweakableStat.TopSpeed: if (entitiesDB.Exists(blockID)) { return entitiesDB.QueryEntity(blockID).maxVelocity; } break; case TweakableStat.Torque: if (entitiesDB.Exists(blockID)) { return entitiesDB.QueryEntity(blockID).maxForce; } break; case TweakableStat.MaxExtension: if (entitiesDB.Exists(blockID)) { return entitiesDB.QueryEntity(blockID).maxDeviation; } break; case TweakableStat.MinAngle: if (entitiesDB.Exists(blockID)) { return entitiesDB.QueryEntity(blockID).minDeviation; } break; case TweakableStat.MaxAngle: if (entitiesDB.Exists(blockID)) { return entitiesDB.QueryEntity(blockID).maxDeviation; } break; case TweakableStat.Reverse: if (entitiesDB.Exists(blockID)) { return entitiesDB.QueryEntity(blockID).reverse; } else if (entitiesDB.Exists(blockID)) { return entitiesDB.QueryEntity(blockID).reverse; } break; case TweakableStat.StartValue: if (entitiesDB.Exists(blockID)) { return entitiesDB.QueryEntity(blockID).startValue; } break; } return null; } public dynamic GetStatDynamic(uint blockID, TweakableStat stat) { return GetStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat); } public T SetStatAny(EGID blockID, TweakableStat stat, T value) { switch (stat) { case TweakableStat.TopSpeed: if (entitiesDB.Exists(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxVelocity = (float)(object)value; return (T)(object)refStruct.maxVelocity; } break; case TweakableStat.Torque: if (entitiesDB.Exists(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxForce = (float)(object)value; return (T)(object)refStruct.maxForce; } break; case TweakableStat.MaxExtension: if (entitiesDB.Exists(blockID)) { ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxDeviation = (float)(object)value; return (T)(object)refStruct.maxDeviation; } break; case TweakableStat.MinAngle: if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.minDeviation = (float)(object)value; return (T)(object)refStruct.minDeviation; } break; case TweakableStat.MaxAngle: if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxDeviation = (float)(object)value; return (T)(object)refStruct.maxDeviation; } break; case TweakableStat.Reverse: if (entitiesDB.Exists(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.reverse = (bool)(object)value; return (T)(object)refStruct.reverse; } else if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.reverse = (bool)(object)value; return (T)(object)refStruct.reverse; } break; case TweakableStat.StartValue: if (entitiesDB.Exists(blockID)) { ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.startValue = (float)(object)value; return (T)(object)refStruct.startValue; } break; } return default(T); } public T SetStatAny(uint blockID, TweakableStat stat, T value) { return SetStatAny(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(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxVelocity = value; return refStruct.maxVelocity; } break; case TweakableStat.Torque: if (entitiesDB.Exists(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxForce = value; return refStruct.maxForce; } break; case TweakableStat.MaxExtension: if (entitiesDB.Exists(blockID)) { ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxDeviation = value; return refStruct.maxDeviation; } break; case TweakableStat.MinAngle: if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.minDeviation = value; return refStruct.minDeviation; } break; case TweakableStat.MaxAngle: if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxDeviation = value; return refStruct.maxDeviation; } break; case TweakableStat.Reverse: if (entitiesDB.Exists(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.reverse = value; return refStruct.reverse; } else if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.reverse = value; return refStruct.reverse; } break; case TweakableStat.StartValue: if (entitiesDB.Exists(blockID)) { ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(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(EGID blockID, TweakableStat stat, T value) { switch (stat) { case TweakableStat.TopSpeed: if (entitiesDB.Exists(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxVelocity += (float)(object)value; return (T)(object)refStruct.maxVelocity; } break; case TweakableStat.Torque: if (entitiesDB.Exists(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxForce += (float)(object)value; return (T)(object)refStruct.maxForce; } break; case TweakableStat.MaxExtension: if (entitiesDB.Exists(blockID)) { ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxDeviation += (float)(object)value; return (T)(object)refStruct.maxDeviation; } break; case TweakableStat.MinAngle: if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.minDeviation += (float)(object)value; return (T)(object)refStruct.minDeviation; } break; case TweakableStat.MaxAngle: if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(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(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.reverse = refStruct.reverse || (bool)(object)value; return (T)(object)refStruct.reverse; } else if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.reverse = refStruct.reverse || (bool)(object)value; return (T)(object)refStruct.reverse; } break; case TweakableStat.StartValue: if (entitiesDB.Exists(blockID)) { ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.startValue += (float)(object)value; return (T)(object)refStruct.startValue; } break; } return default(T); } public T AddStatAny(uint blockID, TweakableStat stat, T value) { return AddStatAny(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(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxVelocity += value; return refStruct.maxVelocity; } break; case TweakableStat.Torque: if (entitiesDB.Exists(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxForce += value; return refStruct.maxForce; } break; case TweakableStat.MaxExtension: if (entitiesDB.Exists(blockID)) { ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.maxDeviation += value; return refStruct.maxDeviation; } break; case TweakableStat.MinAngle: if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.minDeviation += value; return refStruct.minDeviation; } break; case TweakableStat.MaxAngle: if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(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(blockID)) { ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.reverse = refStruct.reverse || value; return refStruct.reverse; } else if (entitiesDB.Exists(blockID)) { ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); refStruct.reverse = refStruct.reverse || value; return refStruct.reverse; } break; case TweakableStat.StartValue: if (entitiesDB.Exists(blockID)) { ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(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); } } }