Compare commits

..

6 Commits

View File

@ -4,7 +4,7 @@
#Extends "Libs/Nadeo/TMNext/TrackMania/Modes/TMNextRoundsBase.Script.txt" #Extends "Libs/Nadeo/TMNext/TrackMania/Modes/TMNextRoundsBase.Script.txt"
#Const CompatibleMapTypes "TrackMania\\TM_Race,TM_Race" #Const CompatibleMapTypes "TrackMania\\TM_Race,TM_Race"
#Const Version "2023-07-12" #Const Version "2023-07-13"
#Const ScriptName "Modes/TM2020-Gamemodes/LastManStanding.Script.txt" #Const ScriptName "Modes/TM2020-Gamemodes/LastManStanding.Script.txt"
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
@ -345,8 +345,7 @@ foreach (Event in RacePendingEvents) {
Race::ValidEvent(Event); Race::ValidEvent(Event);
if (Event.Player == Null) continue; if (Event.Player == Null) continue;
// Waypoint
switch (Event.Type) { switch (Event.Type) {
case Events::C_Type_Waypoint: { case Events::C_Type_Waypoint: {
ThrottleUpdate = True; ThrottleUpdate = True;
@ -374,14 +373,23 @@ foreach (Event in PendingEvents) {
if (Event.Type == CSmModeEvent::EType::OnPlayerRemoved) { if (Event.Type == CSmModeEvent::EType::OnPlayerRemoved) {
if (Event.User == Null ) continue; if (Event.User == Null ) continue;
if (!AccountIdsOfPlayers.exists(Event.User.WebServicesUserId)) continue; if (!AccountIdsOfPlayers.exists(Event.User.WebServicesUserId)) continue;
if (IsEliminated(Event.User, Null)) continue;
ThrottleUpdate = True; ThrottleUpdate = True;
UpdateCustomRanking(Event.User, True); UpdateCustomRanking(Event.User, True);
} }
} }
if (PlayersNbAlive <= 1 && AccountIdsOfPlayers.count >= 2) { //TODO just respawn in case of 1 player // Detect when a players count changed without having triggered any of Event (when becoming spectator for example)
Net_TimeBeforeMalus = -1; if (!ThrottleUpdate && Net_PlayersNbAlive != PlayersNbAlive) {
MB_StopRound(); log("Trying to detect why the player count changed");
foreach (Player in AllPlayers) {
if (Player.User == Null || Player.Score == Null) continue;
if (!AccountIdsOfPlayers.exists(Player.User.WebServicesUserId)) continue;
if (Player.SpawnStatus != CSmPlayer::ESpawnStatus::NotSpawned) continue;
if (IsEliminated(Player.User, Player.Score)) continue;
UpdateCustomRanking(Player.User, True);
ThrottleUpdate = True;
}
} }
if (ThrottleUpdate) { if (ThrottleUpdate) {
@ -396,6 +404,11 @@ if (ThrottleUpdate) {
} }
} }
if (PlayersNbAlive <= 1 && AccountIdsOfPlayers.count >= 2) { //TODO just respawn in case of 1 player
Net_TimeBeforeMalus = -1;
MB_StopRound();
}
// Update the map duration setting // Update the map duration setting
if (Map_TimeBeforeMalus != S_TimeBeforeMalus || Map_TimeBeforeMalus != S_TimeBeforeNightmare || Map_MalusEveryNSecs != S_MalusEveryNSecs || Map_NextMalusPreparationTime != S_NextMalusPreparationTime || Map_MalusDuration != S_MalusDuration || Map_RoundsPerMap != S_RoundsPerMap) { if (Map_TimeBeforeMalus != S_TimeBeforeMalus || Map_TimeBeforeMalus != S_TimeBeforeNightmare || Map_MalusEveryNSecs != S_MalusEveryNSecs || Map_NextMalusPreparationTime != S_NextMalusPreparationTime || Map_MalusDuration != S_MalusDuration || Map_RoundsPerMap != S_RoundsPerMap) {
@ -423,20 +436,11 @@ if (Players.count > 0 && S_MalusDuration > 0 && MalusTime != -1 && Now > MalusTi
if (!ActiveMalus && !PendingMalus) { if (!ActiveMalus && !PendingMalus) {
if (S_TimeBeforeNightmare >= 0 && Now > (StartTime + (S_TimeBeforeNightmare * 1000))) { if (S_TimeBeforeNightmare >= 0 && Now > (StartTime + (S_TimeBeforeNightmare * 1000))) {
MalusIndex = C_Malus_Nightmare; MalusIndex = C_Malus_Nightmare;
} else if (AllPlayersAreInTurtle()) {
log("All players are in turtle");
MalusIndex = ML::Rand(7, 10); // Boost if all players in Turtle
} else { } else {
declare Boolean AllPlayersInTurtle = True; MalusIndex = ML::Rand(1, 15);
foreach (Player in Players) {
if (Player.WheelsContactCount > 1 || Player.Speed > 1) {
AllPlayersInTurtle = False;
break;
}
}
if (AllPlayersInTurtle) {
log("All players are in turtle");
MalusIndex = ML::Rand(7, 10); // Boost if all players in Turtle
} else {
MalusIndex = ML::Rand(1, 15);
}
} }
PendingMalus = True; PendingMalus = True;
ActiveMalus = False; ActiveMalus = False;
@ -453,7 +457,6 @@ if (Players.count > 0 && S_MalusDuration > 0 && MalusTime != -1 && Now > MalusTi
ActiveMalus = True; ActiveMalus = True;
NextStepMalusTime = Now + (S_MalusDuration*1000); NextStepMalusTime = Now + (S_MalusDuration*1000);
UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::Silence;
UIModules_BigMessage::SetMessage("Current Effect: "^C_Malus_Name[MalusIndex]); UIModules_BigMessage::SetMessage("Current Effect: "^C_Malus_Name[MalusIndex]);
// Players UI update // Players UI update
@ -474,7 +477,6 @@ if (Players.count > 0 && S_MalusDuration > 0 && MalusTime != -1 && Now > MalusTi
NextStepMalusTime = Now + (S_MalusEveryNSecs*1000); NextStepMalusTime = Now + (S_MalusEveryNSecs*1000);
UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::Silence;
UIModules_BigMessage::SetMessage(""); UIModules_BigMessage::SetMessage("");
// Players UI update // Players UI update
@ -535,8 +537,7 @@ if (Round_ForceEndRound || Round_SkipPauseRound) {
} }
Scores::SetPlayerWinner(WinnerScore); Scores::SetPlayerWinner(WinnerScore);
UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::EndRound; ModeUtils::PlaySound(CUIConfig::EUISound::EndRound, 0);
UIManager.UIAll.BigMessageSoundVariant = 0;
if (WinnerScore == Null) { if (WinnerScore == Null) {
UIModules_BigMessage::SetMessage(_("|Match|Draw")); UIModules_BigMessage::SetMessage(_("|Match|Draw"));
@ -563,6 +564,7 @@ if (Round_ForceEndRound || Round_SkipPauseRound) {
// Functions // Functions
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
// Reset Network Variables
Void ResetNetworkVariables() { Void ResetNetworkVariables() {
declare netwrite Boolean Net_DisplayUI for Teams[0] = False; declare netwrite Boolean Net_DisplayUI for Teams[0] = False;
Net_DisplayUI = False; Net_DisplayUI = False;
@ -580,6 +582,45 @@ Void ResetNetworkVariables() {
Net_CurrentRoundNb = 0; Net_CurrentRoundNb = 0;
} }
/** Check if a Player is already considered eliminated
*
* @param _User The User
* @param _Score The Score, can be Null but it will search the Score in Scores
*
* @return Return True if the player have a time
*/
Boolean IsEliminated(CUser _User, CSmScore _Score) {
if (UIModules_ScoresTable::GetCustomTimes().existskey(_User.WebServicesUserId)) return True;
if (_Score == Null) {
foreach (Score in Scores) {
if (Score.User == Null) continue;
if (Score.User == _User) {
if (Score.PrevRaceTimes.count > 0) return True;
else return False;
break;
}
}
} else if (_Score.PrevRaceTimes.count > 0) {
return True;
}
return False;
}
/** Detect if all players are in Turtle
*
* @return Return False if one player is not in turtle
*/
Boolean AllPlayersAreInTurtle() {
foreach (Player in Players) {
if (Player.WheelsContactCount > 1 || Player.Speed > 1) {
return False;
}
}
return True;
}
/** Get the Time Before the first Malus or NightMare Mode /** Get the Time Before the first Malus or NightMare Mode
* *
* @param _StartTime The starting time of the map * @param _StartTime The starting time of the map