using System.Collections.Generic; using NitroxClient.GameLogic; using NitroxClient.GameLogic.PlayerLogic; using NitroxClient.GameLogic.PlayerLogic.PlayerModel.Abstract; using UnityEngine; namespace NitroxClient.MonoBehaviours.Cyclops; /// /// Script responsible for managing all player movement-related interactions. /// public class NitroxCyclops : MonoBehaviour { public VirtualCyclops Virtual; private CyclopsMotor cyclopsMotor; private SubRoot subRoot; private SubControl subControl; private Rigidbody rigidbody; private WorldForces worldForces; private Stabilizer stabilizer; private CharacterController controller; private CyclopsNoiseManager cyclopsNoiseManager; public readonly Dictionary Pawns = []; public static readonly Dictionary ScaledNoiseByCyclops = []; public void Start() { cyclopsMotor = Player.mainObject.GetComponent(); subRoot = GetComponent(); subControl = GetComponent(); rigidbody = GetComponent(); worldForces = GetComponent(); stabilizer = GetComponent(); controller = cyclopsMotor.controller; cyclopsNoiseManager = GetComponent(); UWE.Utils.SetIsKinematicAndUpdateInterpolation(rigidbody, false, true); WorkaroundColliders(); ScaledNoiseByCyclops.Add(this, 0f); } public void Update() { MaintainPawns(); // Calculation from AttackCyclops.UpdateAggression ScaledNoiseByCyclops[this] = Mathf.Lerp(0f, 150f, cyclopsNoiseManager.GetNoisePercent()); } public void OnDestroy() { ScaledNoiseByCyclops.Remove(this); } /// /// Triggers required on-remove callbacks on children player objects, including the local player. /// public void RemoveAllPlayers() { // This will call OnLocalPlayerExit if (Player.main.currentSub == subRoot) { Player.main.SetCurrentSub(null); } foreach (RemotePlayerIdentifier remotePlayerIdentifier in GetComponentsInChildren(true)) { remotePlayerIdentifier.RemotePlayer.ResetStates(); OnPlayerExit(remotePlayerIdentifier.RemotePlayer); } } /// /// Parents local player to the cyclops and registers it in the current cyclops. /// public void OnLocalPlayerEnter() { Virtual = VirtualCyclops.Instance; Virtual.SetCurrentCyclops(this); Player.mainObject.transform.parent = subRoot.transform; CyclopsPawn pawn = AddPawnForPlayer(this.Resolve()); cyclopsMotor.SetCyclops(this, subRoot, pawn); cyclopsMotor.ToggleCyclopsMotor(true); } /// /// Unregisters the local player from the current cyclops. Ensures the player is not weirdly rotated when it leaves the cyclops. /// public void OnLocalPlayerExit() { RemovePawnForPlayer(this.Resolve()); Player.main.transform.parent = null; Player.main.transform.rotation = Quaternion.identity; cyclopsMotor.ToggleCyclopsMotor(false); cyclopsMotor.Pawn = null; if (Virtual) { Virtual.SetCurrentCyclops(null); } } /// /// Registers a remote player for it to get a pawn in the current cyclops. /// public void OnPlayerEnter(RemotePlayer remotePlayer) { remotePlayer.Pawn = AddPawnForPlayer(remotePlayer); } /// /// Unregisters a remote player from the current cyclops. /// public void OnPlayerExit(RemotePlayer remotePlayer) { RemovePawnForPlayer(remotePlayer); remotePlayer.Pawn = null; } public void MaintainPawns() { foreach (CyclopsPawn pawn in Pawns.Values) { if (pawn.MaintainPredicate()) { pawn.MaintainPosition(); } } } public CyclopsPawn AddPawnForPlayer(INitroxPlayer player) { if (!Pawns.TryGetValue(player, out CyclopsPawn pawn)) { pawn = new(player, this); Pawns.Add(player, pawn); } return pawn; } public void RemovePawnForPlayer(INitroxPlayer player) { if (Pawns.TryGetValue(player, out CyclopsPawn pawn)) { pawn.Terminate(); } Pawns.Remove(player); } public void SetBroadcasting() { worldForces.enabled = true; stabilizer.stabilizerEnabled = true; } public void SetReceiving() { worldForces.enabled = false; stabilizer.stabilizerEnabled = false; } private void WorkaroundColliders() { CyclopsSubNameScreen cyclopsSubNameScreen = transform.GetComponentInChildren(true); TriggerWorkaround subNameTriggerWorkaround = cyclopsSubNameScreen.gameObject.AddComponent(); subNameTriggerWorkaround.Initialize(this,cyclopsSubNameScreen.animator, cyclopsSubNameScreen.ContentOn, nameof(CyclopsSubNameScreen.ContentOff), cyclopsSubNameScreen); CyclopsLightingPanel cyclopsLightingPanel = transform.GetComponentInChildren(true); TriggerWorkaround lightingTriggerWorkaround = cyclopsLightingPanel.gameObject.AddComponent(); lightingTriggerWorkaround.Initialize(this, cyclopsLightingPanel.uiPanel, cyclopsLightingPanel.ButtonsOn, nameof(CyclopsLightingPanel.ButtonsOff), cyclopsLightingPanel); } }