//================================================================================================// /// <summary> /// Constructor for restore /// </summary> public DeadlockPathInfo(BinaryReader inf) { if (null == inf) { throw new ArgumentNullException(nameof(inf)); } Path = new TrackCircuitPartialPathRoute(inf); Name = inf.ReadString(); Groups = new List <string>(); int totalGroups = inf.ReadInt32(); for (int iGroup = 0; iGroup <= totalGroups - 1; iGroup++) { string thisGroup = inf.ReadString(); Groups.Add(thisGroup); } UsefulLength = inf.ReadSingle(); EndSectionIndex = inf.ReadInt32(); LastUsefulSectionIndex = inf.ReadInt32(); AllowedTrains = new List <int>(); int totalIndex = inf.ReadInt32(); for (int iIndex = 0; iIndex <= totalIndex - 1; iIndex++) { int thisIndex = inf.ReadInt32(); AllowedTrains.Add(thisIndex); } }
} // index of linked end section //================================================================================================// /// <summary> /// Constructor /// </summary> public DeadlockPathInfo(TrackCircuitPartialPathRoute path, int pathIndex) { Path = new TrackCircuitPartialPathRoute(path); Name = string.Empty; Groups = new List <string>(); UsefulLength = 0.0f; EndSectionIndex = -1; LastUsefulSectionIndex = -1; AllowedTrains = new List <int>(); Path[0].UsedAlternativePath = pathIndex; }
public void AddPlayers(MSGPlayer player) { if (Players.ContainsKey(player.user)) { return; } if (MultiPlayerManager.Client != null && player.user == MultiPlayerManager.Client.UserName) { return; //do not add self//WARNING: may need to worry about train number here } OnlinePlayer p = new OnlinePlayer(player.user, Path.Combine(Simulator.Instance.RouteFolder.ContentFolder.ConsistsFolder, player.con), Path.Combine(Simulator.Instance.RouteFolder.PathsFolder, player.path)); p.AvatarUrl = player.url; p.LeadingLocomotiveID = player.leadingID; Train train = new Train(); train.TrainType = TrainType.Remote; if (MultiPlayerManager.IsServer()) //server needs to worry about correct train number { } else { train.Number = player.num; } if (player.con.Contains("tilted")) { train.IsTilting = true; } int direction = player.dir; train.DistanceTravelled = player.Travelled; train.TrainMaxSpeedMpS = player.trainmaxspeed; if (MultiPlayerManager.IsServer()) { try { AIPath aiPath = new AIPath(Simulator.Instance.TrackDatabase, Simulator.Instance.TSectionDat, p.Path, Simulator.Instance.TimetableMode); } catch (Exception) { MultiPlayerManager.BroadCast((new MSGMessage(player.user, "Warning", "Server does not have path file provided, signals may always be red for you.")).ToString()); } } try { train.RearTDBTraveller = new Traveller(Simulator.Instance.TSectionDat, Simulator.Instance.TrackDatabase.TrackDB.TrackNodes, player.Location, direction == 1 ? Traveller.TravellerDirection.Forward : Traveller.TravellerDirection.Backward); } catch (Exception e) { if (MultiPlayerManager.IsServer()) { MultiPlayerManager.BroadCast((new MSGMessage(player.user, "Error", "MultiPlayer Error:" + e.Message)).ToString()); } else { throw new Exception(); } } for (var i = 0; i < player.cars.Length; i++)// cars.Length-1; i >= 0; i--) { { string wagonFilePath = Path.Combine(Simulator.Instance.RouteFolder.ContentFolder.TrainSetsFolder, player.cars[i]); TrainCar car = null; try { car = RollingStock.Load(Simulator.Instance, wagonFilePath); car.CarLengthM = player.lengths[i] / 100.0f; } catch (Exception error) { Trace.WriteLine(error.Message); car = MultiPlayerManager.Instance().SubCar(wagonFilePath, player.lengths[i]); } if (car == null) { continue; } bool flip = true; if (player.flipped[i] == 0) { flip = false; } car.Flipped = flip; car.CarID = player.ids[i]; train.Cars.Add(car); car.Train = train; MSTSWagon w = (MSTSWagon)car; if (w != null) { w.SignalEvent((player.pantofirst == 1 ? PowerSupplyEvent.RaisePantograph : PowerSupplyEvent.LowerPantograph), 1); w.SignalEvent((player.pantosecond == 1 ? PowerSupplyEvent.RaisePantograph : PowerSupplyEvent.LowerPantograph), 2); w.SignalEvent((player.pantothird == 1 ? PowerSupplyEvent.RaisePantograph : PowerSupplyEvent.LowerPantograph), 3); w.SignalEvent((player.pantofourth == 1 ? PowerSupplyEvent.RaisePantograph : PowerSupplyEvent.LowerPantograph), 4); } }// for each rail car if (train.Cars.Count == 0) { throw (new Exception("The train of player " + player.user + " is empty from ")); } train.ControlMode = TrainControlMode.Explorer; train.CheckFreight(); train.InitializeBrakes(); TrackCircuitPartialPathRoute tempRoute = train.CalculateInitialTrainPosition(); if (tempRoute.Count == 0) { MultiPlayerManager.BroadCast((new MSGMessage(p.Username, "Error", "Cannot be placed into the game")).ToString());//server will broadcast this error throw new InvalidDataException("Remote train original position not clear"); } train.SetInitialTrainRoute(tempRoute); train.CalculatePositionOfCars(); train.ResetInitialTrainRoute(tempRoute); train.CalculatePositionOfCars(); train.AITrainBrakePercent = 100; //if (MPManager.Instance().AllowedManualSwitch) train.InitializeSignals(false); for (int iCar = 0; iCar < train.Cars.Count; iCar++) { var car = train.Cars[iCar]; if (car.CarID == p.LeadingLocomotiveID) { train.LeadLocomotive = car; (train.LeadLocomotive as MSTSLocomotive).Headlight = player.headlight; (train.LeadLocomotive as MSTSLocomotive).UsingRearCab = player.frontorrearcab == "R" ? true : false; } if (car is MSTSLocomotive && MultiPlayerManager.IsServer()) { MultiPlayerManager.Instance().AddOrRemoveLocomotive(player.user, train.Number, iCar, true); } } if (train.LeadLocomotive == null) { train.LeadNextLocomotive(); if (train.LeadLocomotive != null) { p.LeadingLocomotiveID = train.LeadLocomotive.CarID; } else { p.LeadingLocomotiveID = "NA"; } } if (train.LeadLocomotive != null) { train.Name = Train.GetTrainName(train.LeadLocomotive.CarID); } else if (train.Cars != null && train.Cars.Count > 0) { train.Name = Train.GetTrainName(train.Cars[0].CarID); } else if (player != null && player.user != null) { train.Name = player.user; } if (MultiPlayerManager.IsServer()) { train.InitializeSignals(false); } p.Train = train; Players.Add(player.user, p); MultiPlayerManager.Instance().AddOrRemoveTrain(train, true); }
//================================================================================================// // // Check if conflict is real deadlock situation // Conditions : // if section is part of deadlock definition, it is a deadlock // if section has intermediate signals, it is a deadlock // if section has no intermediate signals but there are signals on both approaches to the deadlock, it is not a deadlock // Return value : boolean to indicate it is a deadlock or not // If not a deadlock, the REF int elementIndex is set to index of the last common section (will be increased in the loop) // internal bool CheckRealDeadlockLocationBased(TrackCircuitPartialPathRoute route, TrackCircuitPartialPathRoute otherRoute, ref int elementIndex) { bool isValidDeadlock = false; TrackCircuitSection section = route[elementIndex].TrackCircuitSection; // check if section is start or part of deadlock definition if (section.DeadlockReference >= 0 || (section.DeadlockBoundaries != null && section.DeadlockBoundaries.Count > 0)) { return(true); } // loop through common section - if signal is found, it is a deadlock bool validLoop = true; int otherRouteIndex = otherRoute.GetRouteIndex(section.Index, 0); for (int i = 0; validLoop; i++) { int thisElementIndex = elementIndex + i; int otherElementIndex = otherRouteIndex - i; if (thisElementIndex > route.Count - 1) { validLoop = false; } if (otherElementIndex < 0) { validLoop = false; } if (validLoop) { TrackCircuitSection thisRouteSection = route[thisElementIndex].TrackCircuitSection; TrackCircuitSection otherRouteSection = otherRoute[otherElementIndex].TrackCircuitSection; if (thisRouteSection.Index != otherRouteSection.Index) { validLoop = false; } else if (thisRouteSection.EndSignals[TrackDirection.Ahead] != null || thisRouteSection.EndSignals[TrackDirection.Reverse] != null) { isValidDeadlock = true; validLoop = false; } } } // if no signals along section, check if section is protected by signals - if so, it is not a deadlock // check only as far as maximum signal check distance if (!isValidDeadlock) { // this route backward first float totalDistance = 0.0f; bool signalFound = false; validLoop = true; for (int i = 0; validLoop; i--) { int thisElementIndex = elementIndex + i; // going backward as iIndex is negative! if (thisElementIndex < 0) { validLoop = false; } else { TrackCircuitRouteElement thisElement = route[thisElementIndex]; TrackCircuitSection thisRouteSection = thisElement.TrackCircuitSection; totalDistance += thisRouteSection.Length; if (thisRouteSection.EndSignals[thisElement.Direction] != null) { validLoop = false; signalFound = true; } if (totalDistance > MinCheckDistanceM) { validLoop = false; } } } // other route backward next totalDistance = 0.0f; bool otherSignalFound = false; validLoop = true; for (int iIndex = 0; validLoop; iIndex--) { int thisElementIndex = otherRouteIndex + iIndex; // going backward as iIndex is negative! if (thisElementIndex < 0) { validLoop = false; } else { TrackCircuitRouteElement thisElement = otherRoute[thisElementIndex]; TrackCircuitSection thisRouteSection = thisElement.TrackCircuitSection; totalDistance += thisRouteSection.Length; if (thisRouteSection.EndSignals[thisElement.Direction] != null) { validLoop = false; otherSignalFound = true; } if (totalDistance > MinCheckDistanceM) { validLoop = false; } } } if (!signalFound || !otherSignalFound) { isValidDeadlock = true; } } // if not a valid deadlock, find end of common section if (!isValidDeadlock) { elementIndex = EndCommonSection(elementIndex, route, otherRoute);; } return(isValidDeadlock); }
// Obtain deadlock details - new style location based logic private int[] SetDeadlockLocationBased(int index, TrackCircuitPartialPathRoute route, TrackCircuitPartialPathRoute otherRoute, Train otherTrain) { int[] returnValue = new int[2]; returnValue[1] = -1; // set to no alternative path used TrackCircuitRouteElement firstElement = route[index]; int firstSectionIndex = firstElement.TrackCircuitSection.Index; bool alreadyActive = false; int trainSectionIndex; int otherTrainSectionIndex; // double index variables required as last valid index must be known when exiting loop int trainIndex = index; int trainNextIndex = trainIndex; int otherTrainIndex = otherRoute.GetRouteIndex(firstSectionIndex, 0); int otherTrainNextIndex = otherTrainIndex; int otherFirstIndex = otherTrainIndex; TrackCircuitRouteElement trainElement; TrackCircuitRouteElement otherTrainElement; bool validPassLocation = false; int endSectionRouteIndex = -1; bool endOfLoop = false; // loop while not at end of route for either train and sections are equal // loop is also exited when alternative path is found for either train while (!endOfLoop) { trainIndex = trainNextIndex; trainElement = route[trainIndex]; otherTrainIndex = otherTrainNextIndex; trainSectionIndex = trainElement.TrackCircuitSection.Index; otherTrainElement = otherRoute[otherTrainIndex]; otherTrainSectionIndex = otherTrainElement.TrackCircuitSection.Index; TrackCircuitSection section = otherTrainElement.TrackCircuitSection; // if sections not equal : test length of next not-common section, if long enough then exit loop if (trainSectionIndex != otherTrainSectionIndex) { int nextThisRouteIndex = trainIndex; TrackCircuitSection passLoopSection = ValidRoute[0][nextThisRouteIndex].TrackCircuitSection; _ = otherRoute.GetRouteIndex(passLoopSection.Index, otherTrainIndex); float passLength = passLoopSection.Length; bool endOfPassLoop = false; while (!endOfPassLoop) { // loop is longer as at least one of the trains so is valid if (passLength > Length || passLength > otherTrain.Length) { endOfPassLoop = true; endOfLoop = true; } // get next section else if (nextThisRouteIndex < ValidRoute[0].Count - 2) { nextThisRouteIndex++; passLoopSection = ValidRoute[0][nextThisRouteIndex].TrackCircuitSection; int nextOtherRouteIndex = otherRoute.GetRouteIndexBackward(passLoopSection.Index, otherTrainIndex); // new common section after too short loop - not a valid deadlock point if (nextOtherRouteIndex >= 0) { endOfPassLoop = true; trainNextIndex = nextThisRouteIndex; otherTrainNextIndex = nextOtherRouteIndex; } else { passLength += passLoopSection.Length; } } // end of route else { endOfPassLoop = true; endOfLoop = true; } } } // if section is a deadlock boundary, check available paths for both trains else { List <int> trainAllocatedPaths = new List <int>(); List <int> otherTrainAllocatedPaths = new List <int>(); bool gotoNextSection = true; if (section.DeadlockReference >= 0 && trainElement.FacingPoint) // test for facing points only { bool trainFits = false; bool otherTrainFits = false; int endSectionIndex = -1; validPassLocation = true; // get allocated paths for this train DeadlockInfo deadlockInfo = Simulator.Instance.SignalEnvironment.DeadlockInfoList[section.DeadlockReference]; // get allocated paths for this train - if none yet set, create references int trainReferenceIndex = deadlockInfo.GetTrainAndSubpathIndex(Number, TCRoute.ActiveSubPath); if (!deadlockInfo.TrainReferences.ContainsKey(trainReferenceIndex)) { deadlockInfo.SetTrainDetails(Number, TCRoute.ActiveSubPath, Length, ValidRoute[0], trainIndex); } // if valid path for this train if (deadlockInfo.TrainReferences.ContainsKey(trainReferenceIndex)) { trainAllocatedPaths = deadlockInfo.TrainReferences[deadlockInfo.GetTrainAndSubpathIndex(Number, TCRoute.ActiveSubPath)]; // if paths available, get end section and check train against shortest path if (trainAllocatedPaths.Count > 0) { endSectionIndex = deadlockInfo.AvailablePathList[trainAllocatedPaths[0]].EndSectionIndex; endSectionRouteIndex = route.GetRouteIndex(endSectionIndex, trainIndex); Dictionary <int, bool> trainFitList = deadlockInfo.TrainLengthFit[deadlockInfo.GetTrainAndSubpathIndex(Number, TCRoute.ActiveSubPath)]; foreach (int i in trainAllocatedPaths) { if (trainFitList[i]) { trainFits = true; break; } } } } else { validPassLocation = false; } // get allocated paths for other train - if none yet set, create references int otherTrainReferenceIndex = deadlockInfo.GetTrainAndSubpathIndex(otherTrain.Number, otherTrain.TCRoute.ActiveSubPath); if (!deadlockInfo.TrainReferences.ContainsKey(otherTrainReferenceIndex)) { int otherTrainElementIndex = otherTrain.ValidRoute[0].GetRouteIndexBackward(endSectionIndex, otherFirstIndex); if (otherTrainElementIndex < 0) // train joins deadlock area on different node { validPassLocation = false; deadlockInfo.RemoveTrainAndSubpathIndex(otherTrain.Number, otherTrain.TCRoute.ActiveSubPath); // remove index as train has no valid path } else { deadlockInfo.SetTrainDetails(otherTrain.Number, otherTrain.TCRoute.ActiveSubPath, otherTrain.Length, otherTrain.ValidRoute[0], otherTrainElementIndex); } } // if valid path for other train if (validPassLocation && deadlockInfo.TrainReferences.ContainsKey(otherTrainReferenceIndex)) { otherTrainAllocatedPaths = deadlockInfo.TrainReferences[deadlockInfo.GetTrainAndSubpathIndex(otherTrain.Number, otherTrain.TCRoute.ActiveSubPath)]; // if paths available, get end section (if not yet set) and check train against shortest path if (otherTrainAllocatedPaths.Count > 0) { if (endSectionRouteIndex < 0) { endSectionIndex = deadlockInfo.AvailablePathList[otherTrainAllocatedPaths[0]].EndSectionIndex; endSectionRouteIndex = route.GetRouteIndex(endSectionIndex, trainIndex); } Dictionary <int, bool> otherTrainFitList = deadlockInfo.TrainLengthFit[deadlockInfo.GetTrainAndSubpathIndex(otherTrain.Number, otherTrain.TCRoute.ActiveSubPath)]; foreach (int iPath in otherTrainAllocatedPaths) { if (otherTrainFitList[iPath]) { otherTrainFits = true; break; } } } } else // other train has no valid path relating to the passing path, so passing not possible { validPassLocation = false; } // if both trains have only one route, make sure it's not the same (inverse) route if (trainAllocatedPaths.Count == 1 && otherTrainAllocatedPaths.Count == 1) { if (deadlockInfo.InverseInfo.ContainsKey(trainAllocatedPaths[0]) && deadlockInfo.InverseInfo[trainAllocatedPaths[0]] == otherTrainAllocatedPaths[0]) { validPassLocation = false; } } // if there are passing paths and at least one train fits in shortest path, it is a valid location so break loop if (validPassLocation) { gotoNextSection = false; if (trainFits || otherTrainFits) { if (section.IsSet(otherTrain, true)) { alreadyActive = true; } endOfLoop = true; } else { trainNextIndex = endSectionRouteIndex; otherTrainNextIndex = otherRoute.GetRouteIndexBackward(endSectionIndex, otherTrainIndex); if (otherTrainNextIndex < 0) { endOfLoop = true; } } } } // if loop not yet ended - not a valid pass location, move to next section (if available) if (gotoNextSection) { // if this section is occupied by other train, break loop - further checks are of no use if (section.IsSet(otherTrain, true)) { alreadyActive = true; endOfLoop = true; } else { trainNextIndex++; otherTrainNextIndex--; if (trainNextIndex > route.Count - 1 || otherTrainNextIndex < 0) { endOfLoop = true; // end of path reached for either train } } } } } // if valid pass location : set return index if (validPassLocation && endSectionRouteIndex >= 0) { returnValue[1] = endSectionRouteIndex; } // get sections on which loop ended trainElement = route[trainIndex]; trainSectionIndex = trainElement.TrackCircuitSection.Index; otherTrainElement = otherRoute[otherTrainIndex]; otherTrainSectionIndex = otherTrainElement.TrackCircuitSection.Index; // if last sections are still equal - end of route reached for one of the trains // otherwise, last common sections was previous sections for this train TrackCircuitSection lastSection = (trainSectionIndex == otherTrainSectionIndex) ? TrackCircuitSection.TrackCircuitList[trainSectionIndex] : route[trainIndex - 1].TrackCircuitSection; // TODO : if section is not a junction but deadlock is already active, wind back to last junction // if section is not a junction, check if either route not ended, if so continue up to next junction if (lastSection.CircuitType != TrackCircuitType.Junction) { bool endSectionFound = false; if (trainIndex < (route.Count - 1)) { for (int iIndex = trainIndex; iIndex < route.Count - 1 && !endSectionFound; iIndex++) { lastSection = route[iIndex].TrackCircuitSection; endSectionFound = lastSection.CircuitType == TrackCircuitType.Junction; } } else if (otherTrainIndex > 0) { for (int i = otherTrainIndex; i >= 0 && !endSectionFound; i--) { lastSection = otherRoute[i].TrackCircuitSection; endSectionFound = false; // junction found - end of loop if (lastSection.CircuitType == TrackCircuitType.Junction) { endSectionFound = true; } // train has active wait condition at this location - end of loop else if (otherTrain.CheckWaitCondition(lastSection.Index)) { endSectionFound = true; } if (lastSection.IsSet(otherTrain, true)) { alreadyActive = true; } } } } // set deadlock info for both trains SetDeadlockInfo(firstSectionIndex, lastSection.Index, otherTrain.Number); otherTrain.SetDeadlockInfo(lastSection.Index, firstSectionIndex, Number); if (alreadyActive) { lastSection.SetDeadlockTrap(otherTrain, otherTrain.DeadlockInfo[lastSection.Index]); returnValue[1] = route.Count; // set beyond end of route - no further checks required } // if any section occupied by own train, reverse deadlock is active TrackCircuitSection firstSection = TrackCircuitSection.TrackCircuitList[firstSectionIndex]; int firstRouteIndex = ValidRoute[0].GetRouteIndex(firstSectionIndex, 0); int lastRouteIndex = ValidRoute[0].GetRouteIndex(lastSection.Index, 0); for (int i = firstRouteIndex; i < lastRouteIndex; i++) { TrackCircuitSection partSection = ValidRoute[0][i].TrackCircuitSection; if (partSection.IsSet(this, true)) { firstSection.SetDeadlockTrap(this, DeadlockInfo[firstSectionIndex]); } } returnValue[0] = route.GetRouteIndex(lastSection.Index, index); if (returnValue[0] < 0) { returnValue[0] = trainIndex; } return(returnValue); }
// Obtain deadlock details - old style path based logic private int[] SetDeadlockPathBased(int index, TrackCircuitPartialPathRoute route, TrackCircuitPartialPathRoute otherRoute, Train otherTrain) { int[] returnValue = new int[2]; returnValue[1] = -1; // set to no alternative path used TrackCircuitRouteElement firstElement = route[index]; int firstSectionIndex = firstElement.TrackCircuitSection.Index; bool allreadyActive = false; int trainSection = firstSectionIndex; int otherTrainSection = firstSectionIndex; int trainIndex = index; int otherTrainIndex = otherRoute.GetRouteIndex(firstSectionIndex, 0); int firstIndex = trainIndex; int otherFirstIndex = otherTrainIndex; TrackCircuitRouteElement trainElement; TrackCircuitRouteElement otherTrainElement; // loop while not at end of route for either train and sections are equal // loop is also exited when alternative path is found for either train for (int i = 0; ((firstIndex + i) <= (route.Count - 1)) && ((otherFirstIndex - i)) >= 0 && (trainSection == otherTrainSection); i++) { trainIndex = firstIndex + i; otherTrainIndex = otherFirstIndex - i; trainElement = route[trainIndex]; otherTrainElement = otherRoute[otherTrainIndex]; trainSection = trainElement.TrackCircuitSection.Index; otherTrainSection = otherTrainElement.TrackCircuitSection.Index; if (trainElement.StartAlternativePath != null) { int endAlternativeSection = trainElement.StartAlternativePath.TrackCircuitSection.Index; returnValue[1] = route.GetRouteIndex(endAlternativeSection, index); break; } if (otherTrainElement.EndAlternativePath != null) { int endAlternativeSection = otherTrainElement.EndAlternativePath.TrackCircuitSection.Index; returnValue[1] = route.GetRouteIndex(endAlternativeSection, index); break; } TrackCircuitSection section = TrackCircuitSection.TrackCircuitList[trainSection]; if (section.IsSet(otherTrain, true)) { allreadyActive = true; } } // get sections on which loop ended trainElement = route[trainIndex]; trainSection = trainElement.TrackCircuitSection.Index; otherTrainElement = otherRoute[otherTrainIndex]; otherTrainSection = otherTrainElement.TrackCircuitSection.Index; // if last sections are still equal - end of route reached for one of the trains // otherwise, last common sections was previous sections for this train int lastSectionIndex = (trainSection == otherTrainSection) ? trainSection : route[trainIndex - 1].TrackCircuitSection.Index; // if section is not a junction, check if either route not ended, if so continue up to next junction TrackCircuitSection lastSection = TrackCircuitSection.TrackCircuitList[lastSectionIndex]; if (lastSection.CircuitType != TrackCircuitType.Junction) { bool endSectionFound = false; if (trainIndex < (route.Count - 1)) { for (int i = trainIndex + 1; i < route.Count - 1 && !endSectionFound; i++) { lastSection = route[i].TrackCircuitSection; endSectionFound = lastSection.CircuitType == TrackCircuitType.Junction; } } else if (otherTrainIndex > 0) { for (int i = otherTrainIndex - 1; i >= 0 && !endSectionFound; i--) { lastSection = otherRoute[i].TrackCircuitSection; endSectionFound = lastSection.CircuitType == TrackCircuitType.Junction; if (lastSection.IsSet(otherTrain, true)) { allreadyActive = true; } } } lastSectionIndex = lastSection.Index; } // set deadlock info for both trains SetDeadlockInfo(firstSectionIndex, lastSectionIndex, otherTrain.Number); otherTrain.SetDeadlockInfo(lastSectionIndex, firstSectionIndex, Number); if (allreadyActive) { TrackCircuitSection section = TrackCircuitSection.TrackCircuitList[lastSectionIndex]; section.SetDeadlockTrap(otherTrain, otherTrain.DeadlockInfo[lastSectionIndex]); } returnValue[0] = route.GetRouteIndex(lastSectionIndex, index); if (returnValue[0] < 0) { returnValue[0] = trainIndex; } return(returnValue); }
// Check on deadlock private protected void CheckDeadlock(TrackCircuitPartialPathRoute route, int number) { // clear existing deadlock info ClearDeadlocks(); // build new deadlock info foreach (Train otherTrain in simulator.Trains) { // check if not AI_Static if (Simulator.Instance.SignalEnvironment.UseLocationPassingPaths && otherTrain.GetAiMovementState() == AiMovementState.Static) { continue; } if (otherTrain.Number != number && otherTrain.TrainType != TrainType.Static) { TrackCircuitPartialPathRoute otherRoute = otherTrain.ValidRoute[0]; ILookup <int, TrackDirection> otherRouteDict = otherRoute.ConvertRoute(); for (int i = 0; i < route.Count; i++) { TrackCircuitRouteElement routeElement = route[i]; TrackCircuitSection section = routeElement.TrackCircuitSection; TrackDirection sectionDirection = routeElement.Direction; if (section.CircuitType != TrackCircuitType.Crossover) { if (otherRouteDict.Contains(section.Index)) { TrackDirection otherTrainDirection = otherRouteDict[section.Index].First(); //<CSComment> Right part of OR clause refers to initial placement with trains back-to-back and running away one from the other</CSComment> if (otherTrainDirection == sectionDirection || (PresentPosition[Direction.Backward].TrackCircuitSectionIndex == otherTrain.PresentPosition[Direction.Backward].TrackCircuitSectionIndex && section.Index == PresentPosition[Direction.Backward].TrackCircuitSectionIndex && PresentPosition[Direction.Backward].Offset + otherTrain.PresentPosition[Direction.Backward].Offset - 1 > section.Length)) { i = EndCommonSection(i, route, otherRoute); } else { if (Simulator.Instance.SignalEnvironment.UseLocationPassingPaths) //new style location based logic { if (CheckRealDeadlockLocationBased(route, otherRoute, ref i)) { int[] endDeadlock = SetDeadlockLocationBased(i, route, otherRoute, otherTrain); // use end of alternative path if set i = endDeadlock[1] > 0 ? --endDeadlock[1] : endDeadlock[0]; } } else //old style path based logic { int[] endDeadlock = SetDeadlockPathBased(i, route, otherRoute, otherTrain); // use end of alternative path if set - if so, compensate for iElement++ i = endDeadlock[1] > 0 ? --endDeadlock[1] : endDeadlock[0]; } } } } } } } }