예제 #1
0
        static void Postfix(LocoControllerSteam __instance, float position)
        {
            TrainCar currentCar = __instance.GetComponent <TrainCar>();
            TrainCar targetCar  = null;
            Trainset trainset   = null;

            if (PlayerManager.Car != null && PlayerManager.Car.trainset != null)
            {
                targetCar = PlayerManager.Car;
                trainset  = PlayerManager.Car.trainset;
            }

            if (currentCar == null || targetCar == null || !targetCar.Equals(currentCar) || trainset == null || trainset.cars.Count < 2)
            {
                return;
            }

            List <TrainCar> trainsetCars = trainset.cars;

            for (int i = 0; i < trainsetCars.Count; i++)
            {
                TrainCar car = trainsetCars[i];

                if (targetCar.Equals(car))
                {
                    continue;
                }

                if (car.carType == TrainCarType.LocoSteamHeavy)
                {
                    LocoControllerSteam steamController = car.GetComponent <LocoControllerSteam>();

                    if (steamController)
                    {
                        if (GetCarsBehind(PlayerManager.Car).Contains(car))
                        {
                            if (GetCarsInFrontOf(car).Contains(PlayerManager.Car))
                            {
                                steamController.SetReverser(position);
                            }
                            else
                            {
                                steamController.SetReverser(position * -1f);
                            }
                        }
                        else if (GetCarsInFrontOf(PlayerManager.Car).Contains(car))
                        {
                            if (GetCarsBehind(car).Contains(PlayerManager.Car))
                            {
                                steamController.SetReverser(position);
                            }
                            else
                            {
                                steamController.SetReverser(position * -1f);
                            }
                        }
                    }
                }
            }
        }
    private void TrainCar_TrainsetChanged(Trainset set)
    {
        if (isBeingDestroyed || set == null || set.firstCar == null || trainCar.logicCar == null || !trainCar)
        {
            return;
        }
        //Issue with trainset being detatched in the middle positioning not updating correctly.
        if (set.locoIndices.Count == 0 && set.firstCar == trainCar)
        {
            StartCoroutine(ResetAuthorityToHostWhenStationary(set));
        }
        else
        {
            CheckAuthorityChange();
        }

        if (!Trainset.allSets.Contains(tempFrontTrainsetWithAuthority))
        {
            tempFrontTrainsetWithAuthority = null;
        }

        if (!Trainset.allSets.Contains(tempRearTrainsetWithAuthority))
        {
            tempRearTrainsetWithAuthority = null;
        }
    }
예제 #3
0
        public static RouteTask FromDestination(Track destination, Trainset trainset)
        {
            RouteTask newTask = new RouteTask();

            newTask.DestinationTrack = destination;
            newTask.TrainSets.Add(trainset);

            return(newTask);
        }
예제 #4
0
 public static RouteTaskChain FromDestination(Track destination, Trainset trainset)
 {
     return(new RouteTaskChain()
     {
         tasks = new List <RouteTask>()
         {
             RouteTask.FromDestination(destination, trainset)
         }
     });
 }
예제 #5
0
    internal GameObject[] GetPlayersInTrainSet(Trainset trainset)
    {
        List <GameObject> players = new List <GameObject>();

        foreach (TrainCar car in trainset.cars)
        {
            if (car)
            {
                players.AddRange(GetPlayersInTrain(car));
            }
        }
        return(players.ToArray());
    }
        static void Postfix(LocoControllerBase __instance, float nextTargetIndependentBrake)
        {
            TrainCar currentCar = __instance.GetComponent <TrainCar>();
            TrainCar targetCar  = null;
            Trainset trainset   = null;

            if (Main.remoteCar)
            {
                targetCar = Main.remoteCar;
                trainset  = targetCar.trainset;
            }
            else if (PlayerManager.Car != null)
            {
                targetCar = PlayerManager.Car;
                trainset  = PlayerManager.Car.trainset;
            }

            if (currentCar == null || targetCar == null || !targetCar.Equals(currentCar) || trainset == null || trainset.cars.Count < 2)
            {
                return;
            }

            for (int i = 0; i < trainset.cars.Count; i++)
            {
                TrainCar car = trainset.cars[i];

                if (targetCar.Equals(car))
                {
                    continue;
                }

                if (car.carType == TrainCarType.LocoShunter)
                {
                    LocoControllerShunter locoController = car.GetComponent <LocoControllerShunter>();

                    if (locoController)
                    {
                        locoController.SetIndependentBrake(nextTargetIndependentBrake);
                    }
                }
                else if (car.carType == TrainCarType.LocoDiesel)
                {
                    LocoControllerDiesel locoController = car.GetComponent <LocoControllerDiesel>();

                    if (locoController)
                    {
                        locoController.SetIndependentBrake(nextTargetIndependentBrake);
                    }
                }
            }
        }
예제 #7
0
        public void UpdateJobCars()
        {
            jobCars.Clear();
            jobCarsUsed.Clear();
            jobConsists.Clear();
            // jobConsistUsed = null;
            currentTracks.Clear();
            List <Task> tasks = GetFirstUnfinishedTasks();

            currentTasks = tasks.Count;
            foreach (Task t in tasks)
            {
                jobCars.AddRange(t.GetTaskData().cars);
            }
            foreach (Car c in jobCars)
            {
                jobCarsUsed[c] = false;
            }
            foreach (Car car in jobCars)
            {
                if (!jobCarsUsed[car])
                {
                    TrackID trackID = car.CurrentTrack?.ID;
                    if (!SingletonBehaviour <IdGenerator> .Instance.logicCarToTrainCar.TryGetValue(car, out TrainCar trainCar))
                    {
                        continue;
                    }

                    Trainset trainset = trainCar.trainset;
                    foreach (TrainCar tc in trainset.cars)
                    {
                        Car c = tc.logicCar;
                        if (c != null)
                        {
                            if (jobCarsUsed.ContainsKey(c))
                            {
                                jobCarsUsed[c] = true;
                            }
                            if (trackID == null)
                            {
                                trackID = c.CurrentTrack?.ID;
                            }
                        }
                    }
                    jobConsists.Add(trainset);
                    currentTracks.Add(trackID);
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Return a transform to point to the the nth consist.
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public Transform GetPointerAt(int index)
        {
            if (jobConsists.Count < 1 || jobNotAllowed)
            {
                return(null);
            }
            index %= jobConsists.Count;
            Trainset t = jobConsists[index];

            if (t == PlayerManager.LastLoco?.trainset)
            {
                return(PlayerManager.LastLoco?.transform);
            }
            // Get car in middle of set.
            // TODO: Raise pointer to middle of car height.
            return(t.cars[t.cars.Count / 2].transform);
        }
예제 #9
0
        public void SetRoute(Route route, Trainset trainset)
        {
            Trainset = trainset;

            if (route == null || route.Path.Count == 0)
            {
                throw new ArgumentNullException(nameof(route));
            }

            Route       = route;
            ElapsedTime = 0.0f;

            TrackState = TrackingState.BeforeStart;

            if (!Running)
            {
                Module.StartCoroutine(PositionUpdate());
            }
        }
예제 #10
0
        public void Init(Trainset set, MultiPlayerId id, List <TrainCar>?carOrder)
        {
            _syncs.Add(set, this);

            _trainset = set;

            if (Authoritative)
            {
                _bogiePosition = new BogiePosition[set.cars.Sum(c => c.Bogies.Length)];
            }
            else
            {
                _offsets       = new double[set.cars.Sum(c => c.Bogies.Length)];
                _trackPosition = new double[_offsets.Length];
                _dampVel       = new double[_offsets.Length];
                _vels          = new float[_offsets.Length];
                _tracks        = new RailTrack[_offsets.Length];
                _bogiePos      = new Vector3[set.cars.Max(c => c.Bogies.Length)];
            }

            if (carOrder is {})
예제 #11
0
        static void Postfix(LocoControllerSteam __instance, float throttle)
        {
            TrainCar currentCar = __instance.GetComponent <TrainCar>();
            TrainCar targetCar  = null;
            Trainset trainset   = null;

            if (PlayerManager.Car != null && PlayerManager.Car.trainset != null)
            {
                targetCar = PlayerManager.Car;
                trainset  = PlayerManager.Car.trainset;
            }

            if (currentCar == null || targetCar == null || !targetCar.Equals(currentCar) || trainset == null || trainset.cars.Count < 2)
            {
                return;
            }

            List <TrainCar> trainsetCars = trainset.cars;

            for (int i = 0; i < trainsetCars.Count; i++)
            {
                TrainCar car = trainsetCars[i];

                if (targetCar.Equals(car))
                {
                    continue;
                }

                if (car.carType == TrainCarType.LocoSteamHeavy)
                {
                    LocoControllerSteam steamController = car.GetComponent <LocoControllerSteam>();

                    if (steamController)
                    {
                        steamController.SetThrottle(throttle);
                    }
                }
            }
        }
        static void Prefix(LocoControllerDiesel __instance, ToggleDirection toggle)
        {
            TrainCar targetCar = __instance.GetComponent <TrainCar>();
            Trainset trainset  = targetCar.trainset;

            if (trainset == null)
            {
                return;
            }

            for (int i = 0; i < trainset.cars.Count; i++)
            {
                TrainCar car = trainset.cars[i];

                if (targetCar.Equals(car))
                {
                    continue;
                }

                if (car.carType == TrainCarType.LocoShunter)
                {
                    LocoControllerShunter locoController = car.GetComponent <LocoControllerShunter>();

                    if (locoController != null)
                    {
                        locoController.SetSandersOn(toggle == ToggleDirection.UP);
                    }
                }
                else if (car.carType == TrainCarType.LocoDiesel)
                {
                    LocoControllerDiesel locoController = car.GetComponent <LocoControllerDiesel>();

                    if (locoController != null)
                    {
                        locoController.SetSandersOn(toggle == ToggleDirection.UP);
                    }
                }
            }
        }
예제 #13
0
 public static float TotalMass(this Trainset trainset) => trainset.cars.Sum(c => c.totalMass + CargoTypes.GetCargoMass(c.LoadedCargo, c.LoadedCargoAmount));
예제 #14
0
 public static float OverallLength(this Trainset trainset) => trainset.cars.Sum(c => c.logicCar.length);
예제 #15
0
 public static float Length(this Trainset trainset)
 {
     return(trainset.cars.Sum(c => c.logicCar.length));
 }
예제 #16
0
 public static bool IsFree(this Track current, Trainset trainset)
 {
     return(IsFree(current, new HashSet <string>(trainset.cars.Select(c => c.logicCar.ID))));
 }
        static void Postfix(LocoControllerDiesel __instance, float position)
        {
            TrainCar currentCar = __instance.GetComponent <TrainCar>();
            TrainCar targetCar  = null;
            Trainset trainset   = null;

            if (Main.remoteCar)
            {
                targetCar = Main.remoteCar;
                trainset  = targetCar.trainset;
            }
            else if (PlayerManager.Car != null)
            {
                targetCar = PlayerManager.Car;
                trainset  = PlayerManager.Car.trainset;
            }

            if (currentCar == null || targetCar == null || !targetCar.Equals(currentCar) || trainset == null || trainset.cars.Count < 2)
            {
                return;
            }

            List <TrainCar> trainsetCars = trainset.cars;

            for (int i = 0; i < trainsetCars.Count; i++)
            {
                TrainCar car = trainsetCars[i];

                if (targetCar.Equals(car))
                {
                    continue;
                }

                LocoControllerBase locoController = null;

                if (car.carType == TrainCarType.LocoShunter)
                {
                    locoController = car.GetComponent <LocoControllerShunter>();
                }
                else if (car.carType == TrainCarType.LocoDiesel)
                {
                    locoController = car.GetComponent <LocoControllerDiesel>();
                }

                if (locoController != null)
                {
                    if (GetCarsBehind(targetCar).Contains(car))
                    {
                        if (GetCarsInFrontOf(car).Contains(targetCar))
                        {
                            locoController.SetReverser(position);
                        }
                        else
                        {
                            locoController.SetReverser(position * -1f);
                        }
                    }
                    else if (GetCarsInFrontOf(targetCar).Contains(car))
                    {
                        if (GetCarsBehind(car).Contains(targetCar))
                        {
                            locoController.SetReverser(position);
                        }
                        else
                        {
                            locoController.SetReverser(position * -1f);
                        }
                    }
                }
            }
        }
    private IEnumerator ResetAuthorityToHostWhenStationary(Trainset set)
    {
        yield return(new WaitUntil(() => velocity.magnitude * 3.6f < 1));

        SingletonBehaviour <NetworkTrainManager> .Instance.SendAuthorityChange(set, localPlayer.Id);
    }
예제 #19
0
        public async static System.Threading.Tasks.Task DoCommand(CommandArg[] args)
        {
            if (args.Length == 0)
            {
                throw new CommandException("No command args");
            }

            if (args[0].String == "job" || args[0].String == "loco")
            {
                List <JobBooklet> allJobBooklets = new List <JobBooklet>(JobBooklet.allExistingJobBooklets);
                JobBooklet        jobBooklet     = null;

                if (allJobBooklets.Count == 0)
                {
                    throw new CommandException("No current job");
                }

                if (allJobBooklets.Count > 1 || args.Length > 1)
                {
                    if (args.Length < 2)
                    {
                        throw new CommandException("Multiple job, specify job name");
                    }

                    jobBooklet = allJobBooklets.FirstOrDefault(j => j.job.ID == args[1].String);
                }
                else
                {
                    jobBooklet = allJobBooklets[0];
                }


                if (jobBooklet == null)
                {
                    throw new CommandException("Unknown job");
                }

                RouteTaskChain chain = RouteTaskChain.FromDVJob(jobBooklet.job);

                if (chain == null)
                {
                    throw new CommandException("Not supported job type yet");
                }

                Terminal.Log($"Using job {jobBooklet.job.ID} chain {chain}");

                TrainCar trainCar;


                RouteTracker routeTracker = new RouteTracker(chain, true);

                if (args[0].String == "loco")
                {
                    trainCar = PlayerManager.LastLoco;

                    if (trainCar == null)
                    {
                        throw new CommandException("No last loco");
                    }
                }
                else
                {
                    trainCar = routeTracker.CurrentTask.TrainSets.FirstOrDefault()?.firstCar;
                }

                if (routeTracker.CurrentTask == null)
                {
                    throw new CommandException("No suitable task");
                }

                Track startTrack = trainCar.trainset.firstCar.Bogies[0].track.logicTrack;

                await FindAndSwitch(startTrack, routeTracker.CurrentTask.DestinationTrack, ReversingStrategy.ChooseBest, trainCar.trainset);

                routeTracker.SetRoute(Module.ActiveRoute.Route, trainCar.trainset);

                Module.ActiveRoute.RouteTracker = routeTracker;
            }
            else if (args[0].String == "tracker")
            {
                TrainCar trainCar = PlayerManager.LastLoco;

                if (trainCar == null)
                {
                    throw new CommandException("No last loco");
                }

                if (Module.ActiveRoute.RouteTracker.CurrentTask == null)
                {
                    throw new CommandException("Tracker has no task");
                }

                Track startTrack = trainCar.trainset.firstCar.Bogies[0].track.logicTrack;

                await FindAndSwitch(startTrack, Module.ActiveRoute.RouteTracker.CurrentTask.DestinationTrack, ReversingStrategy.ChooseBest, trainCar.trainset);

                Module.ActiveRoute.RouteTracker.SetRoute(Module.ActiveRoute.Route, trainCar.trainset);
            }
            else if (args[0].String == "from" && args.Length == 4 && args[2].String == "to")
            {
                Trainset trainset = null; //default value if we don't have consist (trainset)

                if (args[1].String == "loco")
                {
                    TrainCar trainCar = PlayerManager.LastLoco;

                    if (trainCar == null)
                    {
                        throw new CommandException("No last loco");
                    }

                    if (trainCar.trainset.firstCar.logicCar.BogiesOnSameTrack)
                    {
                        args[1].String = trainCar.trainset.firstCar.logicCar.CurrentTrack.ID.FullID;
                    }
                    else
                    {
                        args[1].String = trainCar.trainset.firstCar.logicCar.FrontBogieTrack.ID.FullID;
                    }

                    trainset = trainCar.trainset;
                    Terminal.Log($"current loco track end");
                }
                else if (args[1].String == "job.trainset")
                {
                    //TODO
                }

                if (trainset == null)
                {
                    throw new CommandException("Goal track must be associated with car");
                }


                RailTrack startTrack = RailTrackRegistry.AllTracks.FirstOrDefault((RailTrack track) => track?.logicTrack.ID.FullID == args[1].String);

                RailTrack goalTrack = RailTrackRegistry.AllTracks.FirstOrDefault((RailTrack track) => track?.logicTrack.ID.FullID == args[3].String);

                RouteTaskChain chain   = RouteTaskChain.FromDestination(goalTrack.logicTrack, trainset);
                var            tracker = new RouteTracker(chain, false);


                if (startTrack == null || goalTrack == null)
                {
                    throw new CommandException("start track or goal track not found");
                }

                await FindAndSwitch(startTrack.logicTrack, goalTrack.logicTrack, Module.settings.ReversingStrategy, trainset);

                tracker.SetRoute(Module.ActiveRoute.Route, trainset);
                Module.ActiveRoute.RouteTracker = tracker;
            }
            else if (args[0].String == "opposite")
            {
                if (!Module.ActiveRoute.IsSet)
                {
                    throw new CommandException("No route active");
                }


                var route = await Module.ActiveRoute.Route.FindOppositeRoute();

                if (route != null)
                {
                    Module.ActiveRoute.Route = route;
                    route.AdjustSwitches();

                    Module.ActiveRoute.RouteTracker.SetRoute(route, route.Trainset);

                    Terminal.Log($"Route {route.Length} {route?.SecondTrack?.logicTrack.ID.FullDisplayID}");
                }
                else
                {
                    throw new CommandException("Opposite route could not be found");
                }
            }
            else if (args[0].String == "clear")
            {
                if (Module.ActiveRoute.IsSet)
                {
                    Module.ActiveRoute.ClearRoute();
                }
                else
                {
                    throw new CommandException("no active route");
                }
            }
            else if (args[0].String == "info")
            {
                if (Module.ActiveRoute.IsSet)
                {
                    Terminal.Log("Active route:");
                    Terminal.Log(Module.ActiveRoute.Route.ToString());
#if DEBUG
                    Terminal.Log(Module.ActiveRoute.Route.Path.Select(t => t.logicTrack.ID.FullID).Aggregate((i, j) => i + "->" + j));
#endif
                }
                else
                {
                    throw new CommandException("no active route");
                }
            }
#if DEBUG
            else if (args[0].String == "track")
            {
                var track = RailTrackRegistry.AllTracks.Where(t => t.logicTrack.ID.FullID.ToLower() == args[1].String.ToLower()).FirstOrDefault();
                if (track == null)
                {
                    throw new CommandException("track not found");
                }

                Terminal.Log($"{track.logicTrack.ID.FullID} {track.logicTrack.length}m");

                if (track.inIsConnected)
                {
                    Terminal.Log("IN: " + track.GetAllInBranches().Select(b => b.track.logicTrack.ID.FullID).Aggregate((a, b) => a + "; " + b));
                }
                if (track.outIsConnected)
                {
                    Terminal.Log("OUT: " + track.GetAllOutBranches().Select(b => b.track.logicTrack.ID.FullID).Aggregate((a, b) => a + "; " + b));
                }
            }
            else if (args[0].String == "trainset")
            {
                TrainCar trainCar = PlayerManager.LastLoco;

                if (trainCar == null)
                {
                    throw new CommandException("No last loco");
                }

                Terminal.Log($"loco trainset cars: {trainCar.trainset.cars.Count}");
                Terminal.Log($"first car: {trainCar.trainset.firstCar.logicCar.ID}");
                Terminal.Log($"last car: {trainCar.trainset.lastCar.logicCar.ID}");
                Terminal.Log($"first car track: {trainCar.trainset.firstCar.logicCar.CurrentTrack?.ID.FullDisplayID}");
                Terminal.Log($"last car track: {trainCar.trainset.lastCar.logicCar.CurrentTrack?.ID.FullDisplayID}");
                Terminal.Log($"first car front boogie track: {trainCar.trainset.firstCar.logicCar.FrontBogieTrack?.ID.FullDisplayID}");
                Terminal.Log($"first car rear boogie track: {trainCar.trainset.firstCar.logicCar.RearBogieTrack?.ID.FullDisplayID}");
            }
#endif
            else if (args[0].String == "auto")
            {
                TrainCar trainCar = PlayerManager.LastLoco;

                if (trainCar == null)
                {
                    throw new CommandException("No last loco");
                }

                if (args[1].String == "stop")
                {
                    var locoAI = Module.GetLocoAI(trainCar);
                    locoAI.Stop();
                    return;
                }

                RailTrack goalTrack = RailTrackRegistry.AllTracks.FirstOrDefault((RailTrack track) => track?.logicTrack.ID.FullID == args[1].String);
                if (goalTrack == null)
                {
                    throw new CommandException("Goal track not found");
                }

                RouteTaskChain chain   = RouteTaskChain.FromDestination(goalTrack.logicTrack, trainCar.trainset);
                var            tracker = new RouteTracker(chain, false);

                Track startTrack = trainCar.trainset.firstCar.Bogies[0].track.logicTrack;

                var route = await Route.FindRoute(startTrack, tracker.CurrentTask.DestinationTrack, ReversingStrategy.ChooseBest, trainCar.trainset);

                tracker.SetRoute(route, trainCar.trainset);

                var driver = Module.GetLocoAI(trainCar);
                driver.StartAI(tracker);
            }
            else
            {
                throw new CommandException($"Unknown subcommand {args[0]}");
            }
        }
예제 #20
0
        private async static System.Threading.Tasks.Task FindAndSwitch(Track begin, Track end, ReversingStrategy reversingStrategy, Trainset trainset)
        {
            if (begin is null)
            {
                throw new CommandException("Empty begin");
            }

            if (end is null)
            {
                throw new CommandException("Empty end");
            }

            var route = await Route.FindRoute(begin, end, reversingStrategy, trainset);

            if (route == null)
            {
                Module.ActiveRoute.ClearRoute();
                throw new CommandException("Path cannot be found");
            }
            else
            {
                Module.ActiveRoute.Route = route;
                route.AdjustSwitches();
            }
        }
    private void GainAndReleaseAuthorityOfTrainsInRangeOfCurrent()
    {
        if (!trainCar.rearCoupler || !trainCar.frontCoupler || velocity.magnitude * 3.6f <= .5f)
        {
            return;
        }

        GameObject collidedCouplerRear  = trainCar.rearCoupler.GetFirstCouplerInRange(3)?.gameObject;
        GameObject collidedCouplerFront = trainCar.frontCoupler.GetFirstCouplerInRange(3)?.gameObject;

        if (collidedCouplerRear && collidedCouplerRear.GetComponent <Coupler>() && collidedCouplerRear.GetComponent <Coupler>().train != trainCar)
        {
            var coupler               = collidedCouplerRear.GetComponent <Coupler>();
            var otherTrain            = coupler.train;
            var otherTrainServerState = SingletonBehaviour <NetworkTrainManager> .Instance.GetServerStateById(otherTrain.CarGUID);

            if (otherTrainServerState != null && serverState.AuthorityPlayerId != otherTrainServerState.AuthorityPlayerId)
            {
                if (tempRearTrainsetWithAuthority != otherTrain.trainset)
                {
                    ushort gainer = otherTrainServerState.AuthorityPlayerId;
                    if (tempRearTrainsetWithAuthority == null)
                    {
                        gainer = serverState.AuthorityPlayerId;
                    }

                    var trainSync = otherTrain.GetComponent <NetworkTrainPosSync>();
                    if (coupler.isFrontCoupler)
                    {
                        trainSync.tempFrontTrainsetWithAuthority = trainCar.trainset;
                    }
                    else
                    {
                        trainSync.tempRearTrainsetWithAuthority = trainCar.trainset;
                    }
                    SingletonBehaviour <NetworkTrainManager> .Instance.SendAuthorityChange(otherTrain.trainset, gainer);

                    tempRearTrainsetWithAuthority = otherTrain.trainset;
                }
            }
        }

        if (!collidedCouplerRear && tempRearTrainsetWithAuthority != null)
        {
            var frontTrain = tempRearTrainsetWithAuthority.firstCar.GetComponent <NetworkTrainPosSync>();
            var rearTrain  = tempRearTrainsetWithAuthority.lastCar.GetComponent <NetworkTrainPosSync>();

            tempRearTrainsetWithAuthority = null;
            if (frontTrain.tempFrontTrainsetWithAuthority == trainCar.trainset)
            {
                frontTrain.tempFrontTrainsetWithAuthority = null;
            }

            if (frontTrain.tempRearTrainsetWithAuthority == trainCar.trainset)
            {
                frontTrain.tempRearTrainsetWithAuthority = null;
            }

            if (rearTrain.tempFrontTrainsetWithAuthority == trainCar.trainset)
            {
                rearTrain.tempFrontTrainsetWithAuthority = null;
            }

            if (rearTrain.tempRearTrainsetWithAuthority == trainCar.trainset)
            {
                rearTrain.tempRearTrainsetWithAuthority = null;
            }

            frontTrain.CheckAuthorityChange();
            rearTrain.CheckAuthorityChange();
            CheckAuthorityChange();
        }

        if (collidedCouplerFront && collidedCouplerFront.GetComponent <Coupler>() && collidedCouplerFront.GetComponent <Coupler>().train != trainCar)
        {
            var coupler               = collidedCouplerFront.GetComponent <Coupler>();
            var otherTrain            = coupler.train;
            var otherTrainServerState = SingletonBehaviour <NetworkTrainManager> .Instance.GetServerStateById(otherTrain.CarGUID);

            if (otherTrainServerState != null && serverState.AuthorityPlayerId != otherTrainServerState.AuthorityPlayerId)
            {
                if (tempFrontTrainsetWithAuthority != otherTrain.trainset)
                {
                    var trainSync = otherTrain.GetComponent <NetworkTrainPosSync>();
                    if (coupler.isFrontCoupler)
                    {
                        trainSync.tempFrontTrainsetWithAuthority = trainCar.trainset;
                    }
                    else
                    {
                        trainSync.tempRearTrainsetWithAuthority = trainCar.trainset;
                    }
                    SingletonBehaviour <NetworkTrainManager> .Instance.SendAuthorityChange(otherTrain.trainset, serverState.AuthorityPlayerId);

                    tempFrontTrainsetWithAuthority = otherTrain.trainset;
                }
            }
        }

        if (!collidedCouplerFront && tempFrontTrainsetWithAuthority != null)
        {
            var frontTrain = tempFrontTrainsetWithAuthority.firstCar.GetComponent <NetworkTrainPosSync>();
            var rearTrain  = tempFrontTrainsetWithAuthority.lastCar.GetComponent <NetworkTrainPosSync>();

            tempFrontTrainsetWithAuthority = null;
            if (frontTrain.tempFrontTrainsetWithAuthority == trainCar.trainset)
            {
                frontTrain.tempFrontTrainsetWithAuthority = null;
            }

            if (frontTrain.tempRearTrainsetWithAuthority == trainCar.trainset)
            {
                frontTrain.tempRearTrainsetWithAuthority = null;
            }

            if (rearTrain.tempFrontTrainsetWithAuthority == trainCar.trainset)
            {
                rearTrain.tempFrontTrainsetWithAuthority = null;
            }

            if (rearTrain.tempRearTrainsetWithAuthority == trainCar.trainset)
            {
                rearTrain.tempRearTrainsetWithAuthority = null;
            }

            frontTrain.CheckAuthorityChange();
            rearTrain.CheckAuthorityChange();
            CheckAuthorityChange();
        }
    }
예제 #22
0
        void IDispatch.UpdateDispatch()
        {
            // Recatalogue groups of cars for this task.
            groups.Clear();
            foreach (Car c in cars.Keys)
            {
                cars[c] = false;
            }
            foreach (Car c in cars.Keys)
            {
                bool test = uncouple && c.BogiesOnSameTrack && c.CurrentTrack == track;
            }
            // Will go through up to cars.Count different groups.
            List <Group> detachedGroups = new List <Group>();

            foreach (Car car in cars.Keys)
            {
                if (cars[car] || !SingletonBehaviour <IdGenerator> .Instance.logicCarToTrainCar.TryGetValue(car, out TrainCar trainCar))
                {
                    continue;
                }
                while (!cars[car])
                {
                    /*
                     * Comb through the trainset for contiguous groups of cars that are associated with this task.
                     */
                    Trainset trainset = trainCar.trainset;

                    List <Car> currentCars = new List <Car>();
                    bool       inGroup     = false;

                    for (int i = 0; i < trainset.cars.Count; i++)
                    {
                        TrainCar tc = trainset.cars[i];
                        Car      c  = tc.logicCar;
                        if (c != null && cars.ContainsKey(c) && !cars[c])
                        {
                            cars[c] = true;
                            // If this is an uncoupling dispatch, only add if car is not on destination.
                            if (!uncouple || c.CurrentTrack != track || !c.BogiesOnSameTrack)
                            {
                                currentCars.Add(c);
                            }
                            inGroup = true;
                        }
                        else if (inGroup)
                        {
                            if (currentCars.Count > 0)
                            {
                                Group group = new Group(currentCars);
                                if (trainset == PlayerManager.LastLoco?.trainset)
                                {
                                    int place = i - currentCars.Count;
                                    if (!trainset.cars.First().IsLoco&& trainset.cars.Last().IsLoco)
                                    {
                                        currentCars.Reverse();
                                        place = trainset.cars.Count - i;
                                    }
                                    group.consistPos = place;
                                    groups.Add(group);
                                }
                                else
                                {
                                    detachedGroups.Add(group);
                                }
                            }
                            break;
                        }
                    }
                }
            }
            groups.AddRange(detachedGroups);
        }