#Extends "Modes/Nadeo/Trackmania/Base/TrackmaniaBase.Script.txt"

#Const	CompatibleMapTypes	"TrackMania\\TM_Race,TM_Race"
#Const	Version							"2022-11-05"
#Const	ScriptName					"Modes/Nsgr/TwitchPlays.Script.txt"

#Const Author "Nsgr"

#Include "TextLib" as TL
#Include "MathLib" as ML

#Include "Libs/Nsgr/TwitchPlays/Timer.Script.txt" as TwitchPlaysTimer
#Include "Libs/Nsgr/TwitchPlays/Inputs.Script.txt" as TwitchPlaysInputs
#Include "Libs/Nsgr/TwitchPlays/Pause.Script.txt" as TwitchPlaysPause
#Include "Libs/Nsgr/TwitchPlays/Checkpoint.Script.txt" as TwitchPlaysCheckpoints

#Setting S_TrustClientSimu False

***Match_Settings***
***
MB_Settings_UseDefaultPodiumSequence = False;
***

***Match_AfterLoadHud***
***
// Can't be empty cause we need a client-side ManiaApp
ClientManiaAppUrl = "Scripts/ManiaApps/Nadeo/CMGame/Modes/AppBase.Script.txt";

UIManager.UIAll.DisplayControl_UseEsportsProgrammation = True;
UIManager.UIAll.OverlayHideSpectatorControllers = True;
UIManager.UIAll.OverlayHideSpectatorInfos = True;
UIManager.UIAll.OverlayHideChrono = True; 

Layers::Create(TwitchPlaysTimer::GetId(), TwitchPlaysTimer::GetManialink());
Layers::SetType(TwitchPlaysTimer::GetId(), TwitchPlaysTimer::GetType());
Layers::Attach(TwitchPlaysTimer::GetId());

Layers::Create(TwitchPlaysPause::GetId(), TwitchPlaysPause::GetManialink());
Layers::SetType(TwitchPlaysPause::GetId(), TwitchPlaysPause::GetType());
Layers::Attach(TwitchPlaysPause::GetId());

Layers::Create(TwitchPlaysCheckpoints::GetId(), TwitchPlaysCheckpoints::GetManialink());
Layers::SetType(TwitchPlaysCheckpoints::GetId(), TwitchPlaysCheckpoints::GetType());
Layers::Attach(TwitchPlaysCheckpoints::GetId());
***

***Match_StartMatch***
***
TwitchPlaysTimer::StartMatch();
***

***Match_StartRound***
***
StartTime = Now + Race::C_SpawnDuration;
TwitchPlaysTimer::StartRound(StartTime);

// Spawn players for the race
foreach (Player in Players) {
	Race::Start(Player, StartTime);
	SetFinished(Player, False);
}
***

***Match_PlayLoop***
***
// Skip map if finished
declare RacePendingEvents = Race::GetPendingEvents();
foreach (Event in RacePendingEvents) {
	Race::ValidEvent(Event);
	if (Event.Type == Events::C_Type_Waypoint) {
		if (Event.Player != Null) {
			if (Event.IsEndRace) {
				TwitchPlaysTimer::Finish(Event.Player);
				SetFinished(Event.Player, True);
			}
		}
	}
}

// Spawn players & End the PlayLoop
foreach (Player in Players) {
	// Spawning
	if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned) {
		if (Race::IsReadyToStart(Player) && !PlayerHasFinished(Player)) {
			Race::Start(Player);
		}
	} else if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::Spawned) {
		if (PlayerHasFinished(Player)) {
			UnspawnPlayer(Player);
		}
	}

	// Ending the PlayLoop
	if (PlayerHasFinished(Player)) {
		MB_StopRound();
	}
}
***

***Match_Yield***
***
TwitchPlaysInputs::Yield();
***

***Match_EndRound***
***
foreach (Player in Players) {
	if (!PlayerHasFinished(Player)) {
		TwitchPlaysTimer::Finish(Player);
	}
}
TwitchPlaysTimer::EndRound();
Race::StopSkipOutroAll();
MB_StopMap();
***

***Match_EndMap***
***
if (MatchIsOver(MB_GetMapCount(), -1)) MB_StopMatch();

if (!MB_MapIsRunning() && MB_MatchIsRunning()) MB_SkipPodiumSequence();
***

***MB_Private_PodiumSequence***
***
ModeUtils::PlaySound(CUIConfig::EUISound::EndRound, 0);
declare PrevUISequence = UIManager.UIAll.UISequence;
UIManager.UIAll.UISequence = CUIConfig::EUISequence::Podium;
TwitchPlaysTimer::SetTimerIsFinal(True);
MB_Sleep(8000);
TwitchPlaysTimer::SetTimerIsFinal(False);
MB_Sleep(2000);
UIManager.UIAll.UISequence = PrevUISequence;
***

Boolean MatchIsOver(Integer _MapCount, Integer _MapsPerMatch) {
	if (_MapsPerMatch > 0) {
		return _MapCount >= _MapsPerMatch;
	}
	return _MapCount >= MapList.count;
}

Void SetFinished(CSmPlayer _Player, Boolean _Finished) {
	declare Boolean TwitchPlays_FinishedRound for _Player = False;
	TwitchPlays_FinishedRound = _Finished;
}

Boolean PlayerHasFinished(CSmPlayer _Player) {
	declare Boolean TwitchPlays_FinishedRound for _Player = False;
	return TwitchPlays_FinishedRound;
}