-
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move determinstic stuff to separate folder, remove WO dumps
- Loading branch information
1 parent
b04a593
commit cb6b811
Showing
14 changed files
with
307 additions
and
314 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
using HarmonyLib; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using UnityEngine; | ||
|
||
namespace QSB.Utility.Deterministic; | ||
|
||
/// <summary> | ||
/// TODO make this only do cache clearing on pre scene load when HOSTING instead of just all the time | ||
/// </summary> | ||
public static class DeterministicManager | ||
{ | ||
private static readonly Harmony _harmony = new(typeof(DeterministicManager).FullName); | ||
private static bool _patched; | ||
|
||
public static readonly Dictionary<Transform, (int SiblingIndex, Transform Parent)> Cache = new(); | ||
|
||
public static void Init() => | ||
QSBSceneManager.OnPreSceneLoad += (_, _) => | ||
{ | ||
DebugLog.DebugWrite("cleared cache"); | ||
Cache.Clear(); | ||
if (!_patched) | ||
{ | ||
_harmony.PatchAll(typeof(OWRigidbodyPatches)); | ||
_patched = true; | ||
} | ||
}; | ||
|
||
public static void OnWorldObjectsAdded() | ||
{ | ||
//DebugLog.DebugWrite($"cleared cache of {_cache.Count} entries"); | ||
//_cache.Clear(); | ||
|
||
if (_patched) | ||
{ | ||
_harmony.UnpatchSelf(); | ||
_patched = false; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// only call this before world objects added | ||
/// </summary> | ||
public static string DeterministicPath(this Component component) | ||
{ | ||
var sb = new StringBuilder(); | ||
var transform = component.transform; | ||
while (true) | ||
{ | ||
if (!Cache.TryGetValue(transform, out var data)) | ||
{ | ||
data = (transform.GetSiblingIndex(), transform.parent); | ||
Cache.Add(transform, data); | ||
} | ||
|
||
if (!data.Parent) | ||
{ | ||
break; | ||
} | ||
|
||
sb.Append(transform.name); | ||
sb.Append(' '); | ||
sb.Append(data.SiblingIndex); | ||
sb.Append(' '); | ||
transform = data.Parent; | ||
} | ||
|
||
sb.Append(transform.name); | ||
return sb.ToString(); | ||
} | ||
|
||
/// <summary> | ||
/// only call this before world objects added | ||
/// </summary> | ||
public static IEnumerable<T> SortDeterministic<T>(this IEnumerable<T> components) where T : Component | ||
=> components.OrderBy(DeterministicPath); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
using HarmonyLib; | ||
using System.Collections.Generic; | ||
using UnityEngine; | ||
|
||
namespace QSB.Utility.Deterministic; | ||
|
||
[HarmonyPatch(typeof(OWRigidbody))] | ||
public static class OWRigidbodyPatches | ||
{ | ||
private static readonly Dictionary<OWRigidbody, Transform> _setParentQueue = new(); | ||
|
||
[HarmonyPrefix] | ||
[HarmonyPatch(nameof(OWRigidbody.Awake))] | ||
private static bool Awake(OWRigidbody __instance) | ||
{ | ||
__instance._transform = __instance.transform; | ||
|
||
// ADDED | ||
DeterministicManager.Cache.Add(__instance._transform, (__instance._transform.GetSiblingIndex(), __instance._transform.parent)); | ||
|
||
if (!__instance._scaleRoot) | ||
{ | ||
__instance._scaleRoot = __instance._transform; | ||
} | ||
|
||
CenterOfTheUniverse.TrackRigidbody(__instance); | ||
__instance._offsetApplier = __instance.gameObject.GetAddComponent<CenterOfTheUniverseOffsetApplier>(); | ||
__instance._offsetApplier.Init(__instance); | ||
if (__instance._simulateInSector) | ||
{ | ||
__instance._simulateInSector.OnSectorOccupantsUpdated += __instance.OnSectorOccupantsUpdated; | ||
} | ||
|
||
__instance._origParent = __instance._transform.parent; | ||
__instance._origParentBody = __instance._origParent ? __instance._origParent.GetAttachedOWRigidbody() : null; | ||
|
||
// ADDED | ||
if (__instance._transform.parent) | ||
{ | ||
_setParentQueue[__instance] = null; | ||
} | ||
|
||
// REMOVED | ||
/*if (__instance._transform.parent != null) | ||
{ | ||
__instance._transform.parent = null; | ||
}*/ | ||
|
||
__instance._rigidbody = __instance.GetRequiredComponent<Rigidbody>(); | ||
__instance._rigidbody.interpolation = RigidbodyInterpolation.None; | ||
|
||
if (!__instance._autoGenerateCenterOfMass) | ||
{ | ||
__instance._rigidbody.centerOfMass = __instance._centerOfMass; | ||
} | ||
|
||
if (__instance.IsSimulatedKinematic()) | ||
{ | ||
__instance.EnableKinematicSimulation(); | ||
} | ||
|
||
__instance._origCenterOfMass = __instance.RunningKinematicSimulation() ? __instance._kinematicRigidbody.centerOfMass : __instance._rigidbody.centerOfMass; | ||
__instance._referenceFrame = new ReferenceFrame(__instance); | ||
|
||
return false; | ||
} | ||
|
||
[HarmonyPrefix] | ||
[HarmonyPatch(nameof(OWRigidbody.Start))] | ||
private static void Start(OWRigidbody __instance) | ||
{ | ||
if (_setParentQueue.TryGetValue(__instance, out var parent)) | ||
{ | ||
__instance._transform.parent = parent; | ||
_setParentQueue.Remove(__instance); | ||
} | ||
} | ||
|
||
[HarmonyPrefix] | ||
[HarmonyPatch(nameof(OWRigidbody.OnDestroy))] | ||
private static void OnDestroy(OWRigidbody __instance) | ||
{ | ||
DeterministicManager.Cache.Remove(__instance._transform); | ||
_setParentQueue.Remove(__instance); | ||
} | ||
|
||
[HarmonyPrefix] | ||
[HarmonyPatch(nameof(OWRigidbody.Suspend), typeof(Transform), typeof(OWRigidbody))] | ||
private static bool Suspend(OWRigidbody __instance, Transform suspensionParent, OWRigidbody suspensionBody) | ||
{ | ||
if (!__instance._suspended || __instance._unsuspendNextUpdate) | ||
{ | ||
__instance._suspensionBody = suspensionBody; | ||
var direction = __instance.GetVelocity() - suspensionBody.GetPointVelocity(__instance._transform.position); | ||
__instance._cachedRelativeVelocity = suspensionBody.transform.InverseTransformDirection(direction); | ||
__instance._cachedAngularVelocity = __instance.RunningKinematicSimulation() ? __instance._kinematicRigidbody.angularVelocity : __instance._rigidbody.angularVelocity; | ||
__instance.enabled = false; | ||
__instance._offsetApplier.enabled = false; | ||
|
||
if (__instance.RunningKinematicSimulation()) | ||
{ | ||
__instance._kinematicRigidbody.enabled = false; | ||
} | ||
else | ||
{ | ||
__instance.MakeKinematic(); | ||
} | ||
|
||
// ADDED | ||
if (_setParentQueue.ContainsKey(__instance)) | ||
{ | ||
_setParentQueue[__instance] = suspensionParent; | ||
} | ||
else | ||
{ | ||
__instance._transform.parent = suspensionParent; | ||
} | ||
|
||
// REMOVED | ||
// __instance._transform.parent = suspensionParent; | ||
|
||
__instance._suspended = true; | ||
__instance._unsuspendNextUpdate = false; | ||
if (!Physics.autoSyncTransforms) | ||
{ | ||
Physics.SyncTransforms(); | ||
} | ||
|
||
if (__instance._childColliders == null) | ||
{ | ||
__instance._childColliders = __instance.GetComponentsInChildren<Collider>(); | ||
|
||
// CLEANED | ||
foreach (var childCollider in __instance._childColliders) | ||
{ | ||
childCollider.gameObject.GetAddComponent<OWCollider>().ListenForParentBodySuspension(); | ||
} | ||
} | ||
|
||
__instance.RaiseEvent(nameof(__instance.OnSuspendOWRigidbody), __instance); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
[HarmonyPrefix] | ||
[HarmonyPatch(nameof(OWRigidbody.ChangeSuspensionBody))] | ||
private static bool ChangeSuspensionBody(OWRigidbody __instance, OWRigidbody newSuspensionBody) | ||
{ | ||
if (__instance._suspended) | ||
{ | ||
__instance._cachedRelativeVelocity = Vector3.zero; | ||
__instance._suspensionBody = newSuspensionBody; | ||
|
||
// ADDED | ||
if (_setParentQueue.ContainsKey(__instance)) | ||
{ | ||
_setParentQueue[__instance] = newSuspensionBody.transform; | ||
} | ||
else | ||
{ | ||
__instance._transform.parent = newSuspensionBody.transform; | ||
} | ||
|
||
// REMOVED | ||
// __instance._transform.parent = newSuspensionBody.transform; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
[HarmonyPrefix] | ||
[HarmonyPatch(nameof(OWRigidbody.UnsuspendImmediate))] | ||
private static bool UnsuspendImmediate(OWRigidbody __instance, bool restoreCachedVelocity) | ||
{ | ||
if (__instance._suspended) | ||
{ | ||
if (__instance.RunningKinematicSimulation()) | ||
{ | ||
__instance._kinematicRigidbody.enabled = true; | ||
} | ||
else | ||
{ | ||
__instance.MakeNonKinematic(); | ||
} | ||
|
||
__instance.enabled = true; | ||
|
||
// ADDED | ||
if (_setParentQueue.ContainsKey(__instance)) | ||
{ | ||
_setParentQueue[__instance] = null; | ||
} | ||
else | ||
{ | ||
__instance._transform.parent = null; | ||
} | ||
|
||
// REMOVED | ||
// __instance._transform.parent = null; | ||
|
||
if (!Physics.autoSyncTransforms) | ||
{ | ||
Physics.SyncTransforms(); | ||
} | ||
|
||
var cachedVelocity = restoreCachedVelocity ? __instance._suspensionBody.transform.TransformDirection(__instance._cachedRelativeVelocity) : Vector3.zero; | ||
__instance.SetVelocity(__instance._suspensionBody.GetPointVelocity(__instance._transform.position) + cachedVelocity); | ||
__instance.SetAngularVelocity(restoreCachedVelocity ? __instance._cachedAngularVelocity : Vector3.zero); | ||
__instance._suspended = false; | ||
__instance._suspensionBody = null; | ||
__instance.RaiseEvent(nameof(__instance.OnUnsuspendOWRigidbody), __instance); | ||
} | ||
|
||
return false; | ||
} | ||
} |
Oops, something went wrong.