|
1 | | -// COPYRIGHT 2009 - 2022 by the Open Rails project. |
| 1 | +// COPYRIGHT 2009 - 2022 by the Open Rails project. |
2 | 2 | // |
3 | 3 | // This file is part of Open Rails. |
4 | 4 | // |
@@ -2872,6 +2872,8 @@ public void ComputePosition(Traveller traveler, bool backToFront, float elapsedT |
2872 | 2872 | p.FindCenterLine(); |
2873 | 2873 | } |
2874 | 2874 | } |
| 2875 | + |
| 2876 | + UpdatePositionFlags(); |
2875 | 2877 | } |
2876 | 2878 |
|
2877 | 2879 | #region Traveller-based updates |
@@ -3091,140 +3093,67 @@ private void AddVibrations(float factor) |
3091 | 3093 | } |
3092 | 3094 | #endregion |
3093 | 3095 |
|
3094 | | - // TODO These three fields should be in the TrainCarViewer. |
3095 | | - public int TrackSoundType = 0; |
3096 | | - public WorldLocation TrackSoundLocation = WorldLocation.None; |
3097 | | - public float TrackSoundDistSquared = 0; |
3098 | | - |
| 3096 | + public bool IsOverSwitch { get; private set; } |
| 3097 | + public bool IsOverCrossover { get; private set; } |
| 3098 | + public bool IsOverTrough { get; private set; } |
3099 | 3099 |
|
3100 | | - /// <summary> |
3101 | | - /// Checks if traincar is over trough. Used to check if refill possible |
3102 | | - /// </summary> |
3103 | | - /// <returns> returns true if car is over trough</returns> |
3104 | | - |
3105 | | - public bool IsOverTrough() |
| 3100 | + void UpdatePositionFlags() |
3106 | 3101 | { |
3107 | | - var isOverTrough = false; |
3108 | | - // start at front of train |
3109 | | - int thisSectionIndex = Train.PresentPosition[0].TCSectionIndex; |
3110 | | - if (thisSectionIndex < 0) return isOverTrough; |
3111 | | - float thisSectionOffset = Train.PresentPosition[0].TCOffset; |
3112 | | - int thisSectionDirection = Train.PresentPosition[0].TCDirection; |
| 3102 | + // Position flags can only change when we're moving! |
| 3103 | + if (Train == null || AbsSpeedMpS < 0.01f) return; |
3113 | 3104 |
|
| 3105 | + // Calculate the position of the ends of this car relative to the REAR of the train |
| 3106 | + var rearOffsetM = Train.PresentPosition[1].TCOffset; |
| 3107 | + for (var i = Train.Cars.IndexOf(this) + 1; i < Train.Cars.Count; i++) |
| 3108 | + rearOffsetM += Train.Cars[i - 1].CouplerSlackM + Train.Cars[i - 1].GetCouplerZeroLengthM() + Train.Cars[i].CarLengthM; |
| 3109 | + var frontOffsetM = rearOffsetM + CarLengthM; |
3114 | 3110 |
|
3115 | | - float usedCarLength = CarLengthM; |
3116 | | - float processedCarLength = 0; |
3117 | | - bool validSections = true; |
| 3111 | + var isOverSwitch = false; |
| 3112 | + var isOverCrossover = false; |
| 3113 | + var isOverTrough = false; |
3118 | 3114 |
|
3119 | | - while (validSections) |
| 3115 | + // Scan through the track sections forwards from the REAR of the train (`Train.PresentPosition[1]`), |
| 3116 | + // stopping as soon as we've passed this car (`checkedM`) or run out of track (`currentPin.Link`) |
| 3117 | + var checkedM = 0f; |
| 3118 | + var lastPin = new TrPin { Link = -1, Direction = -1 }; |
| 3119 | + var currentPin = new TrPin { Link = Train.PresentPosition[1].TCSectionIndex, Direction = Train.PresentPosition[1].TCDirection }; |
| 3120 | + while (checkedM <= frontOffsetM && currentPin.Link != -1) |
3120 | 3121 | { |
3121 | | - TrackCircuitSection thisSection = Train.signalRef.TrackCircuitList[thisSectionIndex]; |
3122 | | - isOverTrough = false; |
| 3122 | + var section = Simulator.Signals.TrackCircuitList[currentPin.Link]; |
3123 | 3123 |
|
3124 | | - // car spans sections |
3125 | | - if ((CarLengthM - processedCarLength) > thisSectionOffset) |
| 3124 | + // Does this car overlap this track section? |
| 3125 | + if (checkedM <= frontOffsetM && rearOffsetM <= checkedM + section.Length) |
3126 | 3126 | { |
3127 | | - usedCarLength = thisSectionOffset - processedCarLength; |
3128 | | - } |
3129 | | - |
3130 | | - // section has troughs |
3131 | | - if (thisSection.TroughInfo != null) |
3132 | | - { |
3133 | | - foreach (TrackCircuitSection.troughInfoData[] thisTrough in thisSection.TroughInfo) |
| 3127 | + if (section.CircuitType == TrackCircuitSection.TrackCircuitType.Junction) isOverSwitch = true; |
| 3128 | + if (section.CircuitType == TrackCircuitSection.TrackCircuitType.Crossover) isOverCrossover = true; |
| 3129 | + if (section.TroughInfo != null) |
3134 | 3130 | { |
3135 | | - float troughStartOffset = thisTrough[thisSectionDirection].TroughStart; |
3136 | | - float troughEndOffset = thisTrough[thisSectionDirection].TroughEnd; |
3137 | | - |
3138 | | - if (troughStartOffset > 0 && troughStartOffset > thisSectionOffset) // start of trough is in section beyond present position - cannot be over this trough nor any following |
| 3131 | + foreach (var troughs in section.TroughInfo) |
3139 | 3132 | { |
3140 | | - return isOverTrough; |
3141 | | - } |
3142 | | - |
3143 | | - if (troughEndOffset > 0 && troughEndOffset < (thisSectionOffset - usedCarLength)) // beyond end of trough, test next |
3144 | | - { |
3145 | | - continue; |
3146 | | - } |
3147 | | - |
3148 | | - if (troughStartOffset <= 0 || troughStartOffset < (thisSectionOffset - usedCarLength)) // start of trough is behind |
3149 | | - { |
3150 | | - isOverTrough = true; |
3151 | | - return isOverTrough; |
| 3133 | + var trough = troughs[currentPin.Direction]; |
| 3134 | + // Start and end are -1 if the trough extends beyond this section |
| 3135 | + var troughStart = trough.TroughStart < 0 ? 0 : trough.TroughStart; |
| 3136 | + var troughEnd = trough.TroughEnd < 0 ? section.Length : trough.TroughEnd; |
| 3137 | + if (checkedM + troughStart <= frontOffsetM && rearOffsetM <= checkedM + troughEnd) isOverTrough = true; |
3152 | 3138 | } |
3153 | 3139 | } |
3154 | 3140 | } |
3155 | | - // tested this section, any need to go beyond? |
| 3141 | + checkedM += section.Length; |
3156 | 3142 |
|
3157 | | - processedCarLength += usedCarLength; |
3158 | | - { |
3159 | | - // go back one section |
3160 | | - int thisSectionRouteIndex = Train.ValidRoute[0].GetRouteIndexBackward(thisSectionIndex, Train.PresentPosition[0].RouteListIndex); |
3161 | | - if (thisSectionRouteIndex >= 0) |
3162 | | - { |
3163 | | - thisSectionIndex = thisSectionRouteIndex; |
3164 | | - thisSection = Train.signalRef.TrackCircuitList[thisSectionIndex]; |
3165 | | - thisSectionOffset = thisSection.Length; // always at end of next section |
3166 | | - thisSectionDirection = Train.ValidRoute[0][thisSectionRouteIndex].Direction; |
3167 | | - } |
3168 | | - else // ran out of train |
3169 | | - { |
3170 | | - validSections = false; |
3171 | | - } |
3172 | | - } |
| 3143 | + var nextPin = section.GetNextActiveLink(currentPin.Direction, lastPin.Link); |
| 3144 | + lastPin = currentPin; |
| 3145 | + currentPin = nextPin; |
3173 | 3146 | } |
3174 | | - return isOverTrough; |
3175 | | - } |
3176 | 3147 |
|
3177 | | - /// <summary> |
3178 | | - /// Checks if traincar is over junction or crossover. Used to check if water scoop breaks |
3179 | | - /// </summary> |
3180 | | - /// <returns> returns true if car is over junction</returns> |
3181 | | - |
3182 | | - public bool IsOverJunction() |
3183 | | - { |
3184 | | - |
3185 | | - // To Do - This identifies the start of the train, but needs to be further refined to work for each carriage. |
3186 | | - var isOverJunction = false; |
3187 | | - // start at front of train |
3188 | | - int thisSectionIndex = Train.PresentPosition[0].TCSectionIndex; |
3189 | | - float thisSectionOffset = Train.PresentPosition[0].TCOffset; |
3190 | | - int thisSectionDirection = Train.PresentPosition[0].TCDirection; |
3191 | | - |
3192 | | - |
3193 | | - float usedCarLength = CarLengthM; |
3194 | | - |
3195 | | - if (Train.PresentPosition[0].TCSectionIndex != Train.PresentPosition[1].TCSectionIndex) |
3196 | | - { |
3197 | | - try |
3198 | | - { |
3199 | | - var copyOccupiedTrack = Train.OccupiedTrack.ToArray(); |
3200 | | - foreach (var thisSection in copyOccupiedTrack) |
3201 | | - { |
3202 | | - |
3203 | | - // Trace.TraceInformation(" Track Section - Index {0} Ciruit Type {1}", thisSectionIndex, thisSection.CircuitType); |
3204 | | - |
3205 | | - if (thisSection.CircuitType == TrackCircuitSection.TrackCircuitType.Junction || thisSection.CircuitType == TrackCircuitSection.TrackCircuitType.Crossover) |
3206 | | - { |
3207 | | - |
3208 | | - // train is on a switch; let's see if car is on a switch too |
3209 | | - WorldLocation switchLocation = TileLocation(Simulator.TDB.TrackDB.TrackNodes[thisSection.OriginalIndex].UiD); |
3210 | | - var distanceFromSwitch = WorldLocation.GetDistanceSquared(WorldPosition.WorldLocation, switchLocation); |
3211 | | - if (distanceFromSwitch < CarLengthM * CarLengthM + Math.Min(SpeedMpS * 3, 150)) |
3212 | | - { |
3213 | | - isOverJunction = true; |
3214 | | - return isOverJunction; |
3215 | | - } |
3216 | | - } |
3217 | | - } |
3218 | | - } |
3219 | | - catch |
3220 | | - { |
3221 | | - |
3222 | | - } |
3223 | | - } |
3224 | | - |
3225 | | - return isOverJunction; |
| 3148 | + IsOverSwitch = isOverSwitch; |
| 3149 | + IsOverCrossover = isOverCrossover; |
| 3150 | + IsOverTrough = isOverTrough; |
3226 | 3151 | } |
3227 | 3152 |
|
| 3153 | + // TODO These three fields should be in the TrainCarViewer. |
| 3154 | + public int TrackSoundType = 0; |
| 3155 | + public WorldLocation TrackSoundLocation = WorldLocation.None; |
| 3156 | + public float TrackSoundDistSquared = 0; |
3228 | 3157 |
|
3229 | 3158 | public static WorldLocation TileLocation(UiD uid) |
3230 | 3159 | { |
|
0 commit comments