Exemplo n.º 1
0
        public CommuterChainController GenerateNewCommuterRun(TrainCarsPerLogicTrack consistInfo = null)
        {
            StationController destStation = null;
            Track             startSiding;
            int   nCars;
            float trainLength;
            List <TrainCarType> jobCarTypes;

            if (consistInfo == null)
            {
                // generate a consist
                nCars       = Rand.Next(MIN_CARS_COMMUTE, MAX_CARS_COMMUTE + 1);
                jobCarTypes = PassCarTypes.ChooseMany(Rand, nCars);

                trainLength = TrackOrg.GetTotalCarTypesLength(jobCarTypes) + TrackOrg.GetSeparationLengthBetweenCars(nCars);

                // pick start storage track
                var emptyTracks = TrackOrg.FilterOutOccupiedTracks(StorageTracks);
                startSiding = TrackOrg.GetTrackWithEnoughFreeSpace(emptyTracks, trainLength);

                if (startSiding == null)
                {
                    startSiding = TrackOrg.GetTrackWithEnoughFreeSpace(StorageTracks, trainLength);
                }

                if (startSiding == null)
                {
                    //PassengerJobs.ModEntry.Logger.Log($"No available siding for new job at {Controller.stationInfo.Name}");
                    return(null);
                }
            }
            else
            {
                // use existing consist
                nCars       = consistInfo.cars.Count;
                jobCarTypes = consistInfo.cars.Select(c => c.carType).ToList();
                trainLength = TrackOrg.GetTotalTrainCarsLength(consistInfo.cars) + TrackOrg.GetSeparationLengthBetweenCars(nCars);

                startSiding = consistInfo.track;

                if (startSiding == null)
                {
                    PassengerJobs.ModEntry.Logger.Log("Invalid start siding from parent job");
                    return(null);
                }
            }

            // Try to find a loading platform to use
            PlatformDefinition loadingPlatform = PlatformManager.PickPlatform(Controller.stationInfo.YardID);

            // pick ending storage track
            Track destSiding = null;

            if (!CommuterDestinations.TryGetValue(Controller.stationInfo.YardID, out string[] possibleDestinations))
Exemplo n.º 2
0
        public static JobChainControllerWithEmptyHaulGeneration GenerateShuntingUnloadJobWithExistingCars(
            StationController startingStation,
            Track startingTrack,
            StationController destinationStation,
            List <TrainCar> trainCars,
            List <CargoType> transportedCargoPerCar,
            System.Random rng,
            bool forceCorrectCargoStateOnCars = false)
        {
            Debug.Log("[PersistentJobs] unload: generating with pre-spawned cars");
            YardTracksOrganizer          yto = YardTracksOrganizer.Instance;
            HashSet <CargoContainerType> carContainerTypes = new HashSet <CargoContainerType>();

            foreach (TrainCar trainCar in trainCars)
            {
                carContainerTypes.Add(CargoTypes.CarTypeToContainerType[trainCar.carType]);
            }
            float approxTrainLength = yto.GetTotalTrainCarsLength(trainCars)
                                      + yto.GetSeparationLengthBetweenCars(trainCars.Count);

            // choose warehouse machine
            Debug.Log("[PersistentJobs] unload: choosing warehouse machine");
            List <WarehouseMachineController> supportedWMCs = destinationStation.warehouseMachineControllers
                                                              .Where(wm => wm.supportedCargoTypes.Intersect(transportedCargoPerCar).Count() > 0)
                                                              .ToList();

            if (supportedWMCs.Count == 0)
            {
                Debug.LogWarning(string.Format(
                                     "[PersistentJobs] unload: Could not create ChainJob[{0}]: {1} - {2}. Found no supported WarehouseMachine!",
                                     JobType.ShuntingLoad,
                                     startingStation.logicStation.ID,
                                     destinationStation.logicStation.ID));
                return(null);
            }
            WarehouseMachine loadMachine = Utilities.GetRandomFromEnumerable(supportedWMCs, rng).warehouseMachine;

            // choose destination tracks
            int maxCountTracks = destinationStation.proceduralJobsRuleset.maxShuntingStorageTracks;
            int countTracks    = rng.Next(1, maxCountTracks + 1);

            // bias toward less than max number of tracks for shorter trains
            if (trainCars.Count < 2 * maxCountTracks)
            {
                countTracks = rng.Next(0, Mathf.FloorToInt(1.5f * maxCountTracks)) % maxCountTracks + 1;
            }
            Debug.Log(string.Format("[PersistentJobs] unload: choosing {0} destination tracks", countTracks));
            List <Track> destinationTracks = new List <Track>();

            do
            {
                destinationTracks.Clear();
                for (int i = 0; i < countTracks; i++)
                {
                    Track track = Utilities.GetTrackThatHasEnoughFreeSpace(
                        yto,
                        destinationStation.logicStation.yard.StorageTracks.Except(destinationTracks).ToList(),
                        approxTrainLength / (float)countTracks);
                    if (track == null)
                    {
                        break;
                    }
                    destinationTracks.Add(track);
                }
            } while (destinationTracks.Count < countTracks--);
            if (destinationTracks.Count == 0)
            {
                Debug.LogWarning(string.Format(
                                     "[PersistentJobs] unload: Could not create ChainJob[{0}]: {1} - {2}. " +
                                     "Found no StorageTrack with enough free space!",
                                     JobType.ShuntingUnload,
                                     startingStation.logicStation.ID,
                                     destinationStation.logicStation.ID));
                return(null);
            }

            // divide trainCars between destination tracks
            int countCarsPerTrainset       = trainCars.Count / destinationTracks.Count;
            int countTrainsetsWithExtraCar = trainCars.Count % destinationTracks.Count;

            Debug.Log(string.Format(
                          "[PersistentJobs] unload: dividing trainCars {0} per track with {1} extra",
                          countCarsPerTrainset,
                          countTrainsetsWithExtraCar));
            List <TrainCar>     orderedTrainCars        = new List <TrainCar>();
            List <CarsPerTrack> carsPerDestinationTrack = new List <CarsPerTrack>();

            for (int i = 0; i < destinationTracks.Count; i++)
            {
                int   rangeStart       = i * countCarsPerTrainset + Math.Min(i, countTrainsetsWithExtraCar);
                int   rangeCount       = i < countTrainsetsWithExtraCar ? countCarsPerTrainset + 1 : countCarsPerTrainset;
                Track destinationTrack = destinationTracks[i];
                carsPerDestinationTrack.Add(
                    new CarsPerTrack(
                        destinationTrack,
                        (from car in trainCars.GetRange(rangeStart, rangeCount) select car.logicCar).ToList()));
            }

            Debug.Log("[PersistentJobs] unload: calculating time/wage/licenses");
            float bonusTimeLimit;
            float initialWage;

            Utilities.CalculateShuntingBonusTimeLimitAndWage(
                JobType.ShuntingLoad,
                destinationTracks.Count,
                (from tc in trainCars select tc.carType).ToList <TrainCarType>(),
                transportedCargoPerCar,
                out bonusTimeLimit,
                out initialWage
                );
            JobLicenses requiredLicenses = LicenseManager.GetRequiredLicensesForJobType(JobType.ShuntingUnload)
                                           | LicenseManager.GetRequiredLicensesForCargoTypes(transportedCargoPerCar)
                                           | LicenseManager.GetRequiredLicenseForNumberOfTransportedCars(trainCars.Count);

            return(GenerateShuntingUnloadChainController(
                       startingStation,
                       startingTrack,
                       loadMachine,
                       destinationStation,
                       carsPerDestinationTrack,
                       trainCars,
                       transportedCargoPerCar,
                       trainCars.Select(
                           tc => tc.logicCar.CurrentCargoTypeInCar == CargoType.None ? 1.0f : tc.logicCar.LoadedCargoAmount).ToList(),
                       forceCorrectCargoStateOnCars,
                       bonusTimeLimit,
                       initialWage,
                       requiredLicenses));
        }
Exemplo n.º 3
0
        public static JobChainControllerWithEmptyHaulGeneration GenerateTransportJobWithExistingCars(
            StationController startingStation,
            Track startingTrack,
            StationController destStation,
            List <TrainCar> trainCars,
            List <CargoType> transportedCargoPerCar,
            System.Random rng,
            bool forceCorrectCargoStateOnCars = false)
        {
            Debug.Log("[PersistentJobs] transport: generating with pre-spawned cars");
            YardTracksOrganizer          yto = YardTracksOrganizer.Instance;
            HashSet <CargoContainerType> carContainerTypes = new HashSet <CargoContainerType>();

            foreach (TrainCar trainCar in trainCars)
            {
                carContainerTypes.Add(CargoTypes.CarTypeToContainerType[trainCar.carType]);
            }

            Debug.Log("[PersistentJobs] transport: choosing destination track");
            float approxTrainLength = yto.GetTotalTrainCarsLength(trainCars)
                                      + yto.GetSeparationLengthBetweenCars(trainCars.Count);
            Track destinationTrack = Utilities.GetTrackThatHasEnoughFreeSpace(
                yto,
                yto.FilterOutOccupiedTracks(destStation.logicStation.yard.TransferInTracks),
                approxTrainLength);

            if (destinationTrack == null)
            {
                destinationTrack = Utilities.GetTrackThatHasEnoughFreeSpace(
                    yto,
                    destStation.logicStation.yard.TransferInTracks,
                    approxTrainLength);
            }
            if (destinationTrack == null)
            {
                Debug.LogWarning(string.Format(
                                     "[PersistentJobs] transport: Could not create ChainJob[{0}]: {1} - {2}. " +
                                     "Found no TransferInTrack with enough free space!",
                                     JobType.Transport,
                                     startingStation.logicStation.ID,
                                     destStation.logicStation.ID
                                     ));
                return(null);
            }
            List <TrainCarType> transportedCarTypes = (from tc in trainCars select tc.carType)
                                                      .ToList <TrainCarType>();

            Debug.Log("[PersistentJobs] transport: calculating time/wage/licenses");
            float bonusTimeLimit;
            float initialWage;

            Utilities.CalculateTransportBonusTimeLimitAndWage(
                JobType.Transport,
                startingStation,
                destStation,
                transportedCarTypes,
                transportedCargoPerCar,
                out bonusTimeLimit,
                out initialWage
                );
            JobLicenses requiredLicenses = LicenseManager.GetRequiredLicensesForJobType(JobType.Transport)
                                           | LicenseManager.GetRequiredLicensesForCargoTypes(transportedCargoPerCar)
                                           | LicenseManager.GetRequiredLicenseForNumberOfTransportedCars(trainCars.Count);

            return(TransportJobProceduralGenerator.GenerateTransportChainController(
                       startingStation,
                       startingTrack,
                       destStation,
                       destinationTrack,
                       trainCars,
                       transportedCargoPerCar,
                       trainCars.Select(
                           tc => tc.logicCar.CurrentCargoTypeInCar == CargoType.None ? 1.0f : tc.logicCar.LoadedCargoAmount).ToList(),
                       forceCorrectCargoStateOnCars,
                       bonusTimeLimit,
                       initialWage,
                       requiredLicenses
                       ));
        }
        public static JobChainControllerWithEmptyHaulGeneration GenerateShuntingLoadJobWithExistingCars(
            StationController startingStation,
            List <CarsPerTrack> carsPerStartingTrack,
            StationController destStation,
            List <TrainCar> trainCars,
            List <CargoType> transportedCargoPerCar,
            System.Random rng,
            bool forceCorrectCargoStateOnCars = false)
        {
            Debug.Log("[PersistentJobs] load: generating with pre-spawned cars");
            YardTracksOrganizer          yto = YardTracksOrganizer.Instance;
            HashSet <CargoContainerType> carContainerTypes = new HashSet <CargoContainerType>();

            foreach (TrainCar trainCar in trainCars)
            {
                carContainerTypes.Add(CargoTypes.CarTypeToContainerType[trainCar.carType]);
            }
            float approxTrainLength = yto.GetTotalTrainCarsLength(trainCars)
                                      + yto.GetSeparationLengthBetweenCars(trainCars.Count);

            // choose warehosue machine
            Debug.Log("[PersistentJobs] load: choosing warehouse machine");
            List <WarehouseMachineController> supportedWMCs = startingStation.warehouseMachineControllers
                                                              .Where(wm => wm.supportedCargoTypes.Intersect(transportedCargoPerCar).Count() > 0)
                                                              .ToList();

            if (supportedWMCs.Count == 0)
            {
                Debug.LogWarning(string.Format(
                                     "[PersistentJobs] load: Could not create ChainJob[{0}]: {1} - {2}. Found no supported WarehouseMachine!",
                                     JobType.ShuntingLoad,
                                     startingStation.logicStation.ID,
                                     destStation.logicStation.ID
                                     ));
                return(null);
            }
            WarehouseMachine loadMachine = Utilities.GetRandomFromEnumerable(supportedWMCs, rng).warehouseMachine;

            // choose destination track
            Debug.Log("[PersistentJobs] load: choosing destination track");
            Track destinationTrack = Utilities.GetTrackThatHasEnoughFreeSpace(
                yto,
                yto.FilterOutOccupiedTracks(startingStation.logicStation.yard.TransferOutTracks),
                approxTrainLength
                );

            if (destinationTrack == null)
            {
                destinationTrack = Utilities.GetTrackThatHasEnoughFreeSpace(
                    yto,
                    startingStation.logicStation.yard.TransferOutTracks,
                    approxTrainLength
                    );
            }
            if (destinationTrack == null)
            {
                Debug.LogWarning(string.Format(
                                     "[PersistentJobs] load: Could not create ChainJob[{0}]: {1} - {2}. " +
                                     "Found no TransferOutTrack with enough free space!",
                                     JobType.ShuntingLoad,
                                     startingStation.logicStation.ID,
                                     destStation.logicStation.ID
                                     ));
                return(null);
            }

            Debug.Log("[PersistentJobs] load: calculating time/wage/licenses");
            List <TrainCarType> transportedCarTypes = (from tc in trainCars select tc.carType)
                                                      .ToList <TrainCarType>();
            float bonusTimeLimit;
            float initialWage;

            Utilities.CalculateShuntingBonusTimeLimitAndWage(
                JobType.ShuntingLoad,
                carsPerStartingTrack.Count,
                transportedCarTypes,
                transportedCargoPerCar,
                out bonusTimeLimit,
                out initialWage
                );
            JobLicenses requiredLicenses = LicenseManager.GetRequiredLicensesForJobType(JobType.ShuntingLoad)
                                           | LicenseManager.GetRequiredLicensesForCargoTypes(transportedCargoPerCar)
                                           | LicenseManager.GetRequiredLicenseForNumberOfTransportedCars(trainCars.Count);

            return(GenerateShuntingLoadChainController(
                       startingStation,
                       carsPerStartingTrack,
                       loadMachine,
                       destStation,
                       destinationTrack,
                       trainCars,
                       transportedCargoPerCar,
                       Enumerable.Repeat(1.0f, trainCars.Count).ToList(),
                       forceCorrectCargoStateOnCars,
                       bonusTimeLimit,
                       initialWage,
                       requiredLicenses
                       ));
        }