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);
}
}