aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Battlegrounds/Battleground.h4
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp1
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp2
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp951
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundWS.h165
-rw-r--r--src/server/game/Entities/Player/Player.cpp13
6 files changed, 409 insertions, 727 deletions
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index 2b8698860d1..2b5b204732f 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -106,7 +106,9 @@ enum BattlegroundSpells
SPELL_ARENA_PREPARATION = 32727, // use this one, 32728 not correct
SPELL_PREPARATION = 44521, // Preparation
SPELL_SPIRIT_HEAL_MANA = 44535, // Spirit Heal
- SPELL_RECENTLY_DROPPED_FLAG = 42792, // Recently Dropped Flag
+ SPELL_RECENTLY_DROPPED_ALLIANCE_FLAG = 42792, // makes Alliance flag unselectable
+ SPELL_RECENTLY_DROPPED_HORDE_FLAG = 50326, // makes Horde flag unselectable
+ SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG = 50327, // makes Neutral flag unselectable
SPELL_AURA_PLAYER_INACTIVE = 43681, // Inactive
SPELL_HONORABLE_DEFENDER_25Y = 68652, // +50% honor when standing at a capture point that you control, 25yards radius (added in 3.2)
SPELL_HONORABLE_DEFENDER_60Y = 66157, // +50% honor when standing at a capture point that you control, 60yards radius (added in 3.2), probably for 40+ player battlegrounds
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 5b4b958042a..c2c106c43b6 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -330,6 +330,7 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundQueueTypeId que
bg = new BattlegroundAV(bg_template);
break;
case BATTLEGROUND_WS:
+ case BATTLEGROUND_WG_CTF:
bg = new BattlegroundWS(bg_template);
break;
case BATTLEGROUND_AB:
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
index e258b762f68..c842de57e3d 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
@@ -640,7 +640,7 @@ void BattlegroundEY::EventPlayerDroppedFlag(Player* player)
player->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
m_FlagState = BG_EY_FLAG_STATE_ON_GROUND;
m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
- player->CastSpell(player, SPELL_RECENTLY_DROPPED_FLAG, true);
+ player->CastSpell(player, SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG, true);
player->CastSpell(player, BG_EY_PLAYER_DROPPED_FLAG_SPELL, true);
//this does not work correctly :((it should remove flag carrier name)
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
index aa84185f559..6a64373e8ef 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
@@ -16,6 +16,7 @@
*/
#include "BattlegroundWS.h"
+#include "AreaTrigger.h"
#include "BattlegroundMgr.h"
#include "DB2Stores.h"
#include "GameObject.h"
@@ -26,6 +27,7 @@
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Player.h"
+#include "SpellAuras.h"
#include "SpellInfo.h"
// these variables aren't used outside of this file, so declare them only here
@@ -45,30 +47,25 @@ uint32 BG_WSG_Honor[2][BG_WSG_REWARD_NUM] =
BattlegroundWS::BattlegroundWS(BattlegroundTemplate const* battlegroundTemplate) : Battleground(battlegroundTemplate)
{
- BgObjects.resize(BG_WS_OBJECT_MAX);
- BgCreatures.resize(BG_CREATURES_MAX_WS);
+ BgObjects.resize(0);
+ BgCreatures.resize(0);
StartMessageIds[BG_STARTING_EVENT_SECOND] = BG_WS_TEXT_START_ONE_MINUTE;
StartMessageIds[BG_STARTING_EVENT_THIRD] = BG_WS_TEXT_START_HALF_MINUTE;
StartMessageIds[BG_STARTING_EVENT_FOURTH] = BG_WS_TEXT_BATTLE_HAS_BEGUN;
- _flagSpellForceTimer = 0;
_bothFlagsKept = false;
- _flagDebuffState = 0;
- m_FlagKeepers[TEAM_ALLIANCE].Clear();
- m_FlagKeepers[TEAM_HORDE].Clear();
- m_DroppedFlagGUID[TEAM_ALLIANCE].Clear();
- m_DroppedFlagGUID[TEAM_HORDE].Clear();
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
- _flagsTimer[TEAM_ALLIANCE] = 0;
- _flagsTimer[TEAM_HORDE] = 0;
- _flagsDropTimer[TEAM_ALLIANCE] = 0;
- _flagsDropTimer[TEAM_HORDE] = 0;
+
_lastFlagCaptureTeam = 0;
m_ReputationCapture = 0;
m_HonorWinKills = 0;
m_HonorEndKills = 0;
+
+ _flags = { };
+ _capturePointAreaTriggers = { };
+
+ _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
+ _assaultStackCount = 0;
}
BattlegroundWS::~BattlegroundWS() { }
@@ -77,17 +74,17 @@ void BattlegroundWS::PostUpdateImpl(uint32 diff)
{
if (GetStatus() == STATUS_IN_PROGRESS)
{
- if (GetElapsedTime() >= 17*MINUTE*IN_MILLISECONDS)
+ if (GetElapsedTime() >= 17 * MINUTE * IN_MILLISECONDS)
{
if (GetTeamScore(TEAM_ALLIANCE) == 0)
{
- if (GetTeamScore(TEAM_HORDE) == 0) // No one scored - result is tie
+ if (GetTeamScore(TEAM_HORDE) == 0) // No one scored - result is tie
EndBattleground(0);
- else // Horde has more points and thus wins
+ else // Horde has more points and thus wins
EndBattleground(HORDE);
}
- else if (GetTeamScore(TEAM_HORDE) == 0)
- EndBattleground(ALLIANCE); // Alliance has > 0, Horde has 0, alliance wins
+ else if (GetTeamScore(TEAM_HORDE) == 0) // Alliance has > 0, Horde has 0, alliance wins
+ EndBattleground(ALLIANCE);
else if (GetTeamScore(TEAM_HORDE) == GetTeamScore(TEAM_ALLIANCE)) // Team score equal, winner is team that scored the last flag
EndBattleground(_lastFlagCaptureTeam);
else if (GetTeamScore(TEAM_HORDE) > GetTeamScore(TEAM_ALLIANCE)) // Last but not least, check who has the higher score
@@ -96,541 +93,155 @@ void BattlegroundWS::PostUpdateImpl(uint32 diff)
EndBattleground(ALLIANCE);
}
- if (_flagState[TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
- {
- _flagsTimer[TEAM_ALLIANCE] -= diff;
-
- if (_flagsTimer[TEAM_ALLIANCE] < 0)
- {
- _flagsTimer[TEAM_ALLIANCE] = 0;
- RespawnFlag(ALLIANCE, true);
- }
- }
-
- if (_flagState[TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
- {
- _flagsDropTimer[TEAM_ALLIANCE] -= diff;
-
- if (_flagsDropTimer[TEAM_ALLIANCE] < 0)
- {
- _flagsDropTimer[TEAM_ALLIANCE] = 0;
- RespawnFlagAfterDrop(ALLIANCE);
- _bothFlagsKept = false;
- }
- }
-
- if (_flagState[TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
- {
- _flagsTimer[TEAM_HORDE] -= diff;
-
- if (_flagsTimer[TEAM_HORDE] < 0)
- {
- _flagsTimer[TEAM_HORDE] = 0;
- RespawnFlag(HORDE, true);
- }
- }
-
- if (_flagState[TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
- {
- _flagsDropTimer[TEAM_HORDE] -= diff;
-
- if (_flagsDropTimer[TEAM_HORDE] < 0)
- {
- _flagsDropTimer[TEAM_HORDE] = 0;
- RespawnFlagAfterDrop(HORDE);
- _bothFlagsKept = false;
- }
- }
-
if (_bothFlagsKept)
{
- _flagSpellForceTimer += diff;
- if (_flagDebuffState == 0 && _flagSpellForceTimer >= 10*MINUTE*IN_MILLISECONDS) //10 minutes
+ _flagAssaultTimer.Update(diff);
+ if (_flagAssaultTimer.Passed())
{
- // Apply Stage 1 (Focused Assault)
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[0]))
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[1]))
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- _flagDebuffState = 1;
- }
- else if (_flagDebuffState == 1 && _flagSpellForceTimer >= 15*MINUTE*IN_MILLISECONDS) //15 minutes
- {
- // Apply Stage 2 (Brutal Assault)
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[0]))
- {
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[1]))
- {
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
- _flagDebuffState = 2;
- }
- }
- else if ((_flagState[TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_BASE || _flagState[TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN) &&
- (_flagState[TEAM_HORDE] == BG_WS_FLAG_STATE_ON_BASE || _flagState[TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN))
- {
- // Both flags are in base or awaiting respawn.
- // Remove assault debuffs, reset timers
+ _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
+ _assaultStackCount++;
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[0]))
- {
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
- }
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[1]))
- {
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
+ // update assault debuff stacks
+ DoForFlagKeepers([&](Player* player) -> void
+ {
+ ApplyAssaultDebuffToPlayer(player);
+ });
}
-
- _flagSpellForceTimer = 0; //reset timer.
- _flagDebuffState = 0;
}
}
}
-void BattlegroundWS::StartingEventCloseDoors()
+void BattlegroundWS::DoForFlagKeepers(std::function<void(Player*)> action) const
{
- for (uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; ++i)
+ for (ObjectGuid flagGUID : _flags)
{
- DoorClose(i);
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
+ if (GameObject* flag = GetBgMap()->GetGameObject(flagGUID))
+ {
+ if (Player* carrier = ObjectAccessor::FindPlayer(flag->GetFlagCarrierGUID()))
+ action(carrier);
+ }
}
- for (uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i)
- SpawnBGObject(i, RESPAWN_ONE_DAY);
-}
-
-void BattlegroundWS::StartingEventOpenDoors()
-{
- for (uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_6; ++i)
- DoorOpen(i);
- for (uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_4; ++i)
- DoorOpen(i);
-
- for (uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i)
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
-
- SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY);
- SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY);
- SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY);
- SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY);
-
- UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 1);
- UpdateWorldState(BG_WS_STATE_TIMER, GameTime::GetGameTime() + 15 * MINUTE);
-
- // players joining later are not eligibles
- TriggerGameEvent(WS_EVENT_START_BATTLE);
}
-void BattlegroundWS::AddPlayer(Player* player, BattlegroundQueueTypeId queueId)
+void BattlegroundWS::ResetAssaultDebuff()
{
- bool const isInBattleground = IsPlayerInBattleground(player->GetGUID());
- Battleground::AddPlayer(player, queueId);
- if (!isInBattleground)
- PlayerScores[player->GetGUID()] = new BattlegroundWGScore(player->GetGUID(), player->GetBGTeam());
-}
-
-void BattlegroundWS::RespawnFlag(uint32 Team, bool captured)
-{
- if (Team == ALLIANCE)
- {
- TC_LOG_DEBUG("bg.battleground", "Respawn Alliance flag");
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
- }
- else
- {
- TC_LOG_DEBUG("bg.battleground", "Respawn Horde flag");
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
- }
-
- if (captured)
- {
- //when map_update will be allowed for battlegrounds this code will be useless
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
- SendBroadcastText(BG_WS_TEXT_FLAGS_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
- PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED); // flag respawned sound...
- }
_bothFlagsKept = false;
+ _assaultStackCount = 0;
+ _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
+ DoForFlagKeepers([&](Player* player) -> void
+ {
+ RemoveAssaultDebuffFromPlayer(player);
+ });
}
-void BattlegroundWS::RespawnFlagAfterDrop(uint32 team)
+void BattlegroundWS::ApplyAssaultDebuffToPlayer(Player* player)
{
- if (GetStatus() != STATUS_IN_PROGRESS)
+ if (_assaultStackCount == 0)
return;
- RespawnFlag(team, false);
- if (team == ALLIANCE)
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
- else
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
-
- SendBroadcastText(BG_WS_TEXT_FLAGS_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
- PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
-
- if (GameObject* obj = GetBgMap()->GetGameObject(GetDroppedFlagGUID(team)))
- obj->Delete();
- else
- TC_LOG_ERROR("bg.battleground", "unknown dropped flag ({})", GetDroppedFlagGUID(team).ToString());
-
- SetDroppedFlagGUID(ObjectGuid::Empty, GetTeamIndexByTeamId(team));
- _bothFlagsKept = false;
- // Check opposing flag if it is in capture zone; if so, capture it
- HandleFlagRoomCapturePoint(team == ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
-}
-
-void BattlegroundWS::EventPlayerCapturedFlag(Player* player)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- uint32 winner = 0;
-
- player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
- uint32 team = GetPlayerTeam(player->GetGUID());
- if (team == ALLIANCE)
- {
- if (!IsHordeFlagPickedup())
- return;
- SetHordeFlagPicker(ObjectGuid::Empty); // must be before aura remove to prevent 2 events (drop+capture) at the same time
- // horde flag in base (but not respawned yet)
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
- // Drop Horde Flag from Player
- player->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
- if (_flagDebuffState == 1)
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- else if (_flagDebuffState == 2)
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
-
- if (GetTeamScore(TEAM_ALLIANCE) < BG_WS_MAX_TEAM_SCORE)
- AddPoint(ALLIANCE, 1);
- PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
- RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
- }
- else
+ uint32 spellId = WS_SPELL_FOCUSED_ASSAULT;
+ if (_assaultStackCount >= FLAG_BRUTAL_ASSAULT_STACK_COUNT)
{
- if (!IsAllianceFlagPickedup())
- return;
- SetAllianceFlagPicker(ObjectGuid::Empty); // must be before aura remove to prevent 2 events (drop+capture) at the same time
- // alliance flag in base (but not respawned yet)
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
- // Drop Alliance Flag from Player
- player->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
- if (_flagDebuffState == 1)
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- else if (_flagDebuffState == 2)
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
-
- if (GetTeamScore(TEAM_HORDE) < BG_WS_MAX_TEAM_SCORE)
- AddPoint(HORDE, 1);
- PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
- RewardReputationToTeam(889, m_ReputationCapture, HORDE);
+ player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
+ spellId = WS_SPELL_BRUTAL_ASSAULT;
}
- //for flag capture is reward 2 honorable kills
- RewardHonorToTeam(GetBonusHonorFromKill(2), team);
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, BG_WS_FLAG_RESPAWN_TIME);
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, BG_WS_FLAG_RESPAWN_TIME);
-
- if (team == ALLIANCE)
- SendBroadcastText(BG_WS_TEXT_CAPTURED_HORDE_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- else
- SendBroadcastText(BG_WS_TEXT_CAPTURED_ALLIANCE_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
-
- UpdateFlagState(team, BG_WS_FLAG_STATE_WAIT_RESPAWN); // flag state none
- UpdateTeamScore(GetTeamIndexByTeamId(team));
- // only flag capture should be updated
- UpdatePlayerScore(player, SCORE_FLAG_CAPTURES, 1); // +1 flag captures
-
- // update last flag capture to be used if teamscore is equal
- SetLastFlagCapture(team);
-
- if (GetTeamScore(TEAM_ALLIANCE) == BG_WS_MAX_TEAM_SCORE)
- winner = ALLIANCE;
-
- if (GetTeamScore(TEAM_HORDE) == BG_WS_MAX_TEAM_SCORE)
- winner = HORDE;
-
- if (winner)
+ Aura* aura = player->GetAura(spellId);
+ if (!aura)
{
- UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, 1);
- UpdateWorldState(BG_WS_FLAG_STATE_HORDE, 1);
- UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 0);
-
- RewardHonorToTeam(BG_WSG_Honor[BattlegroundMgr::IsBGWeekend(BATTLEGROUND_WS) ? 1 : 0][BG_WSG_WIN], winner);
- EndBattleground(winner);
- }
- else
- {
- _flagsTimer[GetTeamIndexByTeamId(team) ? 0 : 1] = BG_WS_FLAG_RESPAWN_TIME;
+ player->CastSpell(player, spellId, true);
+ aura = player->GetAura(spellId);
}
+
+ if (aura)
+ aura->SetStackAmount(_assaultStackCount);
}
-void BattlegroundWS::HandleFlagRoomCapturePoint(int32 team)
+
+void BattlegroundWS::RemoveAssaultDebuffFromPlayer(Player* player)
{
- Player* flagCarrier = ObjectAccessor::GetPlayer(GetBgMap(), GetFlagPickerGUID(team));
- uint32 areaTrigger = team == TEAM_ALLIANCE ? 3647 : 3646;
- if (flagCarrier && flagCarrier->IsInAreaTriggerRadius(sAreaTriggerStore.LookupEntry(areaTrigger)))
- EventPlayerCapturedFlag(flagCarrier);
+ player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
+ player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
}
-void BattlegroundWS::EventPlayerDroppedFlag(Player* player)
+void BattlegroundWS::StartingEventOpenDoors()
{
- uint32 team = GetPlayerTeam(player->GetGUID());
- if (GetStatus() != STATUS_IN_PROGRESS)
+ for (ObjectGuid door : _doors)
{
- // if not running, do not cast things at the dropper player (prevent spawning the "dropped" flag), neither send unnecessary messages
- // just take off the aura
- if (team == ALLIANCE)
+ if (GameObject* gameObject = GetBgMap()->GetGameObject(door))
{
- if (!IsHordeFlagPickedup())
- return;
-
- if (GetFlagPickerGUID(TEAM_HORDE) == player->GetGUID())
- {
- SetHordeFlagPicker(ObjectGuid::Empty);
- player->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
- }
+ gameObject->UseDoorOrButton();
+ gameObject->DespawnOrUnsummon(3s);
}
- else
- {
- if (!IsAllianceFlagPickedup())
- return;
-
- if (GetFlagPickerGUID(TEAM_ALLIANCE) == player->GetGUID())
- {
- SetAllianceFlagPicker(ObjectGuid::Empty);
- player->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
- }
- }
- return;
}
- bool set = false;
-
- if (team == ALLIANCE)
- {
- if (!IsHordeFlagPickedup())
- return;
- if (GetFlagPickerGUID(TEAM_HORDE) == player->GetGUID())
- {
- SetHordeFlagPicker(ObjectGuid::Empty);
- player->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
- if (_flagDebuffState == 1)
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- else if (_flagDebuffState == 2)
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_GROUND;
- player->CastSpell(player, BG_WS_SPELL_WARSONG_FLAG_DROPPED, true);
- set = true;
- }
- }
- else
- {
- if (!IsAllianceFlagPickedup())
- return;
- if (GetFlagPickerGUID(TEAM_ALLIANCE) == player->GetGUID())
- {
- SetAllianceFlagPicker(ObjectGuid::Empty);
- player->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
- if (_flagDebuffState == 1)
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- else if (_flagDebuffState == 2)
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_GROUND;
- player->CastSpell(player, BG_WS_SPELL_SILVERWING_FLAG_DROPPED, true);
- set = true;
- }
- }
-
- if (set)
- {
- player->CastSpell(player, SPELL_RECENTLY_DROPPED_FLAG, true);
- UpdateFlagState(team, BG_WS_FLAG_STATE_ON_GROUND);
-
- if (team == ALLIANCE)
- SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_HORDE, player);
- else
- SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 1);
+ UpdateWorldState(BG_WS_STATE_TIMER, GameTime::GetGameTime() + 15 * MINUTE);
- _flagsDropTimer[GetTeamIndexByTeamId(team) ? 0 : 1] = BG_WS_FLAG_DROP_TIME;
- }
+ // players joining later are not eligibles
+ TriggerGameEvent(WS_EVENT_START_BATTLE);
}
-void BattlegroundWS::EventPlayerClickedOnFlag(Player* player, GameObject* target_obj)
+void BattlegroundWS::AddPlayer(Player* player, BattlegroundQueueTypeId queueId)
{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- uint32 team = GetPlayerTeam(player->GetGUID());
-
- //alliance flag picked up from base
- if (team == HORDE && GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE
- && BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID())
- {
- SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_HORDE, player);
- PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
- SetAllianceFlagPicker(player->GetGUID());
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
- //update world state to show correct flag carrier
- UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
- player->CastSpell(player, BG_WS_SPELL_SILVERWING_FLAG, true);
- player->StartCriteriaTimer(CriteriaStartEvent::BeSpellTarget, BG_WS_SPELL_SILVERWING_FLAG_PICKED);
- if (_flagState[1] == BG_WS_FLAG_STATE_ON_PLAYER)
- _bothFlagsKept = true;
-
- if (_flagDebuffState == 1)
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- else if (_flagDebuffState == 2)
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
+ bool const isInBattleground = IsPlayerInBattleground(player->GetGUID());
+ Battleground::AddPlayer(player, queueId);
+ if (!isInBattleground)
+ PlayerScores[player->GetGUID()] = new BattlegroundWGScore(player->GetGUID(), player->GetBGTeam());
+}
- //horde flag picked up from base
- if (team == ALLIANCE && GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_BASE
- && BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID())
- {
- SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
- SetHordeFlagPicker(player->GetGUID());
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
- //update world state to show correct flag carrier
- UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
- player->CastSpell(player, BG_WS_SPELL_WARSONG_FLAG, true);
- player->StartCriteriaTimer(CriteriaStartEvent::BeSpellTarget, BG_WS_SPELL_WARSONG_FLAG_PICKED);
- if (_flagState[0] == BG_WS_FLAG_STATE_ON_PLAYER)
- _bothFlagsKept = true;
-
- if (_flagDebuffState == 1)
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- else if (_flagDebuffState == 2)
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
+FlagState BattlegroundWS::GetFlagState(TeamId team) const
+{
+ if (GameObject* gameObject = FindBgMap()->GetGameObject(_flags[team]))
+ return gameObject->GetFlagState();
- //Alliance flag on ground(not in base) (returned or picked up again from ground!)
- if (GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && player->IsWithinDistInMap(target_obj, 10)
- && target_obj->GetGOInfo()->entry == BG_OBJECT_A_FLAG_GROUND_WS_ENTRY)
- {
- if (team == ALLIANCE)
- {
- SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- UpdateFlagState(HORDE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
- RespawnFlag(ALLIANCE, false);
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
- PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
- UpdatePlayerScore(player, SCORE_FLAG_RETURNS, 1);
- _bothFlagsKept = false;
- HandleFlagRoomCapturePoint(TEAM_HORDE); // Check Horde flag if it is in capture zone; if so, capture it
- }
- else
- {
- SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_HORDE, player);
- PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
- SetAllianceFlagPicker(player->GetGUID());
- player->CastSpell(player, BG_WS_SPELL_SILVERWING_FLAG, true);
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
- UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
- if (_flagDebuffState == 1)
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- else if (_flagDebuffState == 2)
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
- //called in HandleGameObjectUseOpcode:
- //target_obj->Delete();
- }
+ return FlagState(0);
+}
- //Horde flag on ground(not in base) (returned or picked up again)
- if (GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && player->IsWithinDistInMap(target_obj, 10)
- && target_obj->GetGOInfo()->entry == BG_OBJECT_H_FLAG_GROUND_WS_ENTRY)
- {
- if (team == HORDE)
- {
- SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_HORDE, player);
- UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
- RespawnFlag(HORDE, false);
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
- PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
- UpdatePlayerScore(player, SCORE_FLAG_RETURNS, 1);
- _bothFlagsKept = false;
- HandleFlagRoomCapturePoint(TEAM_ALLIANCE); // Check Alliance flag if it is in capture zone; if so, capture it
- }
- else
- {
- SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
- SetHordeFlagPicker(player->GetGUID());
- player->CastSpell(player, BG_WS_SPELL_WARSONG_FLAG, true);
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
- UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
- if (_flagDebuffState == 1)
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- else if (_flagDebuffState == 2)
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
- //called in HandleGameObjectUseOpcode:
- //target_obj->Delete();
- }
+ObjectGuid const& BattlegroundWS::GetFlagCarrierGUID(TeamId team) const
+{
+ if (GameObject* gameObject = FindBgMap()->GetGameObject(_flags[team]))
+ return gameObject->GetFlagCarrierGUID();
- player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
+ return ObjectGuid::Empty;
}
-void BattlegroundWS::RemovePlayer(Player* player, ObjectGuid guid, uint32 /*team*/)
+void BattlegroundWS::HandleFlagRoomCapturePoint()
{
- // sometimes flag aura not removed :(
- if (IsAllianceFlagPickedup() && m_FlagKeepers[TEAM_ALLIANCE] == guid)
- {
- if (!player)
- {
- TC_LOG_ERROR("bg.battleground", "BattlegroundWS: Removing offline player who has the FLAG!!");
- SetAllianceFlagPicker(ObjectGuid::Empty);
- RespawnFlag(ALLIANCE, false);
- }
- else
- EventPlayerDroppedFlag(player);
- }
- if (IsHordeFlagPickedup() && m_FlagKeepers[TEAM_HORDE] == guid)
+ DoForFlagKeepers([&](Player* player) -> void
{
- if (!player)
- {
- TC_LOG_ERROR("bg.battleground", "BattlegroundWS: Removing offline player who has the FLAG!!");
- SetHordeFlagPicker(ObjectGuid::Empty);
- RespawnFlag(HORDE, false);
- }
- else
- EventPlayerDroppedFlag(player);
- }
+ TeamId team = GetTeamIndexByTeamId(GetPlayerTeam(player->GetGUID()));
+ if (AreaTrigger* trigger = GetBgMap()->GetAreaTrigger(_capturePointAreaTriggers[team]))
+ if (trigger->GetInsideUnits().contains(player->GetGUID()))
+ if (CanCaptureFlag(trigger, player))
+ OnCaptureFlag(trigger, player);
+ });
}
-void BattlegroundWS::UpdateFlagState(uint32 team, uint32 value)
+void BattlegroundWS::UpdateFlagState(uint32 team, FlagState value)
{
- auto transformValueToOtherTeamControlWorldState = [](uint32 value)
+ auto transformValueToOtherTeamControlWorldState = [](FlagState value)
{
switch (value)
{
- case BG_WS_FLAG_STATE_ON_BASE:
- case BG_WS_FLAG_STATE_ON_GROUND:
- case BG_WS_FLAG_STATE_WAIT_RESPAWN:
+ case FlagState::InBase:
+ case FlagState::Dropped:
+ case FlagState::Respawning:
return 1;
- case BG_WS_FLAG_STATE_ON_PLAYER:
+ case FlagState::Taken:
return 2;
default:
return 0;
}
};
- if (team == HORDE)
+
+ if (team == ALLIANCE)
{
- UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, value);
+ UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, AsUnderlyingType(value));
UpdateWorldState(BG_WS_FLAG_CONTROL_HORDE, transformValueToOtherTeamControlWorldState(value));
}
else
{
- UpdateWorldState(BG_WS_FLAG_STATE_HORDE, value);
+ UpdateWorldState(BG_WS_FLAG_STATE_HORDE, AsUnderlyingType(value));
UpdateWorldState(BG_WS_FLAG_CONTROL_ALLIANCE, transformValueToOtherTeamControlWorldState(value));
}
}
@@ -643,105 +254,8 @@ void BattlegroundWS::UpdateTeamScore(uint32 team)
UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(team));
}
-void BattlegroundWS::HandleAreaTrigger(Player* player, uint32 trigger, bool entered)
-{
- //uint32 SpellId = 0;
- //uint64 buff_guid = 0;
- switch (trigger)
- {
- case 8965: // Horde Start
- case 8966: // Alliance Start
- if (GetStatus() == STATUS_WAIT_JOIN && !entered)
- TeleportPlayerToExploitLocation(player);
- break;
- case 3686: // Alliance elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in Battleground::Update().
- //buff_guid = BgObjects[BG_WS_OBJECT_SPEEDBUFF_1];
- break;
- case 3687: // Horde elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in Battleground::Update().
- //buff_guid = BgObjects[BG_WS_OBJECT_SPEEDBUFF_2];
- break;
- case 3706: // Alliance elixir of regeneration spawn
- //buff_guid = BgObjects[BG_WS_OBJECT_REGENBUFF_1];
- break;
- case 3708: // Horde elixir of regeneration spawn
- //buff_guid = BgObjects[BG_WS_OBJECT_REGENBUFF_2];
- break;
- case 3707: // Alliance elixir of berserk spawn
- //buff_guid = BgObjects[BG_WS_OBJECT_BERSERKBUFF_1];
- break;
- case 3709: // Horde elixir of berserk spawn
- //buff_guid = BgObjects[BG_WS_OBJECT_BERSERKBUFF_2];
- break;
- case 3646: // Alliance Flag spawn
- if (_flagState[TEAM_HORDE] && !_flagState[TEAM_ALLIANCE])
- if (GetFlagPickerGUID(TEAM_HORDE) == player->GetGUID())
- EventPlayerCapturedFlag(player);
- break;
- case 3647: // Horde Flag spawn
- if (_flagState[TEAM_ALLIANCE] && !_flagState[TEAM_HORDE])
- if (GetFlagPickerGUID(TEAM_ALLIANCE) == player->GetGUID())
- EventPlayerCapturedFlag(player);
- break;
- case 3649: // unk1
- case 3688: // unk2
- case 4628: // unk3
- case 4629: // unk4
- break;
- default:
- Battleground::HandleAreaTrigger(player, trigger, entered);
- break;
- }
-
- //if (buff_guid)
- // HandleTriggerBuff(buff_guid, player);
-}
-
bool BattlegroundWS::SetupBattleground()
{
- // flags
- if (!AddObject(BG_WS_OBJECT_A_FLAG, BG_OBJECT_A_FLAG_WS_ENTRY, 1540.423f, 1481.325f, 351.8284f, 3.089233f, 0, 0, 0.9996573f, 0.02617699f, BG_WS_FLAG_RESPAWN_TIME/1000)
- || !AddObject(BG_WS_OBJECT_H_FLAG, BG_OBJECT_H_FLAG_WS_ENTRY, 916.0226f, 1434.405f, 345.413f, 0.01745329f, 0, 0, 0.008726535f, 0.9999619f, BG_WS_FLAG_RESPAWN_TIME/1000)
- // buffs
- || !AddObject(BG_WS_OBJECT_SPEEDBUFF_1, BG_OBJECTID_SPEEDBUFF_ENTRY, 1449.93f, 1470.71f, 342.6346f, -1.64061f, 0, 0, 0.7313537f, -0.6819983f, BUFF_RESPAWN_TIME)
- || !AddObject(BG_WS_OBJECT_SPEEDBUFF_2, BG_OBJECTID_SPEEDBUFF_ENTRY, 1005.171f, 1447.946f, 335.9032f, 1.64061f, 0, 0, 0.7313537f, 0.6819984f, BUFF_RESPAWN_TIME)
- || !AddObject(BG_WS_OBJECT_REGENBUFF_1, BG_OBJECTID_REGENBUFF_ENTRY, 1317.506f, 1550.851f, 313.2344f, -0.2617996f, 0, 0, 0.1305263f, -0.9914448f, BUFF_RESPAWN_TIME)
- || !AddObject(BG_WS_OBJECT_REGENBUFF_2, BG_OBJECTID_REGENBUFF_ENTRY, 1110.451f, 1353.656f, 316.5181f, -0.6806787f, 0, 0, 0.333807f, -0.9426414f, BUFF_RESPAWN_TIME)
- || !AddObject(BG_WS_OBJECT_BERSERKBUFF_1, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1320.09f, 1378.79f, 314.7532f, 1.186824f, 0, 0, 0.5591929f, 0.8290376f, BUFF_RESPAWN_TIME)
- || !AddObject(BG_WS_OBJECT_BERSERKBUFF_2, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1139.688f, 1560.288f, 306.8432f, -2.443461f, 0, 0, 0.9396926f, -0.3420201f, BUFF_RESPAWN_TIME)
- // alliance gates
- || !AddObject(BG_WS_OBJECT_DOOR_A_1, BG_OBJECT_DOOR_A_1_WS_ENTRY, 1503.335f, 1493.466f, 352.1888f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_A_2, BG_OBJECT_DOOR_A_2_WS_ENTRY, 1492.478f, 1457.912f, 342.9689f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_A_3, BG_OBJECT_DOOR_A_3_WS_ENTRY, 1468.503f, 1494.357f, 351.8618f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_A_4, BG_OBJECT_DOOR_A_4_WS_ENTRY, 1471.555f, 1458.778f, 362.6332f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_A_5, BG_OBJECT_DOOR_A_5_WS_ENTRY, 1492.347f, 1458.34f, 342.3712f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_A_6, BG_OBJECT_DOOR_A_6_WS_ENTRY, 1503.466f, 1493.367f, 351.7352f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY)
- // horde gates
- || !AddObject(BG_WS_OBJECT_DOOR_H_1, BG_OBJECT_DOOR_H_1_WS_ENTRY, 949.1663f, 1423.772f, 345.6241f, -0.5756807f, -0.01673368f, -0.004956111f, -0.2839723f, 0.9586737f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_H_2, BG_OBJECT_DOOR_H_2_WS_ENTRY, 953.0507f, 1459.842f, 340.6526f, -1.99662f, -0.1971825f, 0.1575096f, -0.8239487f, 0.5073641f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_H_3, BG_OBJECT_DOOR_H_3_WS_ENTRY, 949.9523f, 1422.751f, 344.9273f, 0.0f, 0, 0, 0, 1, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_H_4, BG_OBJECT_DOOR_H_4_WS_ENTRY, 950.7952f, 1459.583f, 342.1523f, 0.05235988f, 0, 0, 0.02617695f, 0.9996573f, RESPAWN_IMMEDIATELY)
-)
- {
- TC_LOG_ERROR("sql.sql", "BatteGroundWS: Failed to spawn some object Battleground not created!");
- return false;
- }
-
- WorldSafeLocsEntry const* sg = sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_MAIN_ALLIANCE);
- if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_ALLIANCE, sg->Loc.GetPositionX(), sg->Loc.GetPositionY(), sg->Loc.GetPositionZ(), 3.124139f, TEAM_ALLIANCE))
- {
- TC_LOG_ERROR("sql.sql", "BatteGroundWS: Failed to spawn Alliance spirit guide! Battleground not created!");
- return false;
- }
-
- sg = sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_MAIN_HORDE);
- if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_HORDE, sg->Loc.GetPositionX(), sg->Loc.GetPositionY(), sg->Loc.GetPositionZ(), 3.193953f, TEAM_HORDE))
- {
- TC_LOG_ERROR("sql.sql", "BatteGroundWS: Failed to spawn Horde spirit guide! Battleground not created!");
- return false;
- }
-
- TC_LOG_DEBUG("bg.battleground", "BatteGroundWS: BG objects and spirit guides spawned");
-
return true;
}
@@ -750,12 +264,6 @@ void BattlegroundWS::Reset()
//call parent's class reset
Battleground::Reset();
- m_FlagKeepers[TEAM_ALLIANCE].Clear();
- m_FlagKeepers[TEAM_HORDE].Clear();
- m_DroppedFlagGUID[TEAM_ALLIANCE].Clear();
- m_DroppedFlagGUID[TEAM_HORDE].Clear();
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
m_TeamScores[TEAM_ALLIANCE] = 0;
m_TeamScores[TEAM_HORDE] = 0;
@@ -773,12 +281,12 @@ void BattlegroundWS::Reset()
}
_lastFlagCaptureTeam = 0;
_bothFlagsKept = false;
- _flagDebuffState = 0;
- _flagSpellForceTimer = 0;
- _flagsDropTimer[TEAM_ALLIANCE] = 0;
- _flagsDropTimer[TEAM_HORDE] = 0;
- _flagsTimer[TEAM_ALLIANCE] = 0;
- _flagsTimer[TEAM_HORDE] = 0;
+
+ _doors.clear();
+ _flags = { };
+ _assaultStackCount = 0;
+ _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
+ _capturePointAreaTriggers = { };
}
void BattlegroundWS::EndBattleground(uint32 winner)
@@ -788,6 +296,7 @@ void BattlegroundWS::EndBattleground(uint32 winner)
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), ALLIANCE);
if (winner == HORDE)
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), HORDE);
+
// Complete map_end rewards (even if no team wins)
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), ALLIANCE);
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), HORDE);
@@ -826,25 +335,7 @@ bool BattlegroundWS::UpdatePlayerScore(Player* player, uint32 type, uint32 value
WorldSafeLocsEntry const* BattlegroundWS::GetClosestGraveyard(Player* player)
{
- //if status in progress, it returns main graveyards with spiritguides
- //else it will return the graveyard in the flagroom - this is especially good
- //if a player dies in preparation phase - then the player can't cheat
- //and teleport to the graveyard outside the flagroom
- //and start running around, while the doors are still closed
- if (GetPlayerTeam(player->GetGUID()) == ALLIANCE)
- {
- if (GetStatus() == STATUS_IN_PROGRESS)
- return sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_MAIN_ALLIANCE);
- else
- return sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_FLAGROOM_ALLIANCE);
- }
- else
- {
- if (GetStatus() == STATUS_IN_PROGRESS)
- return sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_MAIN_HORDE);
- else
- return sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_FLAGROOM_HORDE);
- }
+ return sObjectMgr->GetClosestGraveyard(*player, player->GetBGTeam(), player);
}
WorldSafeLocsEntry const* BattlegroundWS::GetExploitTeleportLocation(Team team)
@@ -861,3 +352,229 @@ uint32 BattlegroundWS::GetPrematureWinner()
return Battleground::GetPrematureWinner();
}
+
+void BattlegroundWS::OnGameObjectCreate(GameObject* gameObject)
+{
+ switch (gameObject->GetEntry())
+ {
+ case BG_WS_OBJECT_ALLIANCE_DOOR:
+ case BG_WS_OBJECT_PORTCULLIS_009:
+ case BG_WS_OBJECT_PORTCULLIS_002:
+ case BG_WS_OBJECT_COLLISION_PC_SIZE:
+ case BG_WS_OBJECT_HORDE_GATE_1:
+ case BG_WS_OBJECT_HORDE_GATE_2:
+ _doors.insert(gameObject->GetGUID());
+ break;
+ case BG_WS_OBJECT_ALLIANCE_FLAG_IN_BASE:
+ _flags[TEAM_ALLIANCE] = gameObject->GetGUID();
+ break;
+ case BG_WS_OBJECT_HORDE_FLAG_IN_BASE:
+ _flags[TEAM_HORDE] = gameObject->GetGUID();
+ break;
+ default:
+ break;
+ }
+}
+
+void BattlegroundWS::OnAreaTriggerCreate(AreaTrigger* areaTrigger)
+{
+ if (!areaTrigger->IsServerSide())
+ return;
+
+ switch (areaTrigger->GetEntry())
+ {
+ case AT_CAPTURE_POINT_ALLIANCE:
+ _capturePointAreaTriggers[TEAM_ALLIANCE] = areaTrigger->GetGUID();
+ break;
+ case AT_CAPTURE_POINT_HORDE:
+ _capturePointAreaTriggers[TEAM_HORDE] = areaTrigger->GetGUID();
+ break;
+ default:
+ break;
+ }
+}
+
+void BattlegroundWS::OnFlagStateChange(GameObject* flagInBase, FlagState /*oldValue*/, FlagState newValue, Player* player)
+{
+ uint32 team = flagInBase->GetEntry() == BG_WS_OBJECT_HORDE_FLAG_IN_BASE ? HORDE : ALLIANCE;
+ TeamId otherTeamId = GetTeamIndexByTeamId(GetOtherTeam(team));
+
+ UpdateFlagState(team, newValue);
+
+ switch (newValue)
+ {
+ case FlagState::InBase:
+ {
+ if (GetStatus() == STATUS_IN_PROGRESS)
+ {
+ ResetAssaultDebuff();
+ if (player)
+ {
+ // flag got returned to base by player interaction
+ UpdatePlayerScore(player, SCORE_FLAG_RETURNS, 1); // +1 flag returns
+
+ if (team == ALLIANCE)
+ {
+ SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
+ }
+ else
+ {
+ SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
+ }
+ }
+ // Flag respawned due to timeout/capture
+ else if (GetFlagState(otherTeamId) != FlagState::Respawning)
+ {
+ // if other flag is respawning, we will let that one handle the message and sound to prevent double message/sound.
+ SendBroadcastText(BG_WS_TEXT_FLAGS_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
+ }
+
+ HandleFlagRoomCapturePoint();
+ }
+ break;
+ }
+ case FlagState::Dropped:
+ {
+ player->RemoveAurasDueToSpell(BG_WS_SPELL_QUICK_CAP_TIMER);
+ RemoveAssaultDebuffFromPlayer(player);
+
+ uint32 recentlyDroppedSpellId = SPELL_RECENTLY_DROPPED_HORDE_FLAG;
+ if (team == ALLIANCE)
+ {
+ recentlyDroppedSpellId = SPELL_RECENTLY_DROPPED_ALLIANCE_FLAG;
+ SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ }
+ else
+ SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_HORDE, player);
+
+ player->CastSpell(player, recentlyDroppedSpellId, true);
+ break;
+ }
+ case FlagState::Taken:
+ {
+ if (team == HORDE)
+ {
+ SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
+ }
+ else
+ {
+ SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
+ }
+
+ if (GetFlagState(otherTeamId) == FlagState::Taken)
+ _bothFlagsKept = true;
+
+ ApplyAssaultDebuffToPlayer(player);
+
+ flagInBase->CastSpell(player, BG_WS_SPELL_QUICK_CAP_TIMER, true);
+ player->StartCriteriaTimer(CriteriaStartEvent::BeSpellTarget, BG_WS_SPELL_QUICK_CAP_TIMER, uint32(GameTime::GetGameTime() - flagInBase->GetFlagTakenFromBaseTime()));
+ break;
+ }
+ case FlagState::Respawning:
+ ResetAssaultDebuff();
+ break;
+ default:
+ break;
+ }
+}
+
+bool BattlegroundWS::CanCaptureFlag(AreaTrigger* areaTrigger, Player* player)
+{
+ if (GetStatus() != STATUS_IN_PROGRESS)
+ return false;
+
+ uint32 team = GetPlayerTeam(player->GetGUID());
+ TeamId teamId = GetTeamIndexByTeamId(team);
+ TeamId otherTeamId = GetTeamIndexByTeamId(GetOtherTeam(team));
+
+ if (areaTrigger->GetGUID() != _capturePointAreaTriggers[teamId])
+ return false;
+
+ // check if enemy flag's carrier is this player
+ if (GetFlagCarrierGUID(otherTeamId) != player->GetGUID())
+ return false;
+
+ // check that team's flag is in base
+ return GetFlagState(teamId) == FlagState::InBase;
+}
+
+void BattlegroundWS::OnCaptureFlag(AreaTrigger* /*areaTrigger*/, Player* player)
+{
+ uint32 winner = 0;
+
+ uint32 team = GetPlayerTeam(player->GetGUID());
+ TeamId teamId = GetTeamIndexByTeamId(team);
+ TeamId otherTeamId = GetTeamIndexByTeamId(GetOtherTeam(team));
+
+ /*
+ 1. Update flag states & score world states
+ 2. udpate points
+ 3. chat message & sound
+ 4. update criterias & achievements
+ 5. remove all related auras
+ ?. Reward honor & reputation
+ */
+
+ // 1. update the flag states
+ for (uint8 i = 0; i < _flags.size(); i++)
+ if (GameObject* gameObject = GetBgMap()->GetGameObject(_flags[i]))
+ gameObject->HandleCustomTypeCommand(GameObjectType::SetNewFlagState(FlagState::Respawning, player));
+
+ // 2. update points
+ if (GetTeamScore(teamId) < BG_WS_MAX_TEAM_SCORE)
+ AddPoint(team, 1);
+
+ UpdateTeamScore(teamId);
+
+ // 3. chat message & sound
+ if (team == ALLIANCE)
+ {
+ SendBroadcastText(BG_WS_TEXT_CAPTURED_HORDE_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
+ RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
+ player->CastSpell(player, SPELL_CAPTURED_ALLIANCE_COSMETIC_FX);
+ }
+ else
+ {
+ SendBroadcastText(BG_WS_TEXT_CAPTURED_ALLIANCE_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
+ RewardReputationToTeam(889, m_ReputationCapture, HORDE);
+ player->CastSpell(player, SPELL_CAPTURED_HORDE_COSMETIC_FX);
+ }
+
+ // 4. update criteria's for achievement, player score etc.
+ UpdatePlayerScore(player, SCORE_FLAG_CAPTURES, 1); // +1 flag captures
+
+ // 5. Remove all related auras
+ RemoveAssaultDebuffFromPlayer(player);
+
+ if (GameObject* gameObject = GetBgMap()->GetGameObject(_flags[otherTeamId]))
+ player->RemoveAurasDueToSpell(gameObject->GetGOInfo()->newflag.pickupSpell, gameObject->GetGUID());
+
+ player->RemoveAurasDueToSpell(BG_WS_SPELL_QUICK_CAP_TIMER);
+
+ player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
+
+ RewardHonorToTeam(GetBonusHonorFromKill(2), team);
+
+ // update last flag capture to be used if teamscore is equal
+ SetLastFlagCapture(team);
+
+ if (GetTeamScore(teamId) == BG_WS_MAX_TEAM_SCORE)
+ winner = team;
+
+ if (winner)
+ {
+ UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, 1);
+ UpdateWorldState(BG_WS_FLAG_STATE_HORDE, 1);
+ UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 0);
+
+ RewardHonorToTeam(BG_WSG_Honor[BattlegroundMgr::IsBGWeekend(GetTypeID()) ? 1 : 0][BG_WSG_WIN], winner);
+ EndBattleground(winner);
+ }
+}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
index 8a4269ef583..2163ede682a 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
@@ -20,6 +20,7 @@
#include "Battleground.h"
#include "BattlegroundScore.h"
+#include "Timer.h"
enum BG_WS_TimerOrScore
{
@@ -62,12 +63,13 @@ enum BG_WS_SpellId
{
BG_WS_SPELL_WARSONG_FLAG = 23333,
BG_WS_SPELL_WARSONG_FLAG_DROPPED = 23334,
- BG_WS_SPELL_WARSONG_FLAG_PICKED = 61266, // fake spell, does not exist but used as timer start event
+ //BG_WS_SPELL_WARSONG_FLAG_PICKED = 61266,
BG_WS_SPELL_SILVERWING_FLAG = 23335,
BG_WS_SPELL_SILVERWING_FLAG_DROPPED = 23336,
- BG_WS_SPELL_SILVERWING_FLAG_PICKED = 61265, // fake spell, does not exist but used as timer start event
+ //BG_WS_SPELL_SILVERWING_FLAG_PICKED = 61265,
BG_WS_SPELL_FOCUSED_ASSAULT = 46392,
- BG_WS_SPELL_BRUTAL_ASSAULT = 46393
+ BG_WS_SPELL_BRUTAL_ASSAULT = 46393,
+ BG_WS_SPELL_QUICK_CAP_TIMER = 183317, // serverside
};
enum BG_WS_WorldStates
@@ -91,90 +93,52 @@ enum BG_WS_WorldStates
// alliance criteria: BG_WS_FLAG_STATE_HORDE == 1 && BG_WS_FLAG_STATE_NEUTRAL == 0 && WS(1664) > 0
// horde criteria: BG_WS_FLAG_STATE_ALLIANCE == 1 && BG_WS_FLAG_STATE_NEUTRAL == 0 && WS(1664) > 0
-enum BG_WS_ObjectTypes
+enum BG_WS_ExploitTeleportLocations
{
- BG_WS_OBJECT_DOOR_A_1 = 0,
- BG_WS_OBJECT_DOOR_A_2 = 1,
- BG_WS_OBJECT_DOOR_A_3 = 2,
- BG_WS_OBJECT_DOOR_A_4 = 3,
- BG_WS_OBJECT_DOOR_A_5 = 4,
- BG_WS_OBJECT_DOOR_A_6 = 5,
- BG_WS_OBJECT_DOOR_H_1 = 6,
- BG_WS_OBJECT_DOOR_H_2 = 7,
- BG_WS_OBJECT_DOOR_H_3 = 8,
- BG_WS_OBJECT_DOOR_H_4 = 9,
- BG_WS_OBJECT_A_FLAG = 10,
- BG_WS_OBJECT_H_FLAG = 11,
- BG_WS_OBJECT_SPEEDBUFF_1 = 12,
- BG_WS_OBJECT_SPEEDBUFF_2 = 13,
- BG_WS_OBJECT_REGENBUFF_1 = 14,
- BG_WS_OBJECT_REGENBUFF_2 = 15,
- BG_WS_OBJECT_BERSERKBUFF_1 = 16,
- BG_WS_OBJECT_BERSERKBUFF_2 = 17,
- BG_WS_OBJECT_MAX = 18
+ WS_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 7051,
+ WS_EXPLOIT_TELEPORT_LOCATION_HORDE = 7050
};
enum BG_WS_ObjectEntry
{
- BG_OBJECT_DOOR_A_1_WS_ENTRY = 179918,
- BG_OBJECT_DOOR_A_2_WS_ENTRY = 179919,
- BG_OBJECT_DOOR_A_3_WS_ENTRY = 179920,
- BG_OBJECT_DOOR_A_4_WS_ENTRY = 179921,
- BG_OBJECT_DOOR_A_5_WS_ENTRY = 180322,
- BG_OBJECT_DOOR_A_6_WS_ENTRY = 180322,
- BG_OBJECT_DOOR_H_1_WS_ENTRY = 179916,
- BG_OBJECT_DOOR_H_2_WS_ENTRY = 179917,
- BG_OBJECT_DOOR_H_3_WS_ENTRY = 180322,
- BG_OBJECT_DOOR_H_4_WS_ENTRY = 180322,
- BG_OBJECT_A_FLAG_WS_ENTRY = 179830,
- BG_OBJECT_H_FLAG_WS_ENTRY = 179831,
- BG_OBJECT_A_FLAG_GROUND_WS_ENTRY = 179785,
- BG_OBJECT_H_FLAG_GROUND_WS_ENTRY = 179786
+ // doors
+ BG_WS_OBJECT_ALLIANCE_DOOR = 309704,
+ BG_WS_OBJECT_PORTCULLIS_009 = 309705, // Doodad_7NE_Blackrook_Portcullis009
+ BG_WS_OBJECT_PORTCULLIS_002 = 309883, // Doodad_7NE_Blackrook_Portcullis002
+ BG_WS_OBJECT_COLLISION_PC_SIZE = 242273,
+ BG_WS_OBJECT_HORDE_GATE_1 = 352709,
+ BG_WS_OBJECT_HORDE_GATE_2 = 352710,
+
+ // flags
+ BG_WS_OBJECT_ALLIANCE_FLAG_IN_BASE = 227741,
+ BG_WS_OBJECT_HORDE_FLAG_IN_BASE = 227740
};
-enum BG_WS_FlagState
+enum BG_WS_CarrierDebuffs
{
- BG_WS_FLAG_STATE_ON_BASE = 1,
- BG_WS_FLAG_STATE_ON_PLAYER = 2,
- BG_WS_FLAG_STATE_ON_GROUND = 3,
- BG_WS_FLAG_STATE_WAIT_RESPAWN = 4,
-};
+ WS_SPELL_FOCUSED_ASSAULT = 46392,
+ WS_SPELL_BRUTAL_ASSAULT = 46393,
-enum BG_WS_Graveyards
-{
- WS_GRAVEYARD_FLAGROOM_ALLIANCE = 769,
- WS_GRAVEYARD_FLAGROOM_HORDE = 770,
- WS_GRAVEYARD_MAIN_ALLIANCE = 771,
- WS_GRAVEYARD_MAIN_HORDE = 772
+ SPELL_CAPTURED_ALLIANCE_COSMETIC_FX = 262508,
+ SPELL_CAPTURED_HORDE_COSMETIC_FX = 262512,
};
-enum BG_WS_ExploitTeleportLocations
+enum BG_WS_Objectives
{
- WS_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 3784,
- WS_EXPLOIT_TELEPORT_LOCATION_HORDE = 3785
+ WS_OBJECTIVE_CAPTURE_FLAG = 928,
+ WS_OBJECTIVE_RETURN_FLAG = 929
};
-enum BG_WS_CreatureTypes
+enum BG_WS_AreaTriggers
{
- WS_SPIRIT_MAIN_ALLIANCE = 0,
- WS_SPIRIT_MAIN_HORDE = 1,
-
- BG_CREATURES_MAX_WS = 2
+ AT_CAPTURE_POINT_ALLIANCE = 30,
+ AT_CAPTURE_POINT_HORDE = 31
};
-enum BG_WS_CarrierDebuffs
-{
- WS_SPELL_FOCUSED_ASSAULT = 46392,
- WS_SPELL_BRUTAL_ASSAULT = 46393
-};
+static constexpr uint32 WS_EVENT_START_BATTLE = 35912;
-enum BG_WS_Objectives
-{
- WS_OBJECTIVE_CAPTURE_FLAG = 42,
- WS_OBJECTIVE_RETURN_FLAG = 44
-};
-
-#define WS_EVENT_START_BATTLE 8563
+static constexpr Seconds FLAG_ASSAULT_TIMER = 30s;
+static constexpr uint16 FLAG_BRUTAL_ASSAULT_STACK_COUNT = 5;
struct BattlegroundWGScore final : public BattlegroundScore
{
@@ -223,32 +187,13 @@ class BattlegroundWS : public Battleground
/* inherited from BattlegroundClass */
void AddPlayer(Player* player, BattlegroundQueueTypeId queueId) override;
- void StartingEventCloseDoors() override;
void StartingEventOpenDoors() override;
/* BG Flags */
- ObjectGuid GetFlagPickerGUID(int32 team) const override
- {
- if (team == TEAM_ALLIANCE || team == TEAM_HORDE)
- return m_FlagKeepers[team];
- return ObjectGuid::Empty;
- }
- void SetAllianceFlagPicker(ObjectGuid guid) { m_FlagKeepers[TEAM_ALLIANCE] = guid; }
- void SetHordeFlagPicker(ObjectGuid guid) { m_FlagKeepers[TEAM_HORDE] = guid; }
- bool IsAllianceFlagPickedup() const { return !m_FlagKeepers[TEAM_ALLIANCE].IsEmpty(); }
- bool IsHordeFlagPickedup() const { return !m_FlagKeepers[TEAM_HORDE].IsEmpty(); }
- void RespawnFlag(uint32 Team, bool captured);
- void RespawnFlagAfterDrop(uint32 Team);
- uint8 GetFlagState(uint32 team) { return _flagState[GetTeamIndexByTeamId(team)]; }
-
- /* Battleground Events */
- void EventPlayerDroppedFlag(Player* player) override;
- void EventPlayerClickedOnFlag(Player* player, GameObject* target_obj) override;
- void EventPlayerCapturedFlag(Player* player);
- void HandleFlagRoomCapturePoint(int32 team);
-
- void RemovePlayer(Player* player, ObjectGuid guid, uint32 team) override;
- void HandleAreaTrigger(Player* player, uint32 trigger, bool entered) override;
+ FlagState GetFlagState(TeamId team) const;
+ ObjectGuid const& GetFlagCarrierGUID(TeamId team) const;
+ void HandleFlagRoomCapturePoint();
+
void HandleKillPlayer(Player* player, Player* killer) override;
bool SetupBattleground() override;
void Reset() override;
@@ -256,17 +201,10 @@ class BattlegroundWS : public Battleground
WorldSafeLocsEntry const* GetClosestGraveyard(Player* player) override;
WorldSafeLocsEntry const* GetExploitTeleportLocation(Team team) override;
- void UpdateFlagState(uint32 team, uint32 value);
+ void UpdateFlagState(uint32 team, FlagState value);
void SetLastFlagCapture(uint32 team) { _lastFlagCaptureTeam = team; }
void UpdateTeamScore(uint32 team);
bool UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true) override;
- void SetDroppedFlagGUID(ObjectGuid guid, int32 team = -1) override
- {
- if (team == TEAM_ALLIANCE || team == TEAM_HORDE)
- m_DroppedFlagGUID[team] = guid;
- }
-
- ObjectGuid GetDroppedFlagGUID(uint32 TeamID) { return m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)]; }
/* Scorekeeping */
void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; }
@@ -275,22 +213,35 @@ class BattlegroundWS : public Battleground
uint32 GetPrematureWinner() override;
+ void OnGameObjectCreate(GameObject* gameObject) override;
+ void OnAreaTriggerCreate(AreaTrigger* areaTrigger) override;
+ void OnFlagStateChange(GameObject* flagInBase, FlagState oldValue, FlagState newValue, Player* player) override;
+
+ bool CanCaptureFlag(AreaTrigger* areatrigger, Player* player) override;
+ void OnCaptureFlag(AreaTrigger* areatrigger, Player* player) override;
+
protected:
void PostUpdateImpl(uint32 diff) override;
+ void DoForFlagKeepers(std::function<void(Player*)> action) const;
+
+ // Focused & Brutal Assault debuffs
+ void ResetAssaultDebuff();
+ void ApplyAssaultDebuffToPlayer(Player* player);
+ void RemoveAssaultDebuffFromPlayer(Player* player);
private:
- ObjectGuid m_FlagKeepers[2]; // 0 - alliance, 1 - horde
- ObjectGuid m_DroppedFlagGUID[2];
- uint8 _flagState[2]; // for checking flag state
- int32 _flagsTimer[2];
- int32 _flagsDropTimer[2];
uint32 _lastFlagCaptureTeam; // Winner is based on this if score is equal
uint32 m_ReputationCapture;
uint32 m_HonorWinKills;
uint32 m_HonorEndKills;
- int32 _flagSpellForceTimer;
bool _bothFlagsKept;
- uint8 _flagDebuffState; // 0 - no debuffs, 1 - focused assault, 2 - brutal assault
+
+ GuidSet _doors;
+ std::array<ObjectGuid, 2> _flags;
+
+ TimeTracker _flagAssaultTimer;
+ uint16 _assaultStackCount;
+ std::array<ObjectGuid, 2> _capturePointAreaTriggers;
};
#endif
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 4a6b11f002a..5126853d96d 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -25759,10 +25759,21 @@ bool Player::CanUseBattlegroundObject(GameObject* gameobject) const
return false;
}
+ bool hasRecentlyDroppedFlagDebuff = HasAura([](Aura const* aura) -> bool
+ {
+ if (aura->GetSpellInfo()->Id == SPELL_RECENTLY_DROPPED_ALLIANCE_FLAG)
+ return true;
+ else if (aura->GetSpellInfo()->Id == SPELL_RECENTLY_DROPPED_HORDE_FLAG)
+ return true;
+ else if (aura->GetSpellInfo()->Id == SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG)
+ return true;
+ return false;
+ });
+
// BUG: sometimes when player clicks on flag in AB - client won't send gameobject_use, only gameobject_report_use packet
// Note: Mount, stealth and invisibility will be removed when used
return (!isTotalImmune() && // Damage immune
- !HasAura(SPELL_RECENTLY_DROPPED_FLAG) && // Still has recently held flag debuff
+ !hasRecentlyDroppedFlagDebuff && // Still has recently held flag debuff
IsAlive()); // Alive
}