/** @context CSmMode */ #Extends "Modes/TM2020-Gamemodes/PhysicsController.Script.txt" #Setting S_CoolDownBeforeReset 4 #Setting S_CoolDownForEffects 180 #Setting S_FloorsInfo "136,256,384,512,648,768,904,1040,1168,1296,1432" as "comma separated floor height" // Default is floors of the map "Bennett Foddy ate my CPs" #Struct K_PlayerInfo { Text Login; Text Name; Integer PrevRank; Integer CurRank; Integer Altitude; Integer RaceTime; Integer RoundPoints; Boolean Eliminated; Boolean isSpectator; } ***Match_InitMap*** *** declare Integer[Text] ApplyResetAtRespawn_Queue for This; ApplyResetAtRespawn_Queue = []; if (Map.MapInfo.MapUid == "3tMeImoOvcb0hnryDZ9nbw9YVY6") { // Only upload record on the right map Race::SetupRecord( MenuConsts::C_ScopeType_Season, MenuConsts::C_ScopeType_PersonalBest, MenuConsts::C_GameMode_TimeAttack, "", True, //C_UploadRecord False, //C_DisplayRecordGhost False, //C_DisplayRecordMedal False, //C_CelebrateRecordGhost False //C_CelebrateRecordMedal ); } else { Race::SetupRecord( MenuConsts::C_ScopeType_Season, MenuConsts::C_ScopeType_PersonalBest, MenuConsts::C_GameMode_TimeAttack, "", False, //C_UploadRecord False, //C_DisplayRecordGhost False, //C_DisplayRecordMedal False, //C_CelebrateRecordGhost False //C_CelebrateRecordMedal ); } *** // force a reset at respawn to prevent abuse ***PhysicsController_PhysicsAtRespawn*** *** foreach (Event in RacePendingEvents) { Log::Log("[RacePendingEvents][MainLoop] Event.Type: " ^ Event.Type); if (Event.Type == Events::C_Type_StartLine || Event.Type == Events::C_Type_GiveUp || Event.Type == Events::C_Type_SkipOutro || Event.Type == Events::C_Type_Respawn) { if (Event.Player != Null) { if (Event.Type != Events::C_Type_Respawn) { declare netwrite Integer Net_CoolDownForEffects for Event.Player; declare netwrite Integer Net_CoolDownBeforeReset for Event.Player; Net_CoolDownForEffects = 0; Net_CoolDownBeforeReset = 0; } declare netwrite Net_PlayerPhysics for Event.Player = InitPlayerPhysicsVariable(); Net_PlayerPhysics = InitPlayerPhysicsVariable(); if (!ApplyPhysics_Queue.existskey(Event.Player.User.WebServicesUserId)) ApplyPhysics_Queue[Event.Player.User.WebServicesUserId] = []; ApplyPhysics_Queue[Event.Player.User.WebServicesUserId] = GetDiffPhysics(Event.Player, True); } } } *** ***PhysicsController_UI*** *** SetHolidayShowdownControlML(); SetHolidayShowdownLiveRaceML(); UIModules::UnloadModules(["UIModule_Rounds_SmallScoresTable","UIModule_Knockout_KnockoutInfo"]); *** ***PhysicsController_SetPhysicsChange*** *** declare netwrite Integer Net_CoolDownForEffects for _Player = 0; declare netwrite Integer Net_CoolDownBeforeReset for _Player = 0; if (_EventName == "Reset") { Net_CoolDownBeforeReset = 0; if (_Player != Null && !SetPlayer_DelayedIsFull(_Player) && (_Player.SpawnStatus == CSmPlayer::ESpawnStatus::Spawned || _Player.SpawnStatus == CSmPlayer::ESpawnStatus::Spawning)) { declare netwrite Net_PlayerPhysics for _Player = InitPlayerPhysicsVariable(); Net_PlayerPhysics = InitPlayerPhysicsVariable(); } } else { Net_CoolDownBeforeReset = Now + (S_CoolDownBeforeReset * 1000); Net_CoolDownForEffects = Now + (S_CoolDownForEffects * 1000); } *** ***PhysicsController_BeforeAddApplyPhysicsEffect*** *** ApplyPhysics_Queue[Player.User.WebServicesUserId] = []; ApplyPhysics_Queue[Player.User.WebServicesUserId].add(GetPhysics("Reset", "", Now + (S_CoolDownBeforeReset * 1000) - 50)); ApplyPhysics_Queue[Player.User.WebServicesUserId].add(GetPhysics("Reset", "", Now + (S_CoolDownBeforeReset * 1000) + 50)); ApplyPhysics_Queue[Player.User.WebServicesUserId].add(GetPhysics("Reset", "", Now + (S_CoolDownBeforeReset * 1000) + 100)); ApplyPhysics_Queue[Player.User.WebServicesUserId].add(GetPhysics("Reset", "", Now + (S_CoolDownBeforeReset * 1000) + 200)); ApplyPhysics_Queue[Player.User.WebServicesUserId].add(GetPhysics("Reset", "", Now + (S_CoolDownBeforeReset * 1000) + 500)); ApplyPhysics_Queue[Player.User.WebServicesUserId].add(GetPhysics("Reset", "", Now + (S_CoolDownBeforeReset * 1000) + 1000)); ApplyPhysics_Queue[Player.User.WebServicesUserId].add(GetPhysics(EventName, Value, Now + 50)); ApplyPhysics_Queue[Player.User.WebServicesUserId].add(GetPhysics(EventName, Value, Now + 100)); ApplyPhysics_Queue[Player.User.WebServicesUserId].add(GetPhysics(EventName, Value, Now + 200)); ApplyPhysics_Queue[Player.User.WebServicesUserId].add(GetPhysics(EventName, Value, Now + 500)); *** ***Match_InitMap*** *** declare Integer WaitNextUpdate = 0; declare netwrite Text Net_FloorsInfo for Teams[0] = S_FloorsInfo; declare netwrite K_PlayerInfo[] Net_HolidayShowdown_Ranking for Teams[0]; declare netwrite Integer Net_HolidayShowdown_RankingSerial for Teams[0]; *** ***Match_InitPlayLoop*** *** WaitNextUpdate = 0; Net_HolidayShowdown_RankingSerial = 0; *** ***Match_PlayLoop*** *** if (Now > WaitNextUpdate) { WaitNextUpdate = Now + 500; declare Integer[Text] SortedPlayersByRaceTime; declare Integer[Text] SortedPlayersByAltitude; declare Text[] SortedPlayersEliminated; foreach (Player in AllPlayers) { if (!Player.RequestsSpectate || Scores::GetPlayerMatchPoints(Player.Score) > 0) { if (Player.Score.PrevRaceTimes.count > 0 && Player.RaceWaypointTimes.count == Player.Score.PrevRaceTimes.count && Player.RaceWaypointTimes[Player.RaceWaypointTimes.count - 1] == Player.Score.PrevRaceTimes[Player.Score.PrevRaceTimes.count - 1]) { SortedPlayersByRaceTime[Player.User.WebServicesUserId] = Player.Score.PrevRaceTimes[Player.Score.PrevRaceTimes.count - 1]; } else if (UIManager.UIAll.UISequence == CUIConfig::EUISequence::Playing && Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned) { declare netwrite Integer Net_Knockout_KnockoutInfo_PlayersNb for Teams[0] = 0; declare netwrite Boolean Net_Knockout_PlayerIsAlive for Player.Score = False; if (Net_Knockout_KnockoutInfo_PlayersNb == 0 || Net_Knockout_PlayerIsAlive) { SortedPlayersEliminated.add(Player.User.WebServicesUserId); } } else { SortedPlayersByAltitude[Player.User.WebServicesUserId] = ML::FloorInteger(Player.Position.Y); } } } SortedPlayersByRaceTime = SortedPlayersByRaceTime.sort(); SortedPlayersByAltitude = SortedPlayersByAltitude.sortreverse(); declare K_PlayerInfo[] Ranking; declare Integer Rank = 1; foreach (AccountId => RaceTime in SortedPlayersByRaceTime) { if (Rank > 16) break; declare CSmPlayer Player <=> ModeUtils::GetPlayerFromAccountId(AccountId); if (Player != Null) { declare Integer HolidayShowdown_PrevRank for Player = 0; Ranking.add(K_PlayerInfo { Login = Player.User.Login, Name = Player.User.Name, PrevRank = HolidayShowdown_PrevRank, CurRank = Rank, Altitude = -1, RaceTime = RaceTime, RoundPoints = Player.Score.RoundPoints, Eliminated = False, isSpectator = Player.RequestsSpectate }); if (Rank != HolidayShowdown_PrevRank) CarRank::SetRank(Player, Rank); HolidayShowdown_PrevRank = Rank; Rank = Rank + 1; } } foreach (AccountId => PlayerAltitude in SortedPlayersByAltitude) { if (Rank > 16) break; declare CSmPlayer Player <=> ModeUtils::GetPlayerFromAccountId(AccountId); if (Player != Null ) { declare Integer HolidayShowdown_PrevRank for Player = 0; // Add the player to the ranking Ranking.add(K_PlayerInfo { Login = Player.User.Login, Name = Player.User.Name, PrevRank = HolidayShowdown_PrevRank, CurRank = Rank, Altitude = PlayerAltitude, RaceTime = -1, RoundPoints = -1, Eliminated = False, isSpectator = Player.RequestsSpectate }); if (Rank != HolidayShowdown_PrevRank) CarRank::SetRank(Player, Rank); HolidayShowdown_PrevRank = Rank; Rank = Rank + 1; } } foreach (AccountId in SortedPlayersEliminated) { if (Rank > 16) break; declare CSmPlayer Player <=> ModeUtils::GetPlayerFromAccountId(AccountId); if (Player != Null) { declare Integer HolidayShowdown_PrevRank for Player = 0; // Add the player to the ranking Ranking.add(K_PlayerInfo { Login = Player.User.Login, Name = Player.User.Name, PrevRank = HolidayShowdown_PrevRank, CurRank = Rank, Altitude = -1, RaceTime = -1, RoundPoints = -1, Eliminated = True, isSpectator = Player.RequestsSpectate }); if (Rank != HolidayShowdown_PrevRank) CarRank::SetRank(Player, Rank); HolidayShowdown_PrevRank = Rank; Rank = Rank + 1; } } Net_HolidayShowdown_Ranking = Ranking; Net_HolidayShowdown_RankingSerial = Net_HolidayShowdown_RankingSerial + 1; } if (Net_FloorsInfo != S_FloorsInfo) { Net_FloorsInfo = S_FloorsInfo; } *** ***PhysicsController_NewCustomEvents*** *** if (Event.CustomEventType == "Request.ResetCD") { declare Text Target = Event.CustomEventData[0]; Log::Log("[UIManager] Admin send reset CD to : " ^ Target); declare CSmPlayer Player = GetPlayer(Target); if (Player != Null) { declare netwrite Integer Net_CoolDownForEffects for Player = 0; declare netwrite Integer Net_CoolDownBeforeReset for Player = 0; Net_CoolDownForEffects=0; Net_CoolDownBeforeReset=0; } } *** Void SetHolidayShowdownControlML() { declare Text MLText = """