Untitled

 avatar
unknown
plain_text
a year ago
23 kB
5
Indexable
using UnityEngine;
using Fusion;
using Fusion.Sockets;
using System.Collections.Generic;
using System;
using UnityEngine.SceneManagement;
using TMPro;
using System.Collections;
using System.Linq;
using Fusion.Addons.Physics;
using Random = UnityEngine.Random;
using Assets.Scripts.TypewriterEffects;
using System.Threading.Tasks;

public class LobbyManager : NetworkBehaviour, INetworkRunnerCallbacks
{
    public static LobbyManager Instance;

    private SceneRef gameScene;
    public bool isSpawned = false;

    [Networked] private Dictionary<PlayerRef, GameObject> playerGameObjects { get; }

    // Lobby stuff
    [SerializeField] private NetworkPrefabRef playerPrefab;

    // this is why its not properly working and assigning player positions for new clients that join that are not the master client
    // Only masterclient assigns and positions late clients
    // or the possibility for each player to assign and get a position for their player prefab either thru StateAuthority to All
    // or All to StateAuthority, then the authority does a check, then it applies to all


    //[Networked] private PlayerRef Superadmin { get; set; } // State Authority, The Big BOSS
    [Networked] private NetworkDictionary<PlayerRef, NetworkBool> NetworkedReadyStates { get; set; }
    [Networked, Capacity(6)] private NetworkLinkedList<PlayerRef> NetworkedPlayerList { get; set; }
    [Networked, Capacity(6)] private NetworkDictionary<PlayerRef, int> playerPositionMap { get; set; }

    [Networked, Capacity(6)] private NetworkArray<PlayerInfo_NewTemp> playerPositions => default;

    [Networked] private NetworkBool newsStarted { get; set; }
    [Networked] private int currentNewsIndex { get; set; }

    private LTDescr currentNewsTween;
    private bool isMessageCooldown = false;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }

        ServiceLocator.RegisterLobbyManager(this);
        // game scene is 1 (at least the first level)
        gameScene = SceneRef.FromIndex(1);
    }

    private void Start()
    {
        //StartCoroutine(WaitForRunners());
    }

    private IEnumerator WaitForRunners()
    {
        while (FusionLauncher.Instance == null || FusionLauncher.Instance.GetNetworkRunner() == null)
        {
            yield return null;
        }
    }

    public override void Spawned()
    {
        isSpawned = true;
        Runner.AddCallbacks(this);
    }

    public override void Despawned(NetworkRunner runner, bool hasState)
    {
        base.Despawned(runner, hasState);
        isSpawned = false;
    }

    public void ShowLobbyUI()
    {
        ServiceLocator.GetAudioManager().SetCutoffFrequency(10000, 7000);
        UILobby.Instance.ConnectToLobby();
    }

    public void StartGame()
    {
        if (FusionLauncher.Instance.GetNetworkRunner().IsRunning)
        {
            FusionLauncher.Instance.GetNetworkRunner().LoadScene(gameScene, LoadSceneMode.Single);
        }
    }

    public void SetPlayerReadyState(PlayerRef player)
    {
        if (player == Runner.LocalPlayer)
        {
            RPC_RequestToggleReadyState(player);
        }
    }

    [Rpc(RpcSources.All, RpcTargets.StateAuthority)]
    private void RPC_RequestToggleReadyState(PlayerRef player)
    {
        bool newReadyState;

        if (NetworkedReadyStates.ContainsKey(player))
        {
            bool currentReadyState = NetworkedReadyStates[player];
            newReadyState = !currentReadyState;
            NetworkedReadyStates.Set(player, newReadyState);
        }
        else
        {
            newReadyState = true;
            NetworkedReadyStates.Add(player, newReadyState);
        }

        RPC_SyncReadyState(player, newReadyState);
    }

    [Rpc(RpcSources.StateAuthority, RpcTargets.All)]
    private void RPC_SyncReadyState(PlayerRef player, bool isReady)
    {
        if (NetworkedReadyStates.ContainsKey(player))
        {
            NetworkedReadyStates.Set(player, isReady);
        }
        else
        {
            NetworkedReadyStates.Add(player, isReady);
        }

        UpdatePlayerList();
    }

    public bool IsPlayerReady(PlayerRef player)
    {
        return NetworkedReadyStates.ContainsKey(player) && NetworkedReadyStates[player];
    }

    public void ShowMessageAbovePlayer(string message)
    {
        if (isMessageCooldown)
        {
            return;
        }

        RPC_TalkShit(Runner.LocalPlayer, message);
    }

    public void ShowEmoteAbovePlayer(string emote)
    {
        if (isMessageCooldown)
        {
            return;
        }

        RPC_SendEmote(Runner.LocalPlayer, emote);
    }

    [Rpc(RpcSources.All, RpcTargets.All)]
    private void RPC_SendEmote(PlayerRef player, string emote)
    {
        isMessageCooldown = true;

        switch (emote)
        {
            case "<sprite name=\"ManiaMoji_4\">":
                PlayCustomAnimation(player, emote);
                break;
            default:
                PlayDefaultEmoteAnimation(player, emote);
                break;
        }
    }

    private void PlayDefaultEmoteAnimation(PlayerRef player, string emote)
    {
        var runner = FusionLauncher.Instance.GetNetworkRunner();
        int playerIndex = FindPlayerPosition(player);

        if (playerIndex >= 0 && playerIndex < playerPositions.Length)
        {
            Transform position = UILobby.Instance.playerPositionsParent.GetChild(playerIndex);
            var emoteText = position.Find("messageTxt").GetComponent<TextMeshProUGUI>();

            if (emoteText != null)
            {
                LeanTween.cancel(emoteText.gameObject);
                emoteText.gameObject.SetActive(false);

                Vector3 originalPosition = emoteText.transform.localPosition;
                Vector3 belowOriginalPosition = originalPosition + new Vector3(0, -100f, 0);

                emoteText.fontSize = 63;
                emoteText.transform.localPosition = belowOriginalPosition;
                emoteText.transform.localScale = Vector3.zero;

                emoteText.text = emote;
                emoteText.gameObject.SetActive(true);

                LeanTween.moveLocalY(emoteText.gameObject, originalPosition.y, 0.5f).setEase(LeanTweenType.easeInOutBack);
                LeanTween.scale(emoteText.gameObject, Vector3.one, 0.5f).setEase(LeanTweenType.easeOutBounce).setOnComplete(() =>
                {
                    LeanTween.scale(emoteText.gameObject, Vector3.one * 1.2f, 0.3f).setEase(LeanTweenType.easeInOutSine).setLoopPingPong(4).setOnComplete(() =>
                    {
                        LeanTween.moveLocalY(emoteText.gameObject, belowOriginalPosition.y, 0.5f).setEase(LeanTweenType.easeInOutBack);
                        LeanTween.scale(emoteText.gameObject, Vector3.zero, 0.5f).setEase(LeanTweenType.easeInOutBack).setOnComplete(() =>
                        {
                            emoteText.gameObject.SetActive(false);
                            emoteText.transform.localPosition = originalPosition;
                            isMessageCooldown = false;
                        });
                    });
                });
            }
        }
    }

    [Rpc(RpcSources.All, RpcTargets.All)]
    private void RPC_TalkShit(PlayerRef player, string message)
    {
        isMessageCooldown = true;

        var runner = FusionLauncher.Instance.GetNetworkRunner();
        int playerIndex = FindPlayerPosition(player);

        if (playerIndex >= 0 && playerIndex < playerPositions.Length)
        {
            Transform position = UILobby.Instance.playerPositionsParent.GetChild(playerIndex);
            var messageText = position.Find("messageTxt").GetComponent<TextMeshProUGUI>();

            if (messageText != null)
            {
                var typewriter = messageText.GetComponent<Typewriter>();
                var textEffects = messageText.GetComponent<TextEffects>();
                LeanTween.cancel(messageText.gameObject);
                messageText.gameObject.SetActive(false);

                // Store original pos
                Vector3 originalPosition = messageText.transform.localPosition;
                Vector3 belowOriginalPosition = originalPosition + new Vector3(0, -100f, 0);

                messageText.fontSize = 28;

                messageText.gameObject.SetActive(true);
                messageText.text = "";

                typewriter.Animate(message);

                textEffects.SetOnTypingEnd(() =>
                {
                    LeanTween.scale(messageText.gameObject, Vector3.one * 1.1f, 0.3f)
                             .setEase(LeanTweenType.easeOutBack)
                             .setOnComplete(() =>
                             {
                                 LeanTween.scale(messageText.gameObject, Vector3.one, 0.2f)
                                          .setEase(LeanTweenType.easeInOutSine);
                             });
                });

                // Delay before removing msg
                LeanTween.value(messageText.gameObject, 0, 1, ChatboxManager.MESSAGE_DISPLAY_TIME).setOnComplete(() =>
                {
                    // Animate the message popping down smoothly
                    //LeanTween.moveLocalY(messageText.gameObject, belowOriginalPosition.y, 0.5f).setEase(LeanTweenType.easeInCirc);
                    LeanTween.value(messageText.fontSize, 0, 0.3f).setEase(LeanTweenType.easeInOutSine).setOnUpdate((float value) => messageText.fontSize = value).setDelay(0.3f).setOnComplete(() =>
                    {
                        messageText.gameObject.SetActive(false);
                        messageText.text = "";
                        messageText.transform.localPosition = originalPosition;
                        messageText.transform.localScale = Vector3.one;
                        isMessageCooldown = false;
                    });
                });
            }
        }
    }

    public void StartManiaNews()
    {
        if (HasStateAuthority && !newsStarted)
        {
            newsStarted = true;
            currentNewsIndex = 0;
            RPC_RequestUpdateNews(currentNewsIndex);
        }
    }

    public void ScheduleNextNewsPage()
    {
        int newsCount = LobbyManiaNews.Instance.GetNewsCount();
        int nextIndex = LobbyManiaNews.Instance.randomOrder ? Random.Range(0, newsCount) : (currentNewsIndex + 1) % newsCount;
        currentNewsIndex = nextIndex;
        RPC_RequestUpdateNews(nextIndex);
    }

    [Rpc(RpcSources.All, RpcTargets.StateAuthority)]
    public void RPC_RequestUpdateNews(int index)
    {
        if (newsStarted)
        {
            RPC_UpdateManiaNews(index);
        }
    }

    [Rpc(RpcSources.StateAuthority, RpcTargets.All)]
    public void RPC_UpdateManiaNews(int index)
    {
        LobbyManiaNews.Instance.ShowNews(index);

        if (currentNewsTween != null)
        {
            LeanTween.cancel(currentNewsTween.id);
        }

        currentNewsTween = LeanTween.delayedCall(LobbyManiaNews.Instance.displayDuration, ScheduleNextNewsPage);
    }

    private void PlayCustomAnimation(PlayerRef player, string emote)
    {
        var runner = FusionLauncher.Instance.GetNetworkRunner();
        int playerIndex = FindPlayerPosition(player);

        if (playerIndex >= 0 && playerIndex < playerPositions.Length)
        {
            Transform position = UILobby.Instance.playerPositionsParent.GetChild(playerIndex);
            var emoteText = position.Find("messageTxt").GetComponent<TextMeshProUGUI>();

            if (emoteText != null)
            {
                // Cancel any ongoing animations
                LeanTween.cancel(emoteText.gameObject);
                emoteText.gameObject.SetActive(false);

                // Store the original position
                Vector3 originalPosition = emoteText.transform.localPosition;
                Vector3 belowOriginalPosition = originalPosition + new Vector3(0, -100f, 0);

                // Set the font size for the emoji text
                emoteText.fontSize = 55;

                // Set initial position and scale
                emoteText.transform.localPosition = belowOriginalPosition;
                emoteText.transform.localScale = Vector3.zero;

                // Set the emote text and activate the game object
                emoteText.text = emote;
                emoteText.gameObject.SetActive(true);

                // Custom animation for "ManiaMoji_43"
                LeanTween.moveLocalY(emoteText.gameObject, originalPosition.y, 0.5f).setEase(LeanTweenType.easeOutElastic);
                LeanTween.scale(emoteText.gameObject, Vector3.one, 0.5f).setEase(LeanTweenType.easeOutElastic).setOnComplete(() =>
                {
                    // Custom wiggle and ping-pong scale animation
                    LeanTween.rotateZ(emoteText.gameObject, 15f, 0.1f).setEase(LeanTweenType.easeInOutSine).setLoopPingPong(20).setOnComplete(() =>
                    {
                        // Move to center, scale up, and wiggle
                        Vector3 centerPosition = new Vector3(Screen.width / 2, Screen.height / 2, 0);
                        emoteText.transform.SetParent(null); // Detach from the parent to move to screen center
                        LeanTween.move(emoteText.gameObject, centerPosition, 2f).setEase(LeanTweenType.easeInOutExpo);
                        LeanTween.scale(emoteText.gameObject, Vector3.one * 2f, 2f).setEase(LeanTweenType.easeInOutExpo).setOnComplete(() =>
                        {
                            LeanTween.rotateZ(emoteText.gameObject, 10f, 0.05f).setEase(LeanTweenType.easeInOutSine).setLoopPingPong(10);
                            LeanTween.moveLocalY(emoteText.gameObject, Screen.height, 2f).setEase(LeanTweenType.easeInOutExpo).setOnComplete(() =>
                            {
                                emoteText.gameObject.SetActive(false);
                                //emoteText.transform.SetParent(PlayerPositions[playerIndex]);
                                emoteText.transform.localPosition = originalPosition;
                                emoteText.fontSize = 55; // Reset font size
                                isMessageCooldown = false;
                            });
                        });
                    });
                });
            }
        }
    }

    private void InitiateMasterClientTransfer()
    {
        if (NetworkedPlayerList.Count > 0)
        {
            PlayerRef newMasterClient = NetworkedPlayerList[0];
            RPC_NotifyNewMasterClient(newMasterClient);
        }
        else
        {
            Debug.Log("No players left to transfer authority to.");
            return;
        }
    }

    [Rpc(RpcSources.StateAuthority, RpcTargets.All)]
    private void RPC_NotifyNewMasterClient(PlayerRef newMasterClient)
    {
        NetworkObject lobbyManager = FindObjectOfType<LobbyManager>().GetComponent<NetworkObject>();

        if (Runner.LocalPlayer == newMasterClient)
        {
            lobbyManager.RequestStateAuthority();
            Debug.Log($"Requested state authority for new master client: {newMasterClient}");
        }
    }

    private void UpdatePlayerList()
    {
        foreach (var player in playerPositionMap)
        {
            int positionIndex = player.Value;
            Transform positionTransform = UILobby.Instance.playerPositionsParent.GetChild(positionIndex);
            UpdatePlayerUI(positionTransform, player.Key);
        }
    }


    private void DisableMenuComponents(GameObject playerObject)
    {
        var spriteRenderer = playerObject.GetComponent<SpriteRenderer>();
        if (spriteRenderer != null)
        {
            spriteRenderer.sortingLayerName = "UI";
            spriteRenderer.sortingOrder = 10;
            //playerObject.AddComponent<NetworkTransform>();
            Debug.Log($"Sort order: {spriteRenderer.sortingOrder}");
        }

        NetworkRigidbody2D networkRb = playerObject.GetComponent<NetworkRigidbody2D>();
        if (networkRb != null)
        {
            //Destroy(networkRb);
            //Destroy(playerObject.GetComponent<NetworkRigidbody2D>());
            //networkRb.enabled = false;
            // Disabling this prevents setting position
        }

        PlayerController playerController = playerObject.GetComponent<PlayerController>();
        if (playerController != null)
        {
            playerController.enabled = false;
        }

        Rigidbody2D rb = playerObject.GetComponent<Rigidbody2D>();
        if (rb != null)
        {
            rb.bodyType = RigidbodyType2D.Static;
        }

        RunnerSimulatePhysics2D runnerSimulate2D = playerObject.GetComponent<RunnerSimulatePhysics2D>();
        if (runnerSimulate2D != null)
        {
            Destroy(playerObject.GetComponent<RunnerSimulatePhysics2D>());
        }
    }

    private void UpdateUI(int positionIndex, PlayerRef player)
    {
        var playerInfo = playerPositions.Get(positionIndex);
        Transform position = UILobby.Instance.playerPositionsParent.GetChild(positionIndex);

        UpdatePlayerUI(position, player);
    }

    private void ClearUI(int positionIndex)
    {
        Transform position = UILobby.Instance.playerPositionsParent.GetChild(positionIndex);

        var nameText = position.Find("nameText").GetComponent<TextMeshProUGUI>();
        var statusText = position.Find("statusText").GetComponent<TextMeshProUGUI>();
        var messageText = position.Find("messageTxt").GetComponent<TextMeshProUGUI>();

        nameText.text = "";
        statusText.text = "";
        messageText.gameObject.SetActive(false);
    }

    private void UpdatePlayerUI(Transform position, PlayerRef player)
    {
        var nameText = position.Find("nameText").GetComponent<TextMeshProUGUI>();
        var statusText = position.Find("statusText").GetComponent<TextMeshProUGUI>();
        var messageText = position.Find("messageTxt").GetComponent<TextMeshProUGUI>();

        nameText.color = new Color(1f, 1f, 1f);
        bool isReady = NetworkedReadyStates.ContainsKey(player) && NetworkedReadyStates[player];
        nameText.text = $"Player {player.PlayerId}";
        statusText.text = isReady ? "Ready" : "Not Ready";
        messageText.gameObject.SetActive(false);
    }

    private int GetNextAvailablePosition()
    {
        for (int i = 0; i < playerPositions.Length; i++)
        {
            if (IsDefault(playerPositions.Get(i)))
            {
                return i;
            }
        }
        return -1; // Lobby is full
    }

    private bool IsDefault(PlayerInfo_NewTemp playerInfo)
    {
        return playerInfo.Player == default;
    }

    private int FindPlayerPosition(PlayerRef player)
    {
        for (int i = 0; i < playerPositions.Length; i++)
        {
            if (playerPositions.Get(i).Player == player)
            {
                return i;
            }
        }
        return -1;
    }


    private GameObject FindPlayerGameObject(PlayerRef player)
    {
        if (playerGameObjects.ContainsKey(player))
        {
            return playerGameObjects[player];
        }
        return null;
    }

    public void OnObjectExitAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player)
    {
    }

    public void OnObjectEnterAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player)
    {
    }

    public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
    {
        if (HasInputAuthority)
        {
            int positionIndex = GetNextAvailablePosition();
            if (positionIndex != -1)
            {
                playerPositions.Set(positionIndex, new PlayerInfo_NewTemp
                {
                    Player = player,
                    PlayerName = "Player " + player.PlayerId,
                    PlayerState = "Ready",
                    PlayerMessage = "Welcome"
                });

                UpdateUI(positionIndex, player);
            }
        }
    }

    public void OnPlayerLeft(NetworkRunner runner, PlayerRef player)
    {
        bool wasMasterClient = runner.IsSharedModeMasterClient && runner.LocalPlayer == player;

        if (runner.IsServer)
        {
            int positionIndex = FindPlayerPosition(player);
            if (positionIndex != -1)
            {
                playerPositions.Set(positionIndex, default);

                // Optional: Update UI to clear the slot
                ClearUI(positionIndex);
            }
        }
        UpdatePlayerList();

        var playerObject = runner.GetPlayerObject(player);
        if (playerObject != null)
        {
            runner.Despawn(playerObject);
            Destroy(playerObject.gameObject);
        }

        if (wasMasterClient)
        {
            InitiateMasterClientTransfer();
        }
    }

    public void OnSceneLoadDone(NetworkRunner runner)
    {
        Debug.Log("Scene load done!");
    }

    public void OnSceneLoadStart(NetworkRunner runner)
    {

    }

    public void OnInput(NetworkRunner runner, NetworkInput input)
    {
    }

    public void OnInputMissing(NetworkRunner runner, PlayerRef player, NetworkInput input)
    {
    }

    public void OnShutdown(NetworkRunner runner, ShutdownReason shutdownReason)
    {
    }

    public void OnConnectedToServer(NetworkRunner runner)
    {
    }

    public void OnDisconnectedFromServer(NetworkRunner runner, NetDisconnectReason reason)
    {

    }

    public void OnConnectRequest(NetworkRunner runner, NetworkRunnerCallbackArgs.ConnectRequest request, byte[] token)
    {

    }

    public void OnConnectFailed(NetworkRunner runner, NetAddress remoteAddress, NetConnectFailedReason reason)
    {

    }

    public void OnUserSimulationMessage(NetworkRunner runner, SimulationMessagePtr message)
    {

    }

    public void OnSessionListUpdated(NetworkRunner runner, List<SessionInfo> sessionList)
    {

    }

    public void OnCustomAuthenticationResponse(NetworkRunner runner, Dictionary<string, object> data)
    {

    }

    public void OnHostMigration(NetworkRunner runner, HostMigrationToken hostMigrationToken)
    {

    }

    public void OnReliableDataReceived(NetworkRunner runner, PlayerRef player, ReliableKey key, ArraySegment<byte> data)
    {

    }

    public void OnReliableDataProgress(NetworkRunner runner, PlayerRef player, ReliableKey key, float progress)
    {

    }
}
Editor is loading...
Leave a Comment