TrinityCore
BattlegroundEY.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "BattlegroundEY.h"
19#include "AreaTrigger.h"
20#include "BattlegroundMgr.h"
21#include "BattlegroundPackets.h"
22#include "Creature.h"
23#include "GameObject.h"
24#include "Log.h"
25#include "Map.h"
26#include "ObjectAccessor.h"
27#include "ObjectMgr.h"
28#include "Player.h"
29#include "Random.h"
30#include "SpellAuras.h"
31#include "SpellInfo.h"
32#include "Util.h"
33
35{
37};
38
39BattlegroundEY::BattlegroundEY(BattlegroundTemplate const* battlegroundTemplate) : Battleground(battlegroundTemplate)
40{
41 BgObjects.resize(0);
42 BgCreatures.resize(0);
43 m_HonorScoreTics = { 0, 0 };
45 m_HonorTics = 0;
47 _assaultEnabled = false;
50}
51
53
55{
57 {
58 _pointsTimer.Update(diff);
59 if (_pointsTimer.Passed())
60 {
62
63 uint8 baseCountAlliance = GetControlledBaseCount(TEAM_ALLIANCE);
64 uint8 baseCountHorde = GetControlledBaseCount(TEAM_HORDE);
65 if (baseCountAlliance > 0)
66 AddPoints(ALLIANCE, BG_EY_TickPoints[baseCountAlliance - 1]);
67 if (baseCountHorde > 0)
68 AddPoints(HORDE, BG_EY_TickPoints[baseCountHorde - 1]);
69 }
70
72 {
75 {
78
79 // update assault debuff stacks
80 DoForFlagKeepers([&](Player* player) -> void
81 {
83 });
84 }
85 }
86 }
87}
88
90{
91 for (ObjectGuid const& door : _doorGUIDs)
92 {
93 if (GameObject* gameObject = GetBgMap()->GetGameObject(door))
94 {
95 gameObject->UseDoorOrButton();
96 gameObject->DespawnOrUnsummon(3s);
97 }
98 }
99
100 // Achievement: Flurry
102}
103
105{
106 TeamId team_index = GetTeamIndexByTeamId(team);
107 m_TeamScores[team_index] += Points;
108 m_HonorScoreTics[team_index] += Points;
109 if (m_HonorScoreTics[team_index] >= m_HonorTics)
110 {
112 m_HonorScoreTics[team_index] -= m_HonorTics;
113 }
114 UpdateTeamScore(team_index);
115}
116
118{
119 uint8 baseCount = 0;
120 for (auto const& controlZoneHandler : _controlZoneHandlers)
121 {
122 uint32 point = controlZoneHandler.second->GetPoint();
123 switch (teamId)
124 {
125 case TEAM_ALLIANCE:
126 if (GetBgMap()->GetWorldStateValue(m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1)
127 baseCount++;
128 break;
129 case TEAM_HORDE:
130 if (GetBgMap()->GetWorldStateValue(m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1)
131 baseCount++;
132 break;
133 default:
134 break;
135 }
136 }
137 return baseCount;
138}
139
140void BattlegroundEY::DoForFlagKeepers(std::function<void(Player*)> action) const
141{
143 {
144 if (Player* carrier = ObjectAccessor::FindPlayer(flag->GetFlagCarrierGUID()))
145 action(carrier);
146 }
147}
148
150{
151 _assaultEnabled = false;
154 DoForFlagKeepers([&](Player* player) -> void
155 {
157 });
158}
159
161{
162 if (_assaultStackCount == 0)
163 return;
164
167 {
170 }
171
172 Aura* aura = player->GetAura(spellId);
173 if (!aura)
174 {
175 player->CastSpell(player, spellId, true);
176 aura = player->GetAura(spellId);
177 }
178
179 if (aura)
181}
182
184{
187}
188
190{
191 uint32 score = GetTeamScore(Team);
192
193 if (score >= BG_EY_MAX_TEAM_SCORE)
194 {
195 score = BG_EY_MAX_TEAM_SCORE;
196 if (Team == TEAM_ALLIANCE)
198 else
200 }
201
202 if (Team == TEAM_ALLIANCE)
204 else
206}
207
209{
210 // Win reward
211 if (winner == ALLIANCE)
213 if (winner == HORDE)
215
216 // Complete map reward
219
221}
222
224{
225 if (teamId == TEAM_ALLIANCE)
227 else
229}
230
232{
233 switch (gameObject->GetEntry())
234 {
237 _doorGUIDs.insert(gameObject->GetGUID());
238 break;
240 _flagGUID = gameObject->GetGUID();
241 break;
242 default:
243 break;
244 }
245}
246
248{
249 if (areaTrigger->GetEntry() != AREATRIGGER_CAPTURE_FLAG)
250 return false;
251
253 {
254 if (flag->GetFlagCarrierGUID() != player->GetGUID())
255 return false;
256 }
257
258 if (GameObject* controlzone = player->FindNearestGameObjectWithOptions(40.0f, { .StringId = "bg_eye_of_the_storm_control_zone" }))
259 {
260 uint32 point = _controlZoneHandlers[controlzone->GetEntry()]->GetPoint();
261 switch (GetPlayerTeam(player->GetGUID()))
262 {
263 case ALLIANCE:
264 return GetBgMap()->GetWorldStateValue(m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1;
265 case HORDE:
266 return GetBgMap()->GetWorldStateValue(m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1;
267 default:
268 return false;
269 }
270 }
271
272 return false;
273}
274
276{
277 if (areaTrigger->GetEntry() != AREATRIGGER_CAPTURE_FLAG)
278 return;
279
281
282 if (GameObject* gameObject = GetBgMap()->GetGameObject(_flagGUID))
283 gameObject->HandleCustomTypeCommand(GameObjectType::SetNewFlagState(FlagState::Respawning, player));
284
285 Team team = Team(GetPlayerTeam(player->GetGUID()));
286 if (team == ALLIANCE)
287 {
290 }
291 else
292 {
295 }
296
297 if (baseCount > 0)
298 AddPoints(team, BG_EY_FlagPoints[baseCount - 1]);
299
302
304
307}
308
309void BattlegroundEY::OnFlagStateChange(GameObject* /*flagInBase*/, FlagState /*oldValue*/, FlagState newValue, Player* player)
310{
311 switch (newValue)
312 {
315 break;
317 player->CastSpell(player, SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG, true);
319
322
323 if (GetPlayerTeam(player->GetGUID()) == ALLIANCE)
325 else
327 break;
328 case FlagState::Taken:
329 if (GetPlayerTeam(player->GetGUID()) == ALLIANCE)
330 {
334 }
335 else
336 {
340 }
341
343 _assaultEnabled = true;
344
346 break;
349 break;
350 default:
351 break;
352 }
353
355}
356
358{
360
361 _controlZoneHandlers[BG_OBJECT_FR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, FEL_REAVER);
362 _controlZoneHandlers[BG_OBJECT_BE_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, BLOOD_ELF);
363 _controlZoneHandlers[BG_OBJECT_DR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, DRAENEI_RUINS);
364 _controlZoneHandlers[BG_OBJECT_HU_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, MAGE_TOWER);
365
366 return true;
367}
368
370{
371 //call parent's class reset
373
376 m_HonorScoreTics = { 0, 0 };
378 bool isBGWeekend = sBattlegroundMgr->IsBGWeekend(GetTypeID());
380}
381
383{
385 return;
386
387 Battleground::HandleKillPlayer(player, killer);
389}
390
392{
393 if (teamId == TEAM_ALLIANCE)
394 {
395 SendBroadcastText(m_LosingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, controlZone);
396 UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 0);
397 }
398 else if (teamId == TEAM_HORDE)
399 {
400 SendBroadcastText(m_LosingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, controlZone);
401 UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, 0);
402 }
403
404 UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 1);
405 UpdatePointsCount(teamId);
406}
407
409{
410 if (teamId == TEAM_ALLIANCE)
411 {
412 SendBroadcastText(m_CapturingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, controlZone);
413 UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 1);
414 }
415 else if (teamId == TEAM_HORDE)
416 {
417 SendBroadcastText(m_CapturingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, controlZone);
418 UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, 1);
419 }
420
421 UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 0);
422 UpdatePointsCount(teamId);
423}
424
426{
428}
429
431{
433 return ALLIANCE;
435 return HORDE;
436
438}
439
441{
442 Battleground::ProcessEvent(target, eventId, invoker);
443
444 if (invoker)
445 {
446 if (GameObject* gameobject = invoker->ToGameObject())
447 {
448 if (gameobject->GetGoType() == GAMEOBJECT_TYPE_CONTROL_ZONE)
449 {
450 if (!_controlZoneHandlers.contains(gameobject->GetEntry()))
451 return;
452
453 auto controlzone = gameobject->GetGOInfo()->controlZone;
455 if (eventId == controlzone.NeutralEventAlliance)
456 handler.HandleNeutralEventAlliance(gameobject);
457 else if (eventId == controlzone.NeutralEventHorde)
458 handler.HandleNeutralEventHorde(gameobject);
459 else if (eventId == controlzone.ProgressEventAlliance)
460 handler.HandleProgressEventAlliance(gameobject);
461 else if (eventId == controlzone.ProgressEventHorde)
462 handler.HandleProgressEventHorde(gameobject);
463 }
464 }
465 }
466}
467
469 _battleground(bg), _point(point)
470{
471}
472
474{
476}
477
479{
481}
482
484{
486}
487
489{
491}
EyeOfTheStormPvpStats
@ PVP_STAT_FLAG_CAPTURES
@ BG_EY_FLAG_STATE_ON_PLAYER
@ BG_EY_FLAG_STATE_ON_BASE
@ BG_EY_FLAG_STATE_WAIT_RESPAWN
const std::array< BattlegroundEYPointIconsStruct, EY_POINTS_MAX > m_PointsIconStruct
const std::array< uint32, EY_POINTS_MAX > BG_EY_FlagPoints
@ BG_EY_MAX_TEAM_SCORE
const std::array< uint8, EY_POINTS_MAX > BG_EY_TickPoints
static constexpr Seconds BG_EY_FLAG_ASSAULT_TIMER
@ NETHERSTORM_FLAG_STATE_ALLIANCE
@ EY_HORDE_RESOURCES
@ NETHERSTORM_FLAG
@ EY_ALLIANCE_BASE
@ NETHERSTORM_FLAG_STATE_HORDE
@ EY_ALLIANCE_RESOURCES
@ EY_HORDE_BASE
@ EY_MAX_RESOURCES
@ DRAENEI_RUINS
@ BLOOD_ELF
@ MAGE_TOWER
@ FEL_REAVER
#define BG_EY_NotEYWeekendHonorTicks
@ EY_EXPLOIT_TELEPORT_LOCATION_ALLIANCE
@ EY_EXPLOIT_TELEPORT_LOCATION_HORDE
static constexpr Seconds POINTS_TICK_TIME
@ BG_EY_TEXT_TAKEN_FLAG
@ BG_EY_TEXT_ALLIANCE_CAPTURED_FLAG
@ BG_EY_TEXT_FLAG_DROPPED
@ BG_EY_TEXT_HORDE_CAPTURED_FLAG
const std::array< BattlegroundEYCapturingPointStruct, EY_POINTS_MAX > m_CapturingPointTypes
@ BG_EY_EVENT_START_BATTLE
@ BG_OBJECT_HU_TOWER_CAP_EY_ENTRY
@ BG_OBJECT_BE_TOWER_CAP_EY_ENTRY
@ BG_OBJECT_FLAG2_EY_ENTRY
@ BG_OBJECT_FR_TOWER_CAP_EY_ENTRY
@ BG_OBJECT_A_DOOR_EY_ENTRY
@ BG_OBJECT_H_DOOR_EY_ENTRY
@ BG_OBJECT_DR_TOWER_CAP_EY_ENTRY
const std::array< BattlegroundEYLosingPointStruct, EY_POINTS_MAX > m_LosingPointTypes
@ AREATRIGGER_CAPTURE_FLAG
#define BG_EY_EYWeekendHonorTicks
@ BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE
@ BG_EY_SOUND_FLAG_CAPTURED_HORDE
@ BG_EY_SOUND_FLAG_PICKED_UP_HORDE
@ BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE
@ BG_EY_BRUTAL_ASSAULT_SPELL
@ BG_EY_NETHERSTORM_FLAG_SPELL
@ BG_EY_FOCUSED_ASSAULT_SPELL
static constexpr uint16 BG_EY_FLAG_BRUTAL_ASSAULT_STACK_COUNT
#define sBattlegroundMgr
@ SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG
Definition: Battleground.h:113
@ STATUS_IN_PROGRESS
Definition: Battleground.h:167
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
FlagState
Definition: GameObject.h:46
#define sObjectMgr
Definition: ObjectMgr.h:1946
@ GAMEOBJECT_TYPE_CONTROL_ZONE
TeamId
@ TEAM_ALLIANCE
@ TEAM_HORDE
Team
@ ALLIANCE
@ HORDE
@ CHAT_MSG_BG_SYSTEM_ALLIANCE
@ CHAT_MSG_BG_SYSTEM_HORDE
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition: Util.h:491
void SetStackAmount(uint8 num)
void HandleProgressEventAlliance(GameObject *controlZone) override
void HandleProgressEventHorde(GameObject *controlZone) override
void HandleNeutralEventHorde(GameObject *controlZone) override
BattlegroundEYControlZoneHandler(BattlegroundEY *bg, uint32 point)
void HandleNeutralEventAlliance(GameObject *controlZone) override
uint32 m_FlagCapturedBgObjectType
void AddPoints(Team team, uint32 Points)
bool CanCaptureFlag(AreaTrigger *areaTrigger, Player *player) override
GuidUnorderedSet _doorGUIDs
void DoForFlagKeepers(std::function< void(Player *)> action) const
void EndBattleground(Team winner) override
uint8 GetControlledBaseCount(TeamId teamId) const
void HandleKillPlayer(Player *player, Player *killer) override
bool SetupBattleground() override
WorldSafeLocsEntry const * GetExploitTeleportLocation(Team team) override
std::unordered_map< uint32, std::unique_ptr< BattlegroundEYControlZoneHandler > > _controlZoneHandlers
void StartingEventOpenDoors() override
void OnGameObjectCreate(GameObject *gameObject) override
TimeTracker _pointsTimer
void RemoveAssaultDebuffFromPlayer(Player *player)
void ApplyAssaultDebuffToPlayer(Player *player)
uint16 _assaultStackCount
TimeTracker _flagAssaultTimer
void PostUpdateImpl(uint32 diff) override
Post-update hook.
void Reset() override
void EventTeamCapturedPoint(TeamId teamId, uint32 point, GameObject *controlZone)
std::array< uint32, PVP_TEAMS_COUNT > m_HonorScoreTics
void UpdatePointsCount(TeamId teamId)
void UpdateTeamScore(TeamId Team)
void ProcessEvent(WorldObject *target, uint32 eventId, WorldObject *invoker) override
Team GetPrematureWinner() override
BattlegroundEY(BattlegroundTemplate const *battlegroundTemplate)
void EventTeamLostPoint(TeamId teamId, uint32 point, GameObject *controlZone)
void OnFlagStateChange(GameObject *flagInBase, FlagState oldValue, FlagState newValue, Player *player) override
ObjectGuid _flagGUID
void OnCaptureFlag(AreaTrigger *areaTrigger, Player *player) override
virtual Team GetPrematureWinner()
virtual void HandleKillPlayer(Player *player, Player *killer)
virtual void Reset()
void PlaySoundToAll(uint32 SoundID)
uint32 GetTeamScore(TeamId teamId) const
GuidVector BgObjects
Definition: Battleground.h:443
void RewardHonorToTeam(uint32 Honor, Team team)
BattlegroundMap * GetBgMap() const
BattlegroundTypeId GetTypeID() const
void ProcessEvent(WorldObject *, uint32, WorldObject *) override
Definition: Battleground.h:424
void TriggerGameEvent(uint32 gameEventId, WorldObject *source=nullptr, WorldObject *target=nullptr) override
int32 m_TeamScores[PVP_TEAMS_COUNT]
Definition: Battleground.h:565
GuidVector BgCreatures
Definition: Battleground.h:444
static TeamId GetTeamIndexByTeamId(Team team)
Definition: Battleground.h:392
void UpdateWorldState(int32 worldStateId, int32 value, bool hidden=false)
virtual void EndBattleground(Team winner)
void SendBroadcastText(uint32 id, ChatMsg msgType, WorldObject const *target=nullptr)
BattlegroundStatus GetStatus() const
Definition: Battleground.h:284
Team GetPlayerTeam(ObjectGuid guid) const
virtual void EventPlayerDroppedFlag(Player *)
Definition: Battleground.h:420
uint32 GetBonusHonorFromKill(uint32 kills) const
void UpdatePvpStat(Player *player, uint32 pvpStatId, uint32 value)
int32 GetWorldStateValue(int32 worldStateId) const
Definition: Map.cpp:460
static GameObject * ToGameObject(Object *o)
Definition: Object.h:231
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4560
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition: Unit.cpp:4101
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
GameObject * FindNearestGameObjectWithOptions(float range, FindGameObjectOptions const &options) const
Definition: Object.cpp:2179
TC_GAME_API GameObject * GetGameObject(WorldObject const &u, ObjectGuid const &guid)
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
void Update(int32 diff)
Definition: Timer.h:121
bool Passed() const
Definition: Timer.h:131
void Reset(int32 expiry)
Definition: Timer.h:136