예제 #1
0
        public static float RawPowerInWatts(ShunterLocoSimulation sim)
        {
            // 30 kW to run accessories
            var accessoryPower = (0.1f + sim.engineRPM.value) * 30e3f;

            return(CrankshaftPower(sim) + accessoryPower);
        }
예제 #2
0
 static void Postfix(ShunterLocoSimulation __instance, ref float __result)
 {
     if (Main.isFanOn)
     {
         __result *= 1f - Main.POWER_LOSS;
     }
 }
예제 #3
0
        public static float CrankshaftPower(ShunterLocoSimulation sim)
        {
            var atIdle = sim.GetComponent <LocoControllerShunter>().reverser == 0f || sim.throttle.value == 0;
            var power  = atIdle ? 0f : EngineMaxPower *Mathf.Pow(sim.engineRPM.value, ThrottleGamma);

            return(power);
        }
예제 #4
0
파일: Main.cs 프로젝트: xZise/FanService
 static void Postfix(LocoControllerBase __instance)
 {
     if (__instance is LocoControllerShunter)
     {
         ShunterLocoSimulation sim = (ShunterLocoSimulation)Helper.Get(__instance, "sim");
         LocoControllerShunter_Awake_Patch.dict.Remove(sim);
     }
 }
예제 #5
0
 public static ExtraState Instance(ShunterLocoSimulation sim)
 {
     if (!states.TryGetValue(sim, out var state))
     {
         states[sim] = state = new ExtraState(sim.GetComponent <LocoControllerShunter>());
     }
     return(state);
 }
예제 #6
0
 private static bool Prefix(ShunterLocoSimulation __instance)
 {
     if (NetworkManager.IsClient())
     {
         NetworkTrainPosSync networking = __instance.GetComponent <NetworkTrainPosSync>();
         if (networking)
         {
             return(networking.hasLocalPlayerAuthority);
         }
     }
     return(true);
 }
예제 #7
0
        static void Postfix(ShunterLocoSimulation __instance, float delta)
        {
            if (!__instance.engineOn || __instance.fuel.value <= 0.0f)
            {
                return;
            }

            if (Main.isFanOn)
            {
                __instance.fuel.AddNextValue(Mathf.Lerp(0.025f, 1f, __instance.engineRPM.value) * -Main.FUEL_CONSUMPTION * delta);
            }
        }
예제 #8
0
        static void Postfix(ShunterLocoSimulation __instance, float delta)
        {
            if (!__instance.engineOn || __instance.engineTemp.value <= 45f)
            {
                return;
            }

            if (Main.isFanOn)
            {
                __instance.engineTemp.AddNextValue(-Main.FAN_COOL * delta);
            }
        }
    //private TrainAudio trainAudio;
    //private BogieAudioController[] bogieAudios;

#pragma warning disable IDE0051 // Remove unused private members
    private void Awake()
    {
        Main.Log($"NetworkTrainPosSync.Awake()");
        trainCar = GetComponent <TrainCar>();

        //bogieAudios = new BogieAudioController[trainCar.Bogies.Length];

        Main.Log($"[{trainCar.ID}] NetworkTrainPosSync Awake called");

        Main.Log($"Listening to derailment/rerail events");
        trainCar.OnDerailed += TrainDerail;
        trainCar.OnRerailed += TrainRerail;
        localPlayer          = SingletonBehaviour <NetworkPlayerManager> .Instance.GetLocalPlayerSync();

        isStationary = trainCar.isStationary;

        Main.Log($"Listening to movement changed event");
        trainCar.MovementStateChanged += TrainCar_MovementStateChanged;
        trainCar.CarDamage.CarEffectiveHealthStateUpdate += OnBodyDamageTaken;
        if (!trainCar.IsLoco)
        {
            trainCar.CargoDamage.CargoDamaged += OnCargoDamageTaken;
        }


        if (trainCar.carType == TrainCarType.LocoShunter)
        {
            shunterLocoSimulation = GetComponent <ShunterLocoSimulation>();
            shunterExhaust        = trainCar.transform.Find("[particles]").Find("ExhaustEngineSmoke").GetComponent <ParticleSystem>().main;
        }

        if (!trainCar.IsLoco)
        {
            trainCar.CargoLoaded   += OnCargoLoaded;
            trainCar.CargoUnloaded += OnCargoUnloaded;
        }

        //for(int i = 0; i < trainCar.Bogies.Length; i++)
        //{
        //    bogieAudios[i] = trainCar.Bogies[i].GetComponent<BogieAudioController>();
        //}

        if (NetworkManager.IsHost())
        {
            trainCar.TrainsetChanged += TrainCar_TrainsetChanged;
            SetAuthority(true);
        }
        else
        {
            SetAuthority(false);
        }
    }
예제 #10
0
        public static bool Prefix(ShunterLocoSimulation __instance, float delta)
        {
            if (!__instance.engineOn || __instance.oil.value <= 0.0)
            {
                return(false);
            }
            var oilUsage = ShunterPower.RawPowerInWatts(__instance) * OilConsumption * Main.settings.shunterOilConsumptionMultiplier * 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);
        }
예제 #11
0
            public static bool Prefix(ShunterLocoSimulation __instance)
            {
                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);
                return(false);
            }
예제 #12
0
        public static bool Prefix(ShunterLocoSimulation __instance, float delta)
        {
            if (!__instance.engineOn)
            {
                return(false);
            }
            var fuelUsage = DieselFuelUsage(ShunterPower.RawPowerInWatts(__instance)) * Main.settings.shunterFuelConsumptionMultiplier *
                            (delta / __instance.timeMult);

            __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);
        }
예제 #13
0
        public MainWindow()
        {
            _shunterLocoSimulation = new ShunterLocoSimulation();
            _trainSimulation       = new TrainSimulation(_shunterLocoSimulation);
            InitializeComponent();

            var soundMixer = new MixingWaveProvider32();

            InitializeSounds(soundMixer);

            _waveOut.Init(soundMixer);
            _waveOut.Volume = 1.0f;

            DispatcherTimer timer = new DispatcherTimer();

            timer.Interval = TimeSpan.FromSeconds(TimerInterval);
            timer.Tick    += timer_Tick;
            timer.Start();
            _waveOut.Play();
        }
예제 #14
0
파일: Main.cs 프로젝트: xZise/FanService
        static bool Prefix(ShunterLocoSimulation __instance, float delta)
        {
            if (__instance.engineOn)
            {
                if (__instance.engineRPM.value > 0f)
                {
                    __instance.engineTemp.AddNextValue(__instance.engineRPM.value * 12f * delta);
                }
                if (__instance.engineTemp.value < IdleTemp)
                {
                    __instance.engineTemp.AddNextValue(5f * delta);
                }
            }
            if (__instance.engineTemp.value <= __instance.engineTemp.min)
            {
                return(false);
            }
            __instance.engineTemp.AddNextValue(-3f * delta);

            // Here are the changes:
            // If the fan is on, it's like the speed is at least 30 km/h
            float speed = 0f;
            bool  fanOn = LocoControllerShunter_Awake_Patch.dict[__instance].GetFan();

            if (fanOn)
            {
                speed = 30f;
            }

            if (__instance.goingForward && __instance.engineTemp.value > IdleTemp)
            {
                speed = Mathf.Max(speed, __instance.speed.value);
            }
            if (speed > 0f)
            {
                __instance.engineTemp.AddNextValue(-1f * (speed / __instance.speed.max) * 4f * delta);
            }
            return(false);
        }
예제 #15
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);
        }
예제 #16
0
            public static bool Prefix(ShunterLocoSimulation __instance, float delta)
            {
                var heating = Mathf.Lerp(0.025f, 1f, __instance.engineRPM.value) * 12f;

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

                var fanRunning     = ExtraState.Instance(__instance).UpdateFan();
                var thermostatOpen = __instance.engineTemp.value >= ThermostatTemp;
                var airflow        =
                    !thermostatOpen ? NoRadiatorSpeedEquivalent :
                    fanRunning && __instance.speed.value < CoolingFanSpeedEquivalent ? CoolingFanSpeedEquivalent :
                    __instance.speed.value;
                var temperatureDelta = __instance.engineTemp.value - AmbientTemperature;
                var cooling          = airflow / CoolingFanSpeedEquivalent * temperatureDelta * Main.settings.shunterTemperatureMultiplier;

                __instance.engineTemp.AddNextValue(-cooling * delta);
                //Main.DebugLog(car, () => $"{car.ID}: RPM={__instance.engineRPM.value}, temp={__instance.engineTemp.value}, nextTemp={__instance.engineTemp.nextValue}, heating={heating}, airflow={airflow}, cooling={cooling}");

                return(false);
            }
예제 #17
0
            public static void Postfix(ShunterLocoSimulation __instance)
            {
                var car = TrainCar.Resolve(__instance.gameObject);

                car.brakeSystem.compressorProductionRate = (1 + (__instance.engineRPM.value * 2100f / 1250f)) * BaseRate;
            }
예제 #18
0
 public LocoShunter(LocoControllerShunter inner)
 {
     _inner = inner;
     _base  = new LocoBase(inner);
     _sim   = inner.GetComponent <ShunterLocoSimulation>();
 }
예제 #19
0
파일: Main.cs 프로젝트: xZise/FanService
        static void Postfix(LocoControllerShunter __instance)
        {
            ShunterLocoSimulation sim = (ShunterLocoSimulation)Helper.Get(__instance, "sim");

            dict.Add(sim, __instance);
        }
예제 #20
0
 public static bool IsFanRunning(ShunterLocoSimulation sim)
 {
     return(ExtraState.Instance(sim).fanRunning);
 }