11using System . Collections ;
22using UnityEngine ;
3+ using static RunwayCollisionHandler ;
34
45namespace RealSolarSystem
56{
@@ -22,16 +23,12 @@ public class RSSRunwayFix : MonoBehaviour
2223 internal bool isOnRunway = false ;
2324 internal string lastHitColliderName ;
2425
26+ internal bool collidersDisabled = false ;
2527 private bool waiting = false ;
2628 private IEnumerator waitCoro = null ;
2729 private bool coroComplete = false ;
2830
29- private Vector3 down ;
30-
31- private string [ ] collidersToFix =
32- {
33- "End09" , "Section4" , "Section3" , "Section2" , "Section1" , "End27"
34- } ;
31+ private Coroutine _sectionsLoadRoutine ;
3532
3633 public static RSSRunwayFix Instance { get ; private set ; } = null ;
3734
@@ -46,46 +43,51 @@ public void Awake()
4643
4744 public void Start ( )
4845 {
49- PrintDebug ( "Start" ) ;
50-
5146 foreach ( ConfigNode n in GameDatabase . Instance . GetConfigNodes ( "RSSRUNWAYFIX" ) )
5247 {
5348 if ( bool . TryParse ( n . GetValue ( "debug" ) , out bool bTemp ) )
5449 {
5550 debug = bTemp ;
5651 }
52+
5753 if ( float . TryParse ( n . GetValue ( "holdThreshold" ) , out float fTemp ) )
5854 {
5955 holdThreshold = fTemp ;
6056 }
6157 }
6258
63- GameEvents . onVesselGoOffRails . Add ( OnVesselGoOffRails ) ;
64- GameEvents . onVesselGoOnRails . Add ( OnVesselGoOnRails ) ;
65- GameEvents . onVesselSwitching . Add ( OnVesselSwitching ) ;
66- GameEvents . onVesselSituationChange . Add ( OnVesselSituationChange ) ;
67-
68- //GameEvents.onFloatingOriginShift.Add(onFloatingOriginShift);
59+ GameEvents . onVesselGoOffRails . Add ( OnVesselGoOffRails ) ;
60+ GameEvents . onVesselGoOnRails . Add ( OnVesselGoOnRails ) ;
61+ GameEvents . onVesselSwitching . Add ( OnVesselSwitching ) ;
62+ GameEvents . onVesselSituationChange . Add ( OnVesselSituationChange ) ;
63+ DestructibleBuilding . OnLoaded . Add ( OnSectionLoaded ) ;
6964 }
7065
7166 public void OnDestroy ( )
7267 {
73- PrintDebug ( "OnDestroy" ) ;
74- GameEvents . onVesselGoOffRails . Remove ( OnVesselGoOffRails ) ;
75- GameEvents . onVesselGoOnRails . Remove ( OnVesselGoOnRails ) ;
76- GameEvents . onVesselSwitching . Remove ( OnVesselSwitching ) ;
68+ GameEvents . onVesselGoOffRails . Remove ( OnVesselGoOffRails ) ;
69+ GameEvents . onVesselGoOnRails . Remove ( OnVesselGoOnRails ) ;
70+ GameEvents . onVesselSwitching . Remove ( OnVesselSwitching ) ;
7771 GameEvents . onVesselSituationChange . Remove ( OnVesselSituationChange ) ;
78-
79- //GameEvents.onFloatingOriginShift.Remove(onFloatingOriginShift);
72+ DestructibleBuilding . OnLoaded . Remove ( OnSectionLoaded ) ;
8073 }
8174
82- public void OnFloatingOriginShift ( Vector3d v0 , Vector3d v1 )
75+ private void OnSectionLoaded ( DestructibleBuilding data )
8376 {
84- if ( ! hold )
77+ // At the end of the frame, KSP will fire this event for every destructible KSC prop.
78+ // We wait until the next frame so that all of the runway sections are guaranteed to be loaded.
79+ if ( ! collidersDisabled && _sectionsLoadRoutine == null )
8580 {
86- return ;
81+ _sectionsLoadRoutine = StartCoroutine ( SectionsLoadRoutine ( ) ) ;
8782 }
88- if ( debug ) PrintDebug ( $ "RSSRWF: v0: { v0 } , v1: { v1 } , threshold: { FloatingOrigin . fetch . threshold } ") ;
83+ }
84+
85+ private IEnumerator SectionsLoadRoutine ( )
86+ {
87+ yield return null ;
88+
89+ TryDisableColliders ( ) ;
90+ _sectionsLoadRoutine = null ;
8991 }
9092
9193 public void OnVesselGoOnRails ( Vessel v )
@@ -97,25 +99,19 @@ public void OnVesselGoOnRails(Vessel v)
9799
98100 public void OnVesselGoOffRails ( Vessel v )
99101 {
100- PrintDebug ( "started" ) ;
101-
102102 originalThreshold = FloatingOrigin . fetch . threshold ;
103103 originalThresholdSqr = FloatingOrigin . fetch . thresholdSqr ;
104104
105105 if ( debug ) PrintDebug ( $ "original threshold={ originalThreshold } ") ;
106106 holdThresholdSqr = holdThreshold * holdThreshold ;
107107
108- GameObject end09 = GameObject . Find ( collidersToFix [ 0 ] ) ;
109- if ( end09 == null )
108+ if ( ! collidersDisabled )
110109 {
111- PrintDebug ( "no end09 found " ) ;
110+ if ( debug ) PrintDebug ( "colliders not disabled yet " ) ;
112111 hold = false ;
113112 return ;
114113 }
115114
116- //combine(end09.transform.parent.gameObject);
117- DisableColliders ( ) ;
118- GetDownwardVector ( ) ;
119115 hold = true ;
120116 waiting = false ;
121117 }
@@ -128,14 +124,13 @@ public void OnVesselSwitching(Vessel from, Vessel to)
128124 return ;
129125 }
130126
131- GetDownwardVector ( ) ;
132127 waiting = false ;
133128 }
134129
135- private void GetDownwardVector ( )
130+ private Vector3 GetDownwardVector ( )
136131 {
137132 Vessel v = FlightGlobals . ActiveVessel ;
138- down = ( v . CoM - v . mainBody . transform . position ) . normalized * - 1 ;
133+ return ( v . CoM - v . mainBody . transform . position ) . normalized * - 1 ;
139134 }
140135
141136 public void OnVesselSituationChange ( GameEvents . HostedFromToAction < Vessel , Vessel . Situations > data )
@@ -146,19 +141,19 @@ public void OnVesselSituationChange(GameEvents.HostedFromToAction<Vessel, Vessel
146141 }
147142
148143 hold = data . to == Vessel . Situations . LANDED ;
149- PrintDebug ( $ "vessel: { data . host . vesselName } , situation: { data . to } , hold: { hold } ") ;
144+ if ( debug ) PrintDebug ( $ "vessel: { data . host . vesselName } , situation: { data . to } , hold: { hold } ") ;
150145
151146 if ( ! hold && FloatingOrigin . fetch . threshold > originalThreshold && originalThreshold > 0 )
152147 {
153- PrintDebug ( $ "coro: { waitCoro } , complete: { coroComplete } ") ;
148+ if ( debug ) PrintDebug ( $ "coro: { waitCoro } , complete: { coroComplete } ") ;
154149 if ( waitCoro != null && ! coroComplete )
155150 {
156- PrintDebug ( "stopping coro" ) ;
151+ if ( debug ) PrintDebug ( "stopping coro" ) ;
157152 StopCoroutine ( waitCoro ) ;
158153 }
159154
160155 waitCoro = RestoreThreshold ( ) ;
161- PrintDebug ( $ "created new coro: { waitCoro } ") ;
156+ if ( debug ) PrintDebug ( $ "created new coro: { waitCoro } ") ;
162157
163158 coroComplete = false ;
164159 StartCoroutine ( waitCoro ) ;
@@ -174,17 +169,18 @@ private IEnumerator RestoreThreshold()
174169 waiting = true ;
175170 yield return new WaitForSeconds ( 5 ) ;
176171 waiting = false ;
177- PrintDebug ( "waiting is over" ) ;
172+ if ( debug ) PrintDebug ( "waiting is over" ) ;
178173 }
179174
180175 // Check again as situation could have changed
181- if ( ! hold && FloatingOrigin . fetch . threshold > originalThreshold && originalThreshold > 0 ) {
176+ if ( ! hold && FloatingOrigin . fetch . threshold > originalThreshold && originalThreshold > 0 )
177+ {
182178 if ( debug ) PrintDebug ( $ "Restoring original thresholds ({ FloatingOrigin . fetch . threshold } > { originalThreshold } ), "+
183179 $ "alt={ FlightGlobals . ActiveVessel . radarAltitude } ") ;
184180 FloatingOrigin . fetch . threshold = originalThreshold ;
185181 FloatingOrigin . fetch . thresholdSqr = originalThresholdSqr ;
186182 }
187- PrintDebug ( "coro finished" ) ;
183+ if ( debug ) PrintDebug ( "coro finished" ) ;
188184 coroComplete = true ;
189185 }
190186
@@ -228,13 +224,12 @@ private bool CheckRunway()
228224 }
229225
230226 Vessel v = FlightGlobals . ActiveVessel ;
231- if ( v . situation != Vessel . Situations . LANDED && v . situation != Vessel . Situations . PRELAUNCH )
227+ if ( v == null || ( v . situation != Vessel . Situations . LANDED && v . situation != Vessel . Situations . PRELAUNCH ) )
232228 {
233229 return false ;
234230 }
235-
236- GetDownwardVector ( ) ;
237231
232+ Vector3 down = GetDownwardVector ( ) ;
238233 bool hit = Physics . Raycast ( v . transform . position , down , out RaycastHit raycastHit , 100 , layerMask ) ;
239234 if ( ! hit )
240235 {
@@ -243,17 +238,12 @@ private bool CheckRunway()
243238
244239 lastHitColliderName = raycastHit . collider . gameObject . name ;
245240 //if (debug) printDebug($"hit collider: {colliderName}");
246- if ( lastHitColliderName != "runway_collider" )
247- {
248- return false ;
249- }
250241
251- return true ;
242+ return lastHitColliderName == "runway_collider" ;
252243 }
253244
254245 internal void PrintDebug ( string message )
255246 {
256-
257247 if ( ! debug ) return ;
258248
259249 var trace = new System . Diagnostics . StackTrace ( ) ;
@@ -262,38 +252,26 @@ internal void PrintDebug(string message)
262252 Debug . Log ( $ "[RealSolarSystem] { caller } :{ line } : { message } ") ;
263253 }
264254
265- private void DisableColliders ( )
255+ private void TryDisableColliders ( )
266256 {
267- foreach ( string c in collidersToFix )
257+ // Once disabled, the colliders will stay disabled
258+ if ( collidersDisabled ) return ;
259+
260+ var rwHandler = FindObjectOfType < RunwayCollisionHandler > ( ) ;
261+ if ( rwHandler == null )
268262 {
269- bool notFound = true ;
270- foreach ( GameObject o in Resources . FindObjectsOfTypeAll < GameObject > ( ) )
271- {
272- if ( o . name != c )
273- continue ;
274-
275- notFound = false ;
276- if ( ! o . activeInHierarchy )
277- {
278- if ( debug ) PrintDebug ( $ "{ o . name } is not active, skipping") ;
279- continue ;
280- }
281-
282- MeshCollider cl = o . GetComponentInChildren < MeshCollider > ( ) ;
283- if ( cl == null )
284- {
285- if ( debug ) PrintDebug ( $ " No mesh collider in { c } ") ;
286- continue ;
287- }
288- if ( debug ) PrintDebug ( $ " disabling { cl . name } ") ;
289- cl . enabled = false ;
290- }
291- if ( notFound )
292- {
293- if ( debug ) PrintDebug ( $ " Object { c } not found, skipping") ;
294- continue ;
295- }
263+ if ( debug ) PrintDebug ( "rwHandler is null" ) ;
264+ return ;
296265 }
266+
267+ foreach ( RunwaySection section in rwHandler . runwaySections )
268+ {
269+ Collider sc = section . sectionCollider ;
270+ sc . enabled = false ;
297271 }
272+
273+ collidersDisabled = true ;
274+ if ( debug ) PrintDebug ( "disabled runway colliders" ) ;
275+ }
298276 }
299277}
0 commit comments