using System;
using System.Collections;
using System.Collections.Generic;
using Febucci.UI;
using TMPro;
using Unity.Netcode;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
public class GameplayManager : NetworkBehaviour
{
public static GameplayManager Instance { get; private set; }
[SerializeField] private List<TextPopUpSO> TwoPointQuips;
[SerializeField] private List<TextPopUpSO> ThreePointQuips;
[SerializeField] private List<TextPopUpSO> DefenseQuips;
[SerializeField] private TextMeshProUGUI homeScore;
[SerializeField] private TextMeshProUGUI awayScore;
[SerializeField] private TextMeshProUGUI homeQuipText;
[SerializeField] private TextMeshProUGUI awayQuipText;
[SerializeField] private Button ReadyBtn;
[SerializeField]
private TypewriterByCharacter _typewriterByCharacter;
private Dictionary<ulong, bool> playerReadyDictionary;
public event EventHandler OnStateChanged;
public event EventHandler OnLocalPlayerReadyChanged;
private enum State
{
WaitingToStart,
CountdownToStart,
GamePlaying,
GameOver,
}
private float waitingToStartTimer = 1f;
private float countdownToStartTimer = 3f;
private float gamePlayingTimer = 10f;
private bool isLocalPlayerReady = false;
private State state;
private static double homeLevel;
private static double awayLevel;
private double homeTeamScore;
private double awayTeamScore;
private int homeFinalScore;
private int awayFinalScore;
private double pFactor;
private float cFactor = 0.90f;
private System.Random _random = new System.Random();
private void Update()
{
switch (state)
{
case State.WaitingToStart:
break;
case State.CountdownToStart:
countdownToStartTimer -= Time.deltaTime;
if (countdownToStartTimer < 0f)
{
state = State.GamePlaying;
OnStateChanged?.Invoke(this,EventArgs.Empty);
}
break;
case State.GamePlaying:
gamePlayingTimer -= Time.deltaTime;
if (gamePlayingTimer < 0f)
{
state = State.GameOver;
OnStateChanged?.Invoke(this,EventArgs.Empty);
}
break;
case State.GameOver:
break;
}
//Debug.Log(state);
}
public bool IsGamePlaying()
{
return state == State.GamePlaying;
}
public bool IsCountdownToStartActive()
{
return state == State.CountdownToStart;
}
public bool IsGameOver()
{
return state == State.GameOver;
}
public float GetCountdownToStartTimer()
{
return countdownToStartTimer;
}
public static void setHomeLevel(double level)
{
homeLevel = level;
}
public static void setAwayLevel(double level)
{
awayLevel = level;
}
private double calculateTeamScore100(double teamLevel)
{
if (!NetworkManager.Singleton.IsServer)
{
Debug.Log("NOT SERVER Team100");
return 0;
}
pFactor = _random.NextDouble();
Debug.Log("P factor " + pFactor);
double tmpScore = Math.Pow(pFactor, (1 - (teamLevel / cFactor) / 100)) * 100;
Debug.Log("Team Score " + tmpScore);
return tmpScore;
}
private void calculateWinner(double homeScore, double awayScore)
{
if (!NetworkManager.Singleton.IsServer)
{
Debug.Log("NOT SERVER Winner");
return;
}
if (homeScore >= awayScore)
{
homeFinalScore = 21;
awayFinalScore = (int)(awayScore / homeScore * 21);
if (awayFinalScore == 20)
{
homeFinalScore = 22;
}
Debug.Log("Home: " + homeFinalScore + " Away: " + awayFinalScore);
}
else
{
awayFinalScore = 21;
homeFinalScore = (int)(homeScore / awayScore * 21);
if (homeFinalScore == 20)
{
awayFinalScore = 22;
}
Debug.Log("Home: " + homeFinalScore + " Away: " + awayFinalScore);
}
}
/*private double calculateTeamLevel(string nft1, string nft2, string nft3)
{
double total = 0f;
double teamValue = 0f;
total += NFTStats.getNFTScore(nft1);
Debug.Log("Total: " + total);
total += NFTStats.getNFTScore(nft2);
Debug.Log("Total: " + total);
total += NFTStats.getNFTScore(nft3);
Debug.Log("Total: " + total);
teamValue = total / 3;
Debug.Log("Team: " + teamValue);
return teamValue;
}*/
private IEnumerator gameSimulation()
{
int runningHomeScore = 0;
int runningAwayScore = 0;
yield return new WaitForSeconds(4);
while ((runningHomeScore != homeFinalScore) || (runningAwayScore != awayFinalScore))
{
if (runningHomeScore < 21 && runningAwayScore < 21)
{
double posessionPicker = _random.NextDouble();
double defensivePicker = _random.NextDouble();
if (posessionPicker <= 0.5f)
{
if (posessionPicker <= 0.3f && (homeFinalScore - runningHomeScore) >= 1)
{
if (defensivePicker <= 0.1f)
{
int indexOfQuip = _random.Next(DefenseQuips.Count);
_typewriterByCharacter.ShowText("{rdir} <wave>" + DefenseQuips[indexOfQuip].getText() + "</wave> {#rdir}");
_typewriterByCharacter.StartShowingText(true);
homeQuipText.alpha = 1.0f;
yield return new WaitForSeconds(4);
_typewriterByCharacter.StartDisappearingText();
homeQuipText.alpha = 0.0f;
}
else
{
if (runningHomeScore + 1 >= 21 && runningAwayScore != awayFinalScore)
{
continue;
}
int indexOfQuip = _random.Next(TwoPointQuips.Count);
_typewriterByCharacter.ShowText("{rdir} <bounce>" + TwoPointQuips[indexOfQuip].getText() + "/<bounce> {#rdir}");
_typewriterByCharacter.StartShowingText(true);
//homeQuipText.text = "{vertexp} <bounce>" + TwoPointQuips[indexOfQuip].getText() + "/<bounce> {#rot}";
homeQuipText.alpha = 1.0f;
runningHomeScore += 1;
homeScore.text = runningHomeScore.ToString();
yield return new WaitForSeconds(4);
hideText(homeQuipText);
}
}
else if (posessionPicker > 0.3f && (homeFinalScore - runningHomeScore) >= 2)
{
if (defensivePicker <= 0.1f)
{
int indexOfQuip = _random.Next(DefenseQuips.Count);
_typewriterByCharacter.ShowText("{rdir}<incr>" + DefenseQuips[indexOfQuip].getText() + "</incr>{#rdir}");
_typewriterByCharacter.StartShowingText(true);
homeQuipText.alpha = 1.0f;
yield return new WaitForSeconds(4);
_typewriterByCharacter.StartDisappearingText();
homeQuipText.alpha = 0.0f;
}
else
{
if (runningHomeScore + 2 >= 21 && runningAwayScore != awayFinalScore)
{
continue;
}
int indexOfQuip = _random.Next(ThreePointQuips.Count);
_typewriterByCharacter.ShowText("{rdir}<slide>" + ThreePointQuips[indexOfQuip].getText() + "{#rdir}");
_typewriterByCharacter.StartShowingText(true);
homeQuipText.alpha = 1.0f;
runningHomeScore += 2;
homeScore.text = runningHomeScore.ToString();
yield return new WaitForSeconds(4);
_typewriterByCharacter.StartDisappearingText();
homeQuipText.alpha = 0.0f;
}
}
else
{
if (runningHomeScore != homeFinalScore)
{
if (defensivePicker <= 0.1f)
{
int indexOfQuip = _random.Next(DefenseQuips.Count);
_typewriterByCharacter.ShowText("{rdir}<wave>" + DefenseQuips[indexOfQuip].getText() + "</wave>{#rdir}");
_typewriterByCharacter.StartShowingText(true);
homeQuipText.alpha = 1.0f;
yield return new WaitForSeconds(4);
_typewriterByCharacter.StartDisappearingText();
}
else
{
if (runningHomeScore + 1 >= 21 && runningAwayScore != awayFinalScore)
{
continue;
}
int indexOfQuip = _random.Next(TwoPointQuips.Count);
_typewriterByCharacter.ShowText("{rdir}<bounce>" + TwoPointQuips[indexOfQuip].getText() + "</bounce>{#rdir}");
_typewriterByCharacter.StartShowingText(true);
homeQuipText.alpha = 1.0f;
runningHomeScore += 1;
homeScore.text = runningHomeScore.ToString();
yield return new WaitForSeconds(4);
_typewriterByCharacter.StartDisappearingText();
homeQuipText.alpha = 0.0f;
}
}
else
{
Debug.Log("REACHED TARGET");
}
}
}
else if (posessionPicker > 0.5f)
{
if (posessionPicker <= 0.8f && (awayFinalScore - runningAwayScore) >= 1)
{
if (defensivePicker <= 0.1f)
{
int indexOfQuip = _random.Next(DefenseQuips.Count);
awayQuipText.text = DefenseQuips[indexOfQuip].getText();
awayQuipText.alpha = 1.0f;
yield return new WaitForSeconds(4);
awayQuipText.alpha = 0.0f;
}
else
{
if (runningAwayScore + 1 >= 21 && runningHomeScore != homeFinalScore)
{
continue;
}
int indexOfQuip = _random.Next(TwoPointQuips.Count);
awayQuipText.text = TwoPointQuips[indexOfQuip].getText();
awayQuipText.alpha = 1.0f;
runningAwayScore += 1;
awayScore.text = runningAwayScore.ToString();
yield return new WaitForSeconds(4);
awayQuipText.alpha = 0.0f;
}
}
else if (posessionPicker > 0.8f && (awayFinalScore - runningAwayScore) >= 2)
{
if (defensivePicker <= 0.1f)
{
int indexOfQuip = _random.Next(DefenseQuips.Count);
awayQuipText.text = DefenseQuips[indexOfQuip].getText();
awayQuipText.alpha = 1.0f;
yield return new WaitForSeconds(4);
awayQuipText.alpha = 0.0f;
}
else
{
if (runningAwayScore + 2 >= 21 && runningHomeScore != homeFinalScore)
{
continue;
}
int indexOfQuip = _random.Next(ThreePointQuips.Count);
awayQuipText.text = ThreePointQuips[indexOfQuip].getText();
awayQuipText.alpha = 1.0f;
runningAwayScore += 2;
awayScore.text = runningAwayScore.ToString();
yield return new WaitForSeconds(4);
awayQuipText.alpha = 0.0f;
}
}
else
{
if (runningAwayScore != awayFinalScore)
{
if (defensivePicker <= 0.1f)
{
int indexOfQuip = _random.Next(DefenseQuips.Count);
awayQuipText.text = DefenseQuips[indexOfQuip].getText();
awayQuipText.alpha = 1.0f;
yield return new WaitForSeconds(4);
awayQuipText.alpha = 0.0f;
}
else
{
if (runningAwayScore + 1 >= 21 && runningHomeScore != homeFinalScore)
{
continue;
}
int indexOfQuip = _random.Next(TwoPointQuips.Count);
awayQuipText.text = TwoPointQuips[indexOfQuip].getText();
awayQuipText.alpha = 1.0f;
runningAwayScore += 1;
awayScore.text = runningAwayScore.ToString();
yield return new WaitForSeconds(4);
awayQuipText.alpha = 0.0f;
}
}
else
{
Debug.Log("REACHED TARGET");
}
}
}
}
else
{
break;
}
}
}
private void OnEnable()
{
Instance = this;
ReadyBtn.onClick.AddListener(ReadyToPlay);
state = State.WaitingToStart;
playerReadyDictionary = new Dictionary<ulong, bool>();
if (NetworkManager.Singleton.IsServer)
{
print("IS SERVER");
}
if (NetworkManager.Singleton.IsClient)
{
print("IS CLIENT");
}
if(NetworkManager.Singleton.IsHost)
{
print("IS HOST");
}
TestClientRpc();
TestServerRpc();
if (!NetworkManager.Singleton.IsServer)
{
print("NOT SERVER");
return;
}
//homeLevel = calculateTeamLevel("NFT LEAGUEZ #997", "NFT LEAGUEZ #347", "NFT LEAGUEZ #397");
//awayLevel = calculateTeamLevel("NFT LEAGUEZ #450", "NFT LEAGUEZ #597", "NFT LEAGUEZ #577");
homeTeamScore = calculateTeamScore100(homeLevel);
awayTeamScore = calculateTeamScore100(awayLevel);
calculateWinner(homeTeamScore, awayTeamScore);
StartCoroutine(gameSimulation());
}
private void OnDisable()
{
int zero = 0;
homeScore.text = zero.ToString();
awayScore.text = zero.ToString();
}
public void hideText(TextMeshProUGUI text)
{
_typewriterByCharacter.StartDisappearingText();
text.alpha = 0.0f;
}
public string GetHomeScore()
{
return homeScore.text;
}
public string GetAwayScore()
{
return awayScore.text;
}
private void ReadyToPlay()
{
isLocalPlayerReady = true;
OnLocalPlayerReadyChanged?.Invoke(this, EventArgs.Empty);
Debug.Log("CALLING RPC ");
SetPlayerReadyServerRpc();
Debug.Log("FINISH RPC ");
}
[ServerRpc(RequireOwnership = false)]
private void SetPlayerReadyServerRpc(ServerRpcParams serverRpcParams = default)
{
Debug.Log("IN SERVER RPC, ID: ");
Debug.Log(serverRpcParams.Receive.SenderClientId);
playerReadyDictionary[serverRpcParams.Receive.SenderClientId] = true;
bool allClientsReady = true;
foreach (ulong clientId in NetworkManager.Singleton.ConnectedClientsIds)
{
if (!playerReadyDictionary.ContainsKey(clientId) || !playerReadyDictionary[clientId])
{
//Player not ready
allClientsReady = false;
break;
}
}
Debug.Log("All players ready: " + allClientsReady);
}
[ServerRpc(RequireOwnership = false)]
private void TestServerRpc(ServerRpcParams serverRpcParams = default)
{
Debug.Log("TEST SERVER RPC");
}
[ClientRpc]
private void TestClientRpc(ClientRpcParams clientRpcParams = default)
{
Debug.Log("TEST CLIENT RPC");
}
public bool isLocalPlayerReadyToPlay()
{
return isLocalPlayerReady;
}
}