using OWML.Utils; using QSB.Events; using System.Linq; using System.Reflection; using UnityEngine; namespace QSB.QuantumSync.Events { public class MoonStateChangeEvent : QSBEvent { public override bool RequireWorldObjectsReady => true; public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBMoonStateChange, Handler); public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBMoonStateChange, Handler); private void Handler(int stateIndex, Vector3 onUnitSphere, int orbitAngle) => SendEvent(CreateMessage(stateIndex, onUnitSphere, orbitAngle)); private MoonStateChangeMessage CreateMessage(int stateIndex, Vector3 onUnitSphere, int orbitAngle) => new() { AboutId = LocalPlayerId, StateIndex = stateIndex, OnUnitSphere = onUnitSphere, OrbitAngle = orbitAngle }; public override void OnReceiveRemote(bool server, MoonStateChangeMessage message) { var moon = Locator.GetQuantumMoon(); var wasPlayerEntangled = moon.IsPlayerEntangled(); var location = new RelativeLocationData(Locator.GetPlayerTransform().GetComponent(), moon.transform); var moonBody = moon.GetValue("_moonBody"); var constantFoceDetector = (ConstantForceDetector)moonBody.GetAttachedForceDetector(); var orbits = moon.GetValue("_orbits"); var orbit = orbits.First(x => x.GetStateIndex() == message.StateIndex); var orbitRadius = orbit.GetOrbitRadius(); var owRigidbody = orbit.GetAttachedOWRigidbody(); var position = (message.OnUnitSphere * orbitRadius) + owRigidbody.GetWorldCenterOfMass(); moonBody.transform.position = position; if (!Physics.autoSyncTransforms) { Physics.SyncTransforms(); } constantFoceDetector.AddConstantVolume(owRigidbody.GetAttachedGravityVolume(), true, true); moonBody.SetVelocity(OWPhysics.CalculateOrbitVelocity(owRigidbody, moonBody, message.OrbitAngle) + owRigidbody.GetVelocity()); moon.SetValue("_stateIndex", message.StateIndex); if (moon.IsPlayerInside()) { moon.GetType().GetMethod("SetSurfaceState", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(moon, new object[] { message.StateIndex }); } else { moon.GetType().GetMethod("SetSurfaceState", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(moon, new object[] { -1 }); moon.GetValue("_quantumSignal").SetSignalActivation(message.StateIndex != 5, 2f); } moon.GetValue("_referenceFrameVolume").gameObject.SetActive(message.StateIndex != 5); moonBody.SetIsTargetable(message.StateIndex != 5); foreach (var obj in moon.GetValue("_deactivateAtEye")) { obj.SetActive(message.StateIndex != 5); } GlobalMessenger.FireEvent("QuantumMoonChangeState", moonBody); if (wasPlayerEntangled) { Locator.GetPlayerTransform().GetComponent().MoveToRelativeLocation(location, moon.transform); } } } }