Compare commits
	
		
			10 Commits
		
	
	
		
			9b9fd4596d
			...
			057800e992
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 057800e992 | |||
| 7e276cac52 | |||
| a3c7553f60 | |||
| 74dc086876 | |||
| a641dff430 | |||
| a97575666a | |||
| f384157680 | |||
| 38c4e45c5c | |||
| d89ee0739e | |||
| c59cc3f3d6 | 
| @@ -4,7 +4,7 @@ | ||||
| #Extends "Libs/Nadeo/TMNext/TrackMania/Modes/TMNextRoundsBase.Script.txt" | ||||
|  | ||||
| #Const	CompatibleMapTypes	"TrackMania\\TM_Race,TM_Race" | ||||
| #Const	Version							"2023-07-10" | ||||
| #Const	Version							"2023-07-12" | ||||
| #Const	ScriptName					"Modes/TM2020-Gamemodes/LastManStanding.Script.txt" | ||||
|  | ||||
| // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // | ||||
| @@ -28,7 +28,7 @@ | ||||
| #Setting S_RoundsPerMap 1 as _("Number of rounds per map") ///< Number of round to play on one map before going to the next one | ||||
|  | ||||
|  | ||||
| #Setting S_AFKIdleTime 10000 as "Time before being an AFK player will be kicked" | ||||
| #Setting S_AFKIdleTime 120000 as "Time before being an AFK player will be kicked" | ||||
|  | ||||
| #Setting S_IntroTime 5 as "Time of the map intro" | ||||
| #Setting S_TimeBeforeMalus 10 as "Time Before Malus" | ||||
| @@ -164,12 +164,12 @@ UsePvECollisions = True; | ||||
| StateMgr::ForcePlayersStates([StateMgr::C_State_Waiting]); | ||||
| WarmUp::SetAvailability(True); | ||||
| CarRank::Reset(); | ||||
| ResetNetworkVariables(); | ||||
| *** | ||||
|  | ||||
| ***Match_InitMap*** | ||||
| *** | ||||
| declare Integer Map_ValidRoundsNb; | ||||
| declare Boolean RankInitialized = False; | ||||
|  | ||||
| declare Integer Map_TimeBeforeMalus; | ||||
| declare Integer Map_TimeBeforeNightmare; | ||||
| @@ -189,6 +189,7 @@ declare Integer NextStepMalusTime = 0; | ||||
| declare Integer MalusIndex; | ||||
| declare Integer MalusTime; | ||||
|  | ||||
| declare netwrite Boolean Net_DisplayUI for Teams[0] = False; | ||||
| declare netwrite Integer Net_NBPlayers for Teams[0] = 0; | ||||
| declare netwrite Integer Net_PlayersNbAlive for Teams[0] = 0; | ||||
| declare netwrite Integer Net_NextMalus for Teams[0] = -1; | ||||
| @@ -196,6 +197,8 @@ declare netwrite Integer Net_TimeBeforeMalus for Teams[0] = -1; | ||||
| declare netwrite Integer Net_RoundsPerMap for Teams[0] = 0; | ||||
| declare netwrite Integer Net_CurrentRoundNb for Teams[0] = 0; | ||||
|  | ||||
| ResetNetworkVariables(); | ||||
|  | ||||
| // Map Intro | ||||
| declare Boolean MapIsCompatible; | ||||
| declare CMapLandmark[] Landmarks = Map::GetFinishesAndMultilaps(); | ||||
| @@ -210,7 +213,7 @@ if (!MapIsCompatible) { | ||||
| 	MB_Sleep(3000); | ||||
| 	MB_StopMap(); | ||||
| } else if (S_IntroTime > 0) { | ||||
| 	declare netwrite Boolean Net_LMS_IsIntro for Teams[0]; | ||||
| 	declare netwrite Boolean Net_LMS_IsIntro for Teams[0] = False; | ||||
| 	Net_LMS_IsIntro = True; | ||||
| 	StateMgr::ForcePlayersStates([StateMgr::C_State_Waiting]); | ||||
| 	if (Map.HasCustomIntro) { | ||||
| @@ -239,12 +242,20 @@ Race::SetRespawnBehaviour(Race::C_RespawnBehaviour_AlwaysGiveUp); | ||||
| CarRank::Reset(); | ||||
| *** | ||||
|  | ||||
| ***Match_InitRound*** | ||||
| *** | ||||
| declare Boolean ThrottleUpdate; | ||||
| *** | ||||
|  | ||||
| ***Match_StartRound*** | ||||
| *** | ||||
| Scores::Clear(); | ||||
|  | ||||
| declare netwrite Integer Net_LMS_AFKIdleTime for Teams[0] = 120000; | ||||
| Net_LMS_AFKIdleTime = S_AFKIdleTime; | ||||
|  | ||||
| // WorkAround for longloading | ||||
| declare StartMapTime = Now; | ||||
| declare Integer StartMapTime = Now; | ||||
| while (Players.count < 2 && Now < (StartMapTime + 3000)) { | ||||
| 	MB_Yield(); | ||||
| } | ||||
| @@ -259,6 +270,7 @@ Map_MalusDuration = S_MalusDuration; | ||||
| Map_RoundsPerMap = S_RoundsPerMap; | ||||
| UpdateScoresTableFooter(); | ||||
| MalusTime = GetTimeBeforeMalus(StartTime, S_TimeBeforeMalus, S_TimeBeforeNightmare); | ||||
| Net_DisplayUI = True; | ||||
| Net_TimeBeforeMalus = MalusTime; | ||||
| Net_NextMalus = -1; | ||||
| Net_RoundsPerMap = Map_RoundsPerMap; | ||||
| @@ -275,22 +287,23 @@ declare Integer LandmarkIndex for This = 0; | ||||
| AccountIdsOfPlayers = []; | ||||
|  | ||||
| // Suffle Players list to randomise spawn | ||||
| declare CSmPlayer[] ShuffledPlayers = Players; | ||||
| declare Integer i=0; | ||||
| while(i<ShuffledPlayers.count) { // this should be enough, you can use arbitrary values, should the need arise | ||||
| 	// find a pair (a,b) of valid indices to swap | ||||
| 	declare a=ML::Rand(0, ShuffledPlayers.count-1); | ||||
| 	declare b=ML::Rand(0, ShuffledPlayers.count-1); | ||||
| 	 | ||||
| 	// now swap them | ||||
| 	declare tmp=ShuffledPlayers[b]; | ||||
| 	ShuffledPlayers[b]=ShuffledPlayers[a]; | ||||
| 	ShuffledPlayers[a]=tmp; | ||||
| 	 | ||||
| 	i=i+1; | ||||
| declare CSmPlayer[Integer] ShuffledPlayers; | ||||
|  | ||||
| foreach (Player in Players) { | ||||
| 	declare Integer RandomIndex = 0; | ||||
| 	while (RandomIndex == 0 || ShuffledPlayers.existskey(RandomIndex)) { | ||||
| 		RandomIndex = ML::Rand(1, 10000); | ||||
| 	} | ||||
| 	ShuffledPlayers[RandomIndex] = Player; | ||||
| } | ||||
|  | ||||
| ShuffledPlayers = ShuffledPlayers.sortkey(); | ||||
|  | ||||
| Net_NBPlayers = ShuffledPlayers.count; | ||||
| Net_PlayersNbAlive = Net_NBPlayers; | ||||
|  | ||||
| foreach (Player in ShuffledPlayers) { | ||||
| 	if (Player == Null) continue; | ||||
| 	PlayerLM = Null; | ||||
| 	while (PlayerLM == Null) { | ||||
| 		if (LandmarkIndex > Landmarks.count - 1 ) { | ||||
| @@ -302,102 +315,45 @@ foreach (Player in ShuffledPlayers) { | ||||
| 		LandmarkIndex = LandmarkIndex + 1 ; | ||||
| 	} | ||||
| 	Race::Start(Player, PlayerLM , StartTime); | ||||
| 	CarRank::SetRank(Player, Net_NBPlayers); | ||||
| 	AccountIdsOfPlayers.add(Player.User.WebServicesUserId); | ||||
| 	MalusQueue[Player.User.Login] = GetNewMalus(C_Malus_Reset, 1500); | ||||
| } | ||||
|  | ||||
| Net_NBPlayers = AccountIdsOfPlayers.count; | ||||
| UIModules_ScoresTable::DisplayOnly(AccountIdsOfPlayers); | ||||
|  | ||||
| UpdateCustomRanking(Null, -1); | ||||
| StateMgr::ForcePlayersStates([StateMgr::C_State_Playing]); | ||||
| CarRank::Update(CarRank::C_SortCriteria_BestRace); | ||||
| Race::EnableIntroDuringMatch(False); | ||||
| UIManager.UIAll.SendChat("$<$ff3$> Stay the most time on the structure. $<$ff9GL HF!$>"); | ||||
|  | ||||
| *** | ||||
|  | ||||
| /***Match_InitPlayLoop*** | ||||
| *** | ||||
| MalusQueue = []; | ||||
| ***/ | ||||
|  | ||||
| ***Match_PlayLoop*** | ||||
| *** | ||||
| // Update CarRank & UI Interface | ||||
| if (!RankInitialized) { | ||||
| 	RankInitialized = True; | ||||
| 	Net_PlayersNbAlive = PlayersNbAlive; | ||||
| 	Net_NBPlayers = AccountIdsOfPlayers.count; | ||||
| 	foreach (Player in Players) { | ||||
| 		CarRank::SetRank(Player, PlayersNbAlive); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Spawn players who have longloading | ||||
| if (Now < StartTime + 3000) { | ||||
| 	declare Boolean PlayerSpawned = False; | ||||
| 	declare CMapLandmark[] Landmarks = Map::GetFinishesAndMultilaps(); | ||||
| 	declare CMapLandmark PlayerLM = Null; | ||||
| 	if (PlayersNbDead >= 1) { | ||||
| 		foreach (Player in Players) { | ||||
| 			if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned && !AccountIdsOfPlayers.exists(Player.User.WebServicesUserId)) { | ||||
| 				PlayerSpawned = True; | ||||
| 				PlayerLM = Null; | ||||
| 				while (PlayerLM == Null) { | ||||
| 					if (LandmarkIndex > Landmarks.count - 1 ) { | ||||
| 						LandmarkIndex = 0; | ||||
| 					} | ||||
| 					if (Map::IsMultilap(Landmarks[LandmarkIndex])) { | ||||
| 						PlayerLM = Landmarks[LandmarkIndex]; | ||||
| 					} | ||||
| 					LandmarkIndex = LandmarkIndex + 1 ; | ||||
| 				} | ||||
| 				Race::Start(Player, PlayerLM , StartTime); | ||||
| 				AccountIdsOfPlayers.add(Player.User.WebServicesUserId); | ||||
|  | ||||
| 				MalusQueue[Player.User.Login] = GetNewMalus(C_Malus_Reset); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if (PlayerSpawned) { | ||||
| 		PlayerSpawned = False; | ||||
| 		Net_NBPlayers = AccountIdsOfPlayers.count; | ||||
| 		Net_PlayersNbAlive = PlayersNbAlive; | ||||
| 		UpdateCustomRanking(Null, -1); | ||||
| 		foreach (Player in Players) { | ||||
| 			CarRank::SetRank(Player, PlayersNbAlive); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Manage race events | ||||
| declare RacePendingEvents = Race::GetPendingEvents(); | ||||
| declare Events::K_RaceEvent[] RacePendingEvents = Race::GetPendingEvents(); | ||||
| foreach (Event in RacePendingEvents) { | ||||
| 	Race::ValidEvent(Event); | ||||
|  | ||||
| 	if (Event.Player == Null) continue; | ||||
| 	 | ||||
| 	// Waypoint | ||||
| 	if (Event.Type == Events::C_Type_Waypoint) { | ||||
| 		if (Event.IsEndLap) { | ||||
| 	switch (Event.Type) { | ||||
| 		case Events::C_Type_Waypoint: { | ||||
| 			ThrottleUpdate = True; | ||||
|  | ||||
| 			Scores::UpdatePlayerBestRaceIfBetter(Event.Player); | ||||
| 			Race::StopSkipOutro(Event.Player); | ||||
| 			foreach (Player in Players) {  | ||||
| 				CarRank::SetRank(Player, PlayersNbAlive); | ||||
| 				Net_PlayersNbAlive = PlayersNbAlive; | ||||
| 			} | ||||
| 			UpdateCustomRanking(Event.Player, Event.Type); | ||||
| 			UpdateCustomRanking(Event.Player.User, False); | ||||
| 		} | ||||
| 	} else if (Event.Type == Events::C_Type_GiveUp) { | ||||
| 		foreach (Player in Players) {  | ||||
| 			CarRank::SetRank(Player, PlayersNbAlive); | ||||
| 			Net_PlayersNbAlive = PlayersNbAlive; | ||||
| 		case Events::C_Type_GiveUp: { | ||||
| 			ThrottleUpdate = True; | ||||
| 			UpdateCustomRanking(Event.Player.User, True); | ||||
| 		} | ||||
| 		UpdateCustomRanking(Event.Player, Event.Type); | ||||
| 	} else if (Event.Type == Events::C_Type_Eliminated) { | ||||
| 		Race::StopSkipOutro(Event.Player); | ||||
| 		foreach (Player in Players) {  | ||||
| 			CarRank::SetRank(Player, PlayersNbAlive); | ||||
| 			Net_PlayersNbAlive = PlayersNbAlive; | ||||
| 		case Events::C_Type_Eliminated: { | ||||
| 			ThrottleUpdate = True; | ||||
| 			UpdateCustomRanking(Event.Player.User, True); | ||||
| 		} | ||||
| 		UpdateCustomRanking(Event.Player, Event.Type); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -405,6 +361,13 @@ foreach (Event in RacePendingEvents) { | ||||
| foreach (Event in PendingEvents) { | ||||
| 	if (Event.HasBeenPassed || Event.HasBeenDiscarded) continue; | ||||
| 	Events::Invalid(Event); | ||||
|  | ||||
| 	if (Event.Type == CSmModeEvent::EType::OnPlayerRemoved) { | ||||
| 		if (Event.User == Null ) continue; | ||||
| 		if (!AccountIdsOfPlayers.exists(Event.User.WebServicesUserId)) continue; | ||||
| 		ThrottleUpdate = True; | ||||
| 		UpdateCustomRanking(Event.User, True); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| if (PlayersNbAlive <= 1 && AccountIdsOfPlayers.count >= 2) { //TODO just respawn in case of 1 player | ||||
| @@ -412,6 +375,18 @@ if (PlayersNbAlive <= 1 && AccountIdsOfPlayers.count >= 2) { //TODO just respawn | ||||
| 	MB_StopRound(); | ||||
| } | ||||
|  | ||||
| if (ThrottleUpdate) { | ||||
| 	ThrottleUpdate = False; | ||||
| 	Net_PlayersNbAlive = PlayersNbAlive; | ||||
| 	declare Integer Points = Net_NBPlayers - Net_PlayersNbAlive; | ||||
| 	foreach (Player in Players) {  | ||||
| 		CarRank::SetRank(Player, PlayersNbAlive); | ||||
| 		if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::Spawned) { | ||||
| 			Scores::SetPlayerRoundPoints(Player.Score, Points); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| // 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) { | ||||
| @@ -476,7 +451,12 @@ if (Players.count > 0 && S_MalusDuration > 0 && MalusTime != -1 && Now > MalusTi | ||||
| 			Net_NextMalus = 0; | ||||
| 			Net_TimeBeforeMalus = NextStepMalusTime; | ||||
| 		} else if (!PendingMalus && ActiveMalus) { | ||||
| 			if (MalusIndex != 99) { | ||||
| 			if (MalusIndex == 99) { | ||||
| 				foreach (Player in Players) { | ||||
| 					MalusQueue[Player.User.Login] = GetNewMalus(C_Malus_Nightmare); | ||||
| 				} | ||||
| 				NextStepMalusTime = Now + (S_MalusDuration*1000); | ||||
| 			} else { | ||||
| 				foreach (Player in Players) { | ||||
| 					MalusQueue[Player.User.Login] = GetNewMalus(C_Malus_Reset); | ||||
| 				} | ||||
| @@ -491,11 +471,6 @@ if (Players.count > 0 && S_MalusDuration > 0 && MalusTime != -1 && Now > MalusTi | ||||
| 				// Players UI update | ||||
| 				Net_NextMalus = -1; | ||||
| 				Net_TimeBeforeMalus = NextStepMalusTime; | ||||
| 			} else { | ||||
| 				foreach (Player in Players) { | ||||
| 					MalusQueue[Player.User.Login] = GetNewMalus(C_Malus_Nightmare); | ||||
| 				} | ||||
| 				NextStepMalusTime = Now + (S_MalusDuration*1000); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -518,9 +493,9 @@ foreach (Login => Malus in MalusQueue) { | ||||
| *** | ||||
| PendingMalus = False; | ||||
| ActiveMalus = False; | ||||
| Net_DisplayUI = False; | ||||
| Net_TimeBeforeMalus = -1; | ||||
| Net_NextMalus = -1; | ||||
| RankInitialized = False; | ||||
| CustomTimes.clear(); | ||||
|  | ||||
| Race::StopSkipOutroAll(); | ||||
| @@ -555,11 +530,10 @@ if (Round_ForceEndRound || Round_SkipPauseRound) { | ||||
| 	UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::EndRound; | ||||
| 	UIManager.UIAll.BigMessageSoundVariant = 0; | ||||
|  | ||||
| 	declare Text Message = _("|Match|Draw"); | ||||
| 	if (WinnerScore != Null) { | ||||
| 		UIModules_BigMessage::SetMessage("$<%1$> wins the match!", WinnerScore.User.WebServicesUserId); | ||||
| 	} else { | ||||
| 	if (WinnerScore == Null) { | ||||
| 		UIModules_BigMessage::SetMessage(_("|Match|Draw")); | ||||
| 	} else { | ||||
| 		UIModules_BigMessage::SetMessage(_("$<%1$> wins the match!"), WinnerScore.User.WebServicesUserId); | ||||
| 	} | ||||
|  | ||||
| 	Scores::EndRound(); | ||||
| @@ -581,6 +555,23 @@ if (Round_ForceEndRound || Round_SkipPauseRound) { | ||||
| // Functions | ||||
| // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // | ||||
|  | ||||
| Void ResetNetworkVariables() { | ||||
| 	declare netwrite Boolean Net_DisplayUI for Teams[0] = False; | ||||
| 	Net_DisplayUI = False; | ||||
| 	declare netwrite Integer Net_NBPlayers for Teams[0] = 0; | ||||
| 	Net_NBPlayers = 0; | ||||
| 	declare netwrite Integer Net_PlayersNbAlive for Teams[0] = 0; | ||||
| 	Net_PlayersNbAlive = 0; | ||||
| 	declare netwrite Integer Net_NextMalus for Teams[0] = -1; | ||||
| 	Net_NextMalus = 0; | ||||
| 	declare netwrite Integer Net_TimeBeforeMalus for Teams[0] = -1; | ||||
| 	Net_TimeBeforeMalus = 0; | ||||
| 	declare netwrite Integer Net_RoundsPerMap for Teams[0] = 0; | ||||
| 	Net_RoundsPerMap = 0; | ||||
| 	declare netwrite Integer Net_CurrentRoundNb for Teams[0] = 0; | ||||
| 	Net_CurrentRoundNb = 0; | ||||
| } | ||||
|  | ||||
| /** Get the Time Before the first Malus or NightMare Mode | ||||
|  * | ||||
|  *	@param	_StartTime								The starting time of the map | ||||
| @@ -604,31 +595,18 @@ if (Round_ForceEndRound || Round_SkipPauseRound) { | ||||
|  | ||||
| /** Update the Scores Table with hidden custom points | ||||
|  * | ||||
|  *	@param	_EliminatedPlayer						The Player who is eliminated | ||||
|  *	@param	_EventType								Type of event that led to the update (EndRace or GiveUp) | ||||
|  *	@param	_User									The User who is eliminated | ||||
|  *	@param	_OverrideTime							Compute time because it not ended the Map | ||||
|  */ | ||||
|  Void UpdateCustomRanking(CSmPlayer _EliminatedPlayer, Integer _EventType) { | ||||
| 	declare Integer[Text] CustomTimes for This; | ||||
| 	declare Text[] AccountIdsOfPlayers for This; | ||||
| 	foreach (Score in Scores) { | ||||
| 		if (Score == Null) continue; | ||||
| 		declare CSmPlayer Player = GetPlayer(Score.User.Login); | ||||
| 		if (Player == Null) continue; | ||||
| 		if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned) { | ||||
|  | ||||
| 			Scores::UpdatePlayerBestRaceIfBetter(Player); | ||||
| 			if (_EliminatedPlayer != Null && _EliminatedPlayer == Player) { | ||||
| 				if (_EventType == Events::C_Type_GiveUp || _EventType == Events::C_Type_Eliminated) { | ||||
| 					CustomTimes[Score.User.WebServicesUserId] = Now - StartTime; | ||||
| 				} | ||||
| 				UIManager.UIAll.SendChat("""$<$ff3$> Player $<$ff9{{{Player.User.Name}}}$> is eliminated"""); | ||||
| 			} | ||||
| 		} else { | ||||
| 			Scores::SetPlayerRoundPoints(Score,PlayersNbDead); | ||||
| 		} | ||||
|  Void UpdateCustomRanking(CUser _User, Boolean _OverrideTime) { | ||||
| 	if (_User == Null) return; | ||||
| 	 | ||||
| 	if (_OverrideTime) { | ||||
| 		declare Integer[Text] CustomTimes for This = []; | ||||
| 		CustomTimes[_User.WebServicesUserId] = Now - StartTime; | ||||
| 		UIModules_ScoresTable::SetCustomTimes(CustomTimes); | ||||
| 	} | ||||
| 	UIModules_ScoresTable::DisplayOnly(AccountIdsOfPlayers); | ||||
| 	UIModules_ScoresTable::SetCustomTimes(CustomTimes); | ||||
| 	UIManager.UIAll.SendChat("""$<$ff3$> Player $<$ff9{{{_User.Name}}}$> is eliminated"""); | ||||
| } | ||||
|  | ||||
| /** Update the scores table footer text | ||||
| @@ -640,7 +618,7 @@ if (Round_ForceEndRound || Round_SkipPauseRound) { | ||||
| 		Footer ^= "Malus disabled"; | ||||
| 	} else { | ||||
| 		declare Text[] Parts; | ||||
| 		declare Message = ""; | ||||
| 		declare Text Message = ""; | ||||
| 		if (S_TimeBeforeMalus >= 0) { | ||||
| 			if (Parts.count > 0) Message ^= "\n"; | ||||
| 			Message ^= """%{{{Parts.count + 1}}}{{{TL::TimeToText(S_TimeBeforeMalus*1000)}}}"""; | ||||
| @@ -754,7 +732,7 @@ Boolean SetMalus(CSmPlayer _Player, Integer _Type) { | ||||
|  *	@param	_Player									Malus Index | ||||
|  */ | ||||
| Void SetML() { | ||||
| 	declare TotalWidth = 44.5; | ||||
| 	declare Real TotalWidth = 44.5; | ||||
|  | ||||
| 	declare Text MLText = """ | ||||
| 	<manialink name="LMS_InfoPanel" version="3"> | ||||
| @@ -788,6 +766,7 @@ Void SetML() { | ||||
| 				 {{{C_Malus_GravityCoef25}}} => "25% Gravity", {{{C_Malus_Nightmare}}} => "NightMare"] | ||||
|  | ||||
| 		main() { | ||||
| 			declare netread Boolean Net_DisplayUI for Teams[0]; | ||||
| 			declare netread Integer Net_NBPlayers for Teams[0]; | ||||
| 			declare netread Integer Net_PlayersNbAlive for Teams[0]; | ||||
| 			declare netread Integer Net_NextMalus for Teams[0]; | ||||
| @@ -795,6 +774,7 @@ Void SetML() { | ||||
| 			declare netread Integer Net_RoundsPerMap for Teams[0]; | ||||
| 			declare netread Integer Net_CurrentRoundNb for Teams[0]; | ||||
|  | ||||
| 			declare Boolean Last_DisplayUI; | ||||
| 			declare Integer Last_PlayersNbAlive; | ||||
| 			declare Integer Last_NextMalus; | ||||
| 			declare Integer Last_TimeBeforeMalus; | ||||
| @@ -803,15 +783,28 @@ Void SetML() { | ||||
|  | ||||
| 			declare Boolean NeedUpdateChrono = False; | ||||
|  | ||||
| 			declare Label_PlayersAlive <=> (Page.GetFirstChild("label-playersalive") as CMlLabel); | ||||
| 			declare Label_NextMalus <=> (Page.GetFirstChild("label-nextmalus") as CMlLabel); | ||||
| 			declare Label_TimeBeforeMalus <=> (Page.GetFirstChild("label-timebeforemalus") as CMlLabel); | ||||
| 			declare Label_Info_RoundsPerMap <=> (Page.GetFirstChild("label-info-roundspermap") as CMlLabel); | ||||
| 			declare Label_RoundsPerMap <=> (Page.GetFirstChild("label-roundspermap") as CMlLabel); | ||||
| 			declare CMlFrame Frame_Global <=> (Page.GetFirstChild("frame-global") as CMlFrame); | ||||
| 			declare CMlLabel Label_PlayersAlive <=> (Frame_Global.GetFirstChild("label-playersalive") as CMlLabel); | ||||
| 			declare CMlLabel Label_NextMalus <=> (Frame_Global.GetFirstChild("label-nextmalus") as CMlLabel); | ||||
| 			declare CMlLabel Label_TimeBeforeMalus <=> (Frame_Global.GetFirstChild("label-timebeforemalus") as CMlLabel); | ||||
| 			declare CMlLabel Label_Info_RoundsPerMap <=> (Frame_Global.GetFirstChild("label-info-roundspermap") as CMlLabel); | ||||
| 			declare CMlLabel Label_RoundsPerMap <=> (Frame_Global.GetFirstChild("label-roundspermap") as CMlLabel); | ||||
|  | ||||
| 			while(True) { | ||||
| 				yield; | ||||
|  | ||||
| 				if (Last_DisplayUI != Net_DisplayUI) { | ||||
| 					Last_DisplayUI = Net_DisplayUI; | ||||
|  | ||||
| 					AnimMgr.Flush(Frame_Global); | ||||
| 					if (Last_DisplayUI) { | ||||
| 						Frame_Global.Visible = True; | ||||
| 						AnimMgr.Add(Frame_Global, "<a pos=\"-160 0\"/>", 300, CAnimManager::EAnimManagerEasing::Linear); | ||||
| 					} else { | ||||
| 						AnimMgr.Add(Frame_Global, "<a hidden=1 pos=\"-225 0\"/>", 300, CAnimManager::EAnimManagerEasing::Linear); | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				if (Last_CurrentRoundNb != Net_CurrentRoundNb) { | ||||
| 					Last_CurrentRoundNb = Net_CurrentRoundNb; | ||||
| 					if (Last_RoundsPerMap > 0) { | ||||
| @@ -863,7 +856,7 @@ Void SetML() { | ||||
| 			<style class="text-ingame-number" textfont="GameFontBlack" textcolor="ffffff" textsize="1.25" valign="center2" textprefix="$i"/> | ||||
| 		</stylesheet> | ||||
|  | ||||
| 		<frame z-index="-2" id="frame-global" size="{{{TotalWidth + 20}}} 180" pos="-160 0" valign="center"> | ||||
| 		<frame z-index="-2" id="frame-global" size="{{{TotalWidth + 20}}} 180" pos="-225 0" valign="center" hidden=1> | ||||
| 			<quad id="quad-info-bg" pos="0 7.75" size="{{{TotalWidth + 4}}} 21" valign="center" z-index="-3" bgcolor="000" opacity="0.5"/> | ||||
| 			<label id="label-info-roundspermap" pos="1 15" size="{{{TotalWidth/1.75}}} 10" class="text-ingame-text" text="Rounds" halign="left"/> | ||||
| 			<label pos="1 10" size="{{{TotalWidth/1.75}}} 10" class="text-ingame-text" text="Players Alive" halign="left" /> | ||||
| @@ -929,6 +922,62 @@ Void SetML() { | ||||
| 	Layers::Create("LMS_MapInfo", MLText); | ||||
| 	Layers::SetType("LMS_MapInfo", CUILayer::EUILayerType::Normal); | ||||
| 	Layers::Attach("LMS_MapInfo"); | ||||
|  | ||||
| 	MLText = """ | ||||
| 	<manialink name="LMS_AFKManager" version="3"> | ||||
| 		<script><!-- | ||||
| 		#Include "MathLib" as ML | ||||
|  | ||||
| 		main() { | ||||
| 			declare CMlFrame Frame_Global = (Page.GetFirstChild("frame-global") as CMlFrame); | ||||
|  | ||||
| 			wait(InputPlayer != Null); | ||||
|  | ||||
| 			declare netread Integer Net_LMS_AFKIdleTime for Teams[0] = 120000; | ||||
| 			declare Integer Last_AFKIdleTime; | ||||
| 			declare Integer Last_AFKDisplayTime; | ||||
|  | ||||
| 			declare Integer Last_NextCheck; | ||||
|  | ||||
| 			while(True) { | ||||
| 				yield; | ||||
|  | ||||
| 				if (Now > Last_NextCheck) { | ||||
| 					Last_NextCheck = Now + 500; | ||||
|  | ||||
| 					if (Last_AFKIdleTime != Net_LMS_AFKIdleTime) { | ||||
| 						Last_AFKIdleTime = Net_LMS_AFKIdleTime; | ||||
| 						Last_AFKDisplayTime = Last_AFKIdleTime - ML::Clamp(ML::FloorInteger(Net_LMS_AFKIdleTime * 0.33), 3000, 20000); | ||||
| 					} | ||||
|  | ||||
| 					// Check if player is AFK or not | ||||
| 					if (Last_AFKIdleTime > 0 && Input.TimeSinceLatestActivity > Last_AFKIdleTime) { | ||||
| 						log("Player is AFK"); | ||||
| 						Playground.QuitServer(False); | ||||
| 					} else if (Last_AFKIdleTime > 0 && Input.TimeSinceLatestActivity > Last_AFKDisplayTime) { | ||||
| 						Frame_Global.Visible = True; | ||||
| 					} else { | ||||
| 						Frame_Global.Visible = False; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		--></script> | ||||
| 		<stylesheet> | ||||
| 			<style class="text" textfont="GameFontBlack" textcolor="ffffffff" textsize="8" valign="center2" halign="center"/> | ||||
| 		</stylesheet> | ||||
|  | ||||
| 		<frame id="frame-global" pos="0 40" hidden="1"> | ||||
| 			<quad size="150 35" halign="center" z-index="-1" bgcolor="000" opacity="0.7"/> | ||||
| 			<label class="text" pos="0 -8" size="140 10" text="AFK Warning"/> | ||||
| 			<label class="text" pos="0 -21.5" size="140 20" autonewline=1 textsize="4" text="Move your mouse or press a key on your keyboard or gamepad to prevent to be kicked"/> | ||||
| 		</frame> | ||||
|  | ||||
| 	</manialink> | ||||
| 	"""; | ||||
| 	Layers::Create("LMS_AFKManager", MLText); | ||||
| 	Layers::SetType("LMS_AFKManager", CUILayer::EUILayerType::Normal); | ||||
| 	Layers::Attach("LMS_AFKManager"); | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user