Projet-IA-Madelaine/Scripts/GameHandlers/GameHandler.cs
2024-06-12 21:03:42 +02:00

300 lines
8.7 KiB
C#

using Assets.Scripts;
using System;
using System.Collections;
using Unity.VisualScripting;
using UnityEditor.Rendering;
using UnityEngine;
using static PlayersHandler;
/// <summary>
/// GameHandler gère le fonctionnement général d'une partie de jeu. Il se charge de faire apparaître les joueurs
/// </summary>
public class GameHandler : SingletonMB<GameHandler>
{
#region PROPERTIES
int Seed
{
get { return _seed; }
set
{
_seed = value;
UnityEngine.Random.InitState(value);
}
} private int _seed;
public float FrameDistance { get; private set; }
public float TotalDistance { get; private set; }
[SerializeField] public float MapSpeed { get; private set; }
public Attempt CurrentAttempt { get; private set; }
public bool MaxDifficultyReached { get; private set; }
public bool IsPaused { get; private set; } = false;
public bool HaveHumanPlayer { get; private set; } = false;
public bool AttemptEnding { get; private set; }
public int TickAttemptDuration { get; private set; }
public float TimeAttemptDuration {get; private set;}
#endregion
#region VARIABLES
private const float DIFFICULTY_DAMP = 0.01f;
[SerializeField] private GameObject finishLine;
private ScoreHandler _scoreHandler;
private LevelSpawner _levelSpawner;
private PlayersHandler _playerHandler;
private DataBearer _dataBearer;
private TileSpawner _tileSpawner;
private Vector3 playerSpawnPosition = new Vector3(-3, 0, 0);
private float maxSpeed;
private float maxDistance;
private bool raiseScoreOnDistance;
private float difficultyMultiplier;
private bool finishLineSpawned;
private short tickCounter;
#endregion
#region EVENTS
public event EventHandler<AttemptEventArgs> OnAttemptStarted;
public event EventHandler<AttemptEventArgs> OnAttemptEnding;
public event EventHandler<AttemptEventArgs> OnAttemptEnded;
public event EventHandler<EventArgs> OnGamePaused;
public event EventHandler<EventArgs> OnGameResumed;
public event EventHandler<EventArgs> OnInstanciatingPlayers;
public class AttemptEventArgs : EventArgs
{
public Attempt attempt;
public AttemptEventArgs(Attempt attempt) { this.attempt = attempt; }
}
public void HaltAttempt_OnAllPlayersFinished(object sender, EventArgs agrs)
{
HaltAttempt("Tous les joueurs sont Out");
}
public void CheckIfHumanPlayer_OnPlayerInstanciated(object sender, PlayerEventArgs args)
{
if (args.player.IsHuman)
{
HaveHumanPlayer = true;
}
}
#endregion
#region METHODS
/// <summary>
/// Return a seed which depend on selected settings and attempt number
/// </summary>
private int SetSeed()
{
int seed;
if (_dataBearer.Session.Rules.ChangeSeedEachTry & CurrentAttempt.AttemptNumber > 1) //Get a random seed each new try
{
seed = UnityEngine.Random.Range(100000000, 1000000000); //generate a random 9 digits seed
}
else //Get either default seed or custom seed
{
seed = _dataBearer.Session.Rules.UsesDefaultSeed
? PlayerPrefs.GetInt(Settings.DefaultSeedSettingValue)
: PlayerPrefs.GetInt(Settings.CustomSeedSettingValue);
}
return seed;
}
private void RaiseScore()
{
float scoreToAdd = FrameDistance;// * Time.deltaTime;
_scoreHandler.AddScoreToAllAlivePlayers(scoreToAdd);
}
private void RaiseDifficulty()
{
if(MapSpeed > maxSpeed)
{
MapSpeed = maxSpeed;
MaxDifficultyReached = true;
}
MapSpeed += MapSpeed * difficultyMultiplier * Time.deltaTime;
}
private void SpawnPlayers()
{
if (_dataBearer.Session.Players.Human)
_playerHandler.InstanciatePlayer<HumanPlayerBehaviour>(playerSpawnPosition);
if (_dataBearer.Session.Players.OmnicientBot)
_playerHandler.InstanciatePlayer<OmnicientBehaviour>(playerSpawnPosition);
if (_dataBearer.Session.Players.ObserverBot)
_playerHandler.InstanciatePlayer<ObserverBehaviour>(playerSpawnPosition);
if (_dataBearer.Session.Players.IteratorBot)
_playerHandler.InstanciatePlayer<IteratorBehaviour>(playerSpawnPosition);
}
#endregion
#region ENDPOINTS
public void PauseGame()
{
if (!IsPaused)
{
StartCoroutine(PauseGameCoroutine());
}
}
private IEnumerator PauseGameCoroutine()
{
yield return null;
Time.timeScale = 0; // Met le jeu en pause
IsPaused = true;
OnGamePaused.Invoke(this, new EventArgs());
}
public void ResumeGame()
{
if (IsPaused)
{
Time.timeScale = _dataBearer.Rules.RushMode ? 15 : 1; // Reprend le jeu
IsPaused = false;
OnGameResumed.Invoke(this, new EventArgs());
}
}
public void InitAttempt()
{
TimeAttemptDuration = 0;
TickAttemptDuration = 0;
Debug.LogWarning("Initate Attempt !");
AttemptEnding = false;
CurrentAttempt = new Attempt();
CurrentAttempt.AttemptNumber = _dataBearer.Session.Attempts.Count + 1;
Seed = SetSeed();
CurrentAttempt.Seed = Seed;
TotalDistance = 0;
MapSpeed = _dataBearer.Rules.StartSpeed;
raiseScoreOnDistance = _dataBearer.Rules.ScoreOnDistance;
maxSpeed = _dataBearer.Rules.MaxSpeed;
difficultyMultiplier = _dataBearer.Rules.DifficultyMultiplier * DIFFICULTY_DAMP;
if(_dataBearer.Rules.RushMode){
Time.timeScale = 15;
foreach (var renderer in FindObjectsOfType<Renderer>())
{
if(renderer.gameObject.GetComponent<ScorePannelScript>()==null)
{renderer.enabled = false;}
}
}
else{
Time.timeScale = 1;
}
MaxDifficultyReached = false;
TotalDistance = 0;
FrameDistance = 0;
finishLineSpawned = false;
tickCounter = 0;
SpawnPlayers();
_scoreHandler.AddScoreToAllAlivePlayers(500);
OnAttemptStarted?.Invoke(this, new AttemptEventArgs(CurrentAttempt));
}
/// <summary>
/// Halt the current attempt
/// </summary>
public void HaltAttempt(string message)
{
Console.WriteLine(message);
AttemptEnding = true;
OnAttemptEnding?.Invoke(this, new AttemptEventArgs(CurrentAttempt));
OnAttemptEnded?.Invoke(this, new AttemptEventArgs(CurrentAttempt));
}
#endregion
#region LIFECYCLE
protected override void Awake()
{
base.Awake();
_scoreHandler = ScoreHandler.Instance;
_levelSpawner = LevelSpawner.Instance;
_playerHandler = PlayersHandler.Instance;
_dataBearer = DataBearer.Instance;
_tileSpawner = TileSpawner.Instance;
_playerHandler.OnAllPlayersFinished += HaltAttempt_OnAllPlayersFinished;
_playerHandler.OnPlayerInstanciated += CheckIfHumanPlayer_OnPlayerInstanciated;
difficultyMultiplier = _dataBearer.Rules.DifficultyMultiplier;
raiseScoreOnDistance = _dataBearer.Rules.ScoreOnDistance;
maxDistance = _dataBearer.Rules.MaxDistance;
}
void Update()
{
FrameDistance = MapSpeed * Time.deltaTime;
TotalDistance += FrameDistance;
TimeAttemptDuration += Time.deltaTime;
TickAttemptDuration += 1;
tickCounter += 1;
if (tickCounter > 1000)
{
//Debug.Log("1000 TICK " + TimeAttemptDuration);
tickCounter = 0;
_dataBearer.RecordPlayersScore();
}
if(maxDistance != 0 && TotalDistance > maxDistance)
{
HaltAttempt("Ligne d'arrivée atteinte");
}
if (raiseScoreOnDistance) RaiseScore();
if (!MaxDifficultyReached) RaiseDifficulty();
if(maxDistance != 0 && !finishLineSpawned && maxDistance-TotalDistance < 20)
{
Instantiate(finishLine, new Vector3(maxDistance - TotalDistance - 3, 0, -1), finishLine.transform.rotation);
finishLineSpawned = true;
}
if (Input.GetKeyDown(KeyCode.Escape))
(IsPaused ? (Action)ResumeGame : PauseGame)();
}
private void OnDestroy()
{
Clean();
}
private void OnDisable()
{
Clean();
}
private void Clean()
{
/*StopAllCoroutines();
_playerHandler.OnAllPlayersFinished -= HaltAttempt_OnAllPlayersFinished;
_playerHandler.OnPlayerInstanciated -= CheckIfHumanPlayer_OnPlayerInstanciated;*/
}
#endregion
}