public static bool Prefix(DieselLocoSimulation __instance, float delta)
            {
                var engineTemp = __instance.engineTemp.value;
                var state      = ExtraState.Instance(__instance);

                SimulateFanThermostats(engineTemp, state);

                var energyInKJ = RawPowerInWatts(__instance) * delta / __instance.timeMult / 1000;
                var heating    = energyInKJ / WaterHeatCapacity / CoolantCapacity;

                if (__instance.engineOn)
                {
                    __instance.engineTemp.AddNextValue(heating);
                }

                var airflowFraction  = state.runningFans == 1 ? 0.75f : state.runningFans == 2 ? 1f : 0.01f;
                var airflow          = airflowFraction * CoolingAirflow;
                var temperatureDelta = __instance.engineTemp.value - AmbientTemperature;
                var cooling          = airflow * temperatureDelta * Main.settings.dieselCoolingMultiplier * delta / __instance.timeMult;

                __instance.engineTemp.AddNextValue(-cooling);

                // Main.DebugLog(TrainCar.Resolve(__instance.gameObject), () => $"power={RawPowerInWatts(__instance)} W, heating={heating / delta * __instance.timeMult} *C/s, cooling={cooling / delta * __instance.timeMult} *C/s, engineTemp={engineTemp}, nextTemp={__instance.engineTemp.nextValue}, runningFans={state.runningFans}");

                return(false);
            }
        public static float RawPowerInWatts(DieselLocoSimulation sim)
        {
            var atIdle      = sim.GetComponent <LocoControllerDiesel>().reverser == 0f || sim.throttle.value == 0;
            var motivePower = atIdle ? 0f : EngineMaxPower *OutputPower(sim.engineRPM.value);

            return(motivePower + IdleUsage);
        }
 public static ExtraState Instance(DieselLocoSimulation sim)
 {
     if (!states.TryGetValue(sim, out var state))
     {
         states[sim] = state = new ExtraState(sim);
     }
     return(state);
 }
            public static bool Prefix(DieselLocoSimulation __instance, float delta)
            {
                if (!__instance.engineOn || __instance.oil.value <= 0.0)
                {
                    return(false);
                }
                var oilUsage = RawPowerInWatts(__instance) * OilConsumption * Main.settings.dieselOilConsumptionMultiplier * delta / __instance.timeMult;

                __instance.oil.AddNextValue(-oilUsage);
                // Main.DebugLog(TrainCar.Resolve(__instance.gameObject), () => $"oil={__instance.oil.value} / {__instance.oil.max}, oilConsumption={oilUsage / (delta / __instance.timeMult) * 3600} Lph, timeToExhaust={__instance.oil.value/(oilUsage/(delta/__instance.timeMult))} s");

                return(false);
            }
            public static bool Prefix(DieselLocoSimulation __instance, float delta)
            {
                if (!__instance.engineOn)
                {
                    return(false);
                }

                var fuelUsage = DieselFuelUsage(RawPowerInWatts(__instance) * (delta / __instance.timeMult)) * Main.settings.dieselFuelConsumptionMultiplier;

                __instance.TotalFuelConsumed += fuelUsage;
                __instance.fuel.AddNextValue(-fuelUsage);
                // Main.DebugLog(TrainCar.Resolve(__instance.gameObject), () => $"fuel={__instance.fuel.value} / {__instance.fuel.max}, fuelConsumption={fuelUsage / (delta / __instance.timeMult) * 3600} Lph, timeToExhaust={__instance.fuel.value/(fuelUsage/(delta/__instance.timeMult))} s");
                return(false);
            }
                public static bool Prefix(DieselLocoSimulation __instance, float delta)
                {
                    var sand     = __instance.sand;
                    var sandFlow = __instance.sandFlow;

                    if ((__instance.sandOn && sand.value > 0.0 && sandFlow.value < sandFlow.max) ||
                        ((!__instance.sandOn || sand.value == 0.0) && sandFlow.value > sandFlow.min))
                    {
                        sandFlow.AddNextValue((!__instance.sandOn || sand.value <= 0.0 ? -1f : 1f) * 10f * delta);
                    }

                    if (sandFlow.value <= 0.0 || sand.value <= 0.0)
                    {
                        return(false);
                    }
                    sand.AddNextValue(-sandFlow.value * SandingRate * delta / __instance.timeMult);
                    return(false);
                }
            public static bool Prefix(DieselLocoSimulation __instance)
            {
                // var loco = TrainCar.Resolve(__instance.gameObject);
                if (PausePhysicsHandler.PhysicsHandlingInProcess)
                {
                    return(false);
                }

                var throttleVelo = __instance.throttleToTargetDiff.value;
                var nextRPM      = Mathf.SmoothDamp(
                    current: __instance.engineRPM.value,
                    target: TargetRPM(__instance.throttle.value),
                    currentVelocity: ref throttleVelo,
                    smoothTime: 1f,
                    maxSpeed: 1f);

                __instance.throttleToTargetDiff.SetNextValue(throttleVelo);
                __instance.engineRPM.SetNextValue(nextRPM);
                // Main.DebugLog(loco, $"{loco.ID}: throttle={__instance.throttle.value}, RPM={__instance.engineRPM.value}, velo={throttleVelo}");

                var state = ExtraState.Instance(__instance);

                state.CheckTransition();
                var speedMetersPerSecond = __instance.speed.value / 3.6f;
                var powerOutput          = (state.InTransition() || __instance.throttle.value == 0f) ? 0f :
                                           EngineMaxPower *TransmissionEfficiency *OutputPower(__instance.engineRPM.value);

                var target = powerOutput / Mathf.Max(1f, speedMetersPerSecond);

                state.tractiveEffort = Mathf.SmoothDamp(
                    state.tractiveEffort,
                    target,
                    ref state.tractiveEffortVelo,
                    0.5f);

                // Main.DebugLog(loco, () => $"engineRPM={__instance.engineRPM.value}, speed={speedMetersPerSecond}, target={target}, TE={state.tractiveEffort}");

                return(false);
            }
Exemple #8
0
        public static LocoAI GetLocoAI(TrainCar car)
        {
            LocoAI locoAI;

            if (!locosAI.TryGetValue(car.logicCar.ID, out locoAI))
            {
                DieselLocoSimulation dieselSim = car.GetComponent <DieselLocoSimulation>();
                if (dieselSim != null)
                {
                    if (!dieselSim.engineOn)
                    {
                        throw new CommandException("Engine off");
                    }
                }
                else
                {
                    ShunterLocoSimulation shunterSim = car.GetComponent <ShunterLocoSimulation>();
                    if (shunterSim != null)
                    {
                        if (!shunterSim.engineOn)
                        {
                            throw new CommandException("Engine off");
                        }
                    }
                    else
                    {
                        throw new CommandException("Loco not compatible");
                    }
                }

                LocoControllerShunter    shunterController = car.GetComponent <LocoControllerShunter>();
                ILocomotiveRemoteControl remote            = car.GetComponent <ILocomotiveRemoteControl>();
                locoAI = new LocoAI(remote);
                locosAI.Add(car.logicCar.ID, locoAI);
            }

            return(locoAI);
        }
            public static void Postfix(DieselLocoSimulation __instance)
            {
                var car = TrainCar.Resolve(__instance.gameObject);

                car.brakeSystem.compressorProductionRate = (1 + (__instance.engineRPM.value * 825f / 275f)) * BaseRate;
            }
Exemple #10
0
 public ExtraState(DieselLocoSimulation sim)
 {
     this.sim = sim;
 }
Exemple #11
0
 public static void Postfix(DieselLocoSimulation __instance)
 {
     __instance.sand.max = __instance.sand.value = SandCapacity;
 }