TrinityCore
Loading...
Searching...
No Matches
battleground_eye_of_the_storm.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 "AreaTrigger.h"
19#include "BattlegroundScript.h"
20#include "Battleground.h"
21#include "BattlegroundMgr.h"
22#include "GameObject.h"
23#include "GameTime.h"
24#include "Map.h"
25#include "ObjectAccessor.h"
26#include "Player.h"
27#include "ScriptMgr.h"
28#include "SpellAuras.h"
29#include "Timer.h"
30
67
77
87
89{
90 BG_OBJECT_A_DOOR_EY_ENTRY = 184719, //Alliance door
91 BG_OBJECT_H_DOOR_EY_ENTRY = 184720, //Horde door
92 BG_OBJECT_FLAG2_EY_ENTRY = 208977, //Netherstorm flag (flagstand)
93 BG_OBJECT_BE_TOWER_CAP_EY_ENTRY = 184080, //BE Tower Cap Pt
94 BG_OBJECT_FR_TOWER_CAP_EY_ENTRY = 184081, //Fel Reaver Cap Pt
95 BG_OBJECT_HU_TOWER_CAP_EY_ENTRY = 184082, //Human Tower Cap Pt
96 BG_OBJECT_DR_TOWER_CAP_EY_ENTRY = 184083, //Draenei Tower Cap Pt
97};
98
103
114
117
123
131
138
144
173
175{
176 BattlegroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex,
177 uint32 worldStateAllianceStatusBarIcon, uint32 worldStateHordeStatusBarIcon)
178 : WorldStateControlIndex(_WorldStateControlIndex), WorldStateAllianceControlledIndex(_WorldStateAllianceControlledIndex), WorldStateHordeControlledIndex(_WorldStateHordeControlledIndex),
179 WorldStateAllianceStatusBarIcon(worldStateAllianceStatusBarIcon), WorldStateHordeStatusBarIcon(worldStateHordeStatusBarIcon) { }
185};
186
188{
189 BattlegroundEYLosingPointStruct(uint32 _MessageIdAlliance, uint32 _MessageIdHorde)
190 : MessageIdAlliance(_MessageIdAlliance), MessageIdHorde(_MessageIdHorde)
191 { }
192
195};
196
198{
199 BattlegroundEYCapturingPointStruct(uint32 _MessageIdAlliance, uint32 _MessageIdHorde)
200 : MessageIdAlliance(_MessageIdAlliance), MessageIdHorde(_MessageIdHorde)
201 { }
202
205};
206
208{
209public:
210 explicit BattlegroundEYControlZoneHandler(uint32 point) : _point(point) { }
211
212 uint32 GetPoint() const { return _point; }
213
214private:
216};
217
225
233
241
243{
245 {
247 };
248
249 static constexpr Seconds POINTS_TICK_TIME = 2s;
250 static constexpr Seconds BG_EY_FLAG_ASSAULT_TIMER = 30s;
252 static constexpr uint32 BG_EY_EVENT_START_BATTLE = 13180;
253
254 static constexpr std::array<uint8, EY_POINTS_MAX> BG_EY_TickPoints = { 1, 2, 5, 10 };
255 static constexpr std::array<uint32, EY_POINTS_MAX> BG_EY_FlagPoints = { 75, 85, 100, 500 };
256
258 {
259 _honorScoreTics = { 0, 0 };
260 _honorTics = 0;
262 _assaultEnabled = false;
265
266 _controlZoneHandlers[BG_OBJECT_FR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(FEL_REAVER);
267 _controlZoneHandlers[BG_OBJECT_BE_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(BLOOD_ELF);
268 _controlZoneHandlers[BG_OBJECT_DR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(DRAENEI_RUINS);
269 _controlZoneHandlers[BG_OBJECT_HU_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(MAGE_TOWER);
270
271 bool isBGWeekend = sBattlegroundMgr->IsBGWeekend(battleground->GetTypeID());
273 }
274
279
280 void OnUpdate(uint32 diff) override
281 {
283 return;
284
285 _pointsTimer.Update(diff);
286 if (_pointsTimer.Passed())
287 {
289
290 uint8 baseCountAlliance = GetControlledBaseCount(TEAM_ALLIANCE);
291 uint8 baseCountHorde = GetControlledBaseCount(TEAM_HORDE);
292 if (baseCountAlliance > 0)
293 AddPoint(ALLIANCE, BG_EY_TickPoints[baseCountAlliance - 1]);
294 if (baseCountHorde > 0)
295 AddPoint(HORDE, BG_EY_TickPoints[baseCountHorde - 1]);
296 }
297
298 if (_assaultEnabled)
299 {
302 {
304 if (_assaultStackCount < std::numeric_limits<uint8>::max())
305 {
307
308 // update assault debuff stacks
309 DoForFlagKeepers([&](Player* player) -> void
310 {
312 });
313 }
314 }
315 }
316 }
317
318 void OnStart() override
319 {
320 for (ObjectGuid const& door : _doorGUIDs)
321 {
322 if (GameObject* gameObject = battlegroundMap->GetGameObject(door))
323 {
324 gameObject->UseDoorOrButton();
325 gameObject->DespawnOrUnsummon(3s);
326 }
327 }
328
329 // Achievement: Flurry
331 }
332
333 void AddPoint(Team team, uint32 points)
334 {
335 battleground->AddPoint(team, points);
336 TeamId const team_index = Battleground::GetTeamIndexByTeamId(team);
337 _honorScoreTics[team_index] += points;
338 if (_honorScoreTics[team_index] >= _honorTics)
339 {
341 _honorScoreTics[team_index] -= _honorTics;
342 }
343
344 UpdateTeamScore(team_index);
345 }
346
348 {
349 uint8 baseCount = 0;
350 for (auto const& controlZoneHandler : _controlZoneHandlers)
351 {
352 uint32 point = controlZoneHandler.second->GetPoint();
353 switch (teamId)
354 {
355 case TEAM_ALLIANCE:
356 if (battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1)
357 baseCount++;
358 break;
359 case TEAM_HORDE:
360 if (battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1)
361 baseCount++;
362 break;
363 default:
364 break;
365 }
366 }
367 return baseCount;
368 }
369
370 template <std::invocable<Player*> Action>
371 void DoForFlagKeepers(Action const& action) const
372 {
374 if (Player* carrier = ObjectAccessor::FindPlayer(flag->GetFlagCarrierGUID()))
375 action(carrier);
376 }
377
379 {
380 _assaultEnabled = false;
383 DoForFlagKeepers([&](Player* player) -> void
384 {
386 });
387 }
388
390 {
391 if (_assaultStackCount == 0)
392 return;
393
396 {
399 }
400
401 Aura* aura = player->GetAura(spellId);
402 if (!aura)
403 {
404 player->CastSpell(player, spellId, true);
405 aura = player->GetAura(spellId);
406 }
407
408 if (aura)
410 }
411
417
419 {
421
422 if (score >= BG_EY_MAX_TEAM_SCORE)
423 {
424 score = BG_EY_MAX_TEAM_SCORE;
425 if (Team == TEAM_ALLIANCE)
427 else
429 }
430
431 if (Team == TEAM_ALLIANCE)
433 else
435 }
436
450
458
459 void OnGameObjectCreate(GameObject* gameObject) override
460 {
461 switch (gameObject->GetEntry())
462 {
465 _doorGUIDs.insert(gameObject->GetGUID());
466 break;
468 _flagGUID = gameObject->GetGUID();
469 break;
470 default:
471 break;
472 }
473 }
474
475 bool CanCaptureFlag(AreaTrigger* areaTrigger, Player* player) override
476 {
477 if (areaTrigger->GetEntry() != AREATRIGGER_CAPTURE_FLAG)
478 return false;
479
481 {
482 if (flag->GetFlagCarrierGUID() != player->GetGUID())
483 return false;
484 }
485
486 if (GameObject const* controlzone = player->FindNearestGameObjectWithOptions(40.0f, { .StringId = "bg_eye_of_the_storm_control_zone" }))
487 {
488 uint32 const point = _controlZoneHandlers[controlzone->GetEntry()]->GetPoint();
489 switch (battleground->GetPlayerTeam(player->GetGUID()))
490 {
491 case ALLIANCE:
492 return battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1;
493 case HORDE:
494 return battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1;
495 default:
496 return false;
497 }
498 }
499
500 return false;
501 }
502
537
538 void OnFlagStateChange(GameObject* /*flagInBase*/, FlagState /*oldValue*/, FlagState newValue, Player* player) override
539 {
540 switch (newValue)
541 {
544 break;
546 player->CastSpell(player, SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG, true);
548
551
552 if (battleground->GetPlayerTeam(player->GetGUID()) == ALLIANCE)
554 else
556 break;
557 case FlagState::Taken:
558 if (battleground->GetPlayerTeam(player->GetGUID()) == ALLIANCE)
559 {
563 }
564 else
565 {
569 }
570
572 _assaultEnabled = true;
573
575 break;
578 break;
579 default:
580 break;
581 }
582
584 }
585
586 void EventTeamLostPoint(TeamId teamId, uint32 point, GameObject* controlZone) const
587 {
588 if (teamId == TEAM_ALLIANCE)
589 {
590 battleground->SendBroadcastText(m_LosingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, controlZone);
591 UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 0);
592 }
593 else if (teamId == TEAM_HORDE)
594 {
596 UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, 0);
597 }
598
599 UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 1);
600 UpdatePointsCount(teamId);
601 }
602
603 void EventTeamCapturedPoint(TeamId teamId, uint32 point, GameObject* controlZone) const
604 {
605 if (teamId == TEAM_ALLIANCE)
606 {
608 UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 1);
609 }
610 else if (teamId == TEAM_HORDE)
611 {
613 UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, 1);
614 }
615
616 UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 0);
617 UpdatePointsCount(teamId);
618 }
619
630
631 void ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker) override
632 {
633 BattlegroundScript::ProcessEvent(obj, eventId, invoker);
634
635 if (invoker)
636 {
637 if (GameObject* gameobject = invoker->ToGameObject())
638 {
639 if (gameobject->GetGoType() == GAMEOBJECT_TYPE_CONTROL_ZONE)
640 {
641 if (!_controlZoneHandlers.contains(gameobject->GetEntry()))
642 return;
643
644 auto controlzone = gameobject->GetGOInfo()->controlZone;
646 if (eventId == controlzone.NeutralEventAlliance)
647 EventTeamLostPoint(TEAM_ALLIANCE, handler.GetPoint(), gameobject);
648 else if (eventId == controlzone.NeutralEventHorde)
649 EventTeamLostPoint(TEAM_HORDE, handler.GetPoint(), gameobject);
650 else if (eventId == controlzone.ProgressEventAlliance)
651 EventTeamCapturedPoint(TEAM_ALLIANCE, handler.GetPoint(), gameobject);
652 else if (eventId == controlzone.ProgressEventHorde)
653 EventTeamCapturedPoint(TEAM_HORDE, handler.GetPoint(), gameobject);
654 }
655 }
656 }
657 }
658
659private:
660 std::array<uint32, PVP_TEAMS_COUNT> _honorScoreTics;
661
664
665 std::unordered_map<uint32, std::unique_ptr<BattlegroundEYControlZoneHandler>> _controlZoneHandlers;
668
669 // Focused/Brutal Assault
673};
674
#define sBattlegroundMgr
@ SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG
@ STATUS_IN_PROGRESS
uint8_t uint8
Definition Define.h:156
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:28
FlagState
Definition GameObject.h:46
std::unordered_set< ObjectGuid > GuidUnorderedSet
Definition ObjectGuid.h:435
#define RegisterBattlegroundMapScript(script_name, mapId)
Definition ScriptMgr.h:1447
@ GAMEOBJECT_TYPE_CONTROL_ZONE
@ TEAM_ALLIANCE
@ TEAM_HORDE
@ ALLIANCE
@ HORDE
@ CHAT_MSG_BG_SYSTEM_ALLIANCE
@ CHAT_MSG_BG_SYSTEM_HORDE
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition Util.h:565
const std::array< BattlegroundEYPointIconsStruct, EY_POINTS_MAX > m_PointsIconStruct
@ BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE
@ BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE
@ EY_EXPLOIT_TELEPORT_LOCATION_ALLIANCE
constexpr uint32 BG_EY_EYWeekendHonorTicks
const std::array< BattlegroundEYCapturingPointStruct, EY_POINTS_MAX > m_CapturingPointTypes
@ BG_EY_TEXT_HORDE_LOST_BLOOD_ELF_TOWER
@ BG_EY_TEXT_ALLIANCE_TAKEN_MAGE_TOWER
@ BG_EY_TEXT_HORDE_LOST_FEL_REAVER_RUINS
@ BG_EY_TEXT_ALLIANCE_TAKEN_FEL_REAVER_RUINS
@ BG_EY_TEXT_ALLIANCE_LOST_MAGE_TOWER
@ BG_EY_TEXT_HORDE_LOST_DRAENEI_RUINS
@ BG_EY_TEXT_HORDE_TAKEN_DRAENEI_RUINS
@ BG_EY_TEXT_ALLIANCE_TAKEN_BLOOD_ELF_TOWER
@ BG_EY_TEXT_ALLIANCE_TAKEN_DRAENEI_RUINS
@ BG_EY_TEXT_HORDE_TAKEN_FEL_REAVER_RUINS
@ BG_EY_TEXT_HORDE_TAKEN_BLOOD_ELF_TOWER
@ BG_EY_TEXT_ALLIANCE_LOST_BLOOD_ELF_TOWER
@ BG_EY_TEXT_ALLIANCE_LOST_FEL_REAVER_RUINS
@ BG_EY_TEXT_ALLIANCE_LOST_DRAENEI_RUINS
@ DRAENEI_RUINS_HORDE_CONTROL_STATE
@ FEL_REAVER_ALLIANCE_CONTROL_STATE
@ DRAENEI_RUINS_ALLIANCE_CONTROL_STATE
@ MAGE_TOWER_ALLIANCE_CONTROL_STATE
const std::array< BattlegroundEYLosingPointStruct, EY_POINTS_MAX > m_LosingPointTypes
constexpr uint32 BG_EY_NotEYWeekendHonorTicks
void AddSC_battleground_eye_of_the_storm()
Action
void SetStackAmount(uint8 num)
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
Battleground * battleground
void TriggerGameEvent(uint32 gameEventId, WorldObject *source=nullptr, WorldObject *target=nullptr) override
BattlegroundMap * battlegroundMap
virtual void OnEnd(Team winner)
virtual Team GetPrematureWinner()
void UpdateWorldState(int32 worldStateId, int32 value, bool hidden=false) const
void PlaySoundToAll(uint32 SoundID)
uint32 GetTeamScore(TeamId teamId) const
void RewardHonorToTeam(uint32 Honor, Team team)
BattlegroundTypeId GetTypeID() const
static TeamId GetTeamIndexByTeamId(Team team)
virtual void EndBattleground(Team winner)
void SendBroadcastText(uint32 id, ChatMsg msgType, WorldObject const *target=nullptr)
BattlegroundStatus GetStatus() const
void AddPoint(Team team, uint32 points=1)
Team GetPlayerTeam(ObjectGuid guid) const
uint32 GetBonusHonorFromKill(uint32 kills) const
void UpdatePvpStat(Player *player, uint32 pvpStatId, uint32 value)
int32 GetWorldStateValue(int32 worldStateId) const
Definition Map.cpp:427
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:3552
GameObject * ToGameObject()
Definition Object.h:131
uint32 GetEntry() const
Definition Object.h:89
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4700
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition Unit.cpp:4241
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3974
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
GameObject * FindNearestGameObjectWithOptions(float range, FindGameObjectOptions const &options) const
Definition Object.cpp:1548
virtual void ProcessEvent(WorldObject *obj, uint32 eventId, WorldObject *invoker)
Definition ZoneScript.h:103
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
BattlegroundEYCapturingPointStruct(uint32 _MessageIdAlliance, uint32 _MessageIdHorde)
BattlegroundEYLosingPointStruct(uint32 _MessageIdAlliance, uint32 _MessageIdHorde)
BattlegroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex, uint32 worldStateAllianceStatusBarIcon, uint32 worldStateHordeStatusBarIcon)
void Update(int32 diff)
Definition Timer.h:121
bool Passed() const
Definition Timer.h:131
void Reset(int32 expiry)
Definition Timer.h:136
static constexpr uint16 BG_EY_FLAG_BRUTAL_ASSAULT_STACK_COUNT
std::unordered_map< uint32, std::unique_ptr< BattlegroundEYControlZoneHandler > > _controlZoneHandlers
void OnGameObjectCreate(GameObject *gameObject) override
uint8 GetControlledBaseCount(TeamId teamId) const
void DoForFlagKeepers(Action const &action) const
void OnFlagStateChange(GameObject *, FlagState, FlagState newValue, Player *player) override
void EventTeamCapturedPoint(TeamId teamId, uint32 point, GameObject *controlZone) const
std::array< uint32, PVP_TEAMS_COUNT > _honorScoreTics
bool CanCaptureFlag(AreaTrigger *areaTrigger, Player *player) override
void EventTeamLostPoint(TeamId teamId, uint32 point, GameObject *controlZone) const
void OnCaptureFlag(AreaTrigger *areaTrigger, Player *player) override
static constexpr std::array< uint32, EY_POINTS_MAX > BG_EY_FlagPoints
static constexpr std::array< uint8, EY_POINTS_MAX > BG_EY_TickPoints
void ProcessEvent(WorldObject *obj, uint32 eventId, WorldObject *invoker) override