|
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