Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Mode Battle & Battle Waves
- */
- #Extends "Modes/ShootMania/ModeMatchmaking.Script.txt"
- #Const CompatibleMapTypes "BattleArena"
- #Const Version "2014-11-26"
- #Const ScriptName "Battle.Script.txt"
- #Include "MathLib" as MathLib
- #Include "TextLib" as TextLib
- #Include "Libs/Nadeo/Victory.Script.txt" as Victory
- #Include "Libs/Nadeo/Interface.Script.txt" as Interface
- #Include "Libs/Nadeo/TabsServer.Script.txt" as Tabs
- #Include "Libs/Nadeo/Top2.Script.txt" as Top
- #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/BalancedWeapons.Script.txt" as BalancedWeapons
- #Include "Libs/Nadeo/ShootMania/BeginnersWelcome.Script.txt" as Beginners
- #Include "Libs/Nadeo/ShootMania/WarmUp2.Script.txt" as WarmUp2
- // ---------------------------------- //
- // Settings
- // ---------------------------------- //
- #Setting S_RespawnTime 6001 as "<hidden>" //_("Respawn time") ///< Time before respawn
- #Setting S_RoundsToWin 2 as _("Rounds to win") ///< Number of rounds to win a map
- #Setting S_RoundGapToWin 1 as _("Round gap to win") ///< Minimum gap between the two leaders to win a map
- #Setting S_RoundsLimit 3 as _("Rounds limit") ///< Point limit on map
- #Setting S_TimeLimit 300 as "<hidden>" //_("Time limit (seconds)")///< Time limit (seconds)
- #Setting S_UseOvertime True as _("Use overtime") ///< Activate the overtime system
- #Setting S_CaptureMaxValue 30000 as _("Capture time (milliseconds)") ///< Pole capture time (milliseconds)
- #Setting S_AlternativePoints False as "<hidden>" //_("Use atk and def points as score")
- #Setting S_AllowBeginners False as "<hidden>" //_("Is a Beginners Welcome server")
- //#Setting S_AutoManageAFK True as _("Switch inactive players to spectators")
- #Setting S_ArmorPoints 2 as _("Armor points")
- #Setting S_WarmUpDuration 0 as _("Warm up duration (sec.)") ///< Duration of the warm up round (0 = no warmup)
- #Setting S_NbPlayersPerTeamMax 0 as "<hidden>" //_("Maximum number of players per team (0: no max)") ///< Do not spawn players beyond this limit, 0=no limit
- #Setting S_NbPlayersPerTeamMin 1 as "<hidden>" //_("Minumum number of players per team") ///< Wait until this minimum is reach
- // Waves Settings
- #Setting S_BattleWaves True as "<hidden>" //_("Use Waves Mode")
- #Setting S_TimeLimitForFirstCapture 300 as _("Time limit for first capture") // en s
- #Setting S_TimeLimitAfterFirstCapture 600 as _("Time limit after first capture") // en s
- #Setting S_WaveDuration 15 as _("Wave duration") // en s
- #Setting S_StayInAttackOnCapture True as _("Reset timer when a pole is beeing captured")
- #Setting S_GladiatorMode False as "<hidden>" ///< Give bonus on hit
- // Clublinks settings
- #Setting S_UsePlayerClublinks True as "<hidden>" //_("Use players clublinks") ///< Use the players clublinks, or otherwise use the default teams
- #Setting S_ForceClublinkTeam1 "" as "<hidden>" ///< Force the Clublink of team 1 (format: http://www.example.com/MyTeam.Club.xml)
- #Setting S_ForceClublinkTeam2 "" as "<hidden>" ///< Force the Clublink of team 2 (format: http://www.example.com/MyTeam.Club.xml)
- // UI setting
- #Setting S_DisplayTopsRound True as _("Display the tops at the end of the round")
- #Setting S_DisplayTopsMap True as _("Display the tops at the end of the map")
- #Setting S_DisplayTopsOnlyShooter False as "<hidden>" //_("Only display the shooter top")
- #Setting S_DisplayPoleRecords True as _("Display pole running time record")
- // Auto balance
- #Setting S_AutoBalance True as _("Use map autobalance") ///< Use auto balance at the start of the map
- #Setting S_AutoBalanceRound True as _("Use round autobalance") ///< Use auto balance at the end of the round
- #Setting S_AutoBalanceDelta 2 as _("Maximum clan players number difference") ///< Maximum difference of players number before autobalance
- // Score Constants (used to be settings)
- #Const S_HotSpotsRadius 20.
- #Const S_AtkHotSpotsRadius 4.
- #Const S_ScoreDefense_HitOnPole 3
- #Const S_ScoreDefense_HitNearPole 3
- #Const S_ScoreAttack_HitNearPole 2
- #Const S_ScoreAttack_ClassicHit 1
- #Const S_PointsPerPole 10.
- #Const S_DefPointOnDenyForOnePole 20.
- #Const S_ScoreDefense_CaptureJiT 1 //as _("Defense points granted for a Just In Time capture")
- #Const S_PointsOnEngage 1 //as _("Attack points granted for the engage pole")
- // round phases for UI
- #Const C_RoundPhase_Playing 1
- #Const C_RoundPhase_EndRound 2
- #Const S_ResetTimeOnCapturedPole False
- #Const C_ImgBaseDir "file://Media/Manialinks/Shootmania/Common/"
- #Const UITickPeriod 200
- #Const C_JustInTimeLimit 3000 //milli sec.
- #Const C_NoCollisionsDuration 6000 ///< No collision duration at the beginning of the round
- #Const C_Top5SequenceDuration 10000 ///< Duration of the top 5 sequence at the end of the round and the map
- #Const C_MinimumExtendedTime 30000 ///< Minimum duration of the extended time
- #Const C_PoleCaptureState_Neutral 0
- #Const C_PoleCaptureState_Capturing 1
- #Const C_PoleCaptureState_Captured 2
- #Const C_PoleCaptureState_Protected 3
- #Const C_PoleCaptureState_Locked 4
- #Const C_PoleCaptureState_Denied 5
- #Const C_TopId_Hit "HIT"
- #Const C_TopId_Capture "CAPTURE"
- #Const C_TopId_Defense "DEFENSE"
- #Const C_TopId_Attack "ATTACK"
- #Const C_TopId_Combo "COMBO"
- #Const C_SlideId_Attack 0
- #Const C_SlideId_Defense 1
- #Const C_SlideId_Combo 3
- #Const Description _("TYPE: Team versus Team\nOBJECTIVE:\nCapture all the poles of the opposing team before the end of the time limit.\nIn Waves mode you can only capture when your team is in attack.\nThe team with the more poles at the end of the round scores 1 point. If
- this team reaches the points limit she wins the map.")
- #Const C_DisplayRulesReminder True
- #Const C_Battle_BlueBots 0
- #Const C_Battle_RedBots 0
- declare Text G_ScoreTeam1;
- declare Text G_ScoreTeam2;
- declare Integer[Ident] G_PolesIndice;
- declare Ident G_EngagePoleId;
- declare Ident G_LayerRoundInfoId;
- declare Ident G_TimeLeftLayerId;
- declare Integer G_CurrentRoundIndex;
- declare Integer G_CaptureMaxValue;
- declare CSmMapLandmark[Integer] G_ClanSpawnAnchors;
- declare Boolean G_OvertimeActivated;
- declare Integer G_OvertimeAdvantage;
- ***LogVersion***
- ***
- MB_LogVersion(ScriptName, Version);
- MB_LogVersion(SM::GetScriptName(), SM::GetScriptVersion());
- MB_LogVersion(Top::GetScriptName(), Top::GetScriptVersion());
- MB_LogVersion(Score::GetScriptName(), Score::GetScriptVersion());
- MB_LogVersion(Layers::GetScriptName(), Layers::GetScriptVersion());
- MB_LogVersion(Victory::GetScriptName(), Victory::GetScriptVersion());
- MB_LogVersion(WarmUp2::GetScriptName(), WarmUp2::GetScriptVersion());
- MB_LogVersion(Interface::GetScriptName(), Interface::GetScriptVersion());
- MB_LogVersion(Tabs::GetScriptName(), Tabs::GetScriptVersion());
- MB_LogVersion(SpawnScreen::GetScriptName(), SpawnScreen::GetScriptVersion());
- MB_LogVersion(BalancedWeapons::GetScriptName(), BalancedWeapons::GetScriptVersion());
- MB_LogVersion(Beginners::GetScriptName(), Beginners::GetScriptVersion());
- ***
- ***LobbyStartServer***
- ***
- MM_SetFormat([S_NbPlayersPerTeamMax, S_NbPlayersPerTeamMax]);
- if (S_NbPlayersPerTeamMax > S_NbPlayersPerTeamMin) {
- declare Formats = Integer[][];
- for (I, S_NbPlayersPerTeamMin, S_NbPlayersPerTeamMax-1) {
- if (I > 0) Formats.add([I, I]);
- }
- MM_SetProgressiveFormats(Formats);
- }
- ***
- ***InitServer***
- ***
- declare IsRematch = False; ///< Do the players want a rematch ?
- declare RematchNb = 0; ///< Number of consecutive rematch
- ***
- ***Reinit***
- ***
- //MB_UseLogging = True;
- ---LoadBeginnersLib---
- // Set mode options
- UseClans = True;
- MB_UseSectionRound = True;
- MB_UsePlayerClublinks = S_UsePlayerClublinks;
- // Set UIAll settings
- UIManager.UIAll.ScreenIn3dHideScoreSummary=True;
- UIManager.UIAll.AltMenuNoCustomScores = True;
- UIManager.UIAll.AltMenuNoDefaultScores = True;
- // Init variables
- G_CurrentRoundIndex = 0;
- // Create various layers for the UI :
- // * ScoresTable - the custom scores table
- // * Tops - the tops (in a sperate tab)
- // * LayerRoundInfo - infos about the game always shown in the UI (e.g. captured poles, capture state, etc.).
- // * LayerMarkers - markers above poles
- // * TabsLayer - A layer for the tabs and tabs management
- // /////////
- // Tops
- Top::Load();
- declare Real TopXPosition = -76.;
- declare Real TopYPosition = 31.;
- declare Real TopXOffset = 38.;
- declare Integer NbPlayersPerTop = 12;
- declare Text TopBGImg = C_ImgBaseDir^"topsBg.dds";
- Top::SetTopWidth(37.);
- Top::SetDefaultTitle();
- Top::Create(C_TopId_Hit, _("Hit"), NbPlayersPerTop, <TopXPosition, TopYPosition>);
- TopXPosition += TopXOffset;
- Top::Create(C_TopId_Capture, _("Capture"), NbPlayersPerTop, <TopXPosition, TopYPosition>);
- TopXPosition += TopXOffset;
- Top::Create(C_TopId_Defense, _("Defense"), NbPlayersPerTop, <TopXPosition, TopYPosition>);
- TopXPosition += TopXOffset;
- Top::Create(C_TopId_Attack, _("|Substantive|Attack"), NbPlayersPerTop, <TopXPosition, TopYPosition>);
- TopXPosition += TopXOffset;
- Top::Create(C_TopId_Combo, "Combo", NbPlayersPerTop, <TopXPosition, TopYPosition>);
- Top::SetCommonBackgroundImage(TopBGImg, <0.05, 95.75>, <207., 175.75>);
- Top::SetLayerType(CUILayer::EUILayerType::AltMenu);
- // /////////
- // Round info
- declare LayerRoundInfo <=> UIManager.UILayerCreate();
- G_LayerRoundInfoId = LayerRoundInfo.Id;
- // This layer is added at the beginning of each round
- // /////////
- // Markers
- declare LayerMarkers <=> UIManager.UILayerCreate();
- LayerMarkers.Type = CUILayer::EUILayerType::Markers;
- UIManager.UIAll.UILayers.add(LayerMarkers);
- // /////////
- // Tabs
- Tabs::Load();
- /*
- declare TabsLayer <=> Tabs::CreateTabPaneLayer(
- [
- "TopTab" => "Buddies",
- "ScoresTab" => "Rankings"
- ], 7, -1, False);
- */
- declare TabsLayer <=> Tabs::CreateTabPaneLayer(
- [
- "TopTab" => "Buddies",
- "ScoresTab" => "Rankings"
- ], 29, -5, False);
- TabsLayer.Type = CUILayer::EUILayerType::AltMenu;
- UIManager.UIAll.UILayers.add(TabsLayer);
- declare CUILayer TimeLeftLayer;
- declare Ident G_TimeLeftLayerId;
- if(S_BattleWaves) {
- TimeLeftLayer <=> UIManager.UILayerCreate();
- G_TimeLeftLayerId = TimeLeftLayer.Id;
- }
- CreateRulesReminderLayer();
- ***
- ***StartServer***
- ***
- WarmUp2::Load();
- // ---------------------------------- //
- // Matchmaking mode
- if (MM_IsMatchServer()) {
- MM_Init([S_NbPlayersPerTeamMax, S_NbPlayersPerTeamMax]);
- }
- +++Reinit+++
- ---ScoresTable---
- AFK::SetIdleTimeLimit(30000);
- // ---------------------------------- //
- // Create layers
- Layers::Create("Top5", GetMLTop5());
- Layers::Attach("Top5");
- Layers::Hide("Top5");
- ***
- ***ScoresTable***
- ***
- ST2::SetStyle("LibST_SMBaseTeams");
- ST2::SetStyle("LibST_SMBasePoints");
- ST2::SetStyle("LibST_SMWithLegends");
- ST2::CreateCol("Capture", _("|Capture,Substantive|Cap"), "0", 3., 60.);
- ST2::CreateCol("Attack", _("|Attack,Substantive|Atk"), "0", 3., 70.);
- ST2::CreateCol("Defense", _("|Defense|Def"), "0", 3., 80.);
- ST2::SetColLegend("LibST_SMRoundPoints", _("|Substantive|Hit"));
- ST2::SetColLegend("LibST_SMPoints", _("Score"));
- MM_SetScoresTableStyleFromXml(S_ScoresTableStylePath);
- ST2::GetLayer().Type = CUILayer::EUILayerType::Normal;
- ST2::Build("SM");
- ***
- ***LoadBeginnersLib***
- ***
- // TODO : sperate beginners for Battle/waves ?
- if(S_BattleWaves) {
- Beginners::Load("Nadeo_Battle");
- Beginners::CreateWelcomeWindow(TextLib::Compose(_("Welcome to Battle!")), TextLib::Compose(_("Capture the $<$0f0poles$> to win.\nYou cannot capture during $<$0f0defense$> phases."), TextLib::ToText(S_WaveDuration), TextLib::ToText(S_RoundsToWin)));
- } else {
- Beginners::Load("Nadeo_Battle");
- Beginners::CreateWelcomeWindow(TextLib::Compose(_("Welcome to Battle!")), TextLib::Compose(_("Capture the $<$0f0poles$> to win.")));
- }
- ***
- // ---------------------------------- //
- // Match begin
- // ---------------------------------- //
- ***StartMatch***
- ***
- // Init libs
- Score::MatchBegin(False);
- BalancedWeapons::MatchBegin();
- Victory::MatchBegin();
- Mode::Ladder_OpenMatch_All();
- G_PolesIndice = Integer[Ident];
- +++MatchBegin+++
- // Reset clan scores
- ClanScores[1] = 0;
- ClanScores[2] = 0;
- ***
- // ---------------------------------- //
- // Map begin
- // ---------------------------------- //
- ***InitMap***
- ***
- if (MM_IsMatchServer()) MB_UseIntro = False;
- else MB_UseIntro = True;
- ***
- ***StartMap***
- ***
- MM_SetScores([ClanScores[1], ClanScores[2]]);
- G_CurrentRoundIndex = 0;
- Users_SetNbFakeUsers(C_Battle_BlueBots, C_Battle_RedBots); // add bots for debug purpose
- ComputeCaptureMaxValue();
- ResetMapRunnersRanking();
- foreach (Score in Scores) {
- Score.Clear();
- declare Integer Battle_ScoreDefenseBonus for Score;
- declare Integer Battle_ScoreAttackBonus for Score;
- declare Integer Battle_ScoreAlternative for Score;
- declare Integer Battle_ScoreHit for Score;
- declare Integer Battle_TotalCaptureTime for Score;
- declare Integer Battle_TotalDenyTime for Score;
- Battle_ScoreDefenseBonus = 0;
- Battle_ScoreAttackBonus = 0;
- Battle_ScoreAlternative = 0;
- Battle_ScoreHit = 0;
- Battle_TotalCaptureTime = 0;
- Battle_TotalDenyTime = 0;
- Score.Points = 0;
- Score.RoundPoints = 0;
- }
- foreach (Player in AllPlayers) {
- declare Integer MapHit for Player = 0;
- declare Integer MapCombo for Player = 0;
- declare Integer MapCapture for Player = 0;
- declare Integer MapDefense for Player = 0;
- declare Integer MapAttack for Player = 0;
- MapHit = 0;
- MapCombo = 0;
- MapCapture = 0;
- MapDefense = 0;
- MapAttack = 0;
- declare Integer Battle_RoundIndex for Player.Score = -1;
- Battle_RoundIndex = 0;
- declare Integer RoundCombo for Player = 0;
- RoundCombo = 0;
- declare Integer Battle_ScoreCapture for Player;
- declare Integer Battle_ScoreDefense for Player;
- declare Integer Battle_ScoreAttack for Player;
- Battle_ScoreCapture = 0;
- Battle_ScoreDefense = 0;
- Battle_ScoreAttack = 0;
- declare Battle_BalanceClan for Player = -1;
- Battle_BalanceClan = -1;
- InitializePlayer(Player, "");
- }
- SpawnScreen::CreateMapInfo();
- SpawnScreen::SetModeName("Battle");
- SpawnScreen::CreateScores("Score.Points + Score.RoundPoints");
- Top::ResetAll();
- InitWarmUp();
- // ---------------------------------- //
- // Wait players when using matchmaking
- // ---------------------------------- //
- // Wait players when using matchmaking
- if (MM_IsMatchServer()) {
- if (!IsRematch) {
- MM_MatchWait();
- MM_VoteForNextMap(True);
- } else {
- MM_WaitPlayers(15000);
- }
- } else if (S_WarmUpDuration > 0 && S_NbPlayersPerTeamMax > 0) {
- MB_CurrentSection = "WarmUp";
- DoWarmUp();
- MB_CurrentSection = "StartMap";
- } else {
- MB_CurrentSection = "WarmUp";
- WaitForPlayers(S_NbPlayersPerTeamMin, S_WarmUpDuration);
- MB_CurrentSection = "StartMap";
- // Team balance
- if (S_AutoBalance && !MM_IsMatchmakingServer()) Mode::AutoTeamBalance();
- }
- IsRematch = False;
- // ---------------------------------- //
- // Matchmaking : allow substitutes
- if (MM_IsMatchServer()) MM_AllowSubstitutes(True);
- MM_SetScores([ClanScores[1], ClanScores[2]]);
- // ---------------------------------- //
- // Create tops slider
- Interface::CreateSlider();
- Interface::SetSliderAnimation(<-208., 40.>, <-160., 40.>);
- //Interface::AddSlide(C_SlideId_Attack, "Top", _("|Battle Top5 Attack|Top Attack"), C_TopId_Attack);
- //Interface::AddSlide(C_SlideId_Defense, "Top", _("|Battle Top5 Defense|Top Defense"), C_TopId_Defense);
- Interface::AddSlide(C_SlideId_Combo, "Top", _("|Top5 hits combo|Top Combo"), C_TopId_Combo);
- ***
- // ---------------------------------- //
- // Round initalization
- // ---------------------------------- //
- ***InitRound***
- ***
- declare Boolean RoundBattleWaves = S_BattleWaves;
- declare CaptureOngoing = False;
- declare TouchdownUserId = NullId;
- declare FinalCaptureUserId = NullId;
- declare OvertimeCaptureUserId = NullId;
- declare ExtendedTimeRatio = 0.5;
- SetOvertime(False);
- SetOvertimeAdvantage(-1);
- declare UpdateLayerScoresTable = False; ///< The scores table UI need an update
- declare ClanPoles = [1=>CSmMapLandmark[], 2=>CSmMapLandmark[]];
- declare MapSidesIndices = [1=>(MB_SectionRoundNb % 2)+1, 2=>2-(MB_SectionRoundNb % 2)];
- G_ClanSpawnAnchors = [
- 1=>Map::GetLandmarkPlayerSpawn("Spawn", MapSidesIndices[1]),
- 2=>Map::GetLandmarkPlayerSpawn("Spawn", MapSidesIndices[2])
- ];
- declare LastestCapturedGoalId = NullId;
- declare FirstClanToStartCapture = 0;
- declare LatestUITick = Now;
- ComputeCaptureMaxValue();
- G_EngagePoleId = NullId;
- for (Clan, 1, 2) {
- foreach (Pole in MapLandmarks_Gauge) {
- if((Pole.Tag == "Goal") || (Pole.Tag == "Checkpoint")) { // for retro-compatibility
- if((Pole.Order == 3) && (G_EngagePoleId == NullId)) { // Engage Pole
- G_EngagePoleId = Pole.Id;
- Pole.Gauge.Clan = 0;
- } else {
- if (Pole.Order != MapSidesIndices[Clan]) continue;
- ClanPoles[Clan].add(Pole);
- Pole.Gauge.Value = 0;
- Pole.Gauge.Max = G_CaptureMaxValue;
- Pole.Gauge.Clan = 3-Clan;
- }
- }
- }
- }
- declare Integer NbPolesByClan = ClanPoles[1].count;
- // ////////////////////////////
- // INITIALIZE MARKERS
- // build Markers list
- declare Text PoleMarkers = "";
- foreach(Pole in MapLandmarks_Gauge) {
- if (Pole.Tag != "Goal" && Pole.Tag != "Checkpoint") continue;
- declare Vec3 Pos = Pole.Position + <0., 25., 0.>;
- if(Pole.Gauge.Clan == 0) {
- Pos.Y = Pole.Position.Y + 5.; // only 5 meters for the engage checkpoint
- }
- PoleMarkers ^= """<marker pos="{{{Pos.X}}} {{{Pos.Y}}} {{{Pos.Z}}}" manialinkframeid="PoleMarker{{{Pole.Id}}}"/>
- """;
- }
- // build Pole indice
- for (Clan, 1, 2) {
- declare Integer PoleIndex = 0;
- foreach (Pole in ClanPoles[Clan])
- {
- PoleIndex += 1;
- G_PolesIndice[Pole.Id] = PoleIndex;
- }
- }
- // ////////////////////////////
- declare NumberOfCapturedPoles = [1 => 0,2 => 0];
- declare TotalCaptureValue = [1 => 0,2 => 0];
- declare Real SqDistanceToScoreNearPole = S_HotSpotsRadius * S_HotSpotsRadius;
- declare Real SqDistanceAtkNearPole = S_AtkHotSpotsRadius * S_AtkHotSpotsRadius;
- declare Boolean DoUpdateScore = True;
- declare Boolean[Ident] PoleTakers = Boolean[Ident]; // Emulates a Set (collection of unique elements - the boolean value is never read)
- declare Boolean[Ident] PoleDeniers = Boolean[Ident];
- // for Waves Mode
- declare FirstWaveClanAttack = 0;
- declare DurationBeforePivot = 0;
- declare CurrentAckClan = 0;
- declare FirstWaveStartTime = -1;
- declare WavesDuration = S_WaveDuration; // Waves durations can only be changed between rounds.
- declare Boolean AllowBeginners = S_AllowBeginners;
- declare Integer NoCollisionsEndTime;
- ***
- // ---------------------------------- //
- // Round begin
- // ---------------------------------- //
- ***StartRound***
- ***
- G_CurrentRoundIndex += 1;
- UIManager.UIAll.UISequence = CUIConfig::EUISequence::Playing;
- UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
- Score::RoundBegin();
- BalancedWeapons::RoundBegin();
- Victory::RoundBegin();
- +++RoundBegin+++
- SM::SetupDefaultVisibility();
- // the countdown
- //UIManager.UIAll.CountdownCoord.Y = C_CountdownY;
- //UIManager.UIAll.CountdownCoord.X = 0.;
- StartTime = Now + S_RespawnTime;
- ---EndTime---
- // No collisions at the beginning of the round
- NoCollisionsEndTime = StartTime + C_NoCollisionsDuration;
- UsePvPCollisions = False;
- UpdateBasesColors();
- // ---------------------------------- //
- // Init capture time records
- declare Text EngageLogin for This;
- EngageLogin = "";
- declare netwrite Integer[Text] Net_RoundTop_CaptureTimeRecords for Teams[0];
- declare netwrite Integer Net_RoundTop_CaptureTimeRecordsUpdate for Teams[0];
- Net_RoundTop_CaptureTimeRecords.clear();
- Net_RoundTop_CaptureTimeRecordsUpdate = Now;
- foreach (Score in Scores) {
- declare Integer[Ident] RoundTop_CaptureTime for Score;
- RoundTop_CaptureTime.clear();
- declare Integer Battle_ScoreCombo for Score;
- Battle_ScoreCombo = 0;
- }
- foreach (Player in AllPlayers) {
- declare Integer RoundCombo for Player = 0;
- RoundCombo = 0;
- InitializePlayer(Player, PoleMarkers);
- }
- // ---------------------------------- //
- // Update the players clublinks
- if (S_ForceClublinkTeam1 == "" && S_ForceClublinkTeam2 == "") Clublink::DefineTeamAuto();
- else Clublink::DefineTeamFromUrl(S_ForceClublinkTeam1, S_ForceClublinkTeam2);
- Clublink::SyncUpdate();
- MM_Sleep(1);
- CreateRoundInfoUI(LayerRoundInfo, ClanPoles);
- UIManager.UIAll.UILayers.add(LayerRoundInfo);
- // Set markers layer
- LayerMarkers.ManialinkPage = CreateMarkersManialinkPage(ClanPoles);
- LayerMarkers.IsVisible = True;
- // Update the rules now, if a change occured in the settings
- ---Rules---
- SpawnScreen::CreateRules(ModeName, ModeRules);
- // +++UpdateScore+++
- ---UpdateTotalCapture---
- ---UpdateTeamsScoresUI---
- if(S_BattleWaves) {
- if(TimeLeftLayer == Null) TimeLeftLayer <=> UIManager.UILayerCreate();
- TimeLeftLayer.ManialinkPage = BuildTimeLeftManialink(WavesDuration);
- UIManager.UIAll.UILayers.add(TimeLeftLayer);
- }
- ST2::SetFooterText(TextLib::Compose("%1 "^S_RoundsToWin, _("Points limit : ")));
- ***
- ***OnNewPlayer***
- ***
- InitializePlayer(Player, PoleMarkers);
- // Show welcome window to beginners
- if(S_AllowBeginners) {
- Beginners::NotifyNewPlayer(Player);
- }
- if (Now > StartTime + 10) UpdateLayerScoresTable = True;
- Interface::ShowSlider(Player, 0);
- ***
- ***OnNewSpectator***
- ***
- InitializePlayer(Spectator, PoleMarkers);
- if (Now > StartTime + 10) UpdateLayerScoresTable = True;
- Interface::ShowSlider(Spectator, 0);
- ***
- ***Yield***
- ***
- Top::Loop();
- Message::Loop();
- Tabs::XmlRpcLoop();
- ***
- // ---------------------------------- //
- // Play loop
- // ---------------------------------- //
- ***PlayLoop***
- ***
- if(S_BattleWaves != RoundBattleWaves) {
- MB_StopMatch = True;
- ResetAllUIs();
- +++Reinit+++
- break;
- }
- if(AllowBeginners != S_AllowBeginners) {
- Beginners::ResetPlayers();
- MB_StopMatch = True;
- }
- CaptureOngoing = False;
- OvertimeCaptureUserId = NullId;
- // No collisions
- if (NoCollisionsEndTime > 0 && NoCollisionsEndTime <= Now) {
- NoCollisionsEndTime = -1;
- UsePvPCollisions = True;
- }
- // for each players
- foreach (Player in Players) {
- if (Player.CurrentClan == CurrentAckClan)
- if (Player.CurWeapon != 1) SetPlayerWeapon(Player, CSmMode::EWeapon::Laser, False);
- if (Player.CurrentClan != CurrentAckClan)
- if (Player.CurWeapon != 2 && Player.IsOnTeachWeapon) SetPlayerWeapon(Player, CSmMode::EWeapon::Rocket, True);
- }
- foreach (Event in PendingEvents) {
- if (Event.Type == CSmModeEvent::EType::OnHit) {
- if (Event.Shooter == Null || Event.Victim == Null || Event.Shooter == Event.Victim) {
- Discard(Event);
- } else if (UseClans && Event.Shooter.CurrentClan == Event.Victim.CurrentClan) {
- Discard(Event);
- } else {
- if(S_AllowBeginners) {
- Event.Damage = Beginners::GetDamage(Event.Shooter, Event.Victim, Event.Damage);
- }
- if (Event.Damage > 0) {
- declare CSmPlayer Victim <=> Event.Victim;
- declare CSmPlayer Shooter <=> Event.Shooter;
- if(S_AllowBeginners) Beginners::NotifyHit(Shooter);
- declare Boolean GivePoints = (!S_AllowBeginners) || Beginners::ShouldGivePoints(Shooter, Victim);
- if(! GivePoints) {
- Event.ShooterPoints = 0;
- XmlRpc::OnHit(Event);
- PassOn(Event);
- continue;
- }
- // declare Boolean GiveExraPointsForDefenseActions = True;
- declare Integer PointsGivenToTheShooter = 1;
- declare Integer Battle_ScoreHit for Shooter.Score;
- declare CustomScorePlayer <=> Shooter;
- ---OnHit---
- // Score::AddPoints(Shooter, PointsGivenToTheShooter);
- declare Integer Battle_ScoreDefenseBonus for Shooter.Score;
- declare Integer Battle_ScoreAttackBonus for Shooter.Score;
- Battle_ScoreHit += PointsGivenToTheShooter;
- // Combo
- declare Integer Battle_ScoreCombo as ComboShooter for Shooter.Score;
- declare Integer Battle_ScoreCombo as ComboVictim for Victim.Score;
- declare Integer MapCombo for Shooter;
- declare Integer RoundCombo for Shooter;
- ComboShooter += 1;
- ComboVictim = 0;
- if (ComboShooter > MapCombo) MapCombo = ComboShooter;
- if (ComboShooter > RoundCombo) RoundCombo = ComboShooter;
- declare Boolean BonusGranted = False;
- // 1. Check if the victim is currently taking a pole
- if( Victim.CapturedLandmark != Null && Victim.CapturedLandmark.Gauge != Null) {
- declare CSmMapLandmark Pole <=> Victim.CapturedLandmark;
- declare Boolean IsPoleActive = ! Pole.Gauge.Captured;
- ---IsPoleActive---
- if((IsPoleActive) && (Victim.CapturedLandmark.Gauge.Clan == Victim.CurrentClan)) {
- // Defensive move : the victim has been shot while taking a pole
- Battle_ScoreDefenseBonus += S_ScoreDefense_HitOnPole;
- BonusGranted = True;
- }
- }
- // 2. Check if the victim or the shooter is in a hot spot
- if (! BonusGranted) {
- foreach(Pole in MapLandmarks_Gauge) {
- if (Pole.Tag != "Goal" && Pole.Tag != "Checkpoint") continue;
- declare Boolean IsPoleActive = ! Pole.Gauge.Captured;
- ---IsPoleActive---
- if(IsPoleActive) {
- declare Boolean ShooterInDefHotSpot = SqCloserThan(Pole.Position, Shooter.Position, SqDistanceToScoreNearPole);
- declare Boolean VictimInDefHotSpot = SqCloserThan(Pole.Position, Victim.Position , SqDistanceToScoreNearPole);
- if(ShooterInDefHotSpot || VictimInDefHotSpot) {
- if(Pole.Gauge.Clan == 3-Shooter.CurrentClan) {
- // Defensive Move : the shooter is close to a pole of his/her clan
- Battle_ScoreDefenseBonus += S_ScoreDefense_HitNearPole;
- declare CustomScorePlayer <=> Shooter;
- BonusGranted = True;
- break;
- }
- }
- declare Boolean ShooterInAtkHotSpot = SqCloserThan(Pole.Position, Shooter.Position, SqDistanceAtkNearPole);
- declare Boolean VictimInAtkHotSpot = SqCloserThan(Pole.Position, Victim.Position , SqDistanceAtkNearPole);
- if(ShooterInAtkHotSpot || VictimInAtkHotSpot) {
- if(Pole.Gauge.Clan == Shooter.CurrentClan) {
- // Offensive Move : the victim is close to a pole of his/her clan
- Battle_ScoreAttackBonus += S_ScoreAttack_HitNearPole;
- declare CustomScorePlayer <=> Shooter;
- BonusGranted = True;
- break;
- }
- }
- }
- }
- if (! BonusGranted) {
- // 1 "classic" hit => Attack Points
- Battle_ScoreAttackBonus += S_ScoreAttack_ClassicHit;
- }
- }
- // Gladiator mode
- if (S_GladiatorMode) {
- if (Event.Shooter.Armor < Event.Shooter.ArmorMax) {
- Event.Shooter.Armor += 100;
- if (Event.Shooter.Armor > Event.Shooter.ArmorMax) {
- Event.Shooter.Armor = Event.Shooter.ArmorMax;
- }
- }
- }
- +++SetCustomScoreHit+++
- }
- XmlRpc::OnHit(Event);
- PassOn(Event);
- }
- } else if (Event.Type == CSmModeEvent::EType::OnArmorEmpty) {
- BalancedWeapons::OnOut(Event.Shooter, Event.Victim);
- XmlRpc::OnArmorEmpty(Event);
- Interface::ShowSlider(Event.Victim, 0);
- PassOn(Event);
- } else if (Event.Type == CSmModeEvent::EType::OnCapture) {
- if (Event.Landmark.Tag == "Goal") {
- UpdateBasesColors();
- LastestCapturedGoalId = Event.Landmark.Id;
- XmlRpc::OnCapture(Event);
- // Get last capturer user id
- foreach(PlayerId in Event.Landmark.Sector.PlayersIds) {
- if (!Players.existskey(PlayerId)) continue;
- declare Player <=> Players[PlayerId];
- if (Player.CurrentClan != Event.Landmark.Gauge.Clan) continue;
- FinalCaptureUserId = Player.User.Id;
- break;
- }
- }
- PassOn(Event);
- } else if (Event.Type == CSmModeEvent::EType::OnPlayerRequestRespawn) {
- Interface::ShowSlider(Event.Player, 0);
- PassOn(Event);
- } else {
- PassOn(Event);
- }
- }
- if(S_BattleWaves) {
- // Update atk countdown and switch atk side when it reaches 0
- if (FirstWaveClanAttack != 0) {
- DurationBeforePivot -= Period;
- if (DurationBeforePivot <= 0) {
- CurrentAckClan = 3-CurrentAckClan;
- DurationBeforePivot = WavesDuration * 1000; // redemarre la jauge.;
- UIManager.UIAll.SendNotice("", CUIConfig::ENoticeLevel::PlayerInfo, Null, CUIConfig::EAvatarVariant::Default,
- CUIConfig::EUISound::PhaseChange, 0);
- // G_UpdateMarkers = True;
- }
- }
- // Check engagement pole
- if(G_EngagePoleId != NullId && (CurrentAckClan==0)) {
- declare CSmMapLandmark EngagePole <=> MapLandmarks_Gauge[G_EngagePoleId];
- if(EngagePole != Null && ! EngagePole.Gauge.Captured) {
- declare EngageClan = -1;
- declare EngageName = "";
- declare Text EngageLogin for This;
- foreach(PlayerId in EngagePole.Sector.PlayersIds) {
- if (!Players.existskey(PlayerId)) continue;
- declare Player <=> Players[PlayerId];
- declare PlayerClan = Player.CurrentClan;
- if (EngageClan < 0) {
- EngageClan = PlayerClan;
- EngageName = Player.User.Name;
- EngageLogin = Player.User.Login;
- } else if (EngageClan != PlayerClan) {
- // 2 diff clans on the pole : no capture
- EngageClan = -1;
- EngageName = "";
- EngageLogin = "";
- break;
- }
- }
- if (EngageClan > 0) {
- EngagePole.Gauge.Max = 1;
- EngagePole.Gauge.Value = 1;
- EngagePole.Gauge.Captured = True;
- EngagePole.Gauge.Clan = 0;
- FirstClanToStartCapture = EngageClan;
- CurrentAckClan = EngageClan;
- FirstWaveClanAttack = EngageClan;
- FirstWaveStartTime = Now;
- EndTime = Now + S_TimeLimitAfterFirstCapture*1000;
- DurationBeforePivot = WavesDuration * 1000;
- //G_UpdateMarkers = True;
- UIManager.UIAll.SendNotice("", CUIConfig::ENoticeLevel::PlayerInfo, Null, CUIConfig::EAvatarVariant::Default,
- CUIConfig::EUISound::PhaseChange, 0);
- if (EngageName != "") Message::SendBigMessage(TL::Compose(_("$<%1$> captured the pole."), EngageName), 3000, 1);
- foreach(PlayerId in EngagePole.Sector.PlayersIds) {
- if (!Players.existskey(PlayerId)) continue;
- declare Player <=> Players[PlayerId];
- declare Integer Battle_ScoreAttackBonus for Player.Score;
- Battle_ScoreAttackBonus += S_PointsOnEngage;
- PoleTakers[PlayerId] = True;
- DoUpdateScore = True;
- }
- }
- }
- }
- }
- // Spawning players
- foreach (Player in Players) {
- if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned && !Player.User.RequestsSpectate) {
- // Skip invalid player in matchmaking
- if (MM_IsMatchServer() && !MM_PlayerIsValid(Player)) continue;
- // Set player clan
- SetPlayerClan(Player, Battle_GetRequestedClan(Player));
- if (SpawnIsLimited()) {
- WarmUp2::Clean();
- if (Player.CurrentClan == 1) WarmUp2::SetPlayerGroup(Player, "Clan1");
- else if (Player.CurrentClan == 2) WarmUp2::SetPlayerGroup(Player, "Clan2");
- WarmUp2::Fill();
- }
- if (!IsSpawnable(Player)) continue;
- //declare Integer ClublinkClan for Player;
- //if (ClublinkClan == 0) continue;
- BalancedWeapons::SetPlayerWeapon(Player, True);
- Player.ArmorMax = 200;
- declare Integer BaseArmor = 200;
- if(S_AllowBeginners) {
- Beginners::UpdateBeginnerStatus(Player);
- declare CUIConfig PlayerUI <=> UIManager.GetUI(Player);
- if(PlayerUI != Null) {
- declare netwrite Boolean Battle_IsBeginner for PlayerUI;
- Battle_IsBeginner = Beginners::IsBeginner(Player);
- }
- }
- // 1. get the difference between beginners and regular players
- declare Integer BeginnerExtraArmor = (Player.ArmorMax - BaseArmor) / 100;
- if(BeginnerExtraArmor <= 0) BeginnerExtraArmor = 0;
- // 2. get the armor setting in correct boundaries
- declare Integer ArmorSetting = S_ArmorPoints;
- if(ArmorSetting <= 0) ArmorSetting = 1;
- else if (ArmorSetting > 9) ArmorSetting = 9;
- // 3. compute armor for beginners-or-not
- declare Integer TotalArmorFactor = ArmorSetting + BeginnerExtraArmor;
- if(TotalArmorFactor > 9) TotalArmorFactor = 9;
- // 4. set it
- declare Integer TotalArmor = 100 * TotalArmorFactor;
- Player.ArmorMax = TotalArmor;
- Player.Armor = TotalArmor;
- // Reset combo
- declare Integer Battle_ScoreCombo for Player.Score;
- Battle_ScoreCombo = 0;
- // Reset touched poles
- declare Ident[] RoundTop_TouchedPoles for Player;
- RoundTop_TouchedPoles.clear();
- //If the player is in the clan who attack, apply a attackweapon
- if (Player.CurrentClan == CurrentAckClan)
- { SetPlayerWeapon(Player, CSmMode::EWeapon::Laser, False); Player.AmmoGain = 1.20; }
- else { SetPlayerWeapon(Player, CSmMode::EWeapon::Rocket, True); Player.AmmoGain = 1.; }
- SM::SpawnPlayer(Player, Player.CurrentClan, G_ClanSpawnAnchors[Player.CurrentClan].PlayerSpawn, Now + S_RespawnTime);
- Interface::HideSlider(Player, 5000);
- if(S_AllowBeginners) {
- Beginners::HighlightPlayer(Player);
- }
- declare AutoBalance_ReloadSpeedBonus for Player.User = 1.;
- Player.AmmoGain = AutoBalance_ReloadSpeedBonus;
- }
- }
- // Capturing points
- // set default state to neutral
- foreach (Player in Players) {
- declare UI <=> UIManager.GetUI(Player);
- if (UI != Null) {
- declare netwrite Integer Battle_PoleCaptureState for UI;
- Battle_PoleCaptureState = C_PoleCaptureState_Neutral;
- }
- }
- // check if a pole is beeing captured
- for (Clan, 1, 2) {
- // ---ContinueToSkipClan---
- declare Integer PoleIndex = -1;
- declare PolesOfClan = ClanPoles[Clan];
- foreach (Pole in PolesOfClan) {
- PoleIndex += 1;
- // This section is useful only if you want to give points to pole denial.
- declare IsGoalThreatened = False; // Is an attacker on the pole ?
- foreach (PlayerId in Pole.Sector.PlayersIds) {
- if (!Players.existskey(PlayerId)) continue;
- declare Player <=> Players[PlayerId];
- if (Player.CurrentClan != Clan) {
- IsGoalThreatened = True;
- break;
- }
- }
- if(!IsGoalThreatened) {
- Pole.Gauge.Speed = 0;
- continue;
- }
- declare IsGoalDenied = False;
- foreach (PlayerId in Pole.Sector.PlayersIds) {
- if (!Players.existskey(PlayerId)) continue;
- declare Player <=> Players[PlayerId];
- if (Player.CurrentClan == Clan) { // GoalClan
- IsGoalDenied = True;
- // Was
- //break;
- PoleDeniers[PlayerId] = True;
- declare Integer Battle_TotalDenyTime for Player.Score;
- Battle_TotalDenyTime += Period;
- DoUpdateScore = True; // fuu
- }
- }
- // Capture time record
- if (S_DisplayPoleRecords && Pole.Sector.PlayersIds.count > 0) {
- foreach (PlayerId in Pole.Sector.PlayersIds) {
- if (!Players.existskey(PlayerId)) continue;
- declare Player <=> Players[PlayerId];
- // We can only touch the poles of the opponent
- if (Player.CurrentClan == Clan) continue;
- declare Ident[] RoundTop_TouchedPoles for Player;
- if (RoundTop_TouchedPoles.exists(Pole.Id)) continue;
- RoundTop_TouchedPoles.add(Pole.Id);
- // Personnal best
- declare Integer[Ident] RoundTop_CaptureTime for Player.Score;
- declare CaptureTime = Now - Player.StartTime;
- if (RoundTop_CaptureTime.existskey(Pole.Id)) {
- if (CaptureTime < RoundTop_CaptureTime[Pole.Id]) {
- RoundTop_CaptureTime[Pole.Id] = CaptureTime;
- SendCaptureTime(Player);
- }
- } else {
- RoundTop_CaptureTime[Pole.Id] = CaptureTime;
- SendCaptureTime(Player);
- }
- // Round best
- declare netwrite Integer[Text] Net_RoundTop_CaptureTimeRecords for Teams[0];
- declare netwrite Integer Net_RoundTop_CaptureTimeRecordsUpdate for Teams[0];
- if (Net_RoundTop_CaptureTimeRecords.existskey(""^Pole.Id)) {
- if (CaptureTime < Net_RoundTop_CaptureTimeRecords[""^Pole.Id]) {
- Net_RoundTop_CaptureTimeRecords[""^Pole.Id] = CaptureTime;
- Net_RoundTop_CaptureTimeRecordsUpdate = Now;
- }
- } else {
- Net_RoundTop_CaptureTimeRecords[""^Pole.Id] = CaptureTime;
- Net_RoundTop_CaptureTimeRecordsUpdate = Now;
- }
- }
- }
- ---IsCapturePossible---
- if (IsCapturePossible && (Pole.Sector.PlayersIds.count > 0)) {
- declare Integer PoleGlobalIndex = ((Clan-1)*NbPolesByClan) + PoleIndex;
- declare NumberOfPlayerCapturing = 0;
- foreach (PlayerId in Pole.Sector.PlayersIds) {
- if (!Players.existskey(PlayerId)) continue;
- declare Player <=> Players[PlayerId];
- if (Player.CurrentClan == Clan) continue; // Opponent team only
- declare UI <=> UIManager.GetUI(Player);
- NumberOfPlayerCapturing += 1;
- OvertimeCaptureUserId = Player.User.Id;
- if (FirstClanToStartCapture == 0) {
- FirstClanToStartCapture = Player.CurrentClan;
- if(S_BattleWaves) {
- if(G_EngagePoleId == NullId) {
- CurrentAckClan = Player.CurrentClan;
- declare Integer Battle_ScoreAttackBonus for Player.Score;
- Battle_ScoreAttackBonus += S_PointsOnEngage;
- // it is ok to give points only to this player.
- // the case where more than 1 player take the pole at the same time is unlikely and invisible.
- // it is just bad luck for the other guys...
- }
- }
- }
- PoleTakers[PlayerId] = True;
- if (Pole.Gauge.Value < G_CaptureMaxValue) {
- declare Integer Battle_TotalCaptureTime for Player.Score;
- Battle_TotalCaptureTime += Period;
- if (UI != Null) {
- declare netwrite Integer Battle_PoleCaptureState for UI;
- declare netwrite Integer Battle_PoleCaptureRate for UI;
- Battle_PoleCaptureState = C_PoleCaptureState_Capturing;
- Battle_PoleCaptureRate = (100 * Pole.Gauge.Value) / G_CaptureMaxValue;
- }
- } else {
- if (UI != Null) {
- declare netwrite Integer Battle_PoleCaptureState for UI;
- Battle_PoleCaptureState = C_PoleCaptureState_Captured;
- }
- }
- }
- +++Capturing+++
- Pole.Gauge.Speed = NumberOfPlayerCapturing;
- if (NumberOfPlayerCapturing > 0) {
- DoUpdateScore = True;
- if (!Pole.Gauge.Captured) {
- CaptureOngoing = True;
- }
- }
- } else {
- Pole.Gauge.Speed = 0;
- ---OnCaptureDenied---
- }
- }
- }
- // Overtime, disadvantaged clan touch an active pole, stop countdown decrease
- if (GetOvertimeAdvantage() != CurrentAckClan) {
- if (CaptureOngoing) {
- DurationBeforePivot += Period;
- }
- }
- if (Now >= EndTime) DoUpdateScore = True;
- // Update UI
- if (Now > LatestUITick + UITickPeriod)
- {
- LatestUITick = Now;
- // Clublink::DefineTeamAuto();
- ---UpdateTeamsScoresUI---
- foreach (Player in Players) {
- declare UI <=> UIManager.GetUI(Player);
- if (UI==Null) continue;
- +++UIPlayer+++
- }
- foreach (Spectator in Spectators) {
- declare UI <=> UIManager.GetUI(Spectator);
- if (UI==Null) continue;
- declare netwrite Integer Battle_PoleCaptureState for UI;
- Battle_PoleCaptureState = C_PoleCaptureState_Neutral;
- }
- +++UIAll+++
- if (DoUpdateScore) {
- DoUpdateScore = False;
- ---UpdateTotalCapture---
- foreach(PlayerId => PoleTaken in PoleTakers) {
- if(! Players.existskey(PlayerId)) continue;
- declare CustomScorePlayer <=> Players[PlayerId];
- +++SetCustomScorePole+++
- }
- PoleTakers.clear();
- foreach(PlayerId => PoleDenied in PoleDeniers) {
- if(! Players.existskey(PlayerId)) continue;
- declare CustomScorePlayer <=> Players[PlayerId];
- +++SetCustomScoreDefenseAction+++
- }
- PoleDeniers.clear();
- }
- }
- // Update the status message
- UpdateModeStatusMessage();
- // Stop match if there's not enough players left in matchmaking
- if (MM_IsMatchServer()) {
- if (MM_RestartMatchmaking || ClansNbPlayers[1] <= 0 || ClansNbPlayers[2] <= 0) {
- MB_StopMatch = True;
- }
- }
- ***
- ***IsPoleActive***
- ***
- if(S_BattleWaves) {
- IsPoleActive = IsPoleActive
- && (Pole.Gauge.Clan > 0)
- && (Pole.Gauge.Clan == CurrentAckClan);
- }
- ***
- ***Capturing***
- ***
- if(S_BattleWaves) {
- // is this parameter is set to false, attack phase is not reset when an attacker captures a pole
- if (NumberOfPlayerCapturing > 0) {
- if(S_StayInAttackOnCapture) {
- if((Pole.Gauge.Value < G_CaptureMaxValue) || S_ResetTimeOnCapturedPole) {
- // Add def points for a "just in time" capture
- if((DurationBeforePivot > 0) && (DurationBeforePivot <= C_JustInTimeLimit)) {
- foreach (PlayerId in Pole.Sector.PlayersIds) {
- if (!Players.existskey(PlayerId)) continue;
- declare CustomScorePlayer <=> Players[PlayerId];
- if (CustomScorePlayer.CurrentClan == Clan) continue; // Opponent team only
- else {
- declare Integer Battle_ScoreDefenseBonus for CustomScorePlayer.Score;
- Battle_ScoreDefenseBonus += S_ScoreDefense_CaptureJiT;
- +++SetCustomScoreDefenseAction+++
- }
- }
- }
- if (!GetOvertime()) {
- // Display the name of the player who did the pivot
- if (DurationBeforePivot <= (WavesDuration * 1000) / 5) {
- foreach (PlayerId in Pole.Sector.PlayersIds) {
- if (!Players.existskey(PlayerId)) continue;
- declare Player <=> Players[PlayerId];
- if (Player.CurrentClan != Clan) {
- declare TimeSplit = TL::Split(".", TL::ToText(DurationBeforePivot / 1000.));
- declare Time = "0";
- if (TimeSplit.existskey(0)) Time = TimeSplit[0];
- if (TimeSplit.existskey(1)) Time ^= "."^TL::SubText(TimeSplit[1], 0, 1);
- declare Message = TL::Compose(_("|Battle: 1=Player name, 2=Time in seconds|$<%1$> restarts attack countdown (%2s)"), Player.Name, Time);
- Message::SendBigMessage(Message, 3000, 1);
- break;
- }
- }
- }
- DurationBeforePivot = WavesDuration * 1000; //< Reset the atk countdown
- }
- }
- }
- if (FirstWaveStartTime == -1) {
- FirstWaveStartTime = Now;
- FirstWaveClanAttack = 3-Clan;
- EndTime = Now + S_TimeLimitAfterFirstCapture*1000;
- }
- }
- }
- ***
- ***SetCustomScorePole***
- ***
- if(True) // Create a context
- {
- UpdatePlayerScore(CustomScorePlayer, G_CaptureMaxValue);
- declare Integer Battle_ScoreCapture for CustomScorePlayer;
- declare Integer Battle_ScoreAttack for CustomScorePlayer;
- ST2::SetColValue("Attack", CustomScorePlayer.Score, TextLib::ToText(Battle_ScoreAttack));
- ST2::SetColValue("Capture", CustomScorePlayer.Score, TextLib::ToText(Battle_ScoreCapture));
- // update tops
- declare Integer MapCapture for CustomScorePlayer = 0;
- declare Integer MapAttack for CustomScorePlayer = 0;
- Top::SetRecord(CustomScorePlayer, C_TopId_Capture , ""^(MapCapture + Battle_ScoreCapture) , -(MapCapture + Battle_ScoreCapture));
- Top::SetRecord(CustomScorePlayer, C_TopId_Attack , ""^(MapAttack + Battle_ScoreAttack) , -(MapAttack + Battle_ScoreAttack));
- }
- ***
- ***SetCustomScoreHit***
- ***
- if(True) // Create a context
- {
- UpdatePlayerScore(CustomScorePlayer, G_CaptureMaxValue);
- declare Integer Battle_ScoreDefense for CustomScorePlayer;
- declare Integer Battle_ScoreAttack for CustomScorePlayer;
- declare Integer Battle_ScoreHit for CustomScorePlayer.Score;
- ST2::SetColValue("Attack", CustomScorePlayer.Score, TextLib::ToText(Battle_ScoreAttack));
- ST2::SetColValue("Defense", CustomScorePlayer.Score, TextLib::ToText(Battle_ScoreDefense));
- // update tops
- declare Integer MapHit for CustomScorePlayer = 0;
- declare Integer MapCombo for CustomScorePlayer = 0;
- declare Integer MapDefense for CustomScorePlayer = 0;
- declare Integer MapAttack for CustomScorePlayer = 0;
- declare Integer RoundCombo for CustomScorePlayer = 0;
- Top::SetRecord(CustomScorePlayer, C_TopId_Hit , ""^(MapHit + Battle_ScoreHit) , -(MapHit + Battle_ScoreHit));
- Top::SetRecord(CustomScorePlayer, C_TopId_Combo , ""^(RoundCombo) , -RoundCombo);
- Top::SetRecord(CustomScorePlayer, C_TopId_Defense , ""^(MapDefense + Battle_ScoreDefense) , -(MapDefense + Battle_ScoreDefense));
- Top::SetRecord(CustomScorePlayer, C_TopId_Attack , ""^(MapAttack + Battle_ScoreAttack) , -(MapAttack + Battle_ScoreAttack));
- }
- ***
- ***SetCustomScoreDefenseAction***
- ***
- if(True) // Create a context
- {
- UpdatePlayerScore(CustomScorePlayer, G_CaptureMaxValue);
- declare Integer Battle_ScoreDefense for CustomScorePlayer;
- ST2::SetColValue("Defense", CustomScorePlayer.Score, TextLib::ToText(Battle_ScoreDefense));
- // update tops
- declare Integer MapDefense for CustomScorePlayer = 0;
- Top::SetRecord(CustomScorePlayer, C_TopId_Defense , ""^(MapDefense + Battle_ScoreDefense) , -(MapDefense + Battle_ScoreDefense));
- }
- ***
- ***SetCustomScoreAll***
- ***
- if(True) // Create a context
- {
- UpdatePlayerScore(CustomScorePlayer, G_CaptureMaxValue);
- declare Integer Battle_ScoreCapture for CustomScorePlayer;
- declare Integer Battle_ScoreDefense for CustomScorePlayer;
- declare Integer Battle_ScoreAttack for CustomScorePlayer;
- declare Integer Battle_ScoreHit for CustomScorePlayer.Score;
- ST2::SetColValue("Capture", CustomScorePlayer.Score, TextLib::ToText(Battle_ScoreCapture));
- ST2::SetColValue("Attack", CustomScorePlayer.Score, TextLib::ToText(Battle_ScoreAttack));
- ST2::SetColValue("Defense", CustomScorePlayer.Score, TextLib::ToText(Battle_ScoreDefense));
- // update tops
- declare Integer MapHit for CustomScorePlayer = 0;
- declare Integer MapCombo for CustomScorePlayer = 0;
- declare Integer MapCapture for CustomScorePlayer = 0;
- declare Integer MapDefense for CustomScorePlayer = 0;
- declare Integer MapAttack for CustomScorePlayer = 0;
- declare Integer RoundCombo for CustomScorePlayer = 0;
- Top::SetRecord(CustomScorePlayer, C_TopId_Hit , ""^(MapHit + Battle_ScoreHit) , -(MapHit + Battle_ScoreHit));
- Top::SetRecord(CustomScorePlayer, C_TopId_Combo , ""^(RoundCombo) , -(RoundCombo));
- Top::SetRecord(CustomScorePlayer, C_TopId_Capture , ""^(MapCapture + Battle_ScoreCapture) , -(MapCapture + Battle_ScoreCapture));
- Top::SetRecord(CustomScorePlayer, C_TopId_Defense , ""^(MapDefense + Battle_ScoreDefense) , -(MapDefense + Battle_ScoreDefense));
- Top::SetRecord(CustomScorePlayer, C_TopId_Attack , ""^(MapAttack + Battle_ScoreAttack) , -(MapAttack + Battle_ScoreAttack));
- }
- ***
- ***OnCaptureDenied***
- ***
- if(S_BattleWaves) {
- declare Integer PoleClan = Pole.Gauge.Clan;
- foreach (PlayerId in Pole.Sector.PlayersIds) {
- if (!Players.existskey(PlayerId)) continue;
- declare Player <=> Players[PlayerId];
- declare UI <=> UIManager.GetUI(Player);
- if (UI != Null) {
- declare Integer PlayerClan = Player.CurrentClan;
- declare netwrite Integer Battle_PoleCaptureState for UI;
- declare Integer OldState = Battle_PoleCaptureState;
- if(PoleClan == PlayerClan) { // A pole current player must capture
- if (Pole.Gauge.Value < G_CaptureMaxValue) { // not captured yet
- if((PlayerClan != CurrentAckClan) || (CurrentAckClan==0)) { // pole locked if player is not attacking
- Battle_PoleCaptureState = C_PoleCaptureState_Locked;
- } else {
- Battle_PoleCaptureState = C_PoleCaptureState_Denied;
- }
- } else { // already captured
- Battle_PoleCaptureState = C_PoleCaptureState_Captured;
- }
- } else { // A pole current player must defend
- if (Pole.Gauge.Value < G_CaptureMaxValue) { // pole protected
- Battle_PoleCaptureState = C_PoleCaptureState_Protected;
- } else { // already captured
- Battle_PoleCaptureState = C_PoleCaptureState_Neutral;
- }
- }
- }
- }
- } else {
- declare Integer PoleClan = Pole.Gauge.Clan;
- foreach (PlayerId in Pole.Sector.PlayersIds) {
- if (!Players.existskey(PlayerId)) continue;
- declare Player <=> Players[PlayerId];
- declare UI <=> UIManager.GetUI(Player);
- if (UI != Null) {
- declare netwrite Integer Battle_PoleCaptureState for UI;
- if (Pole.Gauge.Value < G_CaptureMaxValue) {
- if(Player.CurrentClan == PoleClan) {
- Battle_PoleCaptureState = C_PoleCaptureState_Denied;
- } else {
- Battle_PoleCaptureState = C_PoleCaptureState_Protected;
- }
- } else if(PoleClan == Player.CurrentClan) {
- Battle_PoleCaptureState = C_PoleCaptureState_Captured;
- } else {
- //Battle_PoleCaptureState = C_PoleCaptureState_Lost;
- Battle_PoleCaptureState = C_PoleCaptureState_Neutral;
- }
- }
- }
- }
- ***
- // ---------------------------------- //
- // Round end
- // ---------------------------------- //
- ***EndRound***
- ***
- Message::CleanAllMessages();
- foreach(Player in Players) {
- if(Player.Score == Null) continue;
- declare Integer Battle_ScoreHit for Player.Score;
- declare Real AutoBalance_ReloadSpeedBonus for Player.User = 1.;
- if(S_AllowBeginners && Beginners::IsBeginner(Player)) {
- Beginners::BalanceBeginner(Player, Battle_ScoreHit);
- } else {
- if(Battle_ScoreHit <= 1) {
- if (AutoBalance_ReloadSpeedBonus < 1.3) AutoBalance_ReloadSpeedBonus += .1;
- } else {
- AutoBalance_ReloadSpeedBonus = 1.;
- }
- }
- }
- foreach(Player in AllPlayers) {
- Interface::HideSlider(Player, 0);
- declare UI <=> UIManager.GetUI(Player);
- if(UI == Null) continue;
- declare netwrite Integer Battle_UIRoundPhase for UI;
- Battle_UIRoundPhase = C_RoundPhase_EndRound;
- }
- ResetAllUIs();
- // LayerMarkers.ManialinkPage = "";
- LayerMarkers.IsVisible = False;
- // update map tops
- foreach(Player in Players) {
- declare Integer MapHit for Player = 0;
- declare Integer MapCapture for Player = 0;
- declare Integer MapDefense for Player = 0;
- declare Integer MapAttack for Player = 0;
- declare Integer Battle_ScoreCapture for Player;
- declare Integer Battle_ScoreDefense for Player;
- declare Integer Battle_ScoreAttack for Player;
- declare Integer Battle_ScoreHit for Player.Score;
- MapHit += Battle_ScoreHit;
- MapCapture += Battle_ScoreCapture;
- MapDefense += Battle_ScoreDefense;
- MapAttack += Battle_ScoreAttack;
- }
- UpdateMapRunnersRanking();
- UpdatePlayersScores(G_CaptureMaxValue);
- StartTime = -1;
- EndTime = -1;
- UIManager.UIAll.OverlayHideCountdown = False;
- for (Clan, 1, 2) {
- foreach (Pole in ClanPoles[Clan]) {
- Pole.Gauge.Speed = 0;
- }
- }
- MM_Sleep(1700);
- UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::EndRound;
- if (TouchdownUserId != NullId && Users.existskey(TouchdownUserId)) {
- UIManager.UIAll.StatusMessage = TL::Compose(_("$<%1$> touched the pole."), Users[TouchdownUserId].Name);
- } else if (FinalCaptureUserId != NullId && Users.existskey(FinalCaptureUserId)) {
- UIManager.UIAll.StatusMessage = TL::Compose(_("$<%1$> captured the last pole."), Users[FinalCaptureUserId].Name);
- }
- if (Victory::IsRoundWinner(1)) {
- UIManager.UIAll.BigMessage = TextLib::Compose(_("$<%1$> wins the round!"), Teams[0].ColorizedName);
- ClanScores[1] += 1;
- } else if (Victory::IsRoundWinner(2)) {
- UIManager.UIAll.BigMessage = TextLib::Compose(_("$<%1$> wins the round!"), Teams[1].ColorizedName);
- ClanScores[2] += 1;
- } else {
- UIManager.UIAll.BigMessage = _("Draw round");
- }
- MM_SetScores([ClanScores[1], ClanScores[2]]);
- // UIManager.UIAll.ScoreSummary_Points1 = Clan1Score;
- // UIManager.UIAll.ScoreSummary_Points2 = Clan2Score;
- ---UpdateTeamsScoresUI---
- ST2::SetFooterText(TextLib::Compose("%1 "^S_RoundsToWin, _("Points limit : ")));
- Victory::SetMatchWinnerFromScore(S_RoundsToWin, S_RoundGapToWin, S_RoundsLimit);
- foreach (Player in Players) {
- UnspawnPlayer(Player);
- }
- UIManager.UIAll.UISequence = CUIConfig::EUISequence::EndRound;
- if (S_DisplayTopsRound) {
- UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::ForcedVisible;
- MM_Sleep(5000);
- UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
- LaunchTop5Sequence("round");
- } else {
- UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::ForcedVisible;
- MM_Sleep(7*1000);
- }
- +++RoundEnd+++
- if (S_AlternativePoints) {
- foreach (Score in Scores) {
- declare Integer Battle_ScoreAlternative for Score;
- Score.RoundPoints = Battle_ScoreAlternative;
- }
- }
- Victory::RoundEnd();
- // Match / Map win
- if (!Victory::NoMatchWinner() || MatchEndRequested) {
- MB_StopMatch = True;
- } else {
- // Autoround balance
- if (S_AutoBalanceRound && !MM_IsMatchmakingServer()) {
- AutoTeamBalanceRound();
- }
- }
- Score::RoundEnd();
- BalancedWeapons::RoundEnd();
- UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
- ResetAllUIs();
- // LayerMarkers.ManialinkPage = ""; // Crash.
- if(S_BattleWaves) {
- // once again, to ensure an update of the UI in case of early endround (e.g. vote for next map)
- +++OnRoundStop+++
- if(G_EngagePoleId != NullId) {
- declare CSmMapLandmark EngagePole <=> MapLandmarks_Gauge[G_EngagePoleId];
- if(EngagePole != Null) {
- EngagePole.Gauge.Captured = False;
- EngagePole.Gauge.Value = 0;
- }
- }
- }
- ***
- // ---------------------------------- //
- // Map end
- // ---------------------------------- //
- ***EndMap***
- ***
- ResetAllUIs();
- LayerMarkers.IsVisible = False;
- declare WinnerClan = -1;
- if (Victory::IsMatchWinner(1)) {
- UIManager.UIAll.BigMessage = TextLib::Compose(_("$<%1$> wins the match!"), Teams[0].ColorizedName);
- WinnerClan = 1;
- } else if (Victory::IsMatchWinner(2)) {
- UIManager.UIAll.BigMessage = TextLib::Compose(_("$<%1$> wins the match!"), Teams[1].ColorizedName);
- WinnerClan = 2;
- } else {
- UIManager.UIAll.BigMessage = _("Draw match");
- }
- declare MasterLogin = "";
- declare MasterPoints = 0;
- if (MM_IsMatchServer() && (ClansNbPlayers[1] == 0 || ClansNbPlayers[2] == 0 || MM_RestartMatchmaking) && ClanScores[1] == 0 && ClanScores[2] == 0) {
- MM_SetLadderMatchId();
- Mode::Ladder_CancelMatch();
- MB_Log("Cancel match and don't give LP because one of the team left the match.");
- } else {
- if (MM_IsMatchServer()) {
- MM_SetLadderMatchId();
- }
- if (WinnerClan != -1) {
- foreach(Score in Scores) {
- Score.LadderRankSortValue = - 1 - Score.Points;
- if (Score.Points > MasterPoints) {
- MasterPoints = Score.Points;
- MasterLogin = Score.User.Login;
- }
- }
- Mode::Ladder_CloseMatch();
- } else {
- Mode::Ladder_CancelMatch();
- }
- }
- BalancedWeapons::MatchEnd();
- if (S_DisplayTopsMap) {
- UIManager.UIAll.UISequence = CUIConfig::EUISequence::Podium;
- } else {
- UIManager.UIAll.UISequence = CUIConfig::EUISequence::EndRound;
- }
- UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::EndRound;
- UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::ForcedVisible;
- MM_Sleep(6*1000);
- if (S_DisplayTopsMap) {
- UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
- LaunchTop5Sequence("map");
- } else {
- UIManager.UIAll.UISequence = CUIConfig::EUISequence::Podium;
- MM_Sleep(10*1000);
- }
- UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
- ResetAllUIs();
- Interface::DestroySlider();
- // ---------------------------------- //
- // Send match result and transfert players back to the lobby
- if (MM_IsMatchServer()) {
- if (!MM_RestartMatchmaking && ClansNbPlayers[1] > 0 && ClansNbPlayers[2] > 0) {
- if (MB_StopMatch) {
- if (RematchNb < S_MatchmakingRematchNbMax) {
- IsRematch = MM_VoteForRematch();
- RematchNb += 1;
- }
- if (!IsRematch) {
- RematchNb = 0;
- MM_MatchEnd(MasterLogin);
- MM_MatchToLobby();
- } else {
- MM_VoteForNextMap(False);
- }
- } else {
- MM_VoteForNextMap(False);
- }
- } else {
- RematchNb = 0;
- MM_MatchEnd(MasterLogin);
- MM_MatchToLobby();
- }
- }
- ***
- // ---------------------------------- //
- // Match end
- // ---------------------------------- //
- ***EndMatch***
- ***
- +++MatchEnd+++
- Victory::MatchEnd();
- ***
- // ---------------------------------- //
- // Server end
- // ---------------------------------- //
- ***EndServer***
- ***
- // Destroy layers
- Layers::Detach("Top5");
- Layers::Destroy("Top5");
- UIManager.UILayerDestroy(LayerRoundInfo);
- WarmUp2::Unload();
- ***
- // ---------------------------------- //
- // Set the EndTime of the round
- ***EndTime***
- ***
- if(S_BattleWaves) {
- EndTime = StartTime + S_TimeLimitForFirstCapture*1000;
- } else {
- EndTime = StartTime + S_TimeLimit*1000;
- }
- ***
- // ---------------------------------- //
- // Define when a capture is possible
- ***IsCapturePossible***
- ***
- declare Boolean IsCapturePossible;
- if(S_BattleWaves) {
- declare IsGoalClanAttacking = (CurrentAckClan != 0) && (Clan == CurrentAckClan);
- IsCapturePossible = !IsGoalDenied && !IsGoalClanAttacking;
- if((G_EngagePoleId != NullId) && CurrentAckClan == 0) {
- IsCapturePossible = False;
- }
- } else {
- IsCapturePossible = !IsGoalDenied;
- }
- ***
- // ---------------------------------- //
- // Set the rules in the SpawnScreen
- ***Rules***
- ***
- declare Text ModeName = "Battle";
- declare Text ModeRules;
- SpawnScreen::ResetRulesSection();
- SpawnScreen::AddSubsection(_("Type"), _("Team versus Team"), 0.);
- SpawnScreen::AddSubsection(
- _("Objectives"),
- TextLib::Compose(_("$<%11. $>Capture the poles during Attack phases.\n$<%12. $>If the time limit is reached, only 100%% captured poles count. The first team to win %2 rounds wins the match."), "$"^SpawnScreen::GetModeColor() , ""^S_RoundsToWin),
- 25.);
- if(S_BattleWaves) {
- SpawnScreen::AddSubsection(
- _("Conditions"),
- TextLib::Compose(_("$<%11. $>Touch the engagement point to be the first team to Attack.\n$<%12. $>If a team does not touch any pole during %2 seconds, the other team Attacks."), "$"^SpawnScreen::GetModeColor(), ""^S_WaveDuration),
- 60.);
- }
- UpdateModeStatusMessage();
- SpawnScreen::CreatePrettyRules(ModeName);
- ***
- // ---------------------------------- //
- /** Get the requested clan of a player
- *
- * @param _Player The player to check
- *
- * @return The requested clan of the player
- */
- Integer Battle_GetRequestedClan(CSmPlayer _Player) {
- if (MM_IsMatchServer()) {
- return MM_GetRequestedClan(_Player);
- } else {
- if (_Player == Null) return 0;
- declare Battle_BalanceClan for _Player = -1;
- if (S_AutoBalanceRound && (Battle_BalanceClan == 1 || Battle_BalanceClan == 2)) {
- return Battle_BalanceClan;
- } else {
- return _Player.User.RequestedClan;
- }
- }
- return 0;
- }
- // ---------------------------------- //
- /** Turn on/off the overtime
- *
- * @param _Activate If True activate overtime
- */
- Void SetOvertime(Boolean _Activate) {
- G_OvertimeActivated = _Activate;
- declare netwrite Boolean Net_OvertimeActivated for Teams[0];
- Net_OvertimeActivated = G_OvertimeActivated;
- }
- // ---------------------------------- //
- /** Get the current status of the overtime
- *
- * @return True if the overtime is activated, False otherwise
- */
- Boolean GetOvertime() {
- return G_OvertimeActivated;
- }
- // ---------------------------------- //
- /** Set the overtime advantage
- *
- * @param _Advantage The clan who has the advantage
- */
- Void SetOvertimeAdvantage(Integer _Advantage) {
- G_OvertimeAdvantage = _Advantage;
- declare netwrite Integer Net_OvertimeAdvantage for Teams[0];
- Net_OvertimeAdvantage = G_OvertimeAdvantage;
- }
- // ---------------------------------- //
- /** Get the current overtime advantage
- *
- * @return The clan that has the advantage
- */
- Integer GetOvertimeAdvantage() {
- return G_OvertimeAdvantage;
- }
- Void UpdateScoreTeamsUI(CSmPlayer Player) {
- declare UI <=> UIManager.GetUI(Player);
- if (UI == Null) return;
- declare netwrite Text Battle_ScoreTeam1 for UI;
- declare netwrite Text Battle_ScoreTeam2 for UI;
- Battle_ScoreTeam1 = G_ScoreTeam1;
- Battle_ScoreTeam2 = G_ScoreTeam2;
- }
- /**
- * Convert Integers from 1 to 9 into letters from A to I
- */
- Text GetLetterFromNumber(Integer N) {
- declare Suffix = "";
- if (N > 26) Suffix = TextLib::ToText(((N - 1) / 26) + 1);
- switch(N) {
- case 1 : return "A"^Suffix;
- case 2 : return "B"^Suffix;
- case 3 : return "C"^Suffix;
- case 4 : return "D"^Suffix;
- case 5 : return "E"^Suffix;
- case 6 : return "F"^Suffix;
- case 7 : return "G"^Suffix;
- case 8 : return "H"^Suffix;
- case 9 : return "I"^Suffix;
- case 10: return "J"^Suffix;
- case 11: return "K"^Suffix;
- case 12: return "L"^Suffix;
- case 13: return "M"^Suffix;
- case 14: return "N"^Suffix;
- case 15: return "O"^Suffix;
- case 16: return "P"^Suffix;
- case 17: return "Q"^Suffix;
- case 18: return "R"^Suffix;
- case 19: return "S"^Suffix;
- case 20: return "T"^Suffix;
- case 21: return "U"^Suffix;
- case 22: return "V"^Suffix;
- case 23: return "W"^Suffix;
- case 24: return "X"^Suffix;
- case 25: return "Y"^Suffix;
- case 26: return "Z"^Suffix;
- }
- return "?"^Suffix;
- }
- // ---------------------------------- //
- /// End map timer for MatchMaking
- Void UpdateBasesColors() {
- foreach (Base in MapBases) {
- Base.Clan = 0;
- Base.IsActive = True;
- }
- declare UpdatedBases = Ident[];
- foreach (Clan => Spawn in G_ClanSpawnAnchors) {
- if (Spawn.Base == Null) continue;
- Spawn.Base.Clan = Clan;
- Spawn.Base.IsActive = True;
- UpdatedBases.add(Spawn.Base.Id);
- }
- foreach (Pole in MapLandmarks_Gauge) {
- declare Clan = 0;
- if (Pole.Gauge.Clan == 1 || Pole.Gauge.Clan == 2) {
- if (Pole.Gauge.Value < Pole.Gauge.Max) Clan = 3 - Pole.Gauge.Clan;
- else Clan = Pole.Gauge.Clan;
- }
- if (Pole.Base != Null) {
- if (!UpdatedBases.exists(Pole.Base.Id)) {
- Pole.Base.Clan = Clan;
- UpdatedBases.add(Pole.Base.Id);
- } else if (Pole.Base.Clan != Clan) {
- Pole.Base.Clan = 0;
- }
- }
- }
- }
- Void UpdatePlayerScore(CSmPlayer Player, Integer CaptureMaxValue) {
- if(Player.Score == Null) return;
- declare Real ScoreCaptureFactor = 1.;
- declare Real ScoreDenyFactor = 1.;
- if (CaptureMaxValue != 0) {
- ScoreCaptureFactor = S_PointsPerPole / CaptureMaxValue;
- ScoreDenyFactor = S_DefPointOnDenyForOnePole / CaptureMaxValue;
- }
- declare Integer Battle_ScoreDefenseBonus for Player.Score;
- declare Integer Battle_ScoreAttackBonus for Player.Score;
- declare Integer Battle_ScoreAlternative for Player.Score;
- declare Integer Battle_ScoreHit for Player.Score;
- declare Integer Battle_TotalCaptureTime for Player.Score;
- declare Integer Battle_TotalDenyTime for Player.Score;
- declare Real ScoreCapture = ScoreCaptureFactor * Battle_TotalCaptureTime;
- declare Real ScoreDeny = ScoreDenyFactor * Battle_TotalDenyTime;
- declare Integer Battle_ScoreCapture for Player;
- declare Integer Battle_ScoreDefense for Player;
- declare Integer Battle_ScoreAttack for Player;
- Battle_ScoreCapture = MathLib::NearestInteger(ScoreCapture);
- Battle_ScoreAttack = Battle_ScoreAttackBonus + Battle_ScoreCapture; // etc.
- Battle_ScoreDefense = Battle_ScoreDefenseBonus + MathLib::NearestInteger(ScoreDeny); // etc.
- Battle_ScoreAlternative = Battle_ScoreAttack + Battle_ScoreDefense;
- Player.Score.RoundPoints = Battle_ScoreHit;
- }
- Void UpdatePlayersScores(Integer CaptureMaxValue)
- {
- foreach(Player in Players) {
- UpdatePlayerScore(Player, CaptureMaxValue);
- }
- }
- Void SendCaptureTime(CSmPlayer _Player) {
- declare UI <=> UIManager.GetUI(_Player);
- if (UI == Null) return;
- declare Integer[Ident] RoundTop_CaptureTime for _Player.Score;
- declare netwrite Integer[Text] Net_RoundTop_CaptureTime for UI;
- declare netwrite Integer Net_RoundTop_CaptureTimeUpdate for UI;
- Net_RoundTop_CaptureTime.clear();
- foreach (PoleId => CaptureTime in RoundTop_CaptureTime) {
- Net_RoundTop_CaptureTime[""^PoleId] = CaptureTime;
- }
- Net_RoundTop_CaptureTimeUpdate = Now;
- }
- Void InitializePlayer(CSmPlayer Player, Text PoleMarkers) {
- SetPlayerClan(Player, Battle_GetRequestedClan(Player));
- if(Player.Score == Null) return;
- declare Integer Battle_TotalCaptureTime for Player.Score;
- declare Integer Battle_TotalDenyTime for Player.Score;
- declare Integer Battle_ScoreDefenseBonus for Player.Score;
- declare Integer Battle_ScoreAttackBonus for Player.Score;
- declare Integer Battle_ScoreAlternative for Player.Score;
- declare Integer Battle_ScoreHit for Player.Score;
- declare Integer Battle_RoundIndex for Player.Score = -1;
- if(Battle_RoundIndex != G_CurrentRoundIndex) {
- // reinit the score
- Battle_RoundIndex = G_CurrentRoundIndex;
- Battle_TotalCaptureTime = 0;
- Battle_TotalDenyTime = 0;
- Battle_ScoreDefenseBonus = 0;
- Battle_ScoreAttackBonus = 0;
- Battle_ScoreAlternative = 0;
- Battle_ScoreHit = Player.Score.RoundPoints; // keep trace of previous score if the player disconnects.
- }
- declare CustomScorePlayer <=> Player;
- +++SetCustomScoreAll+++
- // update tops
- declare Integer MapHit for Player = 0;
- declare Integer MapCombo for Player = 0;
- declare Integer MapCapture for Player = 0;
- declare Integer MapDefense for Player = 0;
- declare Integer MapAttack for Player = 0;
- //MapHit = 0;
- //MapCombo = 0;
- //MapCapture = 0;
- //MapDefense = 0;
- //MapAttack = 0;
- declare UI <=> UIManager.GetUI(Player);
- if (UI == Null) return;
- declare netwrite Integer Battle_PoleCaptureState for UI;
- declare netwrite Integer Battle_PoleCaptureRate for UI;
- declare netwrite Boolean Battle_ServToUIShowFrame for UI = False;
- declare netwrite Integer Battle_UIRoundPhase for UI;
- Battle_PoleCaptureState = C_PoleCaptureState_Neutral;
- Battle_PoleCaptureRate = 0;
- Battle_ServToUIShowFrame = ! Battle_ServToUIShowFrame;
- Battle_UIRoundPhase = C_RoundPhase_Playing;
- UI.MarkersXML = PoleMarkers;
- Tabs::UseTabs(UI, "ScoresTab");
- UpdateScoreTeamsUI(Player);
- SendCaptureTime(Player);
- }
- Void UpdateModeStatusMessage() {
- declare Text BaseRules = _("Team vs Team: Capture all the poles of the opposing team.");
- declare Text WavesRules;
- if(S_BattleWaves) {
- WavesRules = _("Waves mode: On");
- } else {
- WavesRules = _("Waves mode: Off");
- }
- declare Text RoundsToWinSetting = ""^S_RoundsToWin;
- declare Text MatchScore = ClanScores[1] ^ " - " ^ ClanScores[2];
- declare Text RoundScore;
- if((G_ScoreTeam1 == "") && (G_ScoreTeam2 == "")) {
- RoundScore = "0% - 0%";
- } else {
- RoundScore = G_ScoreTeam1 ^ " - " ^G_ScoreTeam2;
- }
- ModeStatusMessage = TextLib::Compose("%1\n%2, Rounds to win: %3\nMatch Score: %4, Round Score: %5", BaseRules, WavesRules, RoundsToWinSetting, MatchScore, RoundScore);
- }
- Text GetMLColor(Text DollarColor) {
- return TextLib::SubString(DollarColor, 1, 3)^"f";
- }
- Void CreateRoundInfoUI(CUILayer LayerRoundInfo, CSmMapLandmark[][Integer] ClanPoles)
- {
- declare Integer GaugesXPos = 93; //50
- declare Integer GaugesYPos = 71; //57
- declare Integer PolesXPos = 0;
- declare Integer PolesYPos = 0;
- declare Text ImgGoalCaptured = C_ImgBaseDir^"c_goal_captured.dds";
- declare Text ImgGoalCapture = C_ImgBaseDir^"c_goal_capture.dds";
- declare Text ImgGoalProtected = C_ImgBaseDir^"c_goal_shield.dds";
- declare Text ImgGoalDenied = C_ImgBaseDir^"c_goal_shield_block.dds";
- declare Text ImgGoalLocked = C_ImgBaseDir^"c_goal_lock.dds";
- declare Text ImgGoalBg = C_ImgBaseDir^"goal.dds";
- declare Team0Color = GetMLColor(Teams[0].ColorText);
- declare Team1Color = GetMLColor(Teams[1].ColorText);
- declare Text MLPage = """
- <script><!--
- #Include "MathLib" as MathLib
- #Include "TextLib" as TextLib
- Text TimeToText(Integer _Time) {
- if (_Time < 0) {
- return "???";
- }
- declare MilliSeconds = _Time % 1000;
- declare CentiSeconds = (_Time / 10) % 100;
- declare Seconds = (_Time / 1000) % 60;
- declare Minutes = (_Time / 60000) % 60;
- declare Hours = (_Time / 3600000) % 24;
- declare Time = TextLib::FormatInteger(Seconds, 2)^"."^TextLib::FormatInteger(CentiSeconds, 2);
- if (Minutes > 0) Time = TextLib::FormatInteger(Minutes, 2)^":"^Time;
- if (Hours > 0) Time = Hours^":"^Time;
- return Time;
- }
- Void UpdateCaptureTime(Boolean _IsRoundRecord, Integer[Text] _CaptureTime) {
- foreach (PoleId => CaptureTime in _CaptureTime) {
- declare Frame_Pole <=> (Page.GetFirstChild("PoleId_"^PoleId) as CMlFrame);
- if (Frame_Pole == Null) continue;
- if (_IsRoundRecord) {
- declare Label_RB <=> (Frame_Pole.GetFirstChild("Label_RB") as CMlLabel);
- Label_RB.Value = TimeToText(CaptureTime);
- } else {
- declare Label_PB <=> (Frame_Pole.GetFirstChild("Label_PB") as CMlLabel);
- Label_PB.Value = TimeToText(CaptureTime);
- }
- }
- }
- main() {
- while(InputPlayer == Null) yield;
- declare netread Text Battle_ScoreTeam1 for UI;
- declare netread Text Battle_ScoreTeam2 for UI;
- declare netread Integer Battle_PoleCaptureState for UI;
- declare netread Integer Battle_PoleCaptureRate for UI;
- declare netread Integer[Text] Net_RoundTop_CaptureTimeRecords for Teams[0];
- declare netread Integer Net_RoundTop_CaptureTimeRecordsUpdate for Teams[0];
- declare netread Integer[Text] Net_RoundTop_CaptureTime for UI;
- declare netread Integer Net_RoundTop_CaptureTimeUpdate for UI;
- declare LabelScoreTeam1 <=> (Page.GetFirstChild("LabelScoreTeam1") as CMlLabel);
- declare LabelScoreTeam2 <=> (Page.GetFirstChild("LabelScoreTeam2") as CMlLabel);
- declare FrameSmallPoleText <=> (Page.GetFirstChild("FrameSmallPoleText") as CMlFrame);
- declare LabelCaptureMessage <=> (Page.GetFirstChild("LabelCaptureMessage") as CMlLabel);
- declare QuadCaptureMessage <=> (Page.GetFirstChild("QuadCaptureMessage") as CMlQuad);
- declare Frame_Clan1 <=> (Page.GetFirstChild("Frame_Clan1") as CMlFrame);
- declare Frame_Clan2 <=> (Page.GetFirstChild("Frame_Clan2") as CMlFrame);
- declare CMlQuad[] QuadGaugesTeam1;
- declare CMlQuad[] QuadGaugesTeam2;
- declare CMlFrame[][Integer] PoleFrame;
- declare CMlFrame[][Integer] PoleCapturedFrame;
- declare CMlGauge[][Integer] PoleGauges;
- declare CMlGauge CaptureGauge <=> (Page.GetFirstChild("CaptureGauge") as CMlGauge);
- declare Real[Integer][Integer] CurrentClanPoles;
- declare Integer[Integer][Integer] HighlightTimer;
- for(ClanIndex, 1, 2) {
- CurrentClanPoles[ClanIndex] = Real[Integer];
- PoleFrame[ClanIndex] = CMlFrame[];
- PoleCapturedFrame[ClanIndex] = CMlFrame[];
- HighlightTimer[ClanIndex] = Integer[Integer];
- PoleGauges[ClanIndex] = CMlGauge[];
- }
- declare Clan1PoleIndex = -1;
- declare Clan2PoleIndex = -1;
- foreach(Pole in MapLandmarks_Gauge) {
- if (Pole.Tag != "Goal" && Pole.Tag != "Checkpoint") continue;
- declare Integer PoleClan = Pole.Gauge.Clan;
- declare Integer PoleIndex = -1;
- if(PoleClan == 1) {
- Clan1PoleIndex += 1;
- PoleIndex = Clan1PoleIndex;
- } else if (PoleClan == 2) {
- Clan2PoleIndex += 1;
- PoleIndex = Clan2PoleIndex;
- }
- if(PoleIndex >= 0) {
- CurrentClanPoles[PoleClan][PoleIndex] = Pole.Gauge.ValueReal; // presumably 0.
- PoleFrame[PoleClan].add((Page.GetFirstChild("PoleFrame"^PoleIndex^"_"^PoleClan) as CMlFrame));
- PoleCapturedFrame[PoleClan].add((Page.GetFirstChild("PoleCapturedFrame"^PoleIndex^"_"^PoleClan) as CMlFrame));
- PoleGauges[PoleClan].add((Page.GetFirstChild("PoleUIGauge"^PoleIndex^"_"^PoleClan) as CMlGauge));
- HighlightTimer[PoleClan][PoleIndex] = Now;
- }
- }
- declare Blinker = 0;
- declare BlinkDelay = 4;
- declare PreviousState = -1;
- declare PrevClan = -1;
- declare PrevCaptureTimeUpdate = -1;
- declare PrevCaptureTimeRecordsUpdate = -1;
- while(True) {
- // yield;
- sleep(200);
- if (!PageIsVisible) continue;
- if (InputPlayer == Null) continue;
- if (PrevClan != InputPlayer.CurrentClan) {
- PrevClan = InputPlayer.CurrentClan;
- Page.GetClassChildren("ClanSpecific", Page.MainFrame, True);
- foreach (Control in Page.GetClassChildren_Result) {
- if (Control.HasClass("Clan1")) {
- if (InputPlayer.CurrentClan == 1 || IsSpectatorMode) Control.Visible = True;
- else Control.Visible = False;
- } else if (Control.HasClass("Clan2")) {
- if (InputPlayer.CurrentClan == 2 || IsSpectatorMode) Control.Visible = True;
- else Control.Visible = False;
- }
- }
- }
- if (PrevCaptureTimeRecordsUpdate != Net_RoundTop_CaptureTimeRecordsUpdate) {
- PrevCaptureTimeRecordsUpdate = Net_RoundTop_CaptureTimeRecordsUpdate;
- UpdateCaptureTime(True, Net_RoundTop_CaptureTimeRecords);
- }
- if (PrevCaptureTimeUpdate != Net_RoundTop_CaptureTimeUpdate) {
- PrevCaptureTimeUpdate = Net_RoundTop_CaptureTimeUpdate;
- UpdateCaptureTime(False, Net_RoundTop_CaptureTime);
- }
- LabelScoreTeam1.SetText("$s$fff"^Battle_ScoreTeam1);
- LabelScoreTeam2.SetText("$s$fff"^Battle_ScoreTeam2);
- if(PreviousState != Battle_PoleCaptureState) {
- PreviousState = Battle_PoleCaptureState;
- switch(Battle_PoleCaptureState) {
- case {{{C_PoleCaptureState_Neutral}}} : {
- CaptureGauge.Hide();
- FrameSmallPoleText.Hide();
- }
- case {{{C_PoleCaptureState_Capturing}}} : {
- QuadCaptureMessage.ImageUrl = "{{{ImgGoalCapture}}}";
- CaptureGauge.Show();
- FrameSmallPoleText.Show();
- }
- case {{{C_PoleCaptureState_Captured}}} : {
- LabelCaptureMessage.SetText(TextLib::Compose("$s%1", _("Pole captured")));
- QuadCaptureMessage.ImageUrl = "{{{ImgGoalCaptured}}}";
- CaptureGauge.Hide();
- FrameSmallPoleText.Show();
- }
- case {{{C_PoleCaptureState_Protected}}} : {
- LabelCaptureMessage.SetText(TextLib::Compose("$s%1", _("Pole protected")));
- QuadCaptureMessage.ImageUrl = "{{{ImgGoalProtected}}}";
- CaptureGauge.Hide();
- FrameSmallPoleText.Show();
- }
- case {{{C_PoleCaptureState_Denied}}} : {
- LabelCaptureMessage.SetText(TextLib::Compose("$s%1", _("Pole denied")));
- QuadCaptureMessage.ImageUrl = "{{{ImgGoalDenied}}}";
- CaptureGauge.Hide();
- FrameSmallPoleText.Show();
- }
- case {{{C_PoleCaptureState_Locked}}} : {
- LabelCaptureMessage.SetText(TextLib::Compose("$s%1", _("Pole locked")));
- QuadCaptureMessage.ImageUrl = "{{{ImgGoalLocked}}}";
- CaptureGauge.Hide();
- FrameSmallPoleText.Show();
- }
- }
- }
- if(Battle_PoleCaptureState == {{{C_PoleCaptureState_Capturing}}}) {
- LabelCaptureMessage.SetText(TextLib::Compose("$s%1 (%2%%)", _("Capturing"), ""^Battle_PoleCaptureRate));
- CaptureGauge.SetRatio(Battle_PoleCaptureRate/100.);
- }
- declare Clan1PoleIndex = -1;
- declare Clan2PoleIndex = -1;
- foreach(Pole in MapLandmarks_Gauge) {
- if (Pole.Tag != "Goal" && Pole.Tag != "Checkpoint") continue;
- declare Integer PoleClan = Pole.Gauge.Clan;
- if(PoleClan == 0) continue; // inconsistent data.
- if(CurrentClanPoles[PoleClan].count <= 0) continue; // inconsistent data.
- declare Integer PoleIndex = -1;
- if(PoleClan == 1) {
- Clan1PoleIndex += 1;
- PoleIndex = Clan1PoleIndex;
- } else if (PoleClan == 2) {
- Clan2PoleIndex += 1;
- PoleIndex = Clan2PoleIndex;
- }
- if(PoleIndex >= 0) {
- declare Integer OpposingClan = 3-PoleClan;
- declare PoleFrameOppClan = PoleFrame[PoleClan];
- declare Real ServerCapture = Pole.Gauge.ValueReal;
- // Blink timer
- if(ServerCapture != CurrentClanPoles[PoleClan][PoleIndex]) {
- CurrentClanPoles[PoleClan][PoleIndex] = ServerCapture;
- HighlightTimer[PoleClan][PoleIndex] = Now + 500;
- }
- declare Real FakeValue = (MathLib::Sqrt(ServerCapture) + ServerCapture) / 2;
- //PoleGauges[PoleClan][PoleIndex].SetRatio(ServerCapture);
- PoleGauges[PoleClan][PoleIndex].SetRatio(FakeValue);
- if(ServerCapture >= 1.) {
- PoleFrame[PoleClan][PoleIndex].Hide();
- PoleCapturedFrame[PoleClan][PoleIndex].Show();
- } else if(HighlightTimer[PoleClan][PoleIndex] > Now) {
- if((Blinker % BlinkDelay) == 0) {
- //PoleFrameOppClan[PoleIndex].Show();
- PoleCapturedFrame[PoleClan][PoleIndex].Show();
- } else if((Blinker % BlinkDelay) == (BlinkDelay/2)) {
- //PoleFrameOppClan[PoleIndex].Hide();
- PoleCapturedFrame[PoleClan][PoleIndex].Hide();
- }
- } else {
- PoleFrame[PoleClan][PoleIndex].Show();
- PoleCapturedFrame[PoleClan][PoleIndex].Hide();
- }
- }
- }
- Blinker += 1;
- } // end while
- }
- --></script>
- <frame>
- <frame posn="0 76 257">
- <label id="LabelScoreTeam1" valign="bottom" posn="-37 0 0" halign="right" scale="1" />
- <label id="LabelScoreTeam2" valign="bottom" posn=" 37 0 0" halign="left" scale="1" />
- </frame>
- <frame id="FrameSmallPoleText" hidden="1" posn="0 -56 3">
- <label id="LabelCaptureMessage" valign="center" halign="center" posn="0 0 1" textsize="5" />
- <quad id="QuadCaptureMessage" valign="center" halign="center" sizen="18 18" />
- <gauge posn="-30 -5" sizen="60 6" halign="left" style="EnergyBar" id="CaptureGauge" />
- </frame>
- """;
- declare Real ScoresXPos = 93.;//22.;//30;//28;//95; //138
- declare Real ScoresYPos = 90.;//68.5; //71
- declare Real ScoresZPos = 200.; //4
- declare CommonAttribs = """ valign="center" halign="center" """;
- declare PolesByClan = ClanPoles[1].count-1;
- declare Width = 80.;
- declare Margin = 0.5;
- declare ItemNb = 9;
- declare ItemWidth = (Width / ItemNb) - Margin;
- declare ItemHeight = ItemWidth;
- declare LabelTextSize = 1.5;
- declare LeftPosX = -160. + Width - ((ItemWidth + Margin) / 2.);
- declare RightPosX = LeftPosX * -1;
- declare RecordsHidden = "0";
- if (!S_DisplayPoleRecords) RecordsHidden = "1";
- declare Clan1TextColor = Teams[0].ColorText;
- declare Clan2TextColor = Teams[1].ColorText;
- declare Clan1Color = Teams[0].ColorPrimary;
- declare Clan2Color = Teams[1].ColorPrimary;
- declare Text Clan1ColorTextVector = """{{{Clan1Color.X}}} {{{Clan1Color.Y}}} {{{Clan1Color.Z}}} 1.""";
- declare Text Clan2ColorTextVector = """{{{Clan2Color.X}}} {{{Clan2Color.Y}}} {{{Clan2Color.Z}}} 1.""";
- MLPage ^= """<frame posn="{{{LeftPosX}}} {{{ScoresYPos}}} {{{ScoresZPos}}}" id="Frame_Clan1" >""";
- for (I, 0, PolesByClan) {
- declare PoleId = "";
- if (ClanPoles[2].existskey(I)) {
- PoleId = ""^ClanPoles[2][I].Id;
- }
- MLPage ^= """
- <frame posn="{{{-I*(ItemWidth + Margin)}}} 0 0" id="PoleId_{{{PoleId}}}">
- <frame id="PoleFrame{{{I}}}_1" >
- <label posn="0 {{{-ItemHeight*0.3}}} 0" halign="center" valign="center" text="{{{GetLetterFromNumber(I+1)}}}" textsize="{{{LabelTextSize}}}" />
- <quad sizen="{{{ItemWidth}}} {{{ItemHeight}}}" halign="center" image="{{{ImgGoalBg}}}" colorize="000" />
- </frame>
- <frame hidden="1" id="PoleCapturedFrame{{{I}}}_1" >
- <label posn="0 {{{-ItemHeight*0.3}}} 0" halign="center" valign="center" text="{{{Clan1TextColor}}}{{{GetLetterFromNumber(I+1)}}}" textsize="{{{LabelTextSize}}}"/>
- <quad sizen="{{{ItemWidth}}} {{{ItemHeight}}}" halign="center" image="{{{ImgGoalBg}}}" colorize="{{{Clan1ColorTextVector}}}"/>
- </frame>
- <gauge posn="{{{ItemWidth*0.4}}} {{{-ItemHeight*0.9}}}" sizen="{{{ItemHeight*1.5}}} 6." color="{{{Clan1ColorTextVector}}}" style="EnergyBar" drawbg="false" rotation="-90" drawblockbg="false" id="PoleUIGauge{{{I}}}_1" />
- <frame hidden="{{{RecordsHidden}}}">
- <frame posn="0 -{{{ItemHeight + Margin}}}" class="ClanSpecific Clan1">
- <quad posn="{{{-ItemWidth/2.}}} 0" sizen="3 3" style="Icons64x64_1" substyle="First" />
- <label posn="{{{(-ItemWidth/2.)+3}}} 0" sizen="{{{ItemWidth-3}}} 3" textsize="1" text="--.--" id="Label_RB" />
- <quad posn="{{{-ItemWidth/2.}}} -3" sizen="3 3" style="UIConstruction_Buttons" substyle="Author" />
- <label posn="{{{(-ItemWidth/2.)+3}}} -3" sizen="{{{ItemWidth-3}}} 3" textsize="1" text="--.--" id="Label_PB" />
- </frame>
- </frame>
- </frame>
- """;
- }
- MLPage ^= """</frame><frame posn="{{{RightPosX}}} {{{ScoresYPos}}} {{{ScoresZPos}}}" id="Frame_Clan2" >""";
- for (I, 0, PolesByClan) {
- declare PoleId = "";
- if (ClanPoles[1].existskey(I)) {
- PoleId = ""^ClanPoles[1][I].Id;
- }
- MLPage ^= """
- <frame posn="{{{I*(ItemWidth + Margin)}}} 0 0" id="PoleId_{{{PoleId}}}">
- <frame id="PoleFrame{{{I}}}_2" >
- <label posn="0 {{{-ItemHeight*0.3}}} 0" halign="center" valign="center" text="{{{GetLetterFromNumber(I+1)}}}" textsize="{{{LabelTextSize}}}" />
- <quad sizen="{{{ItemWidth}}} {{{ItemHeight}}}" halign="center" image="{{{ImgGoalBg}}}" colorize="000" />
- </frame>
- <frame hidden="1" id="PoleCapturedFrame{{{I}}}_2" >
- <label posn="0 {{{-ItemHeight*0.3}}} 0" halign="center" valign="center" text="{{{Clan2TextColor}}}{{{GetLetterFromNumber(I+1)}}}" textsize="{{{LabelTextSize}}}"/>
- <quad sizen="{{{ItemWidth}}} {{{ItemHeight}}}" halign="center" image="{{{ImgGoalBg}}}" colorize="{{{Clan2ColorTextVector}}}"/>
- </frame>
- <gauge posn="{{{ItemWidth*0.4}}} {{{-ItemHeight*0.9}}}" sizen="{{{ItemHeight*1.5}}} 6." color="{{{Clan2ColorTextVector}}}" style="EnergyBar" drawbg="false" rotation="-90" drawblockbg="false" id="PoleUIGauge{{{I}}}_2" />
- <frame hidden="{{{RecordsHidden}}}">
- <frame posn="0 -{{{ItemHeight + Margin}}}" hidden="{{{RecordsHidden}}}" class="ClanSpecific Clan2">
- <quad posn="{{{-ItemWidth/2.}}} 0" sizen="3 3" style="Icons64x64_1" substyle="First" />
- <label posn="{{{(-ItemWidth/2.)+3}}} 0" sizen="{{{ItemWidth-3}}} 3" textsize="1" text="--.--" id="Label_RB" />
- <quad posn="{{{-ItemWidth/2.}}} -3" sizen="3 3" style="UIConstruction_Buttons" substyle="Author" />
- <label posn="{{{(-ItemWidth/2.)+3}}} -3" sizen="{{{ItemWidth-3}}} 3" textsize="1" text="--.--" id="Label_PB" />
- </frame>
- </frame>
- </frame>
- """;
- }
- MLPage ^= """</frame>""";
- MLPage ^= """</frame>""";
- LayerRoundInfo.ManialinkPage = MLPage;
- }
- ***UpdateTotalCapture***
- ***
- // Victory
- for (Clan, 1, 2) {
- TotalCaptureValue[Clan] = 0;
- NumberOfCapturedPoles[Clan] = 0;
- foreach (Pole in ClanPoles[3-Clan]) {
- TotalCaptureValue[Clan] += Pole.Gauge.Value;
- if (Pole.Gauge.Captured) {
- NumberOfCapturedPoles[Clan] += 1;
- }
- }
- if (NumberOfCapturedPoles[Clan] == ClanPoles[3-Clan].count) Victory::SetRoundWinnerIfNoWinner(Clan);
- }
- if (Now >= EndTime) {
- // Overtime
- if (S_UseOvertime && S_BattleWaves && FirstWaveStartTime >= 0) {
- if (EndTime >= 0) {
- UIManager.UIAll.OverlayHideCountdown = True;
- EndTime = -1;
- Message::CleanAllMessages();
- Message::SendBigMessage(_("Overtime"), 3000, 1, CUIConfig::EUISound::PhaseChange, 0);
- }
- SetOvertime(True);
- if (CurrentAckClan == 1 || CurrentAckClan == 2) {
- if (GetOvertimeAdvantage() < 0) {
- if (TotalCaptureValue[CurrentAckClan] > TotalCaptureValue[3 - CurrentAckClan]) {
- SetOvertimeAdvantage(CurrentAckClan);
- }
- // Attacking clan has less points
- else {
- SetOvertimeAdvantage(3 - CurrentAckClan);
- }
- }
- // Advantaged clan is attacking
- if (GetOvertimeAdvantage() == CurrentAckClan) {
- // Advantaged clan touch an active pole, win of this clan
- if (CaptureOngoing) {
- SetOvertime(False);
- Victory::SetRoundWinnerIfNoWinner(GetOvertimeAdvantage());
- TouchdownUserId = OvertimeCaptureUserId;
- }
- }
- // Disadvantaged clan is attacking
- else {
- // Disadvantaged clan catch back, extended time
- if (TotalCaptureValue[3 - GetOvertimeAdvantage()] >= TotalCaptureValue[GetOvertimeAdvantage()]) {
- SetOvertime(False);
- declare ExtendedTime = MathLib::NearestInteger(S_TimeLimitAfterFirstCapture * ExtendedTimeRatio * 1000.);
- if (ExtendedTime < C_MinimumExtendedTime) {
- ExtendedTime = C_MinimumExtendedTime;
- } else {
- ExtendedTimeRatio *= 0.5;
- }
- EndTime = Now + ExtendedTime;
- UIManager.UIAll.OverlayHideCountdown = False;
- Message::CleanAllMessages();
- Message::SendBigMessage(_("Extended time"), 5000, 1, CUIConfig::EUISound::PhaseChange, 0);
- declare TeamA = GetOvertimeAdvantage() - 1;
- declare TeamB = 3 - GetOvertimeAdvantage() - 1;
- if (Teams.existskey(TeamA) && Teams.existskey(TeamB)) {
- Message::SendStatusMessage(
- TextLib::Compose(
- _("|%1 and %2 are teams names|$<%1$> has equaled $<%2$> score, the round continues."),
- Teams[TeamB].ColorizedName,
- Teams[TeamA].ColorizedName
- ),
- 5000,
- 1
- );
- }
- SetOvertimeAdvantage(-1);
- }
- }
- }
- } else {
- // First Criteria : Current Score
- if (NumberOfCapturedPoles[1] > NumberOfCapturedPoles[2]) Victory::SetRoundWinnerIfNoWinner(1);
- if (NumberOfCapturedPoles[2] > NumberOfCapturedPoles[1]) Victory::SetRoundWinnerIfNoWinner(2);
- // 2nd Criteria : most captured
- if (TotalCaptureValue[1] > TotalCaptureValue[2]) Victory::SetRoundWinnerIfNoWinner(1);
- if (TotalCaptureValue[2] > TotalCaptureValue[1]) Victory::SetRoundWinnerIfNoWinner(2);
- // 3rd Criteria : First capture
- if (FirstClanToStartCapture != 0) Victory::SetRoundWinnerIfNoWinner(FirstClanToStartCapture);
- // 4rth Criteria : Draw
- Victory::SetRoundDrawIfNoWinner();
- FinalCaptureUserId = NullId;
- SetOvertime(False);
- SetOvertimeAdvantage(-1);
- }
- } else {
- SetOvertime(False);
- SetOvertimeAdvantage(-1);
- }
- if(!Victory::NoRoundWinner()) {
- MB_StopRound = True;
- if(S_BattleWaves) {
- +++OnRoundStop+++
- }
- }
- ***
- ***OnRoundStop***
- ***
- // Update the UI before starting the "end round" business
- CurrentAckClan = 0;
- if(UIManager.UIAll.UILayers.existskey(G_TimeLeftLayerId)) {
- declare Removed = UIManager.UIAll.UILayers.removekey(G_TimeLeftLayerId);
- }
- if(S_BattleWaves) {
- +++UIAll+++
- }
- ***
- ***UIAll***
- ***
- declare Integer DurationInSeconds = (DurationBeforePivot/1000) + 1;
- foreach(Player in Players) {
- UpdateTimeLeftUI(Player, CurrentAckClan, DurationInSeconds);
- }
- foreach(Spectator in Spectators) {
- UpdateTimeLeftUI(Spectator, CurrentAckClan, DurationInSeconds);
- }
- ***
- ***UpdateTeamsScoresUI***
- ***
- // Update UI
- declare ClanTotalRatios1 = 100 * TotalCaptureValue[1] / (G_CaptureMaxValue * NbPolesByClan);
- declare ClanTotalRatios2 = 100 * TotalCaptureValue[2] / (G_CaptureMaxValue * NbPolesByClan);
- // Show a precise score if needed
- if(ClanTotalRatios1 == ClanTotalRatios2) {
- if(ClanTotalRatios1 == 0) {
- G_ScoreTeam1 = "";
- G_ScoreTeam2 = "";
- } else {
- declare Real RealRatio1 = TotalCaptureValue[1] / (1.0* (G_CaptureMaxValue * ClanPoles[1].count));
- declare Real RealRatio2 = TotalCaptureValue[2] / (1.0* (G_CaptureMaxValue * ClanPoles[2].count));
- declare Coma1 = MathLib::NearestInteger(1000.*RealRatio1) % 10;
- declare Coma2 = MathLib::NearestInteger(1000.*RealRatio2) % 10;
- G_ScoreTeam1 = ClanTotalRatios1^"."^Coma1^"%";
- G_ScoreTeam2 = ClanTotalRatios2^"."^Coma2^"%";
- }
- } else {
- G_ScoreTeam1 = ClanTotalRatios1^"%";
- G_ScoreTeam2 = ClanTotalRatios2^"%";
- }
- foreach(Player in Players) {
- UpdateScoreTeamsUI(Player);
- }
- foreach(Spectator in Spectators) {
- UpdateScoreTeamsUI(Spectator);
- }
- // Update OverlayScoreSummary
- 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 && PlayerClan2Id != NullId) {
- UIManager.UIAll.OverlayScoreSummary = True;
- UIManager.UIAll.ScoreSummary_Player1 = PlayerClan1Id;
- UIManager.UIAll.ScoreSummary_Points1 = ClanScores[1];
- UIManager.UIAll.ScoreSummary_Gauge1 = ClanTotalRatios1/100.;
- UIManager.UIAll.ScoreSummary_MatchPoints1 = -1;
- UIManager.UIAll.ScoreSummary_Player2 = PlayerClan2Id;
- UIManager.UIAll.ScoreSummary_Points2 = ClanScores[2];
- UIManager.UIAll.ScoreSummary_Gauge2 = ClanTotalRatios2/100.;
- UIManager.UIAll.ScoreSummary_MatchPoints2 = -1;
- } else {
- UIManager.UIAll.OverlayScoreSummary = False;
- }
- ***
- ***MarkersML_ScriptInit***
- ***
- if(S_BattleWaves) {
- MLPage ^= """
- declare netread Integer BattleWaves_AtkClan for UI;
- declare Integer CurrentStateOfAckClanVariable = -1;
- """;
- if(G_EngagePoleId != NullId) {
- MLPage ^= """
- declare CMlFrame EngagePoleFrame = (Page.GetFirstChild("EngagePoleFrame") as CMlFrame);""";
- }
- }
- ***
- ***MarkersML_ScriptLoop***
- ***
- if(S_BattleWaves) {
- MLPage ^= """
- if(CurrentStateOfAckClanVariable != BattleWaves_AtkClan) {
- CurrentStateOfAckClanVariable = BattleWaves_AtkClan;
- if(BattleWaves_AtkClan > 0) {""";
- if(G_EngagePoleId != NullId) {
- MLPage ^= """
- EngagePoleFrame.Hide();""";
- }
- MLPage ^= """
- for (I, 0, PolesByClan-1) {
- PoleFrame[BattleWaves_AtkClan][I].Hide();
- PoleFrame[3-BattleWaves_AtkClan][I].Show();
- }
- } else {""";
- if(G_EngagePoleId != NullId) {
- MLPage ^= """
- EngagePoleFrame.Show();
- for(ClanIndex, 1, 2) {
- for (I, 0, PolesByClan-1) {
- PoleFrame[ClanIndex][I].Hide();
- }
- }
- """;
- } else {
- MLPage ^= """
- declare Integer PlayerClan;
- if(InputPlayer != Null) {
- if((InputPlayer.CurrentClan == 1) || (InputPlayer.CurrentClan == 2)) {
- PlayerClan = InputPlayer.CurrentClan;
- } else {
- PlayerClan = 1;
- }
- } else {
- // arbitrary
- PlayerClan = 1;
- }
- /*
- // sometimes, GUIPlayer does not exist.
- if(GUIPlayer != Null) {
- PlayerClan = GUIPlayer.CurrentClan;
- } else {
- PlayerClan = InputPlayer.CurrentClan;
- }
- */
- for (I, 0, PolesByClan-1) {
- PoleFrame[3-PlayerClan][I].Show();
- PoleFrame[ PlayerClan][I].Hide();
- }
- """;
- }
- MLPage ^= """
- }
- }
- """;
- }
- ***
- ***MarkersML_Markups***
- ***
- if(S_BattleWaves) {
- if(G_EngagePoleId != NullId) {
- declare Vec3 Clan1Color = Teams[1].ColorPrimary; // inverted to avoid the "blue/white/red" effect with default teams ;)
- declare Vec3 Clan2Color = Teams[0].ColorPrimary;
- declare Text ImgPoleEngageLeft = C_ImgBaseDir^"shield_left.dds";
- declare Text ImgPoleEngageRight = C_ImgBaseDir^"shield_right.dds";
- declare Vec3 EngageColor = <.5, .5, .5>;
- declare Real EngagePoleImgSize = 10.;
- declare Pole <=> MapLandmarks_Gauge[G_EngagePoleId];
- MLPage ^= """
- <frame id="PoleMarker{{{Pole.Id}}}" >
- <frame id="EngagePoleFrame">
- <quad posn="-0.1 0." halign="center" valign="center" sizen="{{{WidthFactor*EngagePoleImgSize}}} {{{EngagePoleImgSize}}}" image="{{{
- ImgPoleEngageLeft}}}" colorize="{{{Clan1Color.X}}} {{{Clan1Color.Y}}} {{{Clan1Color.Z}}}" autoscale="False" />
- <quad posn="0.1 0." halign="center" valign="center" sizen="{{{WidthFactor*EngagePoleImgSize}}} {{{EngagePoleImgSize}}}" image="{{{
- ImgPoleEngageRight}}}" colorize="{{{Clan2Color.X}}} {{{Clan2Color.Y}}} {{{Clan2Color.Z}}}" autoscale="False" />
- </frame>
- </frame>""";
- }
- }
- ***
- Text CreateMarkersManialinkPage(CSmMapLandmark[][Integer] ClanPoles)
- {
- declare Text ImgPole = C_ImgBaseDir^"goal.dds";
- declare Text ImgPoleCapture = C_ImgBaseDir^"goal_cap.dds";
- declare Integer ServerPolesByClan = ClanPoles[1].count;
- declare Text MLPage = """
- <script><!--
- #Include "MathLib" as MathLib
- main() {
- while(InputPlayer == Null) yield;
- declare CMlFrame[][Integer] PoleFrame;
- declare CMlQuad [][Integer] PoleQuad;
- declare CMlGauge[][Integer] PoleGauge;
- declare Real[Integer][Integer] CurrentClanPoles;
- declare Integer[Integer][Integer] HighlightTimer;
- declare Integer PolesByClan = 0;
- foreach (Pole in MapLandmarks_Gauge) {
- if (Pole.Tag != "Goal") continue;
- PolesByClan += 1;
- }
- PolesByClan /= 2;
- // Wait data on map change.
- declare Boolean WaitData = True;
- while(WaitData) {
- yield;
- WaitData = False;
- for(ClanIndex, 1, 2) {
- CurrentClanPoles[ClanIndex] = Real[Integer];
- PoleFrame[ClanIndex] = CMlFrame[];
- PoleQuad[ClanIndex] = CMlQuad[];
- PoleGauge[ClanIndex] = CMlGauge[];
- HighlightTimer[ClanIndex] = Integer[Integer];
- for (I, 0, PolesByClan - 1) {
- CurrentClanPoles[ClanIndex][I] = 0.;
- declare CMlFrame TheFrame <=> (Page.GetFirstChild("PoleFrame"^I^"_"^ClanIndex) as CMlFrame);
- if(TheFrame == Null) {
- WaitData = True;
- continue;
- }
- PoleFrame[ClanIndex].add(TheFrame);
- PoleQuad[ClanIndex].add((Page.GetFirstChild("PoleQuad"^I^"_"^ClanIndex) as CMlQuad));
- PoleGauge[ClanIndex].add((Page.GetFirstChild("PoleGauge"^I^"_"^ClanIndex) as CMlGauge));
- HighlightTimer[ClanIndex][I] = Now;
- }
- }
- }
- """;
- +++MarkersML_ScriptInit+++
- MLPage ^= """
- declare Text NeutralColor = "$o$888";
- while(True) {
- sleep(200);
- if(!PageIsVisible) continue;
- declare Clan1PoleIndex = -1;
- declare Clan2PoleIndex = -1;
- foreach(Pole in MapLandmarks_Gauge) {
- if (Pole.Tag != "Goal" && Pole.Tag != "Checkpoint") continue;
- declare Integer PoleClan = Pole.Gauge.Clan;
- declare Integer PoleIndex = -1;
- if(PoleClan == 1) {
- Clan1PoleIndex += 1;
- PoleIndex = Clan1PoleIndex;
- } else if (PoleClan == 2) {
- Clan2PoleIndex += 1;
- PoleIndex = Clan2PoleIndex;
- }
- if(PoleIndex >= 0) {
- declare Integer OpposingClan = 3-PoleClan;
- declare Text ClanTextColor = Teams[2-PoleClan].ColorText;
- declare Real ServerCapture = Pole.Gauge.ValueReal;
- if(ServerCapture != CurrentClanPoles[OpposingClan][PoleIndex]) {
- CurrentClanPoles[OpposingClan][PoleIndex] = ServerCapture;
- HighlightTimer[OpposingClan][PoleIndex] = Now + 500;
- }
- if(ServerCapture >= 0.01) {
- PoleGauge[OpposingClan][PoleIndex].Show();
- }
- if(ServerCapture >= 1.) {
- PoleFrame[OpposingClan][PoleIndex].Hide();
- } else if(HighlightTimer[OpposingClan][PoleIndex] > Now) {
- PoleQuad[OpposingClan][PoleIndex].ImageUrl = "{{{ImgPoleCapture}}}";
- } else {
- PoleQuad[OpposingClan][PoleIndex].ImageUrl = "{{{ImgPole}}}";
- }
- declare Text CaptureLevel = MathLib::NearestInteger(ServerCapture*100)^"%";
- declare Real FakeValue = (MathLib::Sqrt(ServerCapture) + ServerCapture) / 2;
- PoleGauge[OpposingClan][PoleIndex].SetRatio(FakeValue);
- }
- }
- """;
- +++MarkersML_ScriptLoop+++
- MLPage ^= """
- }
- }
- --></script>""";
- declare Real PoleIdLabelYOffset = 1.8;//1.5;//2.;
- declare Real WidthFactor = 9./16.;
- declare Real ImgSize = 9.;//8.;//10.;
- declare Integer NbPoles = ClanPoles[1].count-1;
- //<gauge id="PoleGauge{{{I}}}_{{{ClanIndex}}}" posn="-5 {{{ImgSize}}}" halign="left" sizen="{{{ImgSize}}} {{{ImgSize}}}" clan="{{{3-ClanIndex}}}" style="EnergyBar" drawbg="false" rotation="0"/>
- for(ClanIndex, 1, 2) {
- declare Vec3 ClanColor = Teams[2-ClanIndex].ColorPrimary;
- declare Text ClanColorTextVector = """{{{ClanColor.X}}} {{{ClanColor.Y}}} {{{ClanColor.Z}}} 1.""";
- declare Text ClanTextColor = Teams[2-ClanIndex].ColorText;
- for (I, 0, NbPoles) {
- declare PoleZIndice = (((ClanIndex-1)*NbPoles) + I);
- declare Pole <=> ClanPoles[ClanIndex][I];
- MLPage ^= """
- <frame id="PoleMarker{{{Pole.Id}}}">
- <frame id="PoleFrame{{{I}}}_{{{ClanIndex}}}" posn="0 0 {{{PoleZIndice}}}" >
- <gauge id="PoleGauge{{{I}}}_{{{ClanIndex}}}" posn="2.5 -3. -1" sizen="{{{ImgSize*1.5}}} 6." color="{{{ClanColorTextVector}}}" style="EnergyBar" drawbg="false" rotation="-90" hidden="1" drawblockbg="false" />
- <label posn="0 9" halign="center" id="PoleGaugeLabel{{{I}}}_{{{ClanIndex}}}" textsize="1" />
- <quad halign="center" valign="center" sizen="{{{WidthFactor*ImgSize}}} {{{ImgSize}}}" image="{{{
- ImgPole}}}" id="PoleQuad{{{I}}}_{{{ClanIndex}}}" colorize="{{{
- ClanColor.X}}} {{{ClanColor.Y}}} {{{ClanColor.Z}}}" autoscale="False" />
- <label id="PoleIndexLabel{{{I}}}_{{{ClanIndex}}}" halign="center" valign="center" posn="0 {{{PoleIdLabelYOffset}}}" text="{{{ClanTextColor}}}{{{GetLetterFromNumber(G_PolesIndice[Pole.Id])}}}" textsize="1" />
- </frame>
- </frame>""";
- }
- }
- +++MarkersML_Markups+++
- return MLPage;
- }
- Void ResetAllUIs()
- {
- UIManager.UIAll.BigMessage ="";
- UIManager.UIAll.StatusMessage ="";
- if( UIManager.UIAll.UILayers.existskey(G_LayerRoundInfoId) ) {
- declare Removed = UIManager.UIAll.UILayers.removekey(G_LayerRoundInfoId);
- }
- // Remove markers
- foreach (UI in UIManager.UI) {
- UI.MarkersXML = "";
- }
- }
- Void UpdateTimeLeftUI(CSmPlayer Player, Integer CurrentAckClan, Integer DurationInSeconds) {
- declare UI <=> UIManager.GetUI(Player);
- if (UI == Null) return;
- declare netwrite Integer BattleWaves_TimeLeft for UI;
- declare netwrite Integer BattleWaves_AtkClan for UI;
- BattleWaves_AtkClan = CurrentAckClan;
- BattleWaves_TimeLeft = DurationInSeconds;
- }
- Text BuildTimeLeftManialink(Integer _WavesDuration) {
- // declare EmblemSize = 18;
- declare ArrowsHeight = 18;
- declare EmblemOffset = 24;
- declare Text ImgActionLeft = C_ImgBaseDir^"action_left.dds";
- declare Text ImgActionRight = C_ImgBaseDir^"action_right.dds";
- declare Vec3 ColorClan1 = Teams[1].ColorPrimary;
- declare Vec3 ColorClan2 = Teams[0].ColorPrimary;
- declare MLText = """
- <manialink version="1" name="Battle:TimeLeft">
- <frame posn="0 63 40" halign="center" valign="center" hidden="1" id="FrameTimeLeft">
- <frame posn="0 4">
- <label posn="0 4" halign="center" valign="center" style="TextRaceMessageBig" textsize="4" id="LabelAttack" />
- <label posn="0 -2" halign="center" valign="center" style="TextRaceMessageBig" textsize="4" id="Label_AdditionalRules" />
- <label posn="0 -8" halign="center" valign="center" style="TextRaceMessageBig" textsize="4" id="LabelTimeLeft" />
- </frame>
- </frame>
- <script><!--
- #Include "MathLib" as MathLib
- #Include "TextLib" as TextLib
- main() {
- declare netread Integer BattleWaves_TimeLeft for UI;
- declare netread Integer BattleWaves_AtkClan for UI;
- declare netread Boolean Battle_IsBeginner for UI;
- declare netread Boolean Net_OvertimeActivated for Teams[0];
- declare netread Integer Net_OvertimeAdvantage for Teams[0];
- declare CMlFrame FrameTimeLeft <=> (Page.GetFirstChild("FrameTimeLeft") as CMlFrame);
- declare CMlLabel LabelTimeLeft <=> (Page.GetFirstChild("LabelTimeLeft") as CMlLabel);
- declare CMlLabel LabelAttack <=> (Page.GetFirstChild("LabelAttack") as CMlLabel);
- declare CMlLabel Label_AdditionalRules <=> (Page.GetFirstChild("Label_AdditionalRules") as CMlLabel);
- declare Clan1Color = Teams[0].ColorText;
- declare Clan2Color = Teams[1].ColorText;
- declare PrevAtkClan = -1;
- declare CurrentPlayerClan = -1;
- declare PrevPlayerClan = -1;
- declare PrevOvertimeActivated = False;
- declare PrevOvertimeAdvantage = -1;
- declare PrevBigMessage = "";
- while(True) {
- sleep(100);
- if (GUIPlayer != Null) CurrentPlayerClan = GUIPlayer.CurrentClan;
- else if (InputPlayer != Null && !InputPlayer.RequestsSpectate) CurrentPlayerClan = InputPlayer.CurrentClan;
- else CurrentPlayerClan = -1;
- if (
- PrevAtkClan != BattleWaves_AtkClan
- || PrevPlayerClan != CurrentPlayerClan
- || PrevOvertimeActivated != Net_OvertimeActivated
- || PrevOvertimeAdvantage != Net_OvertimeAdvantage
- || PrevBigMessage != UI.BigMessage
- ) {
- PrevAtkClan = BattleWaves_AtkClan;
- PrevPlayerClan = CurrentPlayerClan;
- PrevOvertimeActivated = Net_OvertimeActivated;
- PrevOvertimeAdvantage = Net_OvertimeAdvantage;
- PrevBigMessage = UI.BigMessage;
- if (BattleWaves_AtkClan <= 0) {
- FrameTimeLeft.Visible = False;
- } else {
- FrameTimeLeft.Visible = True;
- if (CurrentPlayerClan == BattleWaves_AtkClan) {
- LabelAttack.SetText(TextLib::Compose("$s%1", _("|Imperative|Attack")));
- if (Battle_IsBeginner) {
- Label_AdditionalRules.SetText(_("Capture the poles of the opposing team!"));
- LabelTimeLeft.RelativePosition.Y = -8.;
- } else if (Net_OvertimeActivated && UI.BigMessage == "") {
- declare TeamA = Net_OvertimeAdvantage - 1;
- declare TeamB = 3 - Net_OvertimeAdvantage - 1;
- if (Teams.existskey(TeamA) && Teams.existskey(TeamB)) {
- if (BattleWaves_AtkClan == Net_OvertimeAdvantage) {
- Label_AdditionalRules.Value = TextLib::Compose(
- "{{{_("|%1 is a team name|$<%1$> must attack a pole to win.")}}}",
- Teams[TeamA].ColorizedName
- );
- } else {
- Label_AdditionalRules.Value = TextLib::Compose(
- "{{{_("|%1 and %2 are teams names|$<%1$> must equal $<%2$> score.")}}}",
- Teams[TeamB].ColorizedName,
- Teams[TeamA].ColorizedName
- );
- }
- LabelTimeLeft.RelativePosition.Y = -8.;
- } else {
- Label_AdditionalRules.SetText("");
- LabelTimeLeft.RelativePosition.Y = -2.;
- }
- } else {
- Label_AdditionalRules.SetText("");
- LabelTimeLeft.RelativePosition.Y = -2.;
- }
- } else if (CurrentPlayerClan == 3 - BattleWaves_AtkClan) {
- LabelAttack.SetText(TextLib::Compose("$s%1", _("|Imperative|Defend")));
- if (Battle_IsBeginner) {
- Label_AdditionalRules.SetText(_("Prevent your poles from being captured!"));
- LabelTimeLeft.RelativePosition.Y = -8.;
- } else if (Net_OvertimeActivated && UI.BigMessage == "") {
- declare TeamA = Net_OvertimeAdvantage - 1;
- declare TeamB = 3 - Net_OvertimeAdvantage - 1;
- if (Teams.existskey(TeamA) && Teams.existskey(TeamB)) {
- if (BattleWaves_AtkClan == Net_OvertimeAdvantage) {
- Label_AdditionalRules.Value = TextLib::Compose(
- "{{{_("|%1 is a team name|$<%1$> must attack a pole to win.")}}}",
- Teams[TeamA].ColorizedName
- );
- } else {
- Label_AdditionalRules.Value = TextLib::Compose(
- "{{{_("|%1 and %2 are teams names|$<%1$> must equal $<%2$> score.")}}}",
- Teams[TeamB].ColorizedName,
- Teams[TeamA].ColorizedName
- );
- }
- LabelTimeLeft.RelativePosition.Y = -8.;
- } else {
- Label_AdditionalRules.SetText("");
- LabelTimeLeft.RelativePosition.Y = -2.;
- }
- } else {
- Label_AdditionalRules.SetText("");
- LabelTimeLeft.RelativePosition.Y = -2.;
- }
- } else {
- if (Teams.existskey(BattleWaves_AtkClan-1)) {
- LabelAttack.SetText(TextLib::Compose("{{{_("|TeamName is attacking|$<%1$> is attacking")}}}", Teams[BattleWaves_AtkClan-1].ColorizedName));
- if (Net_OvertimeActivated && UI.BigMessage == "") {
- declare TeamA = Net_OvertimeAdvantage - 1;
- declare TeamB = 3 - Net_OvertimeAdvantage - 1;
- if (Teams.existskey(TeamA) && Teams.existskey(TeamB)) {
- if (BattleWaves_AtkClan == Net_OvertimeAdvantage) {
- Label_AdditionalRules.Value = TextLib::Compose(
- "{{{_("|%1 is a team name|$<%1$> must attack a pole to win.")}}}",
- Teams[TeamA].ColorizedName
- );
- } else {
- Label_AdditionalRules.Value = TextLib::Compose(
- "{{{_("|%1 and %2 are teams names|$<%1$> must equal $<%2$> score.")}}}",
- Teams[TeamB].ColorizedName,
- Teams[TeamA].ColorizedName
- );
- }
- LabelTimeLeft.RelativePosition.Y = -8.;
- } else {
- Label_AdditionalRules.SetText("");
- LabelTimeLeft.RelativePosition.Y = -2.;
- }
- } else {
- Label_AdditionalRules.SetText("");
- LabelTimeLeft.RelativePosition.Y = -2.;
- }
- } else {
- LabelAttack.SetText("");
- Label_AdditionalRules.SetText("");
- LabelTimeLeft.RelativePosition.Y = -2.;
- }
- }
- }
- }
- if(BattleWaves_TimeLeft <= {{{_WavesDuration}}}) {
- LabelTimeLeft.SetText("$s"^BattleWaves_TimeLeft);
- } else {
- LabelTimeLeft.SetText("");
- }
- }
- }
- --></script>
- </manialink>""";
- return MLText;
- }
- Void CreateRulesReminderLayer() {
- if(! C_DisplayRulesReminder) return;
- declare Text WelcomeBgImage = C_ImgBaseDir^"WelcomeBg.dds";
- declare Text TitleText = _("You are spectating the game");
- declare Text ModeName = _("Battle Mode");
- declare Text RulesReminder = _("Help your team capture the poles of the opposing team to win.\nYour contribution to victory is given by capture (Cap), attack (Atk) and defense (Def) scores.\nYour ranking depends on the number of hits you performed (Hits)
- during the match.");
- declare Text DoNotShowAgain = _("Do Not Show Again");
- declare Text Close = _("Close");
- declare Integer WindowWidth = 270;
- declare Integer WindowHeight = 25;
- declare Real WindowX = 0.;
- declare Real WindowY = 30.;
- declare Text MLText = """
- <script><!--
- // for the "do not show again" feature
- declare persistent Boolean NadeoBattle_PersistentShowRulesReminder for This = True;
- declare Boolean _TabsLib_ScoresLayerIsVisible for UI;
- declare Boolean _TabsLib_AltLayerIsVisible for UI;
- // NadeoBattle_PersistentShowRulesReminder = True; // Uncomment for testing purpose
- declare netwrite Boolean Battle_UIToServShowRulesReminder for UI = True;
- declare netread Boolean Battle_ServToUIShowFrame for UI;
- declare netread Integer Battle_UIRoundPhase for UI;
- Battle_UIToServShowRulesReminder = True;
- if(! NadeoBattle_PersistentShowRulesReminder) {
- Battle_UIToServShowRulesReminder = False;
- return;
- }
- declare Button_DoNotShowAgain <=> (Page.GetFirstChild("Button_DoNotShowAgain") as CMlLabel);
- declare Button_Close <=> (Page.GetFirstChild("Button_Close") as CMlLabel);
- declare RulesReminderMainFrame <=> (Page.GetFirstChild("RulesReminderMainFrame") as CMlFrame);
- declare Boolean ShowFrame = False;
- declare Boolean SwitchShowFrame = False;
- while(True) {
- yield;
- if(Battle_ServToUIShowFrame != SwitchShowFrame) {
- SwitchShowFrame = Battle_ServToUIShowFrame;
- ShowFrame = True;
- }
- if(
- ! IsSpectatorMode ||
- (_TabsLib_ScoresLayerIsVisible || _TabsLib_AltLayerIsVisible) ||
- (Battle_UIRoundPhase != {{{C_RoundPhase_Playing}}}))
- {
- RulesReminderMainFrame.Hide();
- continue;
- }
- if(ShowFrame) {
- RulesReminderMainFrame.Show();
- }
- foreach(Event in PendingEvents) {
- switch(Event.Type){
- case CMlEvent::Type::MouseClick: {
- if(Event.ControlId == "Button_DoNotShowAgain") {
- NadeoBattle_PersistentShowRulesReminder = False;
- Battle_UIToServShowRulesReminder = False;
- RulesReminderMainFrame.Hide();
- return; // End of this behavior
- }
- if(Event.ControlId == "Button_Close") {
- RulesReminderMainFrame.Hide();
- ShowFrame = False;
- }
- }
- case CMlEvent::Type::KeyPress: {
- if(Event.CharPressed == "2424832" ) { // F1
- RulesReminderMainFrame.Hide();
- ShowFrame = False;
- }
- }
- }
- }
- }
- --></script>
- <frame id="RulesReminderMainFrame" hidden="true" posn="{{{WindowX}}} {{{WindowY}}} 100" >
- <quad posn="0 -2" halign="center" valign="center" sizen="292 44" image="{{{WelcomeBgImage}}}" />
- <label posn="0 {{{(WindowHeight/2)-3}}}" halign="center" valign="center" text="{{{TitleText}}}" textsize="5" />
- <label posn="{{{-(WindowWidth/2)+2}}} {{{(WindowHeight/2)-8}}}" halign="left" valign="center" text="{{{ModeName}}}" textsize="3" textprefix="$0f0"/>
- <label posn="{{{-(WindowWidth/2)+2}}} {{{(WindowHeight/2)-12}}}" halign="left" valign="center" text="{{{RulesReminder}}}" textsize="2"/>
- <label posn="{{{(WindowWidth/2)-2}}} {{{-(WindowHeight/2)+2}}}" halign="right" valign="center" text="{{{DoNotShowAgain}}}" style="CardButtonSmall" ScriptEvents="true" id="Button_DoNotShowAgain" />
- <label posn="{{{(WindowWidth/2)-42}}} {{{-(WindowHeight/2)+2}}}" halign="right" valign="center" text="{{{Close}}}" style="CardButtonSmall" ScriptEvents="true" id="Button_Close" />
- <!--<label halign="center" valign="bottom" posn="0 {{{-(WindowHeight/2)}}}" text="{{{
- _("Press $<$o$f00F1$> to close this window.")}}}" />-->
- </frame>
- """;
- Layers::Create("RulesReminder", MLText);
- Layers::Attach("RulesReminder");
- }
- // ---------------------------------- //
- /// Initialize the warm up properties
- Void InitWarmUp() {
- if (S_NbPlayersPerTeamMax > 0) {
- if (WarmUp2::GroupExists("Clan1")) WarmUp2::SetSlotsNb("Clan1", S_NbPlayersPerTeamMax);
- else WarmUp2::CreateGroup("Clan1", S_NbPlayersPerTeamMax);
- if (WarmUp2::GroupExists("Clan2")) WarmUp2::SetSlotsNb("Clan2", S_NbPlayersPerTeamMax);
- else WarmUp2::CreateGroup("Clan2", S_NbPlayersPerTeamMax);
- WarmUp2::DisplayClanSelection(True);
- } else {
- WarmUp2::DestroyGroup("Clan1");
- WarmUp2::DestroyGroup("Clan2");
- WarmUp2::DisplayClanSelection(False);
- }
- }
- // ---------------------------------- //
- /** Check if the spawns of the players are limited to a specific list
- *
- * @return True if the player spawns are limited, False otherwise
- */
- Boolean SpawnIsLimited() {
- if (WarmUp2::GroupExists("Clan1") && WarmUp2::GroupExists("Clan2")) return True;
- return False;
- }
- // ---------------------------------- //
- /** Check if a player is spawnable
- *
- * @param _Player The player to check
- *
- * @return True if the player is spawnable, false otherwise
- */
- Boolean IsSpawnable(CSmPlayer _Player) {
- if (_Player == Null) return False;
- if (_Player.User.RequestsSpectate) return False;
- if (!SpawnIsLimited()) return True;
- if (WarmUp2::GetPlayerSlot(_Player) <= 0) return False;
- if (_Player.CurrentClan == 1 && WarmUp2::GetPlayerGroup(_Player) == "Clan1") return True;
- if (_Player.CurrentClan == 2 && WarmUp2::GetPlayerGroup(_Player) == "Clan2") return True;
- return False;
- }
- Void ComputeCaptureMaxValue() {
- G_CaptureMaxValue = S_CaptureMaxValue - 100; // small margin to ensure the pole is captured on time.
- if(G_CaptureMaxValue < 500) G_CaptureMaxValue = 500; // 0.5 sec. min
- }
- /**
- * @return True iff the squared distance between A and B is lower than _SqDistance.
- * i.e. ||AB||² <= _SqDistance
- */
- Boolean SqCloserThan(Vec3 _A, Vec3 _B, Real _SqDistance) {
- declare Vec3 VecDistance = _A - _B;
- declare Real ABSqDistance = (VecDistance.X*VecDistance.X) + (VecDistance.Y*VecDistance.Y) + (VecDistance.Z*VecDistance.Z);
- return ABSqDistance <= _SqDistance;
- }
- // ---------------------------------- //
- /** Wait for enough players to play
- *
- * @param _Duration Duration of the warm up
- * @param _MinimumNbPlayers The number of players to wait in each clan before starting the map if there's no duration
- */
- Void WaitForPlayers(Integer _MinimumNbPlayers, Integer _Duration) {
- declare OldSequence = UIManager.UIAll.UISequence;
- UIManager.UIAll.UISequence = CUIConfig::EUISequence::Playing;
- UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::Warning;
- StartTime = Now;
- if (_Duration > 0) {
- UIManager.UIAll.CountdownEndTime = Now + (_Duration * 1000);
- UIManager.UIAll.BigMessage = _("Warm up");
- } else {
- UIManager.UIAll.BigMessage = _("Waiting for players in each team...");
- }
- foreach (Player in AllPlayers) {
- declare UI <=> UIManager.GetUI(Player);
- if (UI != Null) Tabs::UseTabs(UI, "ScoresTab");
- }
- while (!ServerShutdownRequested && !MatchEndRequested) {
- MM_Yield();
- if (_Duration > 0) {
- if (Now >= UIManager.UIAll.CountdownEndTime) break;
- } else {
- if (ClansNbPlayers[1] >= _MinimumNbPlayers && ClansNbPlayers[2] >= _MinimumNbPlayers) break;
- }
- SM::UnspawnPlayersChangingClan();
- foreach(Player in Players) {
- if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned) {
- declare Clan = Battle_GetRequestedClan(Player);
- declare Spawn <=> Map::GetPlayerSpawn("Spawn", Clan);
- if (Spawn != Null) SM::SpawnPlayer(Player, Clan, Spawn);
- }
- }
- foreach (Event in PendingEvents) {
- if (Event.Type == CSmModeEvent::EType::OnPlayerAdded) {
- declare UI <=> UIManager.GetUI(Event.Player);
- if (UI != Null) Tabs::UseTabs(UI, "ScoresTab");
- }
- }
- WarmUp2::ManageEvents();
- }
- SM::UnspawnAllPlayers();
- StartTime = -1;
- UIManager.UIAll.CountdownEndTime = -1;
- UIManager.UIAll.BigMessage = "";
- UIManager.UIAll.UISequence = OldSequence;
- // ---------------------------------- //
- // Update the players clublinks
- if (S_ForceClublinkTeam1 == "" && S_ForceClublinkTeam2 == "") Clublink::DefineTeamAuto();
- else Clublink::DefineTeamFromUrl(S_ForceClublinkTeam1, S_ForceClublinkTeam2);
- }
- Void DoWarmUp() {
- XmlRpc::BeginWarmUp();
- // Shutdown the poles during warmup
- foreach (Goal in MapLandmarks_Gauge) {
- Goal.Gauge.Clan = 0;
- Goal.Gauge.Speed = 0;
- Goal.Gauge.Value = 0;
- Goal.Gauge.Max = 1000;
- Goal.Gauge.Captured = False;
- }
- UIManager.UIAll.UISequence = CUIConfig::EUISequence::Playing;
- UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::PhaseChange;
- UIManager.UIAll.BigMessageSoundVariant = 0;
- UIManager.UIAll.StatusMessage = _("Press F6 once you're ready.");
- UIManager.UIAll.BigMessage = TL::Compose("$f90%1", _("Warm-up"));
- // Wait players sycnhro
- Mode::Synchro_DoBarrier();
- SM::UnspawnAllPlayers();
- foreach (Player in AllPlayers) {
- SetPlayerClan(Player, Battle_GetRequestedClan(Player));
- if (Player.CurrentClan == 1) WarmUp2::SetPlayerGroup(Player, "Clan1");
- else if (Player.CurrentClan == 2) WarmUp2::SetPlayerGroup(Player, "Clan2");
- declare UI <=> UIManager.GetUI(Player);
- if (UI != Null) Tabs::UseTabs(UI, "ScoresTab");
- }
- WarmUp2::Clean();
- WarmUp2::Begin();
- WarmUp2::Fill();
- declare PrevWarmUpDuration = S_WarmUpDuration-1;
- while (!WarmUp2::Stop()) {
- MM_Yield();
- // Let the server sleep if there's no players on it
- if (PlayersNbTotal <= 0) continue;
- foreach (Player in Players) {
- declare RequestedClan = Battle_GetRequestedClan(Player);
- if (Player.CurrentClan != RequestedClan) {
- UnspawnPlayer(Player);
- SetPlayerClan(Player, RequestedClan);
- if (Player.CurrentClan == 1) WarmUp2::SetPlayerGroup(Player, "Clan1");
- else if (Player.CurrentClan == 2) WarmUp2::SetPlayerGroup(Player, "Clan2");
- }
- }
- if (PrevWarmUpDuration != S_WarmUpDuration) {
- PrevWarmUpDuration = S_WarmUpDuration;
- declare LongTimer = S_WarmUpDuration*1000;
- declare ShortTimer = 5000;
- if (LongTimer <= 0) { LongTimer = 0; ShortTimer = 0; }
- WarmUp2::SetGroupTimers("Clan1", [ShortTimer => [-1, S_NbPlayersPerTeamMin], LongTimer => [1, S_NbPlayersPerTeamMin]]);
- WarmUp2::SetGroupTimers("Clan2", [ShortTimer => [-1, S_NbPlayersPerTeamMin], LongTimer => [1, S_NbPlayersPerTeamMin]]);
- }
- WarmUp2::Fill();
- WarmUp2::Loop();
- foreach(Player in Players) {
- if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned) {
- declare Spawn <=> Map::GetPlayerSpawn("Spawn", Battle_GetRequestedClan(Player));
- if (Spawn != Null) SM::SpawnPlayer(Player, Player.CurrentClan, Spawn);
- }
- }
- foreach (Event in PendingEvents) {
- if (Event.Type == CSmModeEvent::EType::OnPlayerAdded) {
- declare UI <=> UIManager.GetUI(Event.Player);
- if (UI != Null) Tabs::UseTabs(UI, "ScoresTab");
- }
- }
- WarmUp2::ManageEvents();
- }
- WarmUp2::End();
- UIManager.UIAll.UISequence = CUIConfig::EUISequence::EndRound;
- UIManager.UIAll.StatusMessage = "";
- UIManager.UIAll.BigMessage = "";
- SM::UnspawnAllPlayers();
- // ---------------------------------- //
- // Update the players clublinks
- if (S_ForceClublinkTeam1 == "" && S_ForceClublinkTeam2 == "") Clublink::DefineTeamAuto();
- else Clublink::DefineTeamFromUrl(S_ForceClublinkTeam1, S_ForceClublinkTeam2);
- XmlRpc::EndWarmUp();
- }
- // ---------------------------------- //
- /** Transfert player for auto team balance
- *
- * @param _CountClan1 Number of players in clan 1
- * @param _CountClan2 Number of players in clan 2
- * @param _HitClan1 Number of hits in clan 1
- * @param _HitClan2 Number of hits in clan 2
- *
- * @return True if a player was transfered, False otherwise
- */
- Boolean AutoTeamBalanceRound_Recursive(Integer _CountClan1, Integer _CountClan2, Integer _HitClan1, Integer _HitClan2) {
- if (_CountClan1 > _CountClan2) {
- declare Diff = (_HitClan1 - _HitClan2) / 2;
- if (Diff < 0) Diff = 0;
- declare MinDiff = -1;
- declare CSmPlayer TransfertPlayer;
- foreach (Player in Players) {
- if (Player.Score == Null || Player.CurrentClan != 1) continue;
- declare CurDiff = MathLib::Abs(Diff - Player.Score.RoundPoints);
- if (MinDiff < 0 || CurDiff < MinDiff) {
- MinDiff = CurDiff;
- TransfertPlayer <=> Player;
- if (MinDiff == 0) break;
- }
- }
- if (TransfertPlayer != Null) {
- declare Battle_BalanceClan for TransfertPlayer = -1;
- Battle_BalanceClan = 2;
- UnspawnPlayer(TransfertPlayer);
- SetPlayerClan(TransfertPlayer, Battle_BalanceClan);
- return True;
- }
- } else if (_CountClan2 > _CountClan1) {
- declare Diff = (_HitClan2 - _HitClan1) / 2;
- if (Diff < 0) Diff = 0;
- declare MinDiff = -1;
- declare CSmPlayer TransfertPlayer;
- foreach (Player in Players) {
- if (Player.Score == Null || Player.CurrentClan != 2) continue;
- declare CurDiff = MathLib::Abs(Diff - Player.Score.RoundPoints);
- if (MinDiff < 0 || CurDiff < MinDiff) {
- MinDiff = CurDiff;
- TransfertPlayer <=> Player;
- if (MinDiff == 0) break;
- }
- }
- if (TransfertPlayer != Null) {
- declare Battle_BalanceClan for TransfertPlayer = -1;
- Battle_BalanceClan = 1;
- UnspawnPlayer(TransfertPlayer);
- SetPlayerClan(TransfertPlayer, Battle_BalanceClan);
- return True;
- }
- }
- return False;
- }
- // ---------------------------------- //
- /// Auto team balance depending on hit and players number
- Void AutoTeamBalanceRound() {
- declare IterationCount = 0;
- // Set the player in the clan they requested before doing the balance
- foreach (Player in Players) {
- declare Battle_BalanceClan for Player = -1;
- declare Battle_PrevClan for Player = -1;
- Battle_BalanceClan = -1;
- Battle_PrevClan = Player.CurrentClan;
- UnspawnPlayer(Player);
- SetPlayerClan(Player, Battle_GetRequestedClan(Player));
- }
- while (True) {
- IterationCount += 1;
- if (IterationCount > 128) break;
- declare CountClan1 = 0;
- declare CountClan2 = 0;
- declare HitClan1 = 0;
- declare HitClan2 = 0;
- foreach (Player in Players) {
- if (Player.CurrentClan == 1) {
- CountClan1 += 1;
- if (Player.Score != Null) HitClan1 += Player.Score.RoundPoints;
- } else if (Player.CurrentClan == 2) {
- CountClan2 += 1;
- if (Player.Score != Null) HitClan2 += Player.Score.RoundPoints;
- }
- }
- declare CountDiff = MathLib::Abs(CountClan1 - CountClan2);
- if (CountDiff < S_AutoBalanceDelta || CountDiff < 2) break;
- declare Transfered = AutoTeamBalanceRound_Recursive(CountClan1, CountClan2, HitClan1, HitClan2);
- if (!Transfered) break;
- MM_Yield();
- }
- foreach (Player in Players) {
- declare Battle_PrevClan for Player = -1;
- if (Battle_PrevClan >= 0 && Battle_PrevClan != Player.CurrentClan && (Player.CurrentClan == 1 || Player.CurrentClan == 2)) {
- declare UI <=> UIManager.GetUI(Player);
- if (UI != Null) UI.SendChat(TextLib::Compose(
- _("|%1 is the name of the team|Auto team balance, you are transfered to the $<%1$> team."),
- Teams[Player.CurrentClan-1].ColorizedName)
- );
- }
- }
- }
- // ---------------------------------- //
- /** Get the runners ranking
- *
- * @param _Level Can be "round" or "map"
- *
- * @return An array containing the ranking of the runners
- */
- Integer[Text] GetRunnersRanking(Text _Level) {
- if (_Level == "map") {
- declare Integer[Text] MapTop_CaptureTimePoints for This;
- return MapTop_CaptureTimePoints;
- }
- declare Integer[Text] Ranking;
- declare Integer[Text][Ident] CaptureTimeRanking;
- foreach (Player in AllPlayers) {
- declare Integer[Ident] RoundTop_CaptureTime for Player.Score;
- foreach (PoleId => CaptureTime in RoundTop_CaptureTime) {
- if (!CaptureTimeRanking.existskey(PoleId)) CaptureTimeRanking[PoleId] = Integer[Text];
- CaptureTimeRanking[PoleId][Player.User.Login] = CaptureTime;
- }
- }
- declare PointsRepartition = [10, 6, 4, 3, 2, 1];
- foreach (PoleId => PoleRanking in CaptureTimeRanking) {
- declare SortedRanking = PoleRanking.sort();
- declare PointsKey = 0;
- foreach (PlayerLogin => CaptureTime in SortedRanking) {
- if (!Ranking.existskey(PlayerLogin)) Ranking[PlayerLogin] = 0;
- declare Points = 0;
- if (PointsRepartition.existskey(PointsKey)) Points = PointsRepartition[PointsKey];
- Ranking[PlayerLogin] -= Points;
- PointsKey += 1;
- }
- }
- declare Text EngageLogin for This;
- if (EngageLogin != "") {
- if (!Ranking.existskey(EngageLogin)) Ranking[EngageLogin] = 0;
- Ranking[EngageLogin] -= 10;
- }
- return Ranking;
- }
- // ---------------------------------- //
- /// Add the round points to the map points
- Void UpdateMapRunnersRanking() {
- declare RoundRanking = GetRunnersRanking("round");
- declare Integer[Text] MapTop_CaptureTimePoints for This;
- foreach (Login => Points in RoundRanking) {
- if (!MapTop_CaptureTimePoints.existskey(Login)) MapTop_CaptureTimePoints[Login] = 0;
- MapTop_CaptureTimePoints[Login] += Points;
- }
- }
- // ---------------------------------- //
- /// Reset the runners map ranking
- Void ResetMapRunnersRanking() {
- declare Integer[Text] MapTop_CaptureTimePoints for This;
- MapTop_CaptureTimePoints.clear();
- }
- // ---------------------------------- //
- /** Set the top 5 name and ranking
- *
- * @param _Name Name of the top 5
- * @param _Ranking Ranking of the top 5
- */
- Void UpdateTop5(Text _Name, Integer[Text] _Ranking) {
- declare netwrite Integer Net_RoundTop_Update for Teams[0];
- declare netwrite Integer[Text] Net_RoundTop_Ranking for Teams[0];
- declare netwrite Text Net_RoundTop_Name for Teams[0];
- Net_RoundTop_Ranking = _Ranking;
- Net_RoundTop_Name = _Name;
- Net_RoundTop_Update = Now;
- }
- // ---------------------------------- //
- /** Launch the top 5 sequence
- *
- * @param _Level Can be "round" or "map"
- */
- Void LaunchTop5Sequence(Text _Level) {
- if (ServerShutdownRequested || MatchEndRequested) return;
- declare PrevUISequence = UIManager.UIAll.UISequence;
- UIManager.UIAll.UISequence = CUIConfig::EUISequence::EndRound;
- UIManager.UIAll.UISequence = CUIConfig::EUISequence::Podium;
- UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::Silence;
- Layers::Show("Top5");
- declare Tops = ["Runners", "Attack", "Defense", "Capture", "Hits"];
- if (!S_DisplayPoleRecords) {
- declare Removed = Tops.remove("Runners");
- }
- if (S_DisplayTopsOnlyShooter) Tops = ["Hits"];
- foreach (Top in Tops) {
- declare Integer[Text] Ranking;
- switch (Top) {
- case "Runners": {
- Ranking = GetRunnersRanking(_Level);
- if (_Level == "round") {
- UIManager.UIAll.StatusMessage = _("Best runner of the round");
- } else {
- UIManager.UIAll.StatusMessage = _("Best runner of the map");
- }
- }
- case "Attack": {
- if (_Level == "round") {
- foreach (Player in AllPlayers) {
- declare Integer Battle_ScoreAttack for Player;
- Ranking[Player.User.Login] = -Battle_ScoreAttack;
- }
- UIManager.UIAll.StatusMessage = _("Best attacker of the round");
- } else {
- foreach (Player in AllPlayers) {
- declare Integer MapAttack for Player;
- Ranking[Player.User.Login] = -MapAttack;
- }
- UIManager.UIAll.StatusMessage = _("Best attacker of the map");
- }
- }
- case "Defense": {
- if (_Level == "round") {
- foreach (Player in AllPlayers) {
- declare Integer Battle_ScoreDefense for Player;
- Ranking[Player.User.Login] = -Battle_ScoreDefense;
- }
- UIManager.UIAll.StatusMessage = _("Best defender of the round");
- } else {
- foreach (Player in AllPlayers) {
- declare Integer MapDefense for Player;
- Ranking[Player.User.Login] = -MapDefense;
- }
- UIManager.UIAll.StatusMessage = _("Best defender of the map");
- }
- }
- case "Capture": {
- if (_Level == "round") {
- foreach (Player in AllPlayers) {
- declare Integer Battle_ScoreCapture for Player;
- Ranking[Player.User.Login] = -Battle_ScoreCapture;
- }
- UIManager.UIAll.StatusMessage = _("Best capturer of the round");
- } else {
- foreach (Player in AllPlayers) {
- declare Integer MapCapture for Player;
- Ranking[Player.User.Login] = -MapCapture;
- }
- UIManager.UIAll.StatusMessage = _("Best capturer of the map");
- }
- }
- case "Hits": {
- if (_Level == "round") {
- foreach (Player in AllPlayers) {
- declare Integer Battle_ScoreHit for Player.Score;
- Ranking[Player.User.Login] = -Battle_ScoreHit;
- }
- UIManager.UIAll.StatusMessage = _("Best shooter of the round");
- } else {
- foreach (Player in AllPlayers) {
- declare Integer MapHit for Player;
- Ranking[Player.User.Login] = -MapHit;
- }
- UIManager.UIAll.StatusMessage = _("Best shooter of the map");
- }
- }
- }
- declare InvertedRanking = Ranking.sort();
- Ranking.clear();
- UIManager.UIAll.UISequence_PodiumPlayersWin = "";
- declare BestPlayerName = "";
- declare Count = 0;
- foreach (Login => Points in InvertedRanking) {
- Count += 1;
- Ranking[Login] = Points * -1;
- if (BestPlayerName == "") {
- declare User = SM::GetUser(Login);
- if (User != Null) BestPlayerName = User.Name;
- }
- if (Count <= 3) {
- if (UIManager.UIAll.UISequence_PodiumPlayersWin != "") UIManager.UIAll.UISequence_PodiumPlayersWin ^= ",";
- UIManager.UIAll.UISequence_PodiumPlayersWin ^= Login;
- }
- }
- UpdateTop5(Top, Ranking);
- UIManager.UIAll.BigMessage = BestPlayerName;
- Mode::PlaySound(CUIConfig::EUISound::Notice, 0);
- MM_Sleep(C_Top5SequenceDuration / Tops.count);
- }
- Layers::Hide("Top5");
- UIManager.UIAll.UISequence_PodiumPlayersWin = "";
- UIManager.UIAll.UISequence = CUIConfig::EUISequence::EndRound;
- UIManager.UIAll.UISequence = PrevUISequence;
- UIManager.UIAll.StatusMessage = "";
- UIManager.UIAll.BigMessage = "";
- }
- // ---------------------------------- //
- /// Get the top 5 manialink
- Text GetMLTop5() {
- declare BgTop = C_ImgBaseDir^"topsbg2.dds";
- declare BgLine = C_ImgBaseDir^"TopsLine.png";
- declare BgTitle = "file://Media/Manialinks/Common/Lobbies/small-button-RED.dds";
- declare CardSizeY = 6.;
- declare RankSizeX = 5.;
- declare NameSizeX = 30.;
- declare RecordSizeX = 9.;
- declare NamePosX = RankSizeX;
- declare RecordPosX = NamePosX + NameSizeX + RecordSizeX;
- return """
- <manialink version="1" name="Battle:Top5">
- <framemodel id="Framemodel_TopEntry">
- <format style="TextCardSmallScores2" />
- <label posn="{{{RankSizeX/2.}}} 0.3" sizen="{{{RankSizeX}}} {{{CardSizeY}}}" halign="center" valign="center" style="TextTitle3" textcolor="000" opacity="0.5" id="Label_Rank" />
- <quad posn="{{{NamePosX+0.15}}} 3 2" sizen="{{{NameSizeX+RecordSizeX-0.1}}} {{{CardSizeY}}}" image="{{{BgLine}}}" opacity="0.8" />
- <quad posn="{{{NamePosX+0.8}}} 1.6 3" sizen="3.5 3.5" image="file://Avatars/LoginDuJoueur/Default" id="Quad_Avatar"/>
- <label posn="{{{NamePosX+4.8}}} 0.3 4" sizen="{{{NameSizeX-2.}}} {{{CardSizeY}}}" valign="center" id="Label_Name" />
- <label posn="{{{RecordPosX-1.}}} 0.3 5" sizen="{{{RecordSizeX-5.}}} {{{CardSizeY}}}" halign="right" valign="center" id="Label_Value" />
- </framemodel>
- <frame posn="-160 31" id="Frame_Tops">
- <quad posn="-5.70 5 -1" sizen="60 42" image="{{{BgTop}}}" />
- <quad posn="3 3" sizen="43 6" image="{{{BgTitle}}}" id="Quad_ButtonRed" />
- <label posn="25 -1.8" sizen="50 5" scale="0.8" halign="center" valign="bottom" style="TextButtonBig" textcolor="fff" textemboss="1" id="Label_Title"/>
- <frame posn="2 -1" id="Frame_Top">
- <frameinstance posn="0 -6" modelid="Framemodel_TopEntry" />
- <frameinstance posn="0 -12" modelid="Framemodel_TopEntry" />
- <frameinstance posn="0 -18" modelid="Framemodel_TopEntry" />
- <frameinstance posn="0 -24" modelid="Framemodel_TopEntry" />
- <frameinstance posn="0 -30" modelid="Framemodel_TopEntry" />
- </frame>
- </frame>
- <frame posn="0 42" id="Frame_Message">
- <label halign="center" textemboss="1" style="TextValueSmallSm" textcolor="fff" text="bla" id="Label_MyRank" />
- </frame>
- <script><!--
- #Include "TextLib" as TL
- Text GetNickname(Text _Login) {
- foreach (Player in Players) {
- if (Player.Login == _Login) return Player.Name;
- }
- return _Login;
- }
- Void UpdateRanking(Text _Name, Integer[Text] _Ranking) {
- declare Label_Title <=> (Page.GetFirstChild("Label_Title") as CMlLabel);
- Label_Title.Value = _Name;
- declare Integer[] Points;
- declare Text[] Logins;
- declare MaxRank = 0;
- declare MyRank = 0;
- foreach (Login => Score in _Ranking) {
- Logins.add(Login);
- Points.add(Score);
- MaxRank += 1;
- if (Login == InputPlayer.Login) MyRank = MaxRank;
- }
- declare Label_MyRank <=> (Page.GetFirstChild("Label_MyRank") as CMlLabel);
- if (MaxRank > 0 && MyRank > 0) {
- Label_MyRank.Value = TL::Compose("{{{_("You are ranked %1/%2")}}}", TL::ToText(MyRank), TL::ToText(MaxRank));
- Label_MyRank.Visible = True;
- } else {
- Label_MyRank.Visible = False;
- }
- declare Frame_Top <=> (Page.GetFirstChild("Frame_Top") as CMlFrame);
- foreach (Key => Control in Frame_Top.Controls) {
- declare Frame_TopEntry <=> (Control as CMlFrame);
- declare Label_Rank <=> (Frame_TopEntry.GetFirstChild("Label_Rank") as CMlLabel);
- declare Quad_Avatar <=> (Frame_TopEntry.GetFirstChild("Quad_Avatar") as CMlQuad);
- declare Label_Name <=> (Frame_TopEntry.GetFirstChild("Label_Name") as CMlLabel);
- declare Label_Value <=> (Frame_TopEntry.GetFirstChild("Label_Value") as CMlLabel);
- Label_Rank.Value = TL::ToText(Key + 1);
- if (Logins.existskey(Key)) {
- declare Login = Logins[Key];
- Quad_Avatar.Visible = True;
- Quad_Avatar.ImageUrl = "file://Avatars/"^Login^"/Default";
- Label_Name.Value = GetNickname(Login);
- Label_Value.Value = TL::ToText(Points[Key]);
- } else {
- Quad_Avatar.Visible = False;
- Label_Name.Value = "---";
- Label_Value.Value = "---";
- }
- }
- }
- main() {
- declare netread Integer Net_RoundTop_Update for Teams[0];
- declare netread Integer[Text] Net_RoundTop_Ranking for Teams[0];
- declare netread Text Net_RoundTop_Name for Teams[0];
- declare PrevTopName = "";
- declare PrevUpdate = -1;
- while (True) {
- yield;
- if (!PageIsVisible || InputPlayer == Null) continue;
- if (PrevUpdate != Net_RoundTop_Update) {
- PrevUpdate = Net_RoundTop_Update;
- UpdateRanking(Net_RoundTop_Name, Net_RoundTop_Ranking);
- }
- }
- }
- --></script>
- </manialink>
- """;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement