Last active
August 29, 2015 14:02
-
-
Save rsepierre/43e8151b80f3ead4b777 to your computer and use it in GitHub Desktop.
Team Arena Master mode for Shootmania
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Mode Team Arena Master | |
*/ | |
#Extends "Modes/ShootMania/ModeMatchmaking.Script.txt" | |
#Const CompatibleMapTypes "ComboArena" | |
#Const Version "2014-06-01" | |
#Const ScriptName "Combo.Script.txt" | |
#Include "Libs/Nadeo/Markers.Script.txt" as Markers | |
#Include "Libs/Nadeo/ShootMania/SM.Script.txt" as SM | |
#Include "Libs/Nadeo/ShootMania/Map.Script.txt" as Map | |
#Include "Libs/Nadeo/ShootMania/Score.Script.txt" as Score | |
#Include "Libs/Nadeo/ShootMania/WarmUp2.Script.txt" as WarmUp2 | |
// ---------------------------------- // | |
// Settings | |
// ---------------------------------- // | |
#Setting S_NbPlayersPerTeam 5 as _("Number of players per team (Max. 5)") | |
#Setting S_PointsLimit 10 as _("Points limit (0: No points limit)") | |
#Setting S_RoundTimeLimit 240 as _("Round time limit (0: No time limit)") | |
#Setting S_WarmUpDuration 45 as _("Warmup duration (0: disabled)") | |
#Setting S_AllowUnbalancedTeams True as _("Allow a game to begin without the same number of players in each team") | |
#Setting S_UseArmorReduction False as _("Reduce the armor of players above two armor points") | |
// Clublinks settings | |
#Setting S_UsePlayerClublinks False as _("Use players Clublinks") default teams | |
#Setting S_ForceClublinkTeam1 "" as "<hidden>" | |
#Setting S_ForceClublinkTeam2 "" as "<hidden>" | |
// ---------------------------------- // | |
// Constants | |
// ---------------------------------- // | |
#Const C_ActionEvent_SwitchWeapon "SwitchWeapon" | |
#Const C_Object [ | |
"Armor" => "Armor", | |
"Arrow" => "Arrow", | |
"Laser" => "Laser", | |
"Nucleus" => "Nucleus", | |
"Rocket" => "Rocket" | |
] | |
#Const C_AmmoGain [ | |
"Rocket" => 0.5, | |
"Laser" => 0.6, | |
"Nucleus" => 0.5, | |
"Arrow" => 0.3 | |
] | |
#Const C_AmmoMax [ | |
"Laser" => 1, | |
"Nucleus" => 2, | |
"Arrow" => 1, | |
"Rocket" => 4 | |
] | |
#Const C_ArmorReductionPeriod 30000 | |
#Const C_ArmorReductionStart 0 | |
#Const C_RoundStartInvicibilityDuration 10000 | |
#Const C_Default_ComboTime 30000 | |
#Const C_Default_Armor 700 | |
#Const C_Default_ArmorMax 700 | |
#Const C_Object_Delay 30000 | |
#Const C_Object_ArmorValue 100 | |
#Const C_NbPlayersPerTeamMax 5 | |
#Const C_ComboTimeStep 2000 | |
#Const C_OffZoneRadiusMax 300. | |
#Const C_OffZoneRadiusMin 16. | |
#Const C_OffZoneDuration 60 | |
#Const C_MaxDamage 100 | |
#Const C_ImgBaseDir "file://Media/Manialinks/Shootmania/Common/" | |
#Const C_WaitConnectionTimeLimit 60000 | |
#Const C_SleepEndMap 10000 | |
#Const C_LayerTimersPosition 151.5 | |
#Const Description _("TYPE: Team DeathMatch\nOBJECTIVE:\n- Eliminate all the enemy team.\n- Use '1', '2', '3' and '4' on your keyboard to switch weapon. You start with all your weapons.") | |
#Const C_BlueBots 0 | |
#Const C_RedBots 0 | |
// ---------------------------------- // | |
// Globales variables | |
// ---------------------------------- // | |
declare Ident[Text] G_ObjectId; | |
// Ids of the objects | |
declare Boolean G_OffZoneIsActivated; | |
// OffZone status | |
declare Integer G_ComboTime; | |
// Timer of the current combo | |
declare Integer G_ComboClan; | |
// Clan doing the combo | |
declare Integer G_ComboNextTick; | |
// Combo time | |
declare Integer[Integer] G_ClanComboTimeLimit; | |
// Timer max of the combo for each clan | |
declare Ident[][Integer] G_ClansPlayers; | |
// List of players allowed to play | |
declare Integer S_Script_RoundTimeLimit; | |
declare Integer S_Script_PointsLimit; | |
declare Integer S_Script_NbPlayersPerTeam; | |
declare CSmMode::EWeapon[Integer] C_Default_Weapons; | |
declare CSmMode::EWeapon C_Default_Weapon; | |
// ---------------------------------- // | |
// Extend | |
// ---------------------------------- // | |
***LogVersion*** | |
*** | |
MB_LogVersion(ScriptName, Version); | |
MB_LogVersion(SM::GetScriptName(), SM::GetScriptVersion()); | |
MB_LogVersion(Score::GetScriptName(), Score::GetScriptVersion()); | |
MB_LogVersion(Layers::GetScriptName(), Layers::GetScriptVersion()); | |
MB_LogVersion(WarmUp2::GetScriptName(), WarmUp2::GetScriptVersion()); | |
MB_LogVersion(Message::GetScriptName(), Message::GetScriptVersion()); | |
MB_LogVersion(SpawnScreen::GetScriptName(), SpawnScreen::GetScriptVersion()); | |
*** | |
***LobbyStartServer*** | |
*** | |
MM_SetFormat([S_NbPlayersPerTeam, S_NbPlayersPerTeam]); | |
*** | |
***Rules*** | |
*** | |
declare ModeName = "Team Arena Master"; | |
declare ModeObjectives = TL::Compose(_("$<%11. $>Eliminate all the enemy team."), "$"^SpawnScreen::GetModeColor()); | |
declare ModeConditions = TL::Compose(_("$<%11. $>Use '1', '2', '3' and '4' on your keyboard to switch weapon. You start with all your weapons."), "$"^SpawnScreen::GetModeColor()); | |
SpawnScreen::AddSubsection(_("Type"), _("Team versus Team"), 0.); | |
SpawnScreen::AddSubsection( | |
_("Objectives"), | |
ModeObjectives, | |
25. | |
); | |
SpawnScreen::AddSubsection( | |
_("Conditions"), | |
ModeConditions, | |
65. | |
); | |
SpawnScreen::CreatePrettyRules(ModeName); | |
*** | |
***InitServer*** | |
*** | |
MB_UsePlayerClublinks = S_UsePlayerClublinks; | |
*** | |
***StartServer*** | |
*** | |
// ---------------------------------- // | |
// Matchmaking mode | |
if (S_MatchmakingMode == 2) { | |
MM_Init([S_NbPlayersPerTeam, S_NbPlayersPerTeam]); | |
} | |
// ---------------------------------- // | |
// Set mode options | |
UseClans = True; | |
MB_UseSectionRound = True; | |
C_Default_Weapons = [GetWeaponOrder(CSmMode::EWeapon::Rocket) => CSmMode::EWeapon::Rocket]; | |
C_Default_Weapon = CSmMode::EWeapon::Rocket; | |
// ---------------------------------- // | |
// Create the rules | |
---Rules--- | |
// ---------------------------------- // | |
// Create the warm up | |
WarmUp2::Load(); | |
WarmUp2::CreateGroup("Clan1", S_NbPlayersPerTeam); | |
WarmUp2::CreateGroup("Clan2", S_NbPlayersPerTeam); | |
WarmUp2::DisplayClanSelection(True); | |
// ---------------------------------- // | |
// Create the scores table | |
ST2::SetStyle("LibST_SMBaseTeams"); | |
ST2::SetStyle("LibST_SMBasePoints"); | |
ST2::SetStyle("LibST_SMWithLegends"); | |
ST2::SetFormat(2, 6); | |
ST2::SetTextScale(1.1); | |
ST2::CreateCol("HitsPerWeapon", _("Hits per weapon"), "0/0/0/0", 8., 50.); | |
ST2::SetColTextAlign("HitsPerWeapon", CMlControl::AlignHorizontal::Right); | |
ST2::SetColLegend("LibST_SMRoundPoints", _("Hits")); | |
ST2::SetColLegend("LibST_SMPoints", _("Score")); | |
ST2::SetColWidth("LibST_Name", 15.); | |
MM_SetScoresTableStyleFromXml(S_ScoresTableStylePath); | |
ST2::Build("SM"); | |
// ---------------------------------- // | |
// Load items | |
//ItemList_Begin(); | |
//G_ObjectId[C_Object["Armor"]] = ItemList_Add("Storm\\MeleeUltimate\\Armor.Item.gbx"); | |
//G_ObjectId[C_Object["Rocket"]] = ItemList_Add("Storm\\MeleeUltimate\\Rocket.Item.gbx"); | |
//G_ObjectId[C_Object["Laser"]] = ItemList_Add("Storm\\MeleeUltimate\\Laser.Item.gbx"); | |
//G_ObjectId[C_Object["Nucleus"]] = ItemList_Add("Storm\\MeleeUltimate\\Nucleus.Item.gbx"); | |
//G_ObjectId[C_Object["Arrow"]] = ItemList_Add("Storm\\MeleeUltimate\\Arrow.Item.gbx"); | |
//ItemList_End(); | |
// ---------------------------------- // | |
// Create layer | |
Layers::Create("Info"); | |
// ---------------------------------- // | |
// Initialize Markers | |
Markers::Load(); | |
*** | |
***InitMap*** | |
*** | |
declare Integer MapWinnerClan; | |
declare CSmMapPlayerSpawn[Integer] Spawns; | |
if (S_MatchmakingMode == 2) MB_UseIntro = False; | |
else MB_UseIntro = True; | |
*** | |
***StartMap*** | |
*** | |
// ---------------------------------- // | |
// Misc initialization | |
Users_SetNbFakeUsers(C_BlueBots, C_RedBots); | |
Score::MatchBegin(); | |
SM::SetupDefaultVisibility(); | |
//UIManager.UIAll.TeamLabelsVisibility = CUIConfig::ELabelsVisibility::Always; | |
MapWinnerClan = 0; | |
G_ClansPlayers = [1 => Ident[], 2 => Ident[]]; | |
Spawns = [1 => Null, 2 => Null]; | |
foreach (MapLandmark in MapLandmarks_PlayerSpawn) { | |
if (MapLandmark.Order == 1) Spawns[1] <=> MapLandmark.PlayerSpawn; | |
else if (MapLandmark.Order == 2) Spawns[2] <=> MapLandmark.PlayerSpawn; | |
} | |
assert(Spawns[1] != Null && Spawns[2] != Null); | |
UpdateModeStatusMessage(); | |
UpdateBasesColors(); | |
// ---------------------------------- // | |
// Initialize players | |
foreach (Player in AllPlayers) { | |
SetPlayerClan(Player, MM_GetRequestedClan(Player)); | |
declare UI <=> UIManager.GetUI(Player); | |
if (UI != Null) { | |
UI.SpectatorForceCameraType = -1; | |
UI.SpectatorForcedClan = -1; | |
} | |
} | |
// ---------------------------------- // | |
// Initialize scores | |
foreach (Score in Scores) { | |
declare HitLaser for Score = 0; | |
declare HitNucleus for Score = 0; | |
declare HitArrow for Score = 0; | |
declare HitRocket for Score = 0; | |
HitLaser = 0; | |
HitNucleus = 0; | |
HitArrow = 0; | |
HitRocket = 0; | |
} | |
// ---------------------------------- // | |
// Set storm center | |
foreach (Pole in MapLandmarks_Gauge) { | |
if (Pole.Tag == "Checkpoint") { | |
OffZoneCenterLandmarkId = Pole.Id; | |
break; | |
} | |
} | |
// ---------------------------------- // | |
// Update the scores table | |
ST2::ClearScores(); | |
ST2::SetFooterText(TL::Compose("%1 "^S_PointsLimit, _("Points limit : "))); | |
UpdateScoresHeader(); | |
// ---------------------------------- // | |
// Initialize markers | |
Markers::Clear(); | |
CreateMarkers(); | |
// ---------------------------------- // | |
// Initalize settings | |
S_Script_RoundTimeLimit = S_RoundTimeLimit; | |
S_Script_PointsLimit = S_PointsLimit; | |
S_Script_NbPlayersPerTeam = S_NbPlayersPerTeam; | |
if (S_Script_NbPlayersPerTeam > C_NbPlayersPerTeamMax) { | |
S_Script_NbPlayersPerTeam = C_NbPlayersPerTeamMax; | |
} | |
// ---------------------------------- // | |
// Wait players when using matchmaking | |
if (S_MatchmakingMode == 2) { | |
MM_MatchWait(); | |
PrepareMatch(); | |
} | |
// ---------------------------------- // | |
// Do warm up | |
else WarmUp(); | |
declare ClansOrder = [1 => WarmUp2::GetGroup("Clan1"), 2 => WarmUp2::GetGroup("Clan2")]; | |
foreach (Clan => ClanOrder in ClansOrder) { | |
if (!G_ClansPlayers.existskey(Clan)) continue; | |
foreach (Slot => PlayerId in ClanOrder) { | |
G_ClansPlayers[Clan].add(PlayerId); | |
} | |
} | |
// ---------------------------------- // | |
// Update the players clublinks | |
if (S_ForceClublinkTeam1 == "" && S_ForceClublinkTeam2 == "") { | |
Clublink::DefineTeamAuto(); | |
Clublink::SyncUpdate(); ///< Try to force the load of the clublink | |
} else { | |
Clublink::DefineTeamFromUrl(S_ForceClublinkTeam1, S_ForceClublinkTeam2); | |
} | |
// ---------------------------------- // | |
// Initialize UI | |
UpdateScoresHeader(); | |
UIManager.UIAll.SendNotice("", CUIConfig::ENoticeLevel::MatchInfo, Null, CUIConfig::EAvatarVariant::Default, CUIConfig::EUISound::StartRound, 0); | |
UIManager.UIAll.UISequence = CUIConfig::EUISequence::Playing; | |
Layers::Attach("Info"); | |
Layers::Update("Info", UpdateLayerInfo()); | |
// ---------------------------------- // | |
// Matchmaking : allow substitutes | |
MM_AllowSubstitutes(True); | |
*** | |
***InitRound*** | |
*** | |
declare Integer RoundWinnerClan; | |
declare Integer SpawnClan1; | |
declare Integer SpawnClan2; | |
declare Integer InvincibilityEndTime; | |
*** | |
***StartRound*** | |
*** | |
// ---------------------------------- // | |
// Combo initialization | |
RoundWinnerClan = 0; | |
G_ComboClan = 0; | |
G_ComboTime = 0; | |
G_ComboNextTick = 0; | |
G_ClanComboTimeLimit = [1 => C_Default_ComboTime, 2 => C_Default_ComboTime]; | |
OffZoneRadius = -1.; | |
OffZoneRadiusSpeed = 0.; | |
G_OffZoneIsActivated = False; | |
Score::RoundBegin(); | |
UpdateModeStatusMessage(); | |
// ---------------------------------- // | |
// Initalize game | |
S_Script_RoundTimeLimit = S_RoundTimeLimit; | |
S_Script_PointsLimit = S_PointsLimit; | |
S_Script_NbPlayersPerTeam = S_NbPlayersPerTeam; | |
if (S_Script_NbPlayersPerTeam > C_NbPlayersPerTeamMax) { | |
S_Script_NbPlayersPerTeam = C_NbPlayersPerTeamMax; | |
} | |
StartTime = Now; | |
if (S_Script_RoundTimeLimit <= 0) { | |
UIManager.UIAll.CountdownEndTime = -1; | |
} else { | |
UIManager.UIAll.CountdownEndTime = StartTime + (S_Script_RoundTimeLimit * 1000); | |
} | |
// ---------------------------------- // | |
// Initialize players | |
foreach (Player in AllPlayers) { | |
InitializePlayer(Player); | |
} | |
UpdateClansPlayers(); | |
// ---------------------------------- // | |
// Initialize objects | |
ObjectDestroyAll(); | |
foreach (MapLandmark in MapLandmarks_ObjectAnchor) { | |
declare ObjectSpawned for MapLandmark = False; | |
declare ObjectNextSpawn for MapLandmark = Now; | |
ObjectSpawned = False; | |
ObjectNextSpawn = Now + C_Object_Delay; | |
declare netwrite Integer[Text] Net_Combo_ItemsRespawn for Teams[0]; | |
Net_Combo_ItemsRespawn["Marker_Object"^MapLandmark.Id] = ObjectNextSpawn; | |
} | |
// ---------------------------------- // | |
// Spawn players | |
SpawnClan1 = 1; | |
SpawnClan2 = 1; | |
if (MB_SectionRoundNb % 2 == 0) { | |
SpawnClan1 = 2; | |
SpawnClan2 = 2; | |
} | |
foreach (Player in Players) { | |
if (!G_ClansPlayers.existskey(Player.CurrentClan)) continue; | |
if (!G_ClansPlayers[Player.CurrentClan].exists(Player.Id)) continue; | |
declare CSmMapPlayerSpawn MapLandmark_PlayerSpawn; | |
if (Player.CurrentClan == 1) { | |
MapLandmark_PlayerSpawn <=> Spawns[SpawnClan1]; | |
SpawnClan1 = 3 - SpawnClan1; | |
} else if (Player.CurrentClan == 2) { | |
MapLandmark_PlayerSpawn <=> Spawns[SpawnClan2]; | |
SpawnClan2 = 3 - SpawnClan2; | |
} | |
declare SpawnTime = Now + 2000; | |
if (SpawnTime < StartTime) SpawnTime = StartTime; | |
if (MapLandmark_PlayerSpawn != Null) SM::SpawnPlayer(Player, Player.CurrentClan, C_Default_Armor, MapLandmark_PlayerSpawn, SpawnTime); | |
} | |
// ---------------------------------- // | |
// Initialize UI | |
Net_Combo_ComboClan1 = G_ClanComboTimeLimit[1]; | |
Net_Combo_ComboClan2 = G_ClanComboTimeLimit[2]; | |
// ---------------------------------- // | |
// Update the players clublinks | |
if (S_ForceClublinkTeam1 == "" && S_ForceClublinkTeam2 == "") { | |
Clublink::DefineTeamAuto(); | |
Clublink::SyncUpdate(); ///< Try to force the load of the clublink | |
} else { | |
Clublink::DefineTeamFromUrl(S_ForceClublinkTeam1, S_ForceClublinkTeam2); | |
} | |
// ---------------------------------- // | |
// Round start invincibility | |
InvincibilityEndTime = StartTime + C_RoundStartInvicibilityDuration; | |
UsePvPCollisions = False; | |
UsePvPWeapons = False; | |
Message::SendStatusMessage(_("Players are invincible"), InvincibilityEndTime - Now, 1); | |
*** | |
***OnNewPlayer*** | |
*** | |
InitializePlayer(Player); | |
declare UI <=> UIManager.GetUI(Player); | |
if (UI != Null) { | |
UI.SpectatorForceCameraType = 1; | |
UI.SpectatorForcedClan = Player.CurrentClan; | |
} | |
*** | |
***OnNewSpectator*** | |
*** | |
declare UI <=> UIManager.GetUI(Spectator); | |
if (UI != Null) { | |
UI.SpectatorForceCameraType = -1; | |
UI.SpectatorForcedClan = -1; | |
} | |
*** | |
***Yield*** | |
*** | |
foreach (Event in XmlRpc.PendingEvents) { | |
if (Event.Type == CXmlRpcEvent::EType::CallbackArray) { | |
switch (Event.ParamArray1) { | |
case "Combo_SetTimersLayerPosition": { | |
declare netwrite Net_Combo_TimersLayerPosition for Teams[0] = C_LayerTimersPosition; | |
if (Event.ParamArray2.existskey(0)) { | |
Net_Combo_TimersLayerPosition.X = TL::ToReal(Event.ParamArray2[0]); | |
} | |
if (Event.ParamArray2.existskey(1)) { | |
Net_Combo_TimersLayerPosition.Y = TL::ToReal(Event.ParamArray2[1]); | |
} | |
if (Event.ParamArray2.existskey(2)) { | |
Net_Combo_TimersLayerPosition.Z = TL::ToReal(Event.ParamArray2[2]); | |
} | |
} | |
} | |
} | |
} | |
*** | |
***PlayLoop*** | |
*** | |
// ---------------------------------- // | |
// Libraries | |
Message::Loop(); | |
// ---------------------------------- // | |
// Check Action events | |
foreach (Event in PendingEvents) { | |
// ---------------------------------- // | |
// On armor empty | |
if (Event.Type == CSmModeEvent::EType::OnArmorEmpty) { | |
if (Event.Victim != Null) { | |
declare NewComboClan = 3 - Event.Victim.CurrentClan; | |
UpdateCombo(NewComboClan); | |
} | |
XmlRpc::OnArmorEmpty(Event); | |
PassOn(Event); | |
} | |
// ---------------------------------- // | |
// On hit | |
else if (Event.Type == CSmModeEvent::EType::OnHit) { | |
if (Event.Victim == Null || Event.Shooter == Event.Victim) { | |
Discard(Event); | |
} else if (Event.Shooter != Null && Event.Victim != Null && Event.Shooter.CurrentClan == Event.Victim.CurrentClan) { | |
Discard(Event); | |
} else { | |
if (Event.Damage > C_MaxDamage) Event.Damage = C_MaxDamage; | |
Score::AddPoints(Event.Shooter, 1); | |
XmlRpc::OnHit(Event); | |
if (Event.Shooter != Null) { | |
declare HitLaser for Event.Shooter.Score = 0; | |
declare HitNucleus for Event.Shooter.Score = 0; | |
declare HitArrow for Event.Shooter.Score = 0; | |
declare HitRocket for Event.Shooter.Score = 0; | |
switch (Event.WeaponNum) { | |
case 1: HitLaser += 1; | |
case 3: HitNucleus += 1; | |
case 5: HitArrow += 1; | |
case 2: HitRocket += 1; | |
} | |
ST2::SetColValue("HitsPerWeapon", Event.Shooter.Score, HitLaser^"/"^HitNucleus^"/"^HitArrow^"/"^HitRocket); | |
} | |
PassOn(Event); | |
} | |
} | |
// ---------------------------------- // | |
// On player request respawn | |
else if (Event.Type == CSmModeEvent::EType::OnPlayerRequestRespawn) { | |
if (Event.Player != Null) { | |
declare NewComboClan = 3 - Event.Player.CurrentClan; | |
UpdateCombo(NewComboClan); | |
} | |
XmlRpc::OnPlayerRequestRespawn(Event); | |
PassOn(Event); | |
} | |
// ---------------------------------- // | |
// On player touches object | |
else if (Event.Type == CSmModeEvent::EType::OnPlayerTouchesObject) { | |
if (Event.Player == Null) { | |
Discard(Event); | |
} else if (Event.Player != Null && Event.Player.SpawnStatus != CSmPlayer::ESpawnStatus::Spawned) { | |
Discard(Event); | |
} else { | |
PickUpObject(Event.Player, Event.Object); | |
PassOn(Event); | |
} | |
} | |
// ---------------------------------- // | |
// On action event | |
else if (Event.Type == CSmModeEvent::EType::OnActionEvent) { | |
if (Event.Player == Null) { | |
Discard(Event); | |
} else { | |
SwitchWeapon(Event.Player, Event.ActionInput); | |
PassOn(Event); | |
} | |
} | |
// ---------------------------------- // | |
// On player request action change | |
else if (Event.Type == CSmModeEvent::EType::OnPlayerRequestActionChange) { | |
if (Event.Player == Null) { | |
Discard(Event); | |
} else { | |
CycleWeapon(Event.Player, Event.ActionChange); | |
PassOn(Event); | |
} | |
} | |
// ---------------------------------- // | |
// Others | |
else { | |
PassOn(Event); | |
} | |
} | |
// ---------------------------------- // | |
// Round start invincibility | |
if (InvincibilityEndTime > 0 && InvincibilityEndTime <= Now) { | |
InvincibilityEndTime = -1; | |
UsePvPCollisions = True; | |
UsePvPWeapons = True; | |
UIManager.UIAll.SendNotice("", CUIConfig::ENoticeLevel::MatchInfo, Null, CUIConfig::EAvatarVariant::Default, CUIConfig::EUISound::PhaseChange, 0); | |
} | |
// ---------------------------------- // | |
// Start the storm | |
if (UIManager.UIAll.CountdownEndTime > 0 && UIManager.UIAll.CountdownEndTime <= Now) { | |
UIManager.UIAll.CountdownEndTime = -1; | |
OffZoneRadius = C_OffZoneRadiusMax; | |
OffZoneRadiusSpeed = (C_OffZoneRadiusMax - C_OffZoneRadiusMin) / ML::ToReal(C_OffZoneDuration); | |
G_OffZoneIsActivated = True; | |
UIManager.UIAll.StatusMessage = _("Direct elimination"); | |
} | |
// ---------------------------------- // | |
// Stop the storm | |
if (OffZoneRadiusSpeed > 0. && OffZoneRadius <= C_OffZoneRadiusMin) { | |
OffZoneRadiusSpeed = 0.; | |
OffZoneRadius = C_OffZoneRadiusMin; | |
} | |
// ---------------------------------- // | |
// Spawn objects | |
Combo_SpawnObjects(); | |
// ---------------------------------- // | |
// Update combo timer | |
if (G_ComboTime > 0) { | |
if (G_ComboNextTick <= Now) { | |
G_ComboNextTick = Now + 1000; | |
if (G_ComboTime > 0) { | |
Message::SendBigMessage(Teams[G_ComboClan-1].ColorText^(G_ComboTime / 1000), 1000, 1); | |
} | |
} | |
G_ComboTime -= Period; | |
if (G_ComboTime <= 0) { | |
G_ComboClan = 0; | |
G_ComboTime = 0; | |
} | |
} | |
// ---------------------------------- // | |
// Spawn players | |
foreach (Player in Players) { | |
if (G_ComboTime <= 0 && !G_OffZoneIsActivated) { | |
if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned && !Player.RequestsSpectate) { | |
SetPlayerClan(Player, MM_GetRequestedClan(Player)); | |
if (!G_ClansPlayers.existskey(Player.CurrentClan)) continue; | |
if (!G_ClansPlayers[Player.CurrentClan].exists(Player.Id)) continue; | |
Player.ArmorMax = C_Default_ArmorMax; | |
declare CSmMapPlayerSpawn MapLandmark_PlayerSpawn; | |
if (Player.CurrentClan == 1) { | |
MapLandmark_PlayerSpawn <=> Spawns[SpawnClan1]; | |
SpawnClan1 = 3 - SpawnClan1; | |
} else if (Player.CurrentClan == 2) { | |
MapLandmark_PlayerSpawn <=> Spawns[SpawnClan2]; | |
SpawnClan2 = 3 - SpawnClan2; | |
} | |
if (MapLandmark_PlayerSpawn != Null) SM::SpawnPlayer(Player, Player.CurrentClan, C_Default_Armor, MapLandmark_PlayerSpawn, Now); | |
declare netwrite Net_Combo_AmmoMax for Player = C_AmmoMax; | |
SetPlayerAmmo(Player, CSmMode::EWeapon::Rocket, Net_Combo_AmmoMax["Rocket"]/2); | |
SetPlayerAmmo(Player, CSmMode::EWeapon::Laser, Net_Combo_AmmoMax["Laser"]/2); | |
SetPlayerAmmo(Player, CSmMode::EWeapon::Nucleus, Net_Combo_AmmoMax["Nucleus"]/2); | |
SetPlayerAmmo(Player, CSmMode::EWeapon::Arrow, Net_Combo_AmmoMax["Arrow"]/2); | |
if (Player.Armor > C_ArmorReductionStart) { | |
declare NextArmorReduction for Player = -1; | |
NextArmorReduction = Now + C_ArmorReductionPeriod; | |
} | |
declare UI <=> UIManager.GetUI(Player); | |
if (UI != Null) { | |
UI.SpectatorForceCameraType = 1; | |
UI.SpectatorForcedClan = Player.CurrentClan; | |
} | |
} | |
} | |
if (S_UseArmorReduction) { | |
if (Player.Armor > C_ArmorReductionStart) { | |
declare NextArmorReduction for Player = -1; | |
if (NextArmorReduction > 0 && NextArmorReduction < Now) { | |
Player.Armor -= 100; | |
if (Player.Armor > C_ArmorReductionStart) { | |
NextArmorReduction = Now + C_ArmorReductionPeriod; | |
} | |
} | |
} | |
} | |
} | |
// ---------------------------------- // | |
// Check if we need more players | |
UpdateClansPlayers(); | |
// ---------------------------------- // | |
// Update settings | |
if (S_Script_RoundTimeLimit != S_RoundTimeLimit) { | |
S_Script_RoundTimeLimit = S_RoundTimeLimit; | |
if (S_Script_RoundTimeLimit <= 0) { | |
UIManager.UIAll.CountdownEndTime = -1; | |
} else { | |
UIManager.UIAll.CountdownEndTime = StartTime + (S_Script_RoundTimeLimit * 1000); | |
} | |
} | |
if (S_Script_PointsLimit != S_PointsLimit) { | |
S_Script_PointsLimit = S_PointsLimit; | |
ST2::SetFooterText(TL::Compose("%1 "^S_PointsLimit, _("Points limit : "))); | |
} | |
if (S_Script_NbPlayersPerTeam != S_NbPlayersPerTeam) { | |
S_Script_NbPlayersPerTeam = S_NbPlayersPerTeam; | |
Layers::Update("Info", UpdateLayerInfo()); | |
} | |
// ---------------------------------- // | |
// victory conditions | |
declare EndRound = False; | |
declare EndMap = False; | |
if (ClansNbPlayers[1] == 0) { | |
EndMap = True; | |
RoundWinnerClan = 2; | |
MapWinnerClan = 2; | |
} else if (ClansNbPlayers[2] == 0) { | |
EndMap = True; | |
RoundWinnerClan = 1; | |
MapWinnerClan = 1; | |
} else if (ClansNbPlayersAlive[1] == 0) { | |
EndRound = True; | |
RoundWinnerClan = 2; | |
} else if (ClansNbPlayersAlive[2] == 0) { | |
EndRound = True; | |
RoundWinnerClan = 1; | |
} | |
if (G_ComboTime > 0) { | |
if (G_ComboClan == 1 && ClansNbPlayersAlive[2] == 0) { | |
EndRound = True; | |
RoundWinnerClan = 1; | |
} else if (G_ComboClan == 2 && ClansNbPlayersAlive[1] == 0) { | |
EndRound = True; | |
RoundWinnerClan = 2; | |
} | |
} | |
if (EndMap || EndRound) MB_StopRound = True; | |
if (EndMap) MB_StopMap = True; | |
*** | |
***EndRound*** | |
*** | |
UIManager.UIAll.StatusMessage = ""; | |
Message::CleanAllMessages(); | |
Score::RoundEnd(); | |
UIManager.UIAll.CountdownEndTime = -1; | |
OffZoneRadius = -1.; | |
OffZoneRadiusSpeed = 0.; | |
G_OffZoneIsActivated = False; | |
// ---------------------------------- // | |
// Update scores | |
if (ClanScores.existskey(RoundWinnerClan)) { | |
ClanScores[RoundWinnerClan] += 1; | |
if (RoundWinnerClan == 1 || RoundWinnerClan == 2) { | |
Message::SendBigMessage(TL::Compose(_("$<%1$> wins the round"), Teams[RoundWinnerClan - 1].ColorizedName), 3000, 1); | |
} | |
} | |
UpdateScoresHeader(); | |
UpdateModeStatusMessage(); | |
// ---------------------------------- // | |
// Save the current player clan for ladder ranking | |
foreach (Player in Players) { | |
if (Player.Score == Null) continue; | |
Player.Score.LadderClan = Player.CurrentClan; | |
} | |
// ---------------------------------- // | |
// Check if the points limit is reached | |
declare EndMap = False; | |
if (S_Script_PointsLimit > 0) { | |
if (ClanScores[1] >= S_Script_PointsLimit && ClanScores[1] > ClanScores[2]) { | |
EndMap = True; | |
MapWinnerClan = 1; | |
} else if (ClanScores[2] >= S_Script_PointsLimit && ClanScores[2] > ClanScores[1]) { | |
EndMap = True; | |
MapWinnerClan = 2; | |
} | |
} | |
if (EndMap) { | |
MB_StopMap = True; | |
} else { | |
MM_Sleep(500); | |
SM::UnspawnAllPlayers(); | |
StartTime = -1; | |
MM_Sleep(2500); | |
} | |
*** | |
***EndMap*** | |
*** | |
MM_Sleep(500); | |
StartTime = -1; | |
EndTime = -1; | |
ObjectDestroyAll(); | |
Markers::Clear(); | |
// ---------------------------------- // | |
// Update UI | |
UIManager.UIAll.CountdownEndTime = -1; | |
Message::CleanAllMessages(); | |
Layers::Detach("Info"); | |
declare MasterLogin = ""; | |
declare MasterPoints = 0; | |
foreach (Score in Scores) { | |
Score.LadderMatchScoreValue = ML::ToReal(Score.Points); | |
declare PrevPoints for Score = 0; | |
PrevPoints = Score.Points; | |
if (Score.Points > MasterPoints) { | |
MasterPoints = Score.Points; | |
MasterLogin = Score.User.Login; | |
} | |
if (Score.LadderClan == MapWinnerClan) { | |
Score.Points = 3; | |
Score.LadderMatchScoreValue *= 2.; | |
} else if (Score.LadderClan == 3 - MapWinnerClan) { | |
Score.Points = 2; | |
Score.LadderMatchScoreValue *= 1.; | |
} else { | |
Score.Points = 1; | |
Score.LadderMatchScoreValue *= 0.5; | |
} | |
} | |
Ladder_SetResultsVersion(1); | |
Score::MatchEnd(True); | |
foreach (Score in Scores) { | |
declare PrevPoints for Score = 0; | |
Score.Points = PrevPoints; | |
} | |
// ---------------------------------- // | |
// Send match result | |
if (S_MatchmakingMode == 2) { | |
MM_MatchEnd(MasterLogin); | |
} | |
// ---------------------------------- // | |
// Winning sequence | |
UIManager.UIAll.UISequence = CUIConfig::EUISequence::EndRound; | |
UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::EndMatch; | |
UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::ForcedVisible; | |
if (MapWinnerClan == 1 || MapWinnerClan == 2) { | |
UIManager.UIAll.BigMessage = TL::Compose(_("$<%1$> wins the map"), Teams[MapWinnerClan - 1].ColorizedName); | |
} else { | |
UIManager.UIAll.BigMessage = _("|Match|Draw"); | |
} | |
MM_Sleep(C_SleepEndMap/2); | |
UIManager.UIAll.UISequence = CUIConfig::EUISequence::Podium; | |
UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal; | |
MM_Sleep(C_SleepEndMap/2); | |
UIManager.UIAll.BigMessage = ""; | |
// ---------------------------------- // | |
// Transfert players back to the lobby | |
if (S_MatchmakingMode == 2) { | |
MM_MatchToLobby(); | |
} | |
*** | |
***EndServer*** | |
*** | |
WarmUp2::Unload(); | |
SpawnScreen::DestroyRules(); | |
Markers::Unload(); | |
// ---------------------------------- // | |
// Destroy layer | |
Layers::Destroy("Info"); | |
*** | |
// ---------------------------------- // | |
/// Update the ModeStatusMessage | |
Void UpdateModeStatusMessage() { | |
declare Text BaseRules = _("Eliminate all the enemy team."); | |
declare Text RoundsToWinSetting = ""^S_PointsLimit; | |
declare Text MatchScore = ClanScores[1] ^ " - " ^ ClanScores[2]; | |
ModeStatusMessage = TL::Compose("%1\nRounds to win: %2 \\ Current Score: %3", BaseRules, RoundsToWinSetting, MatchScore); | |
} | |
Void InitializePlayer(CSmPlayer _Player) { | |
SetPlayerClan(_Player, MM_GetRequestedClan(_Player)); | |
declare NextArmorReduction for _Player = -1; | |
NextArmorReduction = -1; | |
declare netwrite Net_Combo_AmmoUpdate for _Player = _Player.Login^"_"^Now; | |
declare netwrite Net_Combo_AmmoMax for _Player = C_AmmoMax; | |
declare netwrite Net_Combo_Weapon for _Player = "Rocket"; | |
Net_Combo_AmmoUpdate = _Player.Login^"_"^Now; | |
Net_Combo_AmmoMax = C_AmmoMax; | |
Net_Combo_Weapon = "Rocket"; | |
declare CurrentWeapon for _Player = C_Default_Weapon; | |
declare Weapons for _Player = C_Default_Weapons; | |
CurrentWeapon = C_Default_Weapon; | |
Weapons = C_Default_Weapons; | |
_Player.ArmorMax = C_Default_ArmorMax; | |
_Player.AmmoGain = C_AmmoGain["Rocket"]; | |
SetPlayerWeapon(_Player, C_Default_Weapon, False); | |
SetPlayerAmmoMax(_Player, CSmMode::EWeapon::Rocket, Net_Combo_AmmoMax["Rocket"]); | |
SetPlayerAmmoMax(_Player, CSmMode::EWeapon::Laser, Net_Combo_AmmoMax["Laser"]); | |
SetPlayerAmmoMax(_Player, CSmMode::EWeapon::Nucleus, Net_Combo_AmmoMax["Nucleus"]); | |
SetPlayerAmmoMax(_Player, CSmMode::EWeapon::Arrow, Net_Combo_AmmoMax["Arrow"]); | |
SetPlayerReloadAllWeapons(_Player, True); | |
} | |
// ---------------------------------- // | |
/// Update the base colors | |
Void UpdateBasesColors() { | |
foreach (MapBase in MapBases) { | |
MapBase.Clan = 0; | |
MapBase.IsActive = True; | |
} | |
} | |
// ---------------------------------- // | |
/** Update the combo | |
* | |
* @param _NewComboClan The clan who updated the combo | |
*/ | |
Void UpdateCombo(Integer _NewComboClan) { | |
// Start combo | |
if (G_ComboClan == 0 || G_ComboClan == _NewComboClan) { | |
if (!G_OffZoneIsActivated) { | |
G_ComboClan = _NewComboClan; | |
G_ComboNextTick = Now; | |
if (G_ClanComboTimeLimit.existskey(G_ComboClan)) { | |
G_ComboTime = G_ClanComboTimeLimit[G_ComboClan]; | |
G_ClanComboTimeLimit[G_ComboClan] += C_ComboTimeStep; | |
Message::SendBigMessage(Teams[G_ComboClan-1].ColorText^(G_ComboTime / 1000), 1000, 1, CUIConfig::EUISound::TieBreakPoint, 0); | |
if (_NewComboClan == 1) { | |
Net_Combo_ComboClan1 = G_ClanComboTimeLimit[G_ComboClan]; | |
} else if (_NewComboClan == 2) { | |
Net_Combo_ComboClan2 = G_ClanComboTimeLimit[G_ComboClan]; | |
} | |
} | |
} | |
} | |
// Combo breaker | |
else { | |
G_ComboClan = 0; | |
G_ComboTime = 0; | |
if (Teams.existskey(_NewComboClan-1)) { | |
declare Message = TL::Compose("%1%2", Teams[_NewComboClan-1].ColorText, _("Combo breaker")); | |
Message::SendBigMessage(Message, 3000, 1, CUIConfig::EUISound::TiePoint, 0); | |
} | |
} | |
} | |
// ---------------------------------- // | |
/// Update the scores header | |
Void UpdateScoresHeader() { | |
UIManager.UIAll.OverlayScoreSummary = True; | |
declare PlayerClan1Id = NullId; | |
declare PlayerClan2Id = NullId; | |
foreach (Player in Players) { | |
if ((PlayerClan1Id == NullId) && (Player.CurrentClan == 1)) PlayerClan1Id = Player.Id; | |
if ((PlayerClan2Id == NullId) && (Player.CurrentClan == 2)) PlayerClan2Id = Player.Id; | |
if (PlayerClan1Id != NullId && PlayerClan2Id != NullId) break; | |
} | |
if (PlayerClan1Id != NullId) UIManager.UIAll.ScoreSummary_Player1 = PlayerClan1Id; | |
else UIManager.UIAll.ScoreSummary_Player1 = NullId; | |
if (PlayerClan2Id != NullId) UIManager.UIAll.ScoreSummary_Player2 = PlayerClan2Id; | |
else UIManager.UIAll.ScoreSummary_Player2 = NullId; | |
UIManager.UIAll.ScoreSummary_Points1 = ClanScores[1]; | |
UIManager.UIAll.ScoreSummary_Points2 = ClanScores[2]; | |
UIManager.UIAll.ScoreSummary_MatchPoints1 = -1; | |
UIManager.UIAll.ScoreSummary_MatchPoints2 = -1; | |
} | |
// ---------------------------------- // | |
/** Create the script for the layer Markers | |
* | |
* @return The script of the layer Markers | |
*/ | |
Text GetMLMarkersScript() { | |
return """ | |
declare CMlLabel[Integer] Labels_Timer; | |
declare CMlQuad[Integer] Quads_Timer; | |
Void UpdateTimers() { | |
declare netread Integer[Text] Net_Combo_ItemsRespawn for Teams[0]; | |
foreach (Key => Label_Timer in Labels_Timer) { | |
declare Text ObjectId for Label_Timer; | |
declare Quad_Timer = Quads_Timer[Key]; | |
if (ObjectId == "" || !Net_Combo_ItemsRespawn.existskey(ObjectId)) { | |
if (Label_Timer.Value != "-") { | |
Label_Timer.Value = "-"; | |
Quad_Timer.ModulateColor = <0., 1., 0.>; | |
} | |
} else { | |
declare TimeRemaining = (Net_Combo_ItemsRespawn[ObjectId] - ArenaNow) / 1000; | |
if (TimeRemaining > 0) { | |
Label_Timer.Value = ""^TimeRemaining; | |
if (Quads_Timer[Key].ModulateColor != <1., 0., 0.>) Quads_Timer[Key].ModulateColor = <1., 0., 0.>; | |
} else if (Label_Timer.Value != "-") { | |
Label_Timer.Value = "-"; | |
Quad_Timer.ModulateColor = <0., 1., 0.>; | |
} | |
} | |
} | |
} | |
main() { | |
declare Frame_Global <=> (Page.GetFirstChild("Frame_Global") as CMlFrame); | |
Page.GetClassChildren("MarkerObject", Frame_Global, False); | |
declare Key = 0; | |
foreach (Marker_Object in Page.GetClassChildren_Result) { | |
declare Label_Timer <=> ((Marker_Object as CMlFrame).GetFirstChild("Label_Timer") as CMlLabel); | |
declare Text ObjectId for Label_Timer; | |
ObjectId = Marker_Object.ControlId; | |
Labels_Timer[Key] = Label_Timer; | |
declare Quad_Timer <=> ((Marker_Object as CMlFrame).GetFirstChild("Quad_Timer") as CMlQuad); | |
Quads_Timer[Key] = Quad_Timer; | |
Key += 1; | |
} | |
Frame_Global.Visible = False; | |
declare MarkersVisible for UI = False; | |
declare NextUpdate = Now; | |
declare PrevIsSpectatorMode = False; | |
declare PrevMarkersVisible = False; | |
while (True) { | |
yield; | |
if (!PageIsVisible || InputPlayer == Null) continue; | |
if (PrevIsSpectatorMode != IsSpectatorMode || PrevMarkersVisible != MarkersVisible) { | |
PrevIsSpectatorMode = IsSpectatorMode; | |
PrevMarkersVisible = MarkersVisible; | |
if (IsSpectatorMode && MarkersVisible) { | |
Frame_Global.Visible = True; | |
} else { | |
Frame_Global.Visible = False; | |
} | |
} | |
if (Now >= NextUpdate) { | |
NextUpdate = Now + 1000; | |
UpdateTimers(); | |
} | |
} | |
}"""; | |
} | |
// ---------------------------------- // | |
/// Create the markers manialinks | |
Void CreateMarkers() { | |
declare TypeCount = Integer[Text]; | |
declare ImagePath = ""; | |
declare ImageSize = ""; | |
foreach (MapLandmark in MapLandmarks_ObjectAnchor) { | |
if (!C_Object.exists(MapLandmark.Tag)) continue; | |
declare Pos = MapLandmark.Position.X^" "^(MapLandmark.Position.Y+1.)^" "^MapLandmark.Position.Z; | |
declare ManialinkFrameId = "Marker_Object"^MapLandmark.Id; | |
if (!TypeCount.existskey(MapLandmark.Tag)) TypeCount[MapLandmark.Tag] = 0; | |
TypeCount[MapLandmark.Tag] += 1; | |
if (MapLandmark.Tag == "Armor") { | |
ImagePath = C_ImgBaseDir^"ShieldWhite.dds"; | |
ImageSize = "4 6"; | |
} else { | |
ImagePath = C_ImgBaseDir^MapLandmark.Tag^"White.dds"; | |
ImageSize = "5 6"; | |
} | |
declare Marker = """<marker pos="{{{Pos}}}" manialinkframeid="{{{ManialinkFrameId}}}" />"""; | |
declare Manialink = """ | |
<frame scale="0.75" class="MarkerObject" id="{{{ManialinkFrameId}}}"> | |
<quad posn="0 0 -1" sizen="12 10" halign="center" valign="bottom" style="Bgs1InRace" substyle="BgList" modulatecolor="f00" id="Quad_Timer" /> | |
<frame posn="0 5 0"> | |
<format textemboss="1" /> | |
<!--<label posn="-3.5 0" sizen="5 5" textsize="2" halign="right" valign="center2" text="#{{{TypeCount[MapLandmark.Tag]}}}" />--> | |
<quad posn="-1 0" sizen="{{{ImageSize}}}" halign="right" valign="center" image="{{{ImagePath}}}" /> | |
<label posn="2.5 0" sizen="5 5" textsize="3" halign="center" valign="center2" id="Label_Timer" /> | |
</frame> | |
</frame>"""; | |
Markers::Add(Marker, Manialink); | |
} | |
Markers::SetManialinkScript(GetMLMarkersScript()); | |
} | |
// ---------------------------------- // | |
/// Update the players lists on the side of the screen | |
Text UpdateLayerInfo() { | |
declare LoginsTeam = [1 => "", 2 => ""]; | |
for (Clan, 1, 2) { | |
if (!G_ClansPlayers.existskey(Clan)) continue; | |
foreach (PlayerId in G_ClansPlayers[Clan]) { | |
if (!Players.existskey(PlayerId)) continue; | |
if (LoginsTeam[Clan] == "") LoginsTeam[Clan] ^= Players[PlayerId].Login; | |
else LoginsTeam[Clan] ^= ","^Players[PlayerId].Login; | |
} | |
} | |
declare TimersHeight = 0.; | |
declare TypeCount = Integer[Text]; | |
declare ImagePath = ""; | |
declare ImageSize = ""; | |
declare Timers = ""; | |
foreach (MapLandmark in MapLandmarks_ObjectAnchor) { | |
if (!C_Object.exists(MapLandmark.Tag)) continue; | |
if (TimersHeight >= 120.) break; | |
declare Pos = "0 "^TimersHeight; | |
declare ManialinkFrameId = "Marker_Object"^MapLandmark.Id; | |
if (!TypeCount.existskey(MapLandmark.Tag)) TypeCount[MapLandmark.Tag] = 0; | |
TypeCount[MapLandmark.Tag] += 1; | |
if (MapLandmark.Tag == "Armor") { | |
ImagePath = C_ImgBaseDir^"ShieldWhite.dds"; | |
ImageSize = "4 6"; | |
} else { | |
ImagePath = C_ImgBaseDir^MapLandmark.Tag^"White.dds"; | |
ImageSize = "5 6"; | |
} | |
TimersHeight += 10.; | |
Timers ^= """ | |
<frame posn="{{{Pos}}}" class="FrameTimer" id="{{{ManialinkFrameId}}}"> | |
<quad posn="0 0 -1" sizen="21 10" halign="center" valign="bottom" style="Bgs1InRace" substyle="BgList" modulatecolor="f00" id="Quad_Timer" /> | |
<frame posn="-1 5 0"> | |
<format textemboss="1" /> | |
<label posn="-3.5 0" sizen="5 5" textsize="2" halign="right" valign="center2" text="#{{{TypeCount[MapLandmark.Tag]}}}" /> | |
<quad posn="2 0" sizen="{{{ImageSize}}}" halign="right" valign="center" image="{{{ImagePath}}}" /> | |
<label posn="5.5 0" sizen="5 5" textsize="3" halign="center" valign="center2" id="Label_Timer" /> | |
</frame> | |
</frame>"""; | |
} | |
return """ | |
<frame posn="-160 68"> | |
<quad sizen="41 4" halign="left" bgcolor="0007" /> | |
<quad posn="1 5 1" sizen="10 10" halign="left" style="Emblems" substyle="#1" /> | |
<label id="team1name" posn="11 0 1" sizen="40 4" halign="left" textprefix="$s" text="Blue" /> | |
<playerlist posn="0 -5" scale="0.75" halign="left" substyle="Medium" lines="{{{S_Script_NbPlayersPerTeam}}}" columns="1" team="1" status="Playing" logins="{{{LoginsTeam[1]}}}" /> | |
</frame> | |
<frame posn="160 68"> | |
<quad sizen="41 4" halign="right" bgcolor="0007" /> | |
<quad posn="-1 5 1" sizen="10 10" halign="right" style="Emblems" substyle="#2" /> | |
<label id="team2name" posn="-11 0 1" sizen="40 4" halign="right" textprefix="$s" text="Red" /> | |
<playerlist posn="0 -5" scale="0.75" halign="right" substyle="Medium" lines="{{{S_Script_NbPlayersPerTeam}}}" columns="1" team="2" status="Playing" logins="{{{LoginsTeam[2]}}}"/> | |
</frame> | |
<frame posn="0 71 5" id="Frame_ScoreInfo"> | |
<label posn="-25 0.5 6" sizen="15 5" textsize="4" halign="right" valign="center" textemboss="1" text="0" id="Label_ComboClan1" /> | |
<quad posn="-22 0 6" sizen="5 5" halign="center" valign="center" style="Icons64x64_1" substyle="GenericButton" /> | |
<quad posn=" 22 0 6" sizen="5 5" halign="center" valign="center" style="Icons64x64_1" substyle="GenericButton" /> | |
<label posn="25 0.5 6" sizen="15 5" textsize="4" halign="left" valign="center" textemboss="1" text="0" id="Label_ComboClan2" /> | |
</frame> | |
<frame posn="-68 -76" id="Frame_WeaponInfo"> | |
<quad posn="0 0" sizen="6 6" halign="right" valign="center" image="{{{C_ImgBaseDir}}}LaserWhite.dds" id="Quad_IconLaser" /> | |
<quad posn="12 0" sizen="6 6" halign="right" valign="center" image="{{{C_ImgBaseDir}}}NucleusWhite.dds" id="Quad_IconNucleus" /> | |
<quad posn="24 0" sizen="6 6" halign="right" valign="center" image="{{{C_ImgBaseDir}}}ArrowWhite.dds" id="Quad_IconArrow" /> | |
<quad posn="36 0" sizen="6 6" halign="right" valign="center" image="{{{C_ImgBaseDir}}}RocketWhite.dds" id="Quad_IconRocket" /> | |
<frame posn="0 0.3"> | |
<label posn="0 0" sizen="6 6" halign="left" valign="center" textemboss="1" text="0" id="Label_AmmoLaser" /> | |
<label posn="12 0" sizen="6 6" halign="left" valign="center" textemboss="1" text="0" id="Label_AmmoNucleus" /> | |
<label posn="24 0" sizen="6 6" halign="left" valign="center" textemboss="1" text="0" id="Label_AmmoArrow" /> | |
<label posn="36 0" sizen="6 6" halign="left" valign="center" textemboss="1" text="0" id="Label_AmmoRocket" /> | |
</frame> | |
</frame> | |
<frame id="Frame_Spec"> | |
<frame posn="{{{C_LayerTimersPosition.X}}} {{{C_LayerTimersPosition.Y}}} {{{C_LayerTimersPosition.Z}}}" id="Frame_Timers"> | |
{{{Timers}}} | |
</frame> | |
<frame posn="159 -83"> | |
<label halign="right" style="CardButtonSmallS" text="Show markers" scriptevents="1" id="Button_DisplayMarkers" /> | |
<label posn="0 6" halign="right" style="CardButtonSmallS" text="Show list" scriptevents="1" id="Button_DisplayList" /> | |
</frame> | |
</frame> | |
<script><!-- | |
#Include "TextLib" as TL | |
declare CMlQuad Quad_IconLaser; | |
declare CMlQuad Quad_IconNucleus; | |
declare CMlQuad Quad_IconArrow; | |
declare CMlQuad Quad_IconRocket; | |
declare CMlLabel Label_AmmoLaser; | |
declare CMlLabel Label_AmmoNucleus; | |
declare CMlLabel Label_AmmoArrow; | |
declare CMlLabel Label_AmmoRocket; | |
declare CMlLabel[Integer] Labels_Timer; | |
declare CMlQuad[Integer] Quads_Timer; | |
Void UpdateTimers() { | |
declare netread Integer[Text] Net_Combo_ItemsRespawn for Teams[0]; | |
foreach (Key => Label_Timer in Labels_Timer) { | |
declare Text ObjectId for Label_Timer; | |
declare Quad_Timer = Quads_Timer[Key]; | |
if (ObjectId == "" || !Net_Combo_ItemsRespawn.existskey(ObjectId)) { | |
if (Label_Timer.Value != "-") { | |
Label_Timer.Value = "-"; | |
Quad_Timer.ModulateColor = <0., 1., 0.>; | |
} | |
} else { | |
declare TimeRemaining = (Net_Combo_ItemsRespawn[ObjectId] - ArenaNow) / 1000; | |
if (TimeRemaining > 0) { | |
Label_Timer.Value = ""^TimeRemaining; | |
if (Quads_Timer[Key].ModulateColor != <1., 0., 0.>) Quads_Timer[Key].ModulateColor = <1., 0., 0.>; | |
} else if (Label_Timer.Value != "-") { | |
Label_Timer.Value = "-"; | |
Quad_Timer.ModulateColor = <0., 1., 0.>; | |
} | |
} | |
} | |
} | |
Void UpdateAmmoMax(Integer[Text] _AmmoMax) { | |
foreach (Weapon => AmmoMax in _AmmoMax) { | |
declare WeaponText = "$aaa"^AmmoMax; | |
declare WeaponIcon = "{{{C_ImgBaseDir}}}"^Weapon^".dds"; | |
if (AmmoMax > 0) { | |
WeaponText = "$fff"^AmmoMax; | |
WeaponIcon = "{{{C_ImgBaseDir}}}"^Weapon^"White.dds"; | |
} | |
switch (Weapon) { | |
case "Laser" : { | |
Label_AmmoLaser.SetText(WeaponText); | |
if (Http.IsValidUrl(WeaponIcon)) Quad_IconLaser.ChangeImageUrl(WeaponIcon); | |
} | |
case "Nucleus" : { | |
Label_AmmoNucleus.SetText(WeaponText); | |
if (Http.IsValidUrl(WeaponIcon)) Quad_IconNucleus.ChangeImageUrl(WeaponIcon); | |
} | |
case "Arrow" : { | |
Label_AmmoArrow.SetText(WeaponText); | |
if (Http.IsValidUrl(WeaponIcon)) Quad_IconArrow.ChangeImageUrl(WeaponIcon); | |
} | |
case "Rocket" : { | |
Label_AmmoRocket.SetText(WeaponText); | |
if (Http.IsValidUrl(WeaponIcon)) Quad_IconRocket.ChangeImageUrl(WeaponIcon); | |
} | |
} | |
} | |
} | |
Void UpdateWeapon(Text _PrevWeapon, Text _NewWeapon) { | |
switch (_PrevWeapon) { | |
case "Laser" : Quad_IconLaser.RelativeScale = 1.; | |
case "Nucleus" : Quad_IconNucleus.RelativeScale = 1.; | |
case "Arrow" : Quad_IconArrow.RelativeScale = 1.; | |
case "Rocket" : Quad_IconRocket.RelativeScale = 1.; | |
} | |
switch (_NewWeapon) { | |
case "Laser" : Quad_IconLaser.RelativeScale = 1.3; | |
case "Nucleus" : Quad_IconNucleus.RelativeScale = 1.3; | |
case "Arrow" : Quad_IconArrow.RelativeScale = 1.3; | |
case "Rocket" : Quad_IconRocket.RelativeScale = 1.3; | |
} | |
} | |
main() { | |
declare Frame_WeaponInfo <=> (Page.GetFirstChild("Frame_WeaponInfo") as CMlFrame); | |
declare Label_Team1Name <=> (Page.GetFirstChild("team1name") as CMlLabel); | |
declare Label_Team2Name <=> (Page.GetFirstChild("team2name") as CMlLabel); | |
declare Label_ComboClan1 <=> (Page.GetFirstChild("Label_ComboClan1") as CMlLabel); | |
declare Label_ComboClan2 <=> (Page.GetFirstChild("Label_ComboClan2") as CMlLabel); | |
Label_AmmoLaser <=> (Page.GetFirstChild("Label_AmmoLaser") as CMlLabel); | |
Label_AmmoNucleus <=> (Page.GetFirstChild("Label_AmmoNucleus") as CMlLabel); | |
Label_AmmoArrow <=> (Page.GetFirstChild("Label_AmmoArrow") as CMlLabel); | |
Label_AmmoRocket <=> (Page.GetFirstChild("Label_AmmoRocket") as CMlLabel); | |
Quad_IconLaser <=> (Page.GetFirstChild("Quad_IconLaser") as CMlQuad); | |
Quad_IconNucleus <=> (Page.GetFirstChild("Quad_IconNucleus") as CMlQuad); | |
Quad_IconArrow <=> (Page.GetFirstChild("Quad_IconArrow") as CMlQuad); | |
Quad_IconRocket <=> (Page.GetFirstChild("Quad_IconRocket") as CMlQuad); | |
declare Frame_Timers <=> (Page.GetFirstChild("Frame_Timers") as CMlFrame); | |
declare Frame_Spec <=> (Page.GetFirstChild("Frame_Spec") as CMlFrame); | |
declare Button_DisplayList <=> (Page.GetFirstChild("Button_DisplayList") as CMlLabel); | |
declare Button_DisplayMarkers <=> (Page.GetFirstChild("Button_DisplayMarkers") as CMlLabel); | |
Page.GetClassChildren("FrameTimer", Frame_Timers, False); | |
declare Key = 0; | |
foreach (Marker_Object in Page.GetClassChildren_Result) { | |
declare Label_Timer <=> ((Marker_Object as CMlFrame).GetFirstChild("Label_Timer") as CMlLabel); | |
declare Text ObjectId for Label_Timer; | |
ObjectId = Marker_Object.ControlId; | |
Labels_Timer[Key] = Label_Timer; | |
declare Quad_Timer <=> ((Marker_Object as CMlFrame).GetFirstChild("Quad_Timer") as CMlQuad); | |
Quads_Timer[Key] = Quad_Timer; | |
Key += 1; | |
} | |
declare MarkersVisible for UI = False; | |
declare ListVisible = True; | |
if (MarkersVisible) Button_DisplayMarkers.Value = "{{{_("Hide markers")}}}"; | |
else Button_DisplayMarkers.Value = "{{{_("Show markers")}}}"; | |
if (ListVisible) Button_DisplayList.Value = "{{{_("Hide list")}}}"; | |
else Button_DisplayList.Value = "{{{_("Show list")}}}"; | |
declare netread Vec3 Net_Combo_TimersLayerPosition for Teams[0]; | |
declare Vec3 PrevTimersLayerPosition; | |
declare PrevTeam1Name = ""; | |
declare PrevTeam2Name = ""; | |
declare PrevComboClan1 = 0; | |
declare PrevComboClan2 = 0; | |
declare PrevAmmoUpdate = ""; | |
declare PrevWeapon = ""; | |
declare NextUpdateTimers = Now; | |
declare NextUpdate = Now; | |
while (True) { | |
yield; | |
foreach (Event in PendingEvents) { | |
if (Event.Type == CMlEvent::Type::MouseClick) { | |
if (Event.ControlId == "Button_DisplayMarkers") { | |
MarkersVisible = !MarkersVisible; | |
if (MarkersVisible) Button_DisplayMarkers.Value = "{{{_("Hide markers")}}}"; | |
else Button_DisplayMarkers.Value = "{{{_("Show markers")}}}"; | |
} else if (Event.ControlId == "Button_DisplayList") { | |
ListVisible = !ListVisible; | |
if (ListVisible) { | |
Frame_Timers.Visible = True; | |
Button_DisplayList.Value = "{{{_("Hide list")}}}"; | |
} else { | |
Frame_Timers.Visible = False; | |
Button_DisplayList.Value = "{{{_("Show list")}}}"; | |
} | |
} | |
} | |
} | |
if (!PageIsVisible || InputPlayer == Null) continue; | |
if (Now < NextUpdate) continue; | |
NextUpdate = Now + 250; | |
if (PrevTeam1Name != Teams[0].ColorizedName) { | |
PrevTeam1Name = Teams[0].ColorizedName; | |
Label_Team1Name.SetText(Teams[0].ColorizedName); | |
} | |
if (PrevTeam2Name != Teams[1].ColorizedName) { | |
PrevTeam2Name = Teams[1].ColorizedName; | |
Label_Team2Name.SetText(Teams[1].ColorizedName); | |
} | |
if (PrevComboClan1 != Net_Combo_ComboClan1) { | |
PrevComboClan1 = Net_Combo_ComboClan1; | |
Label_ComboClan1.SetText(TL::ToText(PrevComboClan1/1000)); | |
} | |
if (PrevComboClan2 != Net_Combo_ComboClan2) { | |
PrevComboClan2 = Net_Combo_ComboClan2; | |
Label_ComboClan2.SetText(TL::ToText(PrevComboClan2/1000)); | |
} | |
if (PrevTimersLayerPosition != Net_Combo_TimersLayerPosition) { | |
PrevTimersLayerPosition = Net_Combo_TimersLayerPosition; | |
Frame_Timers.RelativePosition = Net_Combo_TimersLayerPosition; | |
} | |
if (Now >= NextUpdateTimers) { | |
NextUpdateTimers = Now + 1000; | |
UpdateTimers(); | |
} | |
if (IsSpectatorMode && GUIPlayer != Null) { | |
declare netread Text Net_Combo_AmmoUpdate for GUIPlayer; | |
declare netread Integer[Text] Net_Combo_AmmoMax for GUIPlayer; | |
declare netread Text Net_Combo_Weapon for GUIPlayer; | |
if (PrevAmmoUpdate != Net_Combo_AmmoUpdate) { | |
PrevAmmoUpdate = Net_Combo_AmmoUpdate; | |
UpdateAmmoMax(Net_Combo_AmmoMax); | |
} | |
if (PrevWeapon != Net_Combo_Weapon) { | |
UpdateWeapon(PrevWeapon, Net_Combo_Weapon); | |
PrevWeapon = Net_Combo_Weapon; | |
} | |
if (!Frame_WeaponInfo.Visible) Frame_WeaponInfo.Visible = True; | |
if (!Frame_Spec.Visible) { | |
Frame_Spec.Visible = True; | |
} | |
} else if (IsSpectatorMode) { | |
if (Frame_WeaponInfo.Visible) Frame_WeaponInfo.Visible = False; | |
if (!Frame_Spec.Visible) { | |
Frame_Spec.Visible = True; | |
} | |
} else { | |
declare netread Text Net_Combo_AmmoUpdate for InputPlayer; | |
declare netread Integer[Text] Net_Combo_AmmoMax for InputPlayer; | |
declare netread Text Net_Combo_Weapon for InputPlayer; | |
if (PrevAmmoUpdate != Net_Combo_AmmoUpdate) { | |
PrevAmmoUpdate = Net_Combo_AmmoUpdate; | |
UpdateAmmoMax(Net_Combo_AmmoMax); | |
} | |
if (PrevWeapon != Net_Combo_Weapon) { | |
UpdateWeapon(PrevWeapon, Net_Combo_Weapon); | |
PrevWeapon = Net_Combo_Weapon; | |
} | |
if (!Frame_WeaponInfo.Visible) Frame_WeaponInfo.Visible = True; | |
if (Frame_Spec.Visible) { | |
Frame_Spec.Visible = False; | |
} | |
} | |
} | |
} | |
--></script>"""; | |
} | |
// ---------------------------------- // | |
/// Update the players allowed to play | |
Void UpdateClansPlayers() { | |
declare ToRemove = [1 => Ident[], 2 => Ident[]]; | |
declare AllowedPlayers = Ident[]; | |
declare PlayersListNeedUpdate = False; | |
foreach (Clan => ClanPlayers in G_ClansPlayers) { | |
foreach (PlayerId in ClanPlayers) { | |
if (!Players.existskey(PlayerId)) { | |
ToRemove[Clan].add(PlayerId); | |
if (!S_AllowUnbalancedTeams || PlayerId != NullId) UpdateCombo(3 - Clan); | |
} else { | |
AllowedPlayers.add(PlayerId); | |
} | |
} | |
} | |
foreach (Clan => ClanPlayers in ToRemove) { | |
foreach (PlayerId in ClanPlayers) { | |
declare Removed = G_ClansPlayers[Clan].remove(PlayerId); | |
PlayersListNeedUpdate = True; | |
} | |
} | |
for (Clan, 1, 2) { | |
if (G_ClansPlayers[Clan].count < S_Script_NbPlayersPerTeam) { | |
if (ClansNbPlayers[Clan] > ClansNbPlayersAlive[Clan]) { | |
foreach (Player in Players) { | |
if (AllowedPlayers.exists(Player.Id)) continue; | |
SetPlayerClan(Player, MM_GetRequestedClan(Player)); | |
if (Player.CurrentClan == Clan) { | |
G_ClansPlayers[Clan].add(Player.Id); | |
PlayersListNeedUpdate = True; | |
} | |
} | |
} | |
} | |
} | |
if (PlayersListNeedUpdate) { | |
Layers::Update("Info", UpdateLayerInfo()); | |
} | |
} | |
Integer GetWeaponOrder(CSmMode::EWeapon _Weapon) { | |
switch (_Weapon) { | |
case CSmMode::EWeapon::Laser : return 1; | |
case CSmMode::EWeapon::Nucleus : return 2; | |
case CSmMode::EWeapon::Arrow : return 3; | |
case CSmMode::EWeapon::Rocket : return 4; | |
default: return 0; | |
} | |
return 0; | |
} | |
// ---------------------------------- // | |
/** Switch the weapon of a player | |
* | |
* @param _Player The player who will switch weapon | |
* @param _Weapon The number of the new weapon | |
*/ | |
Void SwitchWeapon(CSmPlayer _Player, CSmModeEvent::EActionInput _Weapon) { | |
declare Weapons for _Player = C_Default_Weapons; | |
declare CurrentWeapon for _Player = C_Default_Weapon; | |
switch (_Weapon) { | |
// Rocket | |
case CSmModeEvent::EActionInput::Activable4: { | |
if (!Weapons.exists(CSmMode::EWeapon::Rocket)) return; | |
SetPlayerWeapon(_Player, CSmMode::EWeapon::Rocket, False); | |
CurrentWeapon = CSmMode::EWeapon::Rocket; | |
_Player.AmmoGain = C_AmmoGain["Rocket"]; | |
declare netwrite Text Net_Combo_Weapon for _Player; | |
Net_Combo_Weapon = "Rocket"; | |
} | |
// Laser | |
case CSmModeEvent::EActionInput::Activable1: { | |
if (!Weapons.exists(CSmMode::EWeapon::Laser)) return; | |
SetPlayerWeapon(_Player, CSmMode::EWeapon::Laser, False); | |
CurrentWeapon = CSmMode::EWeapon::Laser; | |
_Player.AmmoGain = C_AmmoGain["Laser"]; | |
declare netwrite Text Net_Combo_Weapon for _Player; | |
Net_Combo_Weapon = "Laser"; | |
} | |
// Nucleus | |
case CSmModeEvent::EActionInput::Activable2: { | |
if (!Weapons.exists(CSmMode::EWeapon::Nucleus)) return; | |
SetPlayerWeapon(_Player, CSmMode::EWeapon::Nucleus, False); | |
CurrentWeapon = CSmMode::EWeapon::Nucleus; | |
_Player.AmmoGain = C_AmmoGain["Nucleus"]; | |
declare netwrite Text Net_Combo_Weapon for _Player; | |
Net_Combo_Weapon = "Nucleus"; | |
} | |
// Arrow | |
case CSmModeEvent::EActionInput::Activable3: { | |
if (!Weapons.exists(CSmMode::EWeapon::Arrow)) return; | |
SetPlayerWeapon(_Player, CSmMode::EWeapon::Arrow, False); | |
CurrentWeapon = CSmMode::EWeapon::Arrow; | |
_Player.AmmoGain = C_AmmoGain["Arrow"]; | |
declare netwrite Text Net_Combo_Weapon for _Player; | |
Net_Combo_Weapon = "Arrow"; | |
} | |
} | |
} | |
// ---------------------------------- // | |
/** Cycle through the available weapons | |
* | |
* @param _Player The player who will cycle through his weapons | |
* @param _Step The number of step to go forward or backward in the weapons list | |
*/ | |
Void CycleWeapon(CSmPlayer _Player, Integer _Step) { | |
declare Weapons for _Player = C_Default_Weapons; | |
if (Weapons.count <= 1) return; | |
declare Step = 0; | |
if (_Step < 0) Step = -1; | |
else if (_Step > 0) Step = 1; | |
declare CurrentWeapon for _Player = C_Default_Weapon; | |
if (!Weapons.exists(CurrentWeapon)) return; | |
declare Key = Weapons.keyof(CurrentWeapon) + Step; | |
while (!Weapons.existskey(Key)) { | |
Key += Step; | |
if (Key > 4) Key = 1; | |
else if (Key < 1) Key = 4; | |
} | |
CurrentWeapon = Weapons[Key]; | |
declare netwrite Text Net_Combo_Weapon for _Player; | |
switch (CurrentWeapon) { | |
case CSmMode::EWeapon::Laser : SwitchWeapon(_Player, CSmModeEvent::EActionInput::Activable1); | |
case CSmMode::EWeapon::Nucleus : SwitchWeapon(_Player, CSmModeEvent::EActionInput::Activable2); | |
case CSmMode::EWeapon::Arrow : SwitchWeapon(_Player, CSmModeEvent::EActionInput::Activable3); | |
case CSmMode::EWeapon::Rocket : SwitchWeapon(_Player, CSmModeEvent::EActionInput::Activable4); | |
} | |
} | |
// ---------------------------------- // | |
/// Prepare match for matchmaking | |
Void PrepareMatch() { | |
foreach (Player in AllPlayers) { | |
SetPlayerClan(Player, MM_GetRequestedClan(Player)); | |
if (Player.CurrentClan == 1) WarmUp2::SetPlayerGroup(Player, "Clan1"); | |
else if (Player.CurrentClan == 2) WarmUp2::SetPlayerGroup(Player, "Clan2"); | |
} | |
WarmUp2::Clean(); | |
WarmUp2::Fill(); | |
} | |
// ---------------------------------- // | |
// Manage the warm up sequence | |
Void WarmUp() { | |
XmlRpc::BeginWarmUp(); | |
// Init warm up | |
declare PrevSequence = UIManager.UIAll.UISequence; | |
UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::PhaseChange; | |
UIManager.UIAll.BigMessage = _("Warm-up"); | |
UIManager.UIAll.StatusMessage = _("Press F6 once you're ready."); | |
UIManager.UIAll.UISequence = CUIConfig::EUISequence::Playing; | |
UsePvPCollisions = True; | |
UsePvPWeapons = True; | |
WarmUp2::Begin(); | |
// ---------------------------------- // | |
// Init players | |
foreach (Player in Players) { | |
SetPlayerClan(Player, MM_GetRequestedClan(Player)); | |
if (Player.CurrentClan == 1) WarmUp2::SetPlayerGroup(Player, "Clan1"); | |
else if (Player.CurrentClan == 2) WarmUp2::SetPlayerGroup(Player, "Clan2"); | |
} | |
WarmUp2::Clean(); | |
WarmUp2::Fill(); | |
declare PrevWarmUpDuration = S_WarmUpDuration-1; | |
declare PrevAllowUnbalancedTeams = !S_AllowUnbalancedTeams; | |
while (!WarmUp2::Stop()) { | |
MM_Yield(); | |
// Let the server sleep if there's no players on it | |
if (PlayersNbTotal <= 0) continue; | |
// Manage players | |
foreach (Player in Players) { | |
if (Player.CurrentClan != MM_GetRequestedClan(Player)) { | |
UnspawnPlayer(Player); | |
SetPlayerClan(Player, MM_GetRequestedClan(Player)); | |
if (Player.CurrentClan == 1) WarmUp2::SetPlayerGroup(Player, "Clan1"); | |
else if (Player.CurrentClan == 2) WarmUp2::SetPlayerGroup(Player, "Clan2"); | |
} | |
if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned) { | |
SetPlayerWeapon(Player, CSmMode::EWeapon::Rocket, False); | |
declare PlayerSpawn <=> Map::GetPlayerSpawn("Spawn", Player.CurrentClan); | |
if (PlayerSpawn != Null) SM::SpawnPlayer(Player, Player.CurrentClan, 200, PlayerSpawn, Now); | |
} | |
} | |
WarmUp2::Loop(); | |
WarmUp2::ManageEvents(); | |
if (PrevWarmUpDuration != S_WarmUpDuration || PrevAllowUnbalancedTeams != S_AllowUnbalancedTeams) { | |
PrevWarmUpDuration = S_WarmUpDuration; | |
PrevAllowUnbalancedTeams = S_AllowUnbalancedTeams; | |
declare LongTimer = S_WarmUpDuration*1000; | |
declare ShortTimer = 5000; | |
if (LongTimer <= 0) { LongTimer = 0; ShortTimer = 0; } | |
if (S_AllowUnbalancedTeams) { | |
WarmUp2::SetGroupTimers("Clan1", [ShortTimer => [-1, 1], LongTimer => [1, 1]]); | |
WarmUp2::SetGroupTimers("Clan2", [ShortTimer => [-1, 1], LongTimer => [1, 1]]); | |
} else { | |
WarmUp2::SetGroupTimers("Clan1", [ShortTimer => [-1, S_Script_NbPlayersPerTeam], LongTimer => [1, S_Script_NbPlayersPerTeam]]); | |
WarmUp2::SetGroupTimers("Clan2", [ShortTimer => [-1, S_Script_NbPlayersPerTeam], LongTimer => [1, S_Script_NbPlayersPerTeam]]); | |
} | |
} | |
} | |
WarmUp2::End(); | |
WarmUp2::Clean(); | |
WarmUp2::Fill(); | |
declare PlayersOrder = [1 => WarmUp2::GetGroup("Clan1"), 2 => WarmUp2::GetGroup("Clan2")]; | |
declare AllowedPlayers = Ident[]; | |
for (I, 1, 2) { | |
foreach (Slot => PlayerId in PlayersOrder[I]) { | |
AllowedPlayers.add(PlayerId); | |
} | |
} | |
// Init players | |
foreach (Player in Players) { | |
if (AllowedPlayers.exists(Player.Id)) { | |
declare ValidPlayer for Player = False; | |
ValidPlayer = True; | |
} else { | |
declare ValidPlayer for Player = False; | |
ValidPlayer = False; | |
} | |
} | |
SM::UnspawnAllPlayers(); | |
MM_Sleep(3000); | |
ObjectDestroyAll(); | |
UIManager.UIAll.BigMessage = ""; | |
UIManager.UIAll.StatusMessage = ""; | |
UIManager.UIAll.UISequence = PrevSequence; | |
XmlRpc::EndWarmUp(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment