Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework collider disabling in RSSRunwayFix #291

Merged
merged 1 commit into from
Sep 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Source/GUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ private void ShowGUI(int windowID)

GUILayout.Label("RSSRunwayFix");

GUILayout.BeginHorizontal();
GUILayout.Label("collidersDisabled: ");
GUILayout.Label(RSSRunwayFix.Instance.collidersDisabled.ToString(), GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal();

GUILayout.BeginHorizontal();
GUILayout.Label("isOnRunway: ");
GUILayout.Label(RSSRunwayFix.Instance.isOnRunway.ToString(), GUILayout.ExpandWidth(false));
Expand Down
138 changes: 58 additions & 80 deletions Source/RSSRunwayFix.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections;
using UnityEngine;
using static RunwayCollisionHandler;

namespace RealSolarSystem
{
Expand All @@ -22,16 +23,12 @@ public class RSSRunwayFix : MonoBehaviour
internal bool isOnRunway = false;
internal string lastHitColliderName;

internal bool collidersDisabled = false;
private bool waiting = false;
private IEnumerator waitCoro = null;
private bool coroComplete = false;

private Vector3 down;

private string[] collidersToFix =
{
"End09", "Section4", "Section3", "Section2", "Section1", "End27"
};
private Coroutine _sectionsLoadRoutine;

public static RSSRunwayFix Instance { get; private set; } = null;

Expand All @@ -46,46 +43,51 @@ public void Awake()

public void Start()
{
PrintDebug("Start");

foreach (ConfigNode n in GameDatabase.Instance.GetConfigNodes("RSSRUNWAYFIX"))
{
if (bool.TryParse(n.GetValue("debug"), out bool bTemp))
{
debug = bTemp;
}

if (float.TryParse(n.GetValue("holdThreshold"), out float fTemp))
{
holdThreshold = fTemp;
}
}

GameEvents.onVesselGoOffRails.Add (OnVesselGoOffRails);
GameEvents.onVesselGoOnRails.Add (OnVesselGoOnRails);
GameEvents.onVesselSwitching.Add (OnVesselSwitching);
GameEvents.onVesselSituationChange.Add (OnVesselSituationChange);

//GameEvents.onFloatingOriginShift.Add(onFloatingOriginShift);
GameEvents.onVesselGoOffRails.Add(OnVesselGoOffRails);
GameEvents.onVesselGoOnRails.Add(OnVesselGoOnRails);
GameEvents.onVesselSwitching.Add(OnVesselSwitching);
GameEvents.onVesselSituationChange.Add(OnVesselSituationChange);
DestructibleBuilding.OnLoaded.Add(OnSectionLoaded);
}

public void OnDestroy()
{
PrintDebug("OnDestroy");
GameEvents.onVesselGoOffRails.Remove (OnVesselGoOffRails);
GameEvents.onVesselGoOnRails.Remove (OnVesselGoOnRails);
GameEvents.onVesselSwitching.Remove (OnVesselSwitching);
GameEvents.onVesselGoOffRails.Remove(OnVesselGoOffRails);
GameEvents.onVesselGoOnRails.Remove(OnVesselGoOnRails);
GameEvents.onVesselSwitching.Remove(OnVesselSwitching);
GameEvents.onVesselSituationChange.Remove(OnVesselSituationChange);

//GameEvents.onFloatingOriginShift.Remove(onFloatingOriginShift);
DestructibleBuilding.OnLoaded.Remove(OnSectionLoaded);
}

public void OnFloatingOriginShift(Vector3d v0, Vector3d v1)
private void OnSectionLoaded(DestructibleBuilding data)
{
if (!hold)
// At the end of the frame, KSP will fire this event for every destructible KSC prop.
// We wait until the next frame so that all of the runway sections are guaranteed to be loaded.
if (!collidersDisabled && _sectionsLoadRoutine == null)
{
return;
_sectionsLoadRoutine = StartCoroutine(SectionsLoadRoutine());
}
if (debug) PrintDebug($"RSSRWF: v0: {v0}, v1: {v1}, threshold: {FloatingOrigin.fetch.threshold}");
}

private IEnumerator SectionsLoadRoutine()
{
yield return null;

TryDisableColliders();
_sectionsLoadRoutine = null;
}

public void OnVesselGoOnRails(Vessel v)
Expand All @@ -97,25 +99,19 @@ public void OnVesselGoOnRails(Vessel v)

public void OnVesselGoOffRails(Vessel v)
{
PrintDebug("started");

originalThreshold = FloatingOrigin.fetch.threshold;
originalThresholdSqr = FloatingOrigin.fetch.thresholdSqr;

if (debug) PrintDebug($"original threshold={originalThreshold}");
holdThresholdSqr = holdThreshold * holdThreshold;

GameObject end09 = GameObject.Find(collidersToFix[0]);
if (end09 == null)
if (!collidersDisabled)
{
PrintDebug("no end09 found");
if (debug) PrintDebug("colliders not disabled yet");
hold = false;
return;
}

//combine(end09.transform.parent.gameObject);
DisableColliders();
GetDownwardVector();
hold = true;
waiting = false;
}
Expand All @@ -128,14 +124,13 @@ public void OnVesselSwitching(Vessel from, Vessel to)
return;
}

GetDownwardVector();
waiting = false;
}

private void GetDownwardVector()
private Vector3 GetDownwardVector()
{
Vessel v = FlightGlobals.ActiveVessel;
down = (v.CoM - v.mainBody.transform.position).normalized * -1;
return (v.CoM - v.mainBody.transform.position).normalized * -1;
}

public void OnVesselSituationChange(GameEvents.HostedFromToAction<Vessel, Vessel.Situations> data)
Expand All @@ -146,19 +141,19 @@ public void OnVesselSituationChange(GameEvents.HostedFromToAction<Vessel, Vessel
}

hold = data.to == Vessel.Situations.LANDED;
PrintDebug($"vessel: {data.host.vesselName}, situation: {data.to}, hold: {hold}");
if (debug) PrintDebug($"vessel: {data.host.vesselName}, situation: {data.to}, hold: {hold}");

if (!hold && FloatingOrigin.fetch.threshold > originalThreshold && originalThreshold > 0)
{
PrintDebug($"coro: {waitCoro}, complete: {coroComplete}");
if (debug) PrintDebug($"coro: {waitCoro}, complete: {coroComplete}");
if (waitCoro != null && !coroComplete)
{
PrintDebug("stopping coro");
if (debug) PrintDebug("stopping coro");
StopCoroutine(waitCoro);
}

waitCoro = RestoreThreshold();
PrintDebug($"created new coro: {waitCoro}");
if (debug) PrintDebug($"created new coro: {waitCoro}");

coroComplete = false;
StartCoroutine(waitCoro);
Expand All @@ -174,17 +169,18 @@ private IEnumerator RestoreThreshold()
waiting = true;
yield return new WaitForSeconds(5);
waiting = false;
PrintDebug("waiting is over");
if (debug) PrintDebug("waiting is over");
}

// Check again as situation could have changed
if (!hold && FloatingOrigin.fetch.threshold > originalThreshold && originalThreshold > 0) {
if (!hold && FloatingOrigin.fetch.threshold > originalThreshold && originalThreshold > 0)
{
if (debug) PrintDebug($"Restoring original thresholds ({FloatingOrigin.fetch.threshold} > {originalThreshold}), "+
$"alt={FlightGlobals.ActiveVessel.radarAltitude}");
FloatingOrigin.fetch.threshold = originalThreshold;
FloatingOrigin.fetch.thresholdSqr = originalThresholdSqr;
}
PrintDebug("coro finished");
if (debug) PrintDebug("coro finished");
coroComplete = true;
}

Expand Down Expand Up @@ -228,13 +224,12 @@ private bool CheckRunway()
}

Vessel v = FlightGlobals.ActiveVessel;
if (v.situation != Vessel.Situations.LANDED && v.situation != Vessel.Situations.PRELAUNCH)
if (v == null || (v.situation != Vessel.Situations.LANDED && v.situation != Vessel.Situations.PRELAUNCH))
{
return false;
}

GetDownwardVector();

Vector3 down = GetDownwardVector();
bool hit = Physics.Raycast(v.transform.position, down, out RaycastHit raycastHit, 100, layerMask);
if (!hit)
{
Expand All @@ -243,17 +238,12 @@ private bool CheckRunway()

lastHitColliderName = raycastHit.collider.gameObject.name;
//if (debug) printDebug($"hit collider: {colliderName}");
if (lastHitColliderName != "runway_collider")
{
return false;
}

return true;
return lastHitColliderName == "runway_collider";
}

internal void PrintDebug(string message)
{

if (!debug) return;

var trace = new System.Diagnostics.StackTrace();
Expand All @@ -262,38 +252,26 @@ internal void PrintDebug(string message)
Debug.Log($"[RealSolarSystem] {caller}:{line}: {message}");
}

private void DisableColliders()
private void TryDisableColliders()
{
foreach (string c in collidersToFix)
// Once disabled, the colliders will stay disabled
if (collidersDisabled) return;

var rwHandler = FindObjectOfType<RunwayCollisionHandler>();
if (rwHandler == null)
{
bool notFound = true;
foreach (GameObject o in Resources.FindObjectsOfTypeAll<GameObject>())
{
if (o.name != c)
continue;

notFound = false;
if (!o.activeInHierarchy)
{
if (debug) PrintDebug($"{o.name} is not active, skipping");
continue;
}

MeshCollider cl = o.GetComponentInChildren<MeshCollider>();
if (cl == null)
{
if (debug) PrintDebug($" No mesh collider in {c}");
continue;
}
if (debug) PrintDebug($" disabling {cl.name}");
cl.enabled = false;
}
if (notFound)
{
if (debug) PrintDebug($" Object {c} not found, skipping");
continue;
}
if (debug) PrintDebug("rwHandler is null");
return;
}

foreach (RunwaySection section in rwHandler.runwaySections)
{
Collider sc = section.sectionCollider;
sc.enabled = false;
}

collidersDisabled = true;
if (debug) PrintDebug("disabled runway colliders");
}
}
}