// #RequireContext CSmMode #Include "MathLib" as ML #Include "Libs/Nadeo/CMGame/Utils/Log.Script.txt" as Log #Include "Libs/Nadeo/TMGame/Modes/Events.Script.txt" as Events #Include "Libs/Nadeo/TMGame/Modes/Race.Script.txt" as Race #Const C_Malus_Reset 0 #Const C_Malus_ForceEngine 1 #Const C_Malus_BackwardOnly 2 #Const C_Malus_NoBrakes 3 #Const C_Malus_NoEngine 4 #Const C_Malus_Fragile 5 #Const C_Malus_SlowMotion 6 #Const C_Malus_BoostDown 7 #Const C_Malus_BoostUp 8 #Const C_Malus_Boost2Down 9 #Const C_Malus_Boost2Up 10 #Const C_Malus_AdherenceCoef50 11 #Const C_Malus_ControlCoef50 12 #Const C_Malus_MoonGravity 13 #Const C_Malus_Name [0 => "Reset", 1 => "Force Engine", 2 => "Backward Only" , 3 => "No Brakes", 4 => "No Engine", 5 => "Fragile", 6 => "Slowmotion", 7 => "Boost Down", 8 => "Boost Up", 9 => "Super Boost Down", 10 => "Super Boost Up", 11 => "50% Adherence", 12 => "50% Control", 13 => "Moon Gravity"] #Struct K_Malus { Integer Time; Integer MalusIndex; } declare K_Malus[][Text] G_MalusQueue; declare Integer G_NextStepMalusTime; declare Integer G_MalusDuration; declare Integer G_MinCooldown; declare Integer G_MaxCooldown; /** Set Malus to a specific Players * * @param _Player Player * @param _Type Malus Index */ Boolean SetMalus(CSmPlayer _Player, Integer _Type) { if (_Player.SpawnStatus != CSmPlayer::ESpawnStatus::NotSpawned && !SetPlayer_DelayedIsFull(_Player)) { switch (_Type) { case C_Malus_Reset: { SetPlayer_Delayed_Reset(_Player); } case C_Malus_ForceEngine: { SetPlayer_Delayed_ForceEngine(_Player,True); } case C_Malus_NoEngine: { SetPlayer_Delayed_NoEngine(_Player,True); } case C_Malus_BackwardOnly: { SetPlayer_Delayed_Cruise(_Player,True,-999.); } case C_Malus_NoBrakes: { SetPlayer_Delayed_NoBrakes(_Player,True); } case C_Malus_Fragile: { SetPlayer_Delayed_Fragile(_Player,True); } case C_Malus_SlowMotion: { SetPlayer_Delayed_SlowMotion(_Player,True); } case C_Malus_BoostDown: { SetPlayer_Delayed_BoostDown(_Player,True); } case C_Malus_BoostUp: { SetPlayer_Delayed_BoostUp(_Player,True); } case C_Malus_Boost2Down: { SetPlayer_Delayed_Boost2Down(_Player,True); } case C_Malus_Boost2Up: { SetPlayer_Delayed_Boost2Up(_Player,True); } case C_Malus_AdherenceCoef50: { SetPlayer_Delayed_AdherenceCoef(_Player, 0.5); } case C_Malus_ControlCoef50: { SetPlayer_Delayed_ControlCoef(_Player, 0.5); } case C_Malus_MoonGravity: { SetPlayer_Delayed_GravityCoef(_Player,0.17); } } return True; } return False; } K_Malus GetNewMalus(Integer _MalusIndex, Integer _Time) { return K_Malus { Time = Now + _Time, MalusIndex = _MalusIndex }; } K_Malus GetNewMalus(Integer _MalusIndex) { return GetNewMalus(_MalusIndex, 0); } Void Reset() { declare netwrite Integer Net_Malus_MalusIndex for Teams[0] = 0; Net_Malus_MalusIndex = 0; declare netwrite Integer Net_Malus_MalusStart for Teams[0] = 0; Net_Malus_MalusStart = 0; G_NextStepMalusTime = 0; G_MalusQueue = []; } Void StartRound(Integer _MalusDuration, Integer _MinCooldown, Integer _MaxCooldown) { Reset(); G_MalusDuration = _MalusDuration * 1000; G_MinCooldown = _MinCooldown; G_MaxCooldown = _MaxCooldown; declare netwrite Integer Net_Malus_MalusDuration for Teams[0] = 0; Net_Malus_MalusDuration = G_MalusDuration; G_NextStepMalusTime = Now + 1500 + ML::Rand(G_MinCooldown, G_MaxCooldown) * 1000; } Void Yield() { foreach (Event in Race::GetPendingEvents()) { if (Event.Type == Events::C_Type_StartLine) { if (Event.Player != Null) { if (!G_MalusQueue.existskey(Event.Player.User.Login)) G_MalusQueue[Event.Player.User.Login] = []; G_MalusQueue[Event.Player.User.Login].add(GetNewMalus(C_Malus_Reset)); } } else if (Event.Type == Events::C_Type_Respawn) { if (Event.Player != Null) { if (!G_MalusQueue.existskey(Event.Player.User.Login)) G_MalusQueue[Event.Player.User.Login] = []; G_MalusQueue[Event.Player.User.Login].add(GetNewMalus(C_Malus_Reset)); declare netwrite Integer Net_Malus_MalusStart for Teams[0] = 0; if (Now >= Net_Malus_MalusStart && Now < Net_Malus_MalusStart + G_MalusDuration) { declare netwrite Integer Net_Malus_MalusIndex for Teams[0] = 0; G_MalusQueue[Event.Player.User.Login].add(GetNewMalus(Net_Malus_MalusIndex)); } } } } // Run Malus if (Now > G_NextStepMalusTime) { declare netwrite Integer Net_Malus_MalusIndex for Teams[0] = 0; Net_Malus_MalusIndex = ML::Rand(1, 13); foreach (Player in Players) { if (!G_MalusQueue.existskey(Player.User.Login)) G_MalusQueue[Player.User.Login] = []; G_MalusQueue[Player.User.Login].add(GetNewMalus(Net_Malus_MalusIndex, 3000)); G_MalusQueue[Player.User.Login].add(GetNewMalus(C_Malus_Reset, 3000 + G_MalusDuration)); } declare netwrite Integer Net_Malus_MalusStart for Teams[0] = 0; Net_Malus_MalusStart = Now + 3000; G_NextStepMalusTime = Now + 3000 + G_MalusDuration + ML::Rand(G_MinCooldown, G_MaxCooldown) * 1000; } foreach (Login => PlayerMalusQueue in G_MalusQueue) { declare CSmPlayer Player = GetPlayer(Login); if (Player == Null) { G_MalusQueue.removekey(Login); continue; } foreach (Key => Malus in PlayerMalusQueue) { if (Malus.Time + 5000 < Now) { // Clear old entry log("Malus Timeout for " ^ Player.User.Name); G_MalusQueue.removekey(Login); } else if (Malus.Time <= Now && Player.SpawnStatus != CSmPlayer::ESpawnStatus::NotSpawned) { Log::Log("[ApplyPhysics] Trying to set Event " ^ Malus.MalusIndex ^ " for " ^ Player.User.Name); if (SetMalus(Player, Malus.MalusIndex)) { G_MalusQueue[Login].removekey(Key); } } } if (PlayerMalusQueue.count == 0) { G_MalusQueue.removekey(Login); } } }