Compare commits
15 Commits
a3f042e7f7
...
master
Author | SHA1 | Date | |
---|---|---|---|
dcd89d584d | |||
da04fba158 | |||
a0496073da | |||
ab7dd77649 | |||
b57aaa5179 | |||
26cc4f63d9 | |||
80e4641eb9 | |||
e2dc0d5d73 | |||
b646019307 | |||
80003e1a39 | |||
deea33e0bd | |||
4dea966448 | |||
7891c33934 | |||
e6aa4049a1 | |||
5a9d8abc82 |
@ -4,7 +4,7 @@
|
||||
#Extends "Modes/Nadeo/Trackmania/Base/TrackmaniaRoundsBase.Script.txt"
|
||||
|
||||
#Const CompatibleMapTypes "TrackMania\\TM_Race,TM_Race"
|
||||
#Const Version "2024-08-25"
|
||||
#Const Version "2025-02-15"
|
||||
#Const ScriptName "Modes/TM2020-Gamemodes/TM_MultiLivesKnockout.Script.txt"
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
||||
@ -38,12 +38,14 @@
|
||||
#Setting S_EliminatedPlayersNbRanks "4,16,16" as _("Nb of players above which one extra elim. /round")
|
||||
#Setting S_RoundsWithoutElimination 1 as _("Rounds without elimination")
|
||||
|
||||
#Setting S_EliminatePerRounds False as "Eliminate par rounds instead of per players alive"
|
||||
#Setting S_EliminationMode 0 as "0 per player / 1 per lives / 2 per round"
|
||||
#Setting S_MaximumLives 3
|
||||
#Setting S_MatchName "Final"
|
||||
#Setting S_AlternativeMatchInfosPosition False
|
||||
|
||||
/* About S_EliminatedPlayersNbRanks and S_EliminatePerRounds.
|
||||
* If S_EliminatePerRounds is True, it will decrease the number of lose of life.
|
||||
|
||||
/* About S_EliminatedPlayersNbRanks.
|
||||
* If S_EliminationMode is 2, it will decrease the number of lose of life.
|
||||
* Example : "8,16"
|
||||
* Round 1 to 7 -> 3 eliminations per round
|
||||
* Round 8 to 15 -> 2 eliminations per round
|
||||
@ -61,7 +63,8 @@
|
||||
* Example : ""
|
||||
* 1 elimination per round
|
||||
*
|
||||
* If S_EliminatePerRounds is False, it will work like the official
|
||||
* If S_EliminationMode is 1, it will sum number of remaining lives and apply official system on it
|
||||
* If S_EliminationMode is 0, it will work like the official Knockout Mode
|
||||
*/
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
||||
@ -75,6 +78,10 @@
|
||||
#Const C_ManiaAppUrl "file://Media/ManiaApps/Nadeo/Trackmania/Modes/Knockout.Script.txt" //< Url of the mania app
|
||||
#Const C_FakeUsersNb 0
|
||||
|
||||
#Const C_ElimMode_Rounds 2
|
||||
#Const C_ElimMode_Lives 1
|
||||
#Const C_ElimMode_Official 0
|
||||
|
||||
#Const C_Callback_Elimination "Trackmania.Knockout.Elimination"
|
||||
#Const C_Callback_LostLife "Trackmania.Knockout.LostLife"
|
||||
|
||||
@ -463,13 +470,11 @@ if (Semver::Compare(XmlRpc::GetApiVersion(), ">=", "2.1.1")) {
|
||||
Scores::XmlRpc_SendScores(Scores::C_Section_PreEndRound, "");
|
||||
}
|
||||
|
||||
DisplayLiveRanking(False);
|
||||
|
||||
declare Text[] LostLifeAccountIds;
|
||||
declare Text[] EliminatedAccountIds;
|
||||
declare Integer[] EliminatedRanks;
|
||||
|
||||
if (Round_ForceEndRound || Round_SkipPauseRound) {
|
||||
if (Round_ForceEndRound || Round_SkipPauseRound || Round_Skipped) {
|
||||
// Cancel points
|
||||
foreach (Score in Scores) {
|
||||
Scores::SetPlayerRoundPoints(Score, 0);
|
||||
@ -479,6 +484,7 @@ if (Round_ForceEndRound || Round_SkipPauseRound) {
|
||||
ForcedEndRoundSequence();
|
||||
}
|
||||
MB_SetValidRound(False);
|
||||
Match_CurrentRoundNb -= 1;
|
||||
} else {
|
||||
// Eliminate players that did not finish in time
|
||||
declare Ident[] EliminatedPlayersScoresIds = []; // Score.Id
|
||||
@ -504,7 +510,8 @@ if (Round_ForceEndRound || Round_SkipPauseRound) {
|
||||
LostLifeAccountIds.add(Score.User.WebServicesUserId);
|
||||
|
||||
if (!ScoreIsAlive(Score)) {
|
||||
Scores::SetPlayerMatchPoints(Score, ParticipantsNb - Rank);
|
||||
// Registered Score must have at least 1 point or a best race time to not be reset at end of the map: https://forum.nadeo.com/viewtopic.php?t=4365
|
||||
Scores::SetPlayerMatchPoints(Score, ParticipantsNb + 1 - Rank);
|
||||
EliminatedAccountIds.add(Score.User.WebServicesUserId);
|
||||
EliminatedRanks.add(Rank);
|
||||
|
||||
@ -553,6 +560,7 @@ if (Round_ForceEndRound || Round_SkipPauseRound) {
|
||||
MB_Sleep(S_ChatTime / 2 * 1000);
|
||||
UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
|
||||
}
|
||||
DisplayLiveRanking(False);
|
||||
}
|
||||
***
|
||||
|
||||
@ -689,6 +697,19 @@ Integer GetAliveScoresNb() {
|
||||
return AliveScoresNb;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
||||
/** Number of lives cumulated
|
||||
*
|
||||
* @return Number of lives cumulated
|
||||
*/
|
||||
Integer GetRemainingLivesNb() {
|
||||
declare Integer LivesNb;
|
||||
foreach (Score in Scores) {
|
||||
LivesNb += GetScoreRemainingLives(Score);
|
||||
}
|
||||
return LivesNb;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
||||
/** Compute Lose of Life Milestones
|
||||
*
|
||||
@ -714,14 +735,20 @@ Integer[] GetAllMilestones() {
|
||||
*/
|
||||
Integer GetNextMilestone(Integer _RoundNb, Integer _AliveScoresNb) {
|
||||
if (_AliveScoresNb <= 0) return 0;
|
||||
|
||||
declare Integer ThresholdValue = _AliveScoresNb;
|
||||
if (S_EliminationMode == C_ElimMode_Lives) {
|
||||
ThresholdValue = GetRemainingLivesNb();
|
||||
}
|
||||
|
||||
declare Integer[] Milestones = GetAllMilestones();
|
||||
|
||||
declare Integer NextMilestone = 0;
|
||||
foreach (Milestone in Milestones) {
|
||||
if (S_EliminatePerRounds && Milestone > _RoundNb) {
|
||||
if (S_EliminationMode == C_ElimMode_Rounds && Milestone > _RoundNb) {
|
||||
NextMilestone = Milestone;
|
||||
break;
|
||||
} else if (!S_EliminatePerRounds && Milestone < _AliveScoresNb) { // could be optimized but can change original behavior
|
||||
} else if ((S_EliminationMode == C_ElimMode_Official || S_EliminationMode == C_ElimMode_Lives) && Milestone < ThresholdValue) { // could be optimized but can change original behavior
|
||||
NextMilestone = Milestone;
|
||||
}
|
||||
}
|
||||
@ -738,11 +765,17 @@ Integer GetNextMilestone(Integer _RoundNb, Integer _AliveScoresNb) {
|
||||
Integer GetLossOfLifeNb(Integer _RoundNb, Integer _AliveScoresNb) {
|
||||
if (_AliveScoresNb <= 1) return 0;
|
||||
if (_RoundNb <= S_RoundsWithoutElimination) return 0;
|
||||
|
||||
declare Integer ThresholdValue = _AliveScoresNb;
|
||||
if (S_EliminationMode == C_ElimMode_Lives) {
|
||||
ThresholdValue = GetRemainingLivesNb();
|
||||
}
|
||||
|
||||
declare Integer[] Milestones = GetAllMilestones();
|
||||
|
||||
declare Integer NumberOfElimination;
|
||||
|
||||
if (S_EliminatePerRounds) {
|
||||
if (S_EliminationMode == C_ElimMode_Rounds) {
|
||||
Milestones = Milestones.slice(1);
|
||||
NumberOfElimination = 1;
|
||||
foreach (Milestone in Milestones) {
|
||||
@ -750,10 +783,10 @@ Integer GetLossOfLifeNb(Integer _RoundNb, Integer _AliveScoresNb) {
|
||||
NumberOfElimination += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (S_EliminationMode == C_ElimMode_Official || S_EliminationMode == C_ElimMode_Lives) {
|
||||
declare Integer RoundMinEliminations = Milestones.count + 1;
|
||||
foreach (Index => Milestone in Milestones) {
|
||||
if (Milestone < _AliveScoresNb) {
|
||||
if (Milestone < ThresholdValue) {
|
||||
RoundMinEliminations = Index + 1;
|
||||
}
|
||||
}
|
||||
@ -925,7 +958,7 @@ Boolean MatchIsOver(Integer _RoundNb) {
|
||||
*/
|
||||
Boolean MapIsOver(Integer _RoundNb) {
|
||||
if (MatchIsOver(_RoundNb)) return True;
|
||||
if (S_RoundsPerMap > 0 && MB_GetRoundCount() >= S_RoundsPerMap) return True; //< There is a rounds limit and it is reached
|
||||
if (S_RoundsPerMap > 0 && MB_GetValidRoundCount() >= S_RoundsPerMap) return True; //< There is a rounds limit and it is reached
|
||||
|
||||
return False;
|
||||
}
|
||||
@ -974,8 +1007,8 @@ Void UpdateMatchInfos(Integer _CurrentRoundNb, Integer _LossOfLife, Integer _Ali
|
||||
if (MapNumber == 0) MapNumber = 3;
|
||||
|
||||
if (_CurrentRoundNb == -1) MatchInfo = "Warm Up";
|
||||
else if (S_EliminatePerRounds) MatchInfo = "Match Round "^ _CurrentRoundNb ^ " - Round "^ ML::Max(MB_GetRoundCount(), 1) ^"/"^ S_RoundsPerMap ^" of Map "^ MapNumber ^"/"^ MapList.count;
|
||||
else MatchInfo = "Round "^ ML::Max(MB_GetRoundCount(), 1) ^"/"^ S_RoundsPerMap ^ " - Map "^ MapNumber ^"/"^ MapList.count;
|
||||
else if (S_EliminationMode == C_ElimMode_Rounds) MatchInfo = "Match Round "^ _CurrentRoundNb ^ " - Round "^ ML::Max(MB_GetValidRoundCount(), 1) ^"/"^ S_RoundsPerMap ^" of Map "^ MapNumber ^"/"^ MapList.count;
|
||||
else MatchInfo = "Round "^ ML::Max(MB_GetValidRoundCount(), 1) ^"/"^ S_RoundsPerMap ^ " - Map "^ MapNumber ^"/"^ MapList.count;
|
||||
} else if (_CurrentRoundNb == -1) {
|
||||
MatchInfo = "Warm Up";
|
||||
} else {
|
||||
@ -986,17 +1019,20 @@ Void UpdateMatchInfos(Integer _CurrentRoundNb, Integer _LossOfLife, Integer _Ali
|
||||
if (_LossOfLife == 0) {
|
||||
MatchInfo ^= "\nNo loss of life";
|
||||
ScoreTablesInfo ^= "\nNo loss of life this round";
|
||||
} else if (S_EliminatePerRounds && _LossOfLife > 1 && _Milestone > 1) {
|
||||
MatchInfo ^= "\n"^ _LossOfLife ^" lose of life until Match Round "^ _Milestone;
|
||||
} else if (S_EliminationMode == C_ElimMode_Rounds && _LossOfLife > 1 && _Milestone > 1) {
|
||||
MatchInfo ^= "\n"^ _LossOfLife ^" lives lost until Match Round "^ _Milestone;
|
||||
ScoreTablesInfo ^= "\n"^ _LossOfLife ^" players will lose a life until Match Round "^ _Milestone;
|
||||
} else if (!S_EliminatePerRounds && _LossOfLife > 1 && _Milestone > 1) {
|
||||
MatchInfo ^= "\n"^ _LossOfLife ^" lose of life until "^ _Milestone ^" players are alive";
|
||||
} else if (S_EliminationMode == C_ElimMode_Lives && _LossOfLife > 1 && _Milestone > 1) {
|
||||
MatchInfo ^= "\n"^ _LossOfLife ^" lives lost until "^ _Milestone ^" lives left";
|
||||
ScoreTablesInfo ^= "\n"^ _LossOfLife ^" players will lose a life until "^ _Milestone ^" lives left";
|
||||
} else if (S_EliminationMode == C_ElimMode_Official && _LossOfLife > 1 && _Milestone > 1) {
|
||||
MatchInfo ^= "\n"^ _LossOfLife ^" lives lost until "^ _Milestone ^" players are alive";
|
||||
ScoreTablesInfo ^= "\n"^ _LossOfLife ^" players will lose a life until "^ _Milestone ^" players are alive";
|
||||
} else if (_LossOfLife > 1) {
|
||||
MatchInfo ^= "\n"^ _LossOfLife ^" lose of life";
|
||||
MatchInfo ^= "\n"^ _LossOfLife ^" players will lose a life";
|
||||
ScoreTablesInfo ^= "\n"^ _LossOfLife ^" players will lose a life per round";
|
||||
} else {
|
||||
MatchInfo ^= "\n1 lose of life";
|
||||
MatchInfo ^= "\n1 player will lose a life";
|
||||
ScoreTablesInfo ^= "\n1 player will lose a life";
|
||||
}
|
||||
}
|
||||
@ -1021,6 +1057,13 @@ Void UpdateMatchName() {
|
||||
Net_MultiLivesKnockout_LiveRanking_MatchName = S_MatchName;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
||||
// Update Match Infos
|
||||
Void UpdateMatchInfosPosition() {
|
||||
declare netwrite Boolean Net_MultiLivesKnockout_AlternativePosition for Teams[0];
|
||||
Net_MultiLivesKnockout_AlternativePosition = S_AlternativeMatchInfosPosition;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
||||
// Update Number of lives
|
||||
Void UpdateMaximumLives() {
|
||||
@ -1047,6 +1090,7 @@ Void UpdateLossOfLife(Integer _LossOfLife) {
|
||||
*/
|
||||
Void UpdateInterfacesInfo(Integer _CurrentRoundNb, Integer _LossOfLife, Integer _AliveScoresNb) {
|
||||
UpdateMatchInfos(_CurrentRoundNb, _LossOfLife, _AliveScoresNb, GetNextMilestone(_CurrentRoundNb, _AliveScoresNb));
|
||||
UpdateMatchInfosPosition();
|
||||
UpdateMatchName();
|
||||
UpdateMaximumLives();
|
||||
UpdateLossOfLife(_LossOfLife);
|
||||
@ -1074,7 +1118,7 @@ Void LoadManialinks() {
|
||||
<label id="label-player-time" pos="54 -2" z-index="2" size="10 5" halign="right" valign="center" textsize="2" textfont="Nadeo/Trackmania/BebasNeueRegular" textcolor="ffffff"/>
|
||||
</framemodel>
|
||||
<frame id="frame-global" hidden="1">
|
||||
<frame id="frame-matchinfo" pos="-160 80">
|
||||
<frame id="frame-matchinfo" pos="-160 80" hidden="1">
|
||||
<quad size="55 18" bgcolor="000000" opacity="0.6"/>
|
||||
<label id="label-matchinfo-name" pos="3 -7.8" size="49 6" valign="bottom" textsize="3.5" textfont="GameFontExtraBold" textcolor="ffffff" text=""/>
|
||||
<label id="label-matchinfo-info" pos="3 -8.8" size="49 8" textsize="1.3" maxline="2" linespacing="1.1" textfont="GameFontSemiBold" textcolor="ffffff" text="" />
|
||||
@ -1185,16 +1229,23 @@ Void ToggleUI(Boolean _Display, Boolean _UseAnimation) {
|
||||
// Update Match info
|
||||
Void UpdateMatchInfo() {
|
||||
declare CMlFrame Frame <=> (Page.GetFirstChild("frame-matchinfo") as CMlFrame);
|
||||
|
||||
declare netread Text Net_MultiLivesKnockout_LiveRanking_MatchName for Teams[0];
|
||||
Frame.Visible = (Net_MultiLivesKnockout_LiveRanking_MatchName != "");
|
||||
|
||||
declare CMlLabel Label_Name <=> (Frame.GetFirstChild("label-matchinfo-name") as CMlLabel);
|
||||
declare CMlLabel Label_Info <=> (Frame.GetFirstChild("label-matchinfo-info") as CMlLabel);
|
||||
|
||||
declare netread Text Net_MultiLivesKnockout_LiveRanking_MatchName for Teams[0];
|
||||
declare netread Boolean Net_MultiLivesKnockout_AlternativePosition for Teams[0];
|
||||
if (Net_MultiLivesKnockout_AlternativePosition) Frame.RelativePosition_V3.Y = 50.;
|
||||
else Frame.RelativePosition_V3.Y = 80.;
|
||||
|
||||
Label_Name.Value = Net_MultiLivesKnockout_LiveRanking_MatchName;
|
||||
Tools::FitLabelValue(Label_Name, 3.5, 2., .2);
|
||||
|
||||
declare netread Text Net_MultiLivesKnockout_LiveRanking_MatchInfo for Teams[0];
|
||||
Label_Info.Value = Net_MultiLivesKnockout_LiveRanking_MatchInfo;
|
||||
Tools::FitLabelValue(Label_Info, 1.3, .8, .1);
|
||||
Tools::FitLabelValue(Label_Info, 1.3, .4, .1);
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
||||
@ -1586,7 +1637,7 @@ main() {
|
||||
}
|
||||
|
||||
if (GUIPlayer == Null && Last_GUIPlayer != NullId) {
|
||||
Last_GUIPlayer == NullId;
|
||||
Last_GUIPlayer = NullId;
|
||||
UpdateLiveRanking = True;
|
||||
} else if (GUIPlayer != Null && Last_GUIPlayer != GUIPlayer.Id) {
|
||||
Last_GUIPlayer = GUIPlayer.Id;
|
||||
|
@ -5,7 +5,7 @@
|
||||
#Extends "Modes/Nadeo/Trackmania/Base/TrackmaniaRoundsBase.Script.txt"
|
||||
|
||||
#Const CompatibleMapTypes "TrackMania\\TM_Race,TM_Race"
|
||||
#Const Version "2024-04-11"
|
||||
#Const Version "2025-05-08"
|
||||
#Const ScriptName "Modes/TM2020-Gamemodes/TM_RoundsNearest.Script.txt"
|
||||
|
||||
// #RequireContext CSmMode
|
||||
@ -21,6 +21,7 @@
|
||||
#Include "Libs/Nadeo/TMGame/Utils/Tracking.Script.txt" as Tracking
|
||||
#Include "Libs/Nadeo/TMGame/Modes/Base/UIModules/Checkpoint_Server.Script.txt" as UIModules_Checkpoint
|
||||
#Include "Libs/Nadeo/TMGame/Modes/Base/UIModules/PauseMenuOnline_Server.Script.txt" as UIModules_PauseMenu_Online
|
||||
#Include "Libs/Nadeo/Trackmania/Modes/Rounds/UIModules/SmallScoresTable_Server.Script.txt" as UIModules_SmallScoresTable
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
||||
// Settings
|
||||
@ -33,6 +34,7 @@
|
||||
#Setting S_PointsRepartition "5,4,3,2,1,0"
|
||||
#Setting S_RoundsPerMap 8 as _("Number of rounds per track") ///< Number of round to play on one map before going to the next one
|
||||
#Setting S_TargetTime 20000
|
||||
#Setting S_SendSameTimeMessage False
|
||||
|
||||
#Setting S_WarmUpDuration 30 as _("Duration of one warm up")
|
||||
#Setting S_WarmUpNb 1 as _("Number of warm up")
|
||||
@ -67,6 +69,7 @@ Log::RegisterScript(ScriptName, Version);
|
||||
Log::RegisterScript(Semver::ScriptName, Semver::Version);
|
||||
Log::RegisterScript(ModeUtils::ScriptName, ModeUtils::Version);
|
||||
Log::RegisterScript(StateMgr::ScriptName, StateMgr::Version);
|
||||
Log::RegisterScript(UIModules_SmallScoresTable::ScriptName, UIModules_SmallScoresTable::Version);
|
||||
***
|
||||
|
||||
***Match_LoadLibraries***
|
||||
@ -111,7 +114,7 @@ UIManager.UIAll.OverlayHideSpectatorInfos = True;
|
||||
UIManager.UIAll.OverlayHideCountdown = True;
|
||||
|
||||
UIModules_ScoresTable::DisplayRoundPoints(True);
|
||||
UIModules::UnloadModules(["UIModule_Race_TimeGap", "UIModule_Rounds_SmallScoresTable"]);
|
||||
UIModules::UnloadModules(["UIModule_Race_TimeGap"]);
|
||||
***
|
||||
|
||||
***Match_Yield***
|
||||
@ -163,6 +166,8 @@ Server_MapsPerMatch = S_MapsPerMatch - 1;
|
||||
***Match_StartMatch***
|
||||
***
|
||||
UIModules_ScoresTable::SetCustomPoints([]);
|
||||
UIModules_SmallScoresTable::ResetCustomTimes();
|
||||
UIModules_SmallScoresTable::ResetCustomResults();
|
||||
***
|
||||
|
||||
***Match_InitMap***
|
||||
@ -201,6 +206,13 @@ foreach (Score in Scores) {
|
||||
UpdateScoresTableFooter(S_PointsLimit, S_RoundsPerMap, S_MapsPerMatch, Map_ValidRoundsNb);
|
||||
StateMgr::ForcePlayersStates([StateMgr::C_State_Playing]);
|
||||
UIModules_ScoresTable::SetCustomPoints(GetWinnersCustomPoints());
|
||||
|
||||
foreach (Score in Scores) {
|
||||
declare Boolean RoundsNearest_AlmostPerfectTime_MessageSent for Score;
|
||||
RoundsNearest_AlmostPerfectTime_MessageSent = False;
|
||||
declare Boolean RoundsNearest_DidPerfectTime_MessageSent for Score;
|
||||
RoundsNearest_DidPerfectTime_MessageSent = False;
|
||||
}
|
||||
***
|
||||
|
||||
***Rounds_PlayerSpawned***
|
||||
@ -306,6 +318,8 @@ if (Round_ForceEndRound || Round_SkipPauseRound || Round_Skipped) {
|
||||
MB_StopMap();
|
||||
}
|
||||
}
|
||||
UIModules_SmallScoresTable::ResetCustomTimes();
|
||||
UIModules_SmallScoresTable::ResetCustomResults();
|
||||
***
|
||||
|
||||
***Match_EndMap***
|
||||
@ -448,13 +462,15 @@ Text[][Text] GetWinnersCustomPoints() {
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
||||
/// Compute the latest race scores
|
||||
Void ComputeLatestRaceScores(Boolean _DisplayMessages) {
|
||||
Void ComputeLatestRaceScores(Boolean _IsEndRound) {
|
||||
Race::SortScores(Race::C_Sort_PrevRaceTime);
|
||||
|
||||
// Points distributed between all players
|
||||
|
||||
declare Text[][Text] CustomPoints = GetWinnersCustomPoints();
|
||||
declare CSmScore[][Integer] ScoresPerAbsoluteDelta;
|
||||
declare Integer[Text] CustomTimes;
|
||||
declare Text[Text] CustomResult;
|
||||
foreach (Score in Scores) {
|
||||
if (Score.User == Null) continue;
|
||||
if (Scores::GetPlayerPrevRaceTime(Score) <= 0) continue;
|
||||
@ -470,6 +486,12 @@ Void ComputeLatestRaceScores(Boolean _DisplayMessages) {
|
||||
TextDelta ^= DeltaTimeToText(AbsoluteDelta);
|
||||
if (S_PointsLimit < 0 || Scores::GetPlayerMatchPoints(Score) < S_PointsLimit) {
|
||||
CustomPoints[Score.User.WebServicesUserId] = [Scores::GetPlayerMatchPoints(Score) ^ " (" ^ TextDelta ^ ")"];
|
||||
if (AbsoluteDelta == 0) {
|
||||
CustomResult[Score.User.WebServicesUserId] = "PERFECT";
|
||||
} else {
|
||||
CustomResult[Score.User.WebServicesUserId] = TextDelta;
|
||||
}
|
||||
CustomTimes[Score.User.WebServicesUserId] = AbsoluteDelta;
|
||||
}
|
||||
}
|
||||
UIModules_ScoresTable::SetCustomPoints(CustomPoints);
|
||||
@ -478,12 +500,12 @@ Void ComputeLatestRaceScores(Boolean _DisplayMessages) {
|
||||
|
||||
declare Integer I = 0;
|
||||
declare Integer[] PointsRepartition = PointsRepartition::GetPointsRepartition();
|
||||
declare Text Names;
|
||||
|
||||
foreach (Delta => CustomScores in ScoresPerAbsoluteDelta) {
|
||||
// Attribute less points if they have the same time
|
||||
if (_DisplayMessages && CustomScores.count > 1) {
|
||||
if (S_SendSameTimeMessage && _IsEndRound && CustomScores.count > 1) {
|
||||
I += CustomScores.count - 1;
|
||||
declare Text Names;
|
||||
foreach (Key => Score in CustomScores) {
|
||||
if (Key == 0) {
|
||||
Names = FormatPlayerName(Score.User.Name);
|
||||
@ -495,7 +517,11 @@ Void ComputeLatestRaceScores(Boolean _DisplayMessages) {
|
||||
}
|
||||
UIManager.UIAll.SendChat("$ff3" ^ Names^ " have the same time");
|
||||
}
|
||||
foreach (Score in CustomScores) {
|
||||
|
||||
Names = "";
|
||||
declare Boolean UpdateBigMessage;
|
||||
|
||||
foreach (Key => Score in CustomScores) {
|
||||
declare Integer Points;
|
||||
|
||||
if (PointsRepartition.existskey(I)) {
|
||||
@ -504,19 +530,45 @@ Void ComputeLatestRaceScores(Boolean _DisplayMessages) {
|
||||
Points = PointsRepartition[PointsRepartition.count - 1];
|
||||
}
|
||||
|
||||
if (Delta == 0 && CustomScores.count == 1) {
|
||||
Points += S_BonusForPerfect;
|
||||
if (_DisplayMessages) {
|
||||
if (Delta == 0) {
|
||||
declare Boolean RoundsNearest_DidPerfectTime_MessageSent for Score;
|
||||
if (!RoundsNearest_DidPerfectTime_MessageSent) {
|
||||
RoundsNearest_DidPerfectTime_MessageSent = True;
|
||||
UpdateBigMessage = True;
|
||||
UIManager.UIAll.SendChat("$ff3" ^ FormatPlayerName(Score.User.Name) ^ " did the perfect time");
|
||||
UIModules_BigMessage::SetMessage(FormatPlayerName(Score.User.Name) ^ " did the perfect time");
|
||||
ModeUtils::PlaySound(CUIConfig::EUISound::TieBreakPoint, 0);
|
||||
}
|
||||
|
||||
if (Key == 0) {
|
||||
Names = FormatPlayerName(Score.User.Name);
|
||||
} else if (Key == CustomScores.count - 1) {
|
||||
Names ^= " and " ^ FormatPlayerName(Score.User.Name);
|
||||
} else {
|
||||
Names ^= ", " ^ FormatPlayerName(Score.User.Name);
|
||||
}
|
||||
|
||||
if (CustomScores.count == 1) {
|
||||
Points += S_BonusForPerfect;
|
||||
}
|
||||
} else if (Delta == 1) {
|
||||
declare Boolean RoundsNearest_AlmostPerfectTime_MessageSent for Score;
|
||||
if (!RoundsNearest_AlmostPerfectTime_MessageSent) {
|
||||
RoundsNearest_AlmostPerfectTime_MessageSent = True;
|
||||
UIManager.UIAll.SendChat("$ff3" ^ FormatPlayerName(Score.User.Name) ^ " HAH");
|
||||
}
|
||||
}
|
||||
Scores::SetPlayerRoundPoints(Score, Points);
|
||||
}
|
||||
|
||||
if (UpdateBigMessage) {
|
||||
UIModules_BigMessage::SetMessage(Names ^ " did the perfect time");
|
||||
}
|
||||
|
||||
I += 1;
|
||||
}
|
||||
|
||||
UIModules_SmallScoresTable::SetCustomTimes(CustomTimes);
|
||||
UIModules_SmallScoresTable::SetCustomResults(CustomResult);
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
||||
|
Reference in New Issue
Block a user