private void OnJobChainCompleted(JobChainController chainController) { Chain chain = jobChains.FirstOrDefault(c => c.Controller == chainController); chain.IsCompleted = true; SendChainCompleted(chain.Id); }
private static StaticPassengerJobDefinition PopulateTransportJobAndSpawn( JobChainController chainController, Station startStation, Track startTrack, Track destTrack, List <TrainCarType> carTypes, StationsChainData chainData, float timeLimit, float initialPay, bool unifyConsist = false) { // Spawn the cars RailTrack startRT = SingletonBehaviour <LogicController> .Instance.LogicToRailTrack[startTrack]; var spawnedCars = CarSpawner.SpawnCarTypesOnTrack(carTypes, startRT, true, 0, false, true); if (spawnedCars == null) { return(null); } chainController.trainCarsForJobChain = spawnedCars; var logicCars = TrainCar.ExtractLogicCars(spawnedCars); if (logicCars == null) { PassengerJobs.ModEntry.Logger.Error("Couldn't extract logic cars, deleting spawned cars"); SingletonBehaviour <CarSpawner> .Instance.DeleteTrainCars(spawnedCars, true); return(null); } if (unifyConsist && SkinManager_Patch.Enabled) { SkinManager_Patch.UnifyConsist(spawnedCars); } return(PopulateTransportJobExistingCars(chainController, startStation, startTrack, destTrack, logicCars, chainData, timeLimit, initialPay)); }
// taken from JobChainControllerWithEmptyHaulGeneration.ExtractCorrespondingTrainCars public static List <TrainCar> ExtractCorrespondingTrainCars(JobChainController context, List <Car> logicCars) { if (logicCars == null || logicCars.Count == 0) { return(null); } List <TrainCar> list = new List <TrainCar>(); for (int i = 0; i < logicCars.Count; i++) { for (int j = 0; j < context.trainCarsForJobChain.Count; j++) { if (context.trainCarsForJobChain[j].logicCar == logicCars[i]) { list.Add(context.trainCarsForJobChain[j]); break; } } } if (list.Count != logicCars.Count) { return(null); } return(list); }
private void OnJobInChainExpired(JobChainController chainController) { chainController.JobOfChainExpired -= OnJobInChainExpired; Chain chain = jobChains.FirstOrDefault(c => c.Controller == chainController); chain.IsExpired = true; SendChainExpired(chain.Id); }
internal void OnSingleChainGenerated(JobChainController chain) { Main.Log("Single Chain with existing cars generated"); SingletonBehaviour <NetworkTrainManager> .Instance.SendNewJobChainCars(chain.trainCarsForJobChain); currentChains.Add(chain); OnJobsGenerated?.Invoke(station, new JobChainController[] { chain }); }
private static void Postfix(JobChainController __result, StationController startingStation, Track startingTrack, List <TrainCar> transportedTrainCars, System.Random rng) { if (NetworkManager.IsClient() && NetworkManager.IsHost() && SingletonBehaviour <NetworkJobsManager> .Instance) { SingletonBehaviour <NetworkJobsManager> .Instance.newlyGeneratedJobChains.Add(__result); SingletonBehaviour <NetworkJobsManager> .Instance.newlyGeneratedJobChainStation = startingStation; } }
static void Prefix(JobChainController __instance) { if ((__instance is PassengerTransportChainController) || (__instance is CommuterChainController)) { // force deletion of cars instead of leaving them for the unused car deleter SingletonBehaviour <CarSpawner> .Instance.DeleteTrainCars(__instance.trainCarsForJobChain, true); __instance.trainCarsForJobChain.Clear(); } }
static void Postfix(JobChainController __instance, ref JobChainSaveData __result) { if (__instance is PassengerTransportChainController) { __result = new PassengerChainSaveData(PassengerChainSaveData.PassChainType.Transport, __result); } else if (__instance is CommuterChainController) { __result = new PassengerChainSaveData(PassengerChainSaveData.PassChainType.Commuter, __result); } }
static bool Prefix(JobChainSaveData chainSaveData, ref GameObject __result) { if (chainSaveData.jobChainData.Length < 1) { return(true); } JobChainController chainController = null; if (chainSaveData is PassengerChainSaveData passChainData) { chainController = CreateSavedJobChain(passChainData); } else { var firstJobData = chainSaveData.jobChainData.First(); if (((JobLicenses)firstJobData.requiredLicenses).HasFlag(PassLicenses.Passengers1)) { DeleteOldChain(chainSaveData); } else { return(true); // pass to base game } } if (chainController == null) { return(false); } chainController.FinalizeSetupAndGenerateFirstJob(true); if (chainSaveData.jobTaken) { PlayerJobs.Instance.TakeJob(chainController.currentJobInChain, true); if (chainSaveData.currentJobTaskData != null) { chainController.currentJobInChain.OverrideTasksStates(chainSaveData.currentJobTaskData); } else { PrintError("Job from chain was taken, but there is no task data! Task data won't be loaded!"); } InitializeCorrespondingJobBooklet(chainController.currentJobInChain); } PassengerJobs.ModEntry.Logger.Log($"Successfully loaded job chain: {chainController.jobChainGO.name}"); __result = chainController.jobChainGO; return(false); }
private static StaticPassengerJobDefinition PopulateTransportJobExistingCars( JobChainController chainController, Station startStation, Track startTrack, Track destTrack, List <Car> logicCars, StationsChainData chainData, float timeLimit, float initialPay) { // populate the actual job StaticPassengerJobDefinition jobDefinition = chainController.jobChainGO.AddComponent <StaticPassengerJobDefinition>(); jobDefinition.PopulateBaseJobDefinition(startStation, timeLimit, initialPay, chainData, PassLicenses.Passengers1); jobDefinition.startingTrack = startTrack; jobDefinition.trainCarsToTransport = logicCars; jobDefinition.destinationTrack = destTrack; return(jobDefinition); }
private IEnumerable <CarGroup> GetCarGroups(IEnumerable <TrainCar> cars, bool individual) { Job? prevJob = null; Track?prevDestTrack = null; int startIndex = 0; float maxStress = 0f; var firstCar = cars.First(); var groupCars = new List <TrainCar>() { firstCar }; float minBrakePipePressure = firstCar.brakeSystem.brakePipePressure; float minBrakeReservoirPressure = GetAuxReservoirPressure(firstCar); float maxBrakeCylinderPressure = GetBrakeCylinderPressure(firstCar); float maxBrakeFactor = firstCar.brakeSystem.brakingFactor; int i = 0; foreach (var car in cars) { float carStress = car.GetComponent <TrainStress>().derailBuildUp; Job? job = JobChainController.GetJobOfCar(car); Track? nextDestination = GetNextDestinationTrack(job, car.logicCar); BrakeSystem brakeSystem = car.brakeSystem; float pipePressure = brakeSystem.brakePipePressure; float auxReservoirPressure = GetAuxReservoirPressure(car); float brakeCylinderPressure = GetBrakeCylinderPressure(car); if (individual || nextDestination == null || nextDestination != prevDestTrack || job != prevJob) { // complete previous group if (i > 0) { yield return(new CarGroup( startIndex, i, groupCars, maxStress, prevJob, prevDestTrack, minBrakePipePressure, minBrakeReservoirPressure, maxBrakeCylinderPressure, maxBrakeFactor)); } // start new group startIndex = i; groupCars = new List <TrainCar>() { car }; prevJob = job; prevDestTrack = nextDestination; maxStress = carStress; minBrakePipePressure = pipePressure; minBrakeReservoirPressure = auxReservoirPressure; maxBrakeCylinderPressure = brakeCylinderPressure; maxBrakeFactor = brakeSystem.brakingFactor; } else { groupCars.Add(car); if (carStress > maxStress) { maxStress = carStress; } if (pipePressure < minBrakePipePressure) { minBrakeReservoirPressure = auxReservoirPressure; } if (auxReservoirPressure < minBrakeReservoirPressure) { minBrakeReservoirPressure = auxReservoirPressure; } if (brakeCylinderPressure > maxBrakeCylinderPressure) { maxBrakeCylinderPressure = brakeCylinderPressure; } if (brakeSystem.brakingFactor > maxBrakeFactor) { maxBrakeFactor = brakeSystem.brakingFactor; } } i++; } // complete last group yield return(new CarGroup( startIndex, i, groupCars, maxStress, prevJob, prevDestTrack, minBrakePipePressure, minBrakeReservoirPressure, maxBrakeCylinderPressure, maxBrakeFactor)); }
internal void OnSingleChainGeneratedWithExistingCars(JobChainController chain) { Main.Log("Single Chain with existing cars generated"); currentChains.Add(chain); OnJobsGenerated?.Invoke(station, new JobChainController[] { chain }); }
private static bool Prefix(TrainCar __instance, ref Vector3 ___prevAbsoluteWorldPosition, ref int ___stationaryFramesCounter, Action <bool> ___MovementStateChanged) { if (NetworkManager.IsClient()) { if (AppUtil.IsPaused) { return(true); } if (NumberUtil.AnyInfinityMinMaxNaN(__instance.transform.position) || __instance.transform.position.y < -500f) { Debug.LogWarning(string.Format("Car '{0}' fell through the ground (y: {1}) and will be deleted!", __instance.name, __instance.transform.position.y)); Job jobOfCar = JobChainController.GetJobOfCar(__instance); if (jobOfCar != null) { JobState state = jobOfCar.State; if (state != JobState.Available) { if (state != JobState.InProgress) { Debug.LogError(string.Format("Unexpected state {0}, ignoring force abandon/expire!", jobOfCar.State)); } else { PlayerJobs.Instance.AbandonJob(jobOfCar); } } else { jobOfCar.ExpireJob(); } } CarSpawner.DeleteCar(__instance); SingletonBehaviour <UnusedTrainCarDeleter> .Instance.ClearInvalidCarReferencesAfterManualDelete(); } Vector3 a = __instance.transform.position - WorldMover.currentMove; if ((a - ___prevAbsoluteWorldPosition).sqrMagnitude > 0.0001f) { ___prevAbsoluteWorldPosition = a; ___stationaryFramesCounter = 0; if (__instance.isStationary) { ___MovementStateChanged?.Invoke(true); } __instance.isStationary = (__instance.isEligibleForSleep = false); return(false); } if (!__instance.isEligibleForSleep || !__instance.isStationary) { if (___stationaryFramesCounter < 100) { ___stationaryFramesCounter++; return(false); } if (___stationaryFramesCounter >= 100) { ___stationaryFramesCounter = 0; if (!__instance.isStationary) { ___MovementStateChanged?.Invoke(false); } __instance.isEligibleForSleep = (__instance.isStationary = true); } } } return(true); }