TrinityCore
Loading...
Searching...
No Matches
battleground_temple_of_kotmogu.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 "AreaTriggerAI.h"
20#include "Battleground.h"
21#include "BattlegroundScript.h"
22#include "Creature.h"
23#include "CreatureAI.h"
24#include "GameObject.h"
25#include "Map.h"
26#include "ObjectAccessor.h"
27#include "ObjectGuid.h"
28#include "Player.h"
29#include "ScriptMgr.h"
30#include "SpellAuraEffects.h"
31#include "SpellAuras.h"
32#include "SpellScript.h"
33#include "TaskScheduler.h"
34#include "WorldStateMgr.h"
35
37{
38 namespace Achievements
39 {
40 static constexpr uint32 Powerball = 6950;
41 }
42
43 namespace Actions
44 {
45 static constexpr uint32 CheckScore = 1;
46 static constexpr uint32 ConsumeAreaTrigger = 2;
47 }
48
50 {
51 static constexpr uint32 PvpRuneRejuv = 86;
52 }
53
54 namespace BroadcastTexts
55 {
56 static constexpr uint32 BlueOrbTaken = 62279;
57 static constexpr uint32 OrangeOrbTaken = 62280;
58 static constexpr uint32 GreenOrbTaken = 62281;
59 static constexpr uint32 PurpleOrbTaken = 62282;
60 }
61
62 namespace Creatures
63 {
64 static constexpr uint32 Trigger = 58951; // used for sounds, texts, etc.
65 }
66
67 namespace CreatureTexts::Trigger
68 {
69 static constexpr uint8 OrangeOrbReturned = 0;
70 static constexpr uint8 BlueOrbReturned = 1;
71 static constexpr uint8 PurpleOrbReturned = 2;
72 static constexpr uint8 GreenOrbReturned = 3;
73 }
74
75 namespace GameObjects
76 {
77 static constexpr uint32 GreatWall = 215760;
78 static constexpr uint32 Collision = 215787;
79
80 static constexpr uint32 OrbOfPowerBlue = 212091;
81 static constexpr uint32 OrbOfPowerPurple = 212092;
82 static constexpr uint32 OrbOfPowerGreen = 212093;
83 static constexpr uint32 OrbOfPowerOrange = 212094;
84 }
85
86 namespace Positions
87 {
88 static constexpr std::array<Position, 4> HealingBuffs
89 {{
90 { 1868.2396f, 1391.1198f, 11.52903f, 6.2601f },
91 { 1697.9149f, 1275.7673f, 12.16028f, 3.1154f },
92 { 1698.4271f, 1391.7951f, 11.75756f, 3.1675f },
93 { 1867.8836f, 1274.8872f, 11.85079f, 0.0331f }
94 }};
95
96 static constexpr Position PurpleOrb = { 1850.2170f, 1416.8229f, 13.3382f };
97 static constexpr Position GreenOrb = { 1716.8923f, 1416.6180f, 13.2056f};
98 static constexpr Position BlueOrb = { 1716.9479f, 1250.0173f, 13.3266f};
99 static constexpr Position OrangeOrb = { 1850.1666f, 1250.1180f, 13.2056f};
100 }
101
102 namespace PvpStats
103 {
104 static constexpr uint32 OrbPossessions = 418;
105 static constexpr uint32 VictoryPoints = 419;
106 }
107
108 namespace SoundKits
109 {
110 static constexpr uint32 PVPFlagTakenAlliance = 8174;
111 }
112
113 namespace Spells
114 {
115 static constexpr uint32 PowerOrbScalePeriodic = 127163;
116 static constexpr uint32 PowerOrbImmunityPeriodic = 116524; // also used for achievement to check if player has power orb (Blackout, can't stop won't stop)
117 static constexpr uint32 Plus3VictoryPoints = 112912; // adds 2 victory points (not a typo)
118 static constexpr uint32 Plus4VictoryPoints = 112913; // adds 4 victory points
119 static constexpr uint32 Plus5VictoryPoints = 112914; // adds 6 victory points (not a typo)
120
121 static constexpr uint32 SmallAura = 112052;
122 static constexpr uint32 MediumAura = 112053;
123 static constexpr uint32 LargeAura = 112054;
124
125 // Achievement Powerball
126 // Hold an Orb of Power in the center of the Temple of Kotmogu for 90 seconds.
127 static constexpr uint32 PowerballCredit = 128768; // serverside spell
128
129 static constexpr uint32 HordeInsigniaVisual = 131528;
130 static constexpr uint32 AllianceInsigniaVisual = 131527;
131 static constexpr uint32 Restoration = 294564;
132 }
133
134 namespace WorldStates
135 {
136 static constexpr int32 MaxPoints = 17388;
137 static constexpr int32 AlliancePoints = 6303;
138 static constexpr int32 HordePoints = 6304;
139
140 static constexpr int32 BlueOrbInBase = 6714;
141 static constexpr int32 BlueOrbHorde = 6969;
142 static constexpr int32 BlueOrbAlliance = 6970;
143
144 static constexpr int32 OrangeOrbInBase = 6717;
145 static constexpr int32 OrangeOrbHorde = 6963;
146 static constexpr int32 OrangeOrbAlliance = 6964;
147
148 static constexpr int32 PurpleOrbInBase = 6715;
149 static constexpr int32 PurpleOrbHorde = 6967;
150 static constexpr int32 PurpleOrbAlliance = 6968;
151
152 static constexpr int32 GreenOrbInBase = 6716;
153 static constexpr int32 GreenOrbHorde = 6965;
154 static constexpr int32 GreenOrbAlliance = 6966;
155 }
156
158 {
159 constexpr StaticOrbData(Position spawnPosition, uint32 entry, uint32 broadcastText, uint8 triggerText, int32 worldStateInBase, int32 worldStateHorde, int32 worldStateAlliance) :
160 SpawnPosition(spawnPosition), Entry(entry), BroadcastText(broadcastText), TriggerText(triggerText), WorldStateInBase(worldStateInBase), WorldStateHorde(worldStateHorde), WorldStateAlliance(worldStateAlliance)
161 {
162 }
163
166 uint32 BroadcastText; // when picked up
167 uint8 TriggerText; // when dropped, not a broadcast text but group from creature_text
171 };
172
220}
221
223{
228
229 void OnInit() override
230 {
232 SpawnOrb(&data);
233 }
234
235 void OnUpdate(uint32 diff) override
236 {
237 _scheduler.Update(diff);
238 }
239
240 void OnPrepareStage3() override
241 {
242 _scheduler.Schedule(24s, [&](TaskContext const&)
243 {
244 for (ObjectGuid const& door : _walls)
245 if (GameObject* gameObject = battlegroundMap->GetGameObject(door))
246 gameObject->UseDoorOrButton();
247 });
248 }
249
250 void OnStart() override
251 {
252 for (ObjectGuid const& door : _collisions)
253 if (GameObject* gameObject = battlegroundMap->GetGameObject(door))
254 gameObject->UseDoorOrButton();
255
256 _scheduler.Schedule(5s, [&](TaskContext& context)
257 {
258 for (ObjectGuid const& guid : _orbHolders)
259 {
260 if (Player* player = ObjectAccessor::FindPlayer(guid))
261 {
262 if (player->HasAura(TempleOfKotmogu::Spells::SmallAura))
263 player->CastSpell(player, TempleOfKotmogu::Spells::Plus5VictoryPoints, true);
264 else if (player->HasAura(TempleOfKotmogu::Spells::MediumAura))
265 player->CastSpell(player, TempleOfKotmogu::Spells::Plus4VictoryPoints, true);
266 else if (player->HasAura(TempleOfKotmogu::Spells::LargeAura))
267 player->CastSpell(player, TempleOfKotmogu::Spells::Plus3VictoryPoints, true);
268 }
269 }
270
271 bool const winner = CheckWinner();
272 if (!winner)
273 context.Repeat();
274 });
275 }
276
277 void OnGameObjectCreate(GameObject* gameobject) override
278 {
279 switch (gameobject->GetEntry())
280 {
282 _walls.emplace_back(gameobject->GetGUID());
283 break;
285 _collisions.emplace_back(gameobject->GetGUID());
286 break;
287 default:
288 break;
289 }
290 }
291
292 void OnCreatureCreate(Creature* creature) override
293 {
294 switch (creature->GetEntry())
295 {
297 _triggerGuid = creature->GetGUID();
298 for (std::size_t i = 0; i < TempleOfKotmogu::Positions::HealingBuffs.size(); i++)
300 break;
301 default:
302 break;
303 }
304 }
305
306 void OnFlagTaken(GameObject* flag, Player* player) override
307 {
311
312 Team const team = player->GetBGTeam();
313
315
316 if (team == HORDE)
317 {
319 chatMsg = CHAT_MSG_BG_SYSTEM_HORDE;
320 }
321 else if (team == ALLIANCE)
322 {
325 }
326
327 TempleOfKotmogu::StaticOrbData const* orbData = GetOrbData(flag->GetEntry());
328 if (!orbData)
329 return;
330
333 UpdateWorldState(orbData->WorldStateHorde, team == HORDE);
334 battleground->SendBroadcastText(orbData->BroadcastText, chatMsg, player);
336
337 _orbHolders.insert(player->GetGUID());
339 }
340
341 void OnFlagDropped(ObjectGuid const& flagGuid, Player* player) override
342 {
343 if (!flagGuid.IsGameObject())
344 return;
345
348 _orbHolders.erase(player->GetGUID());
349
350 TempleOfKotmogu::StaticOrbData const* orbData = GetOrbData(flagGuid.GetEntry());
351 if (!orbData)
352 return;
353
357 SpawnOrb(orbData);
359
360 if (Creature const* trigger = battlegroundMap->GetCreature(_triggerGuid))
361 trigger->AI()->Talk(orbData->TriggerText, player);
362 }
363
364 void DoAction(uint32 actionId, WorldObject* source, WorldObject* target) override
365 {
366 switch (actionId)
367 {
369 // ReSharper disable once CppExpressionWithoutSideEffects
370 CheckWinner();
371 break;
374 break;
375 default:
376 break;
377 }
378 }
379
381 {
382 // find index
383 std::size_t index = 0;
384 for (std::size_t i = 0; i < _healingBuffs.size(); i++)
385 {
386 if (_healingBuffs[i] == trigger->GetGUID())
387 {
388 index = i;
389 break;
390 }
391 }
392
393 player->CastSpell(player, TempleOfKotmogu::Spells::Restoration, true);
394 trigger->Remove();
395
396 _scheduler.Schedule(90s, [&, index](TaskContext const&)
397 {
398 SpawnHealingBuff(index);
399 });
400 }
401
429
430 void SpawnHealingBuff(std::size_t index)
431 {
434 _healingBuffs[index] = trigger->GetGUID();
435 }
436
453
454 void SpawnOrb(TempleOfKotmogu::StaticOrbData const* orbData) const
455 {
457 {
458 orb->SetSpawnedByDefault(false);
459 orb->SetRespawnTime(7200);
461 }
462 }
463
464private:
470
471 std::array<ObjectGuid, 4> _healingBuffs;
472};
473
474// 127163 - Power Orb
476{
477 void HandlePeriodic(AuraEffect const* /*aurEff*/) const
478 {
479 if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_0))
480 effect->ChangeAmount(effect->GetAmount() + effect->GetSpellEffectInfo().CalcValue());
481 }
482
487};
488
489// 121164 - Orb of Power
490// 121175 - Orb of Power
491// 121176 - Orb of Power
492// 121177 - Orb of Power
494{
496 {
497 if (AuraEffect* effect = GetAura()->GetEffect(index))
498 effect->ChangeAmount(effect->GetAmount() + effect->GetSpellEffectInfo().CalcValue());
499 }
500
507
512};
513
514// 112912 - +3 Victory Points!
515// 112913 - +4 Victory Points!
516// 112914 - +5 Victory Points!
517// 112910 - +10 Victory Points!
518template<int32 Points>
520{
521public:
522 virtual void OnHit(SpellEffIndex /*effIndex*/) const
523 {
524 Player* player = GetHitPlayer();
525 if (!player)
526 return;
527
528 Battleground* bg = player->GetBattleground();
529 if (!bg)
530 return;
531
534 Team const team = player->GetBGTeam();
535 uint32 const score = bg->GetTeamScore(GetTeamIdForTeam(team));
536
537 int32 const amount = std::min(maxScore, score + Points);
538 bg->SetTeamPoint(team, amount);
541 }
542
547};
548
549// 112910 - +10 Victory Points!
550template<int32 Points>
552{
553 void OnHit(SpellEffIndex effIndex) const override
554 {
557 if (!player)
558 return;
559
560 if (ZoneScript* zonescript = player->FindZoneScript())
561 zonescript->DoAction(TempleOfKotmogu::Actions::CheckScore, player, player);
562 }
563
568};
569
571{
572 explicit at_bg_temple_of_kotmogu_healing_buff(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
573
574 void OnUnitEnter(Unit* unit) override
575 {
576 if (Player* player = unit->ToPlayer())
577 if (ZoneScript* zonescript = at->GetZoneScript())
578 zonescript->DoAction(TempleOfKotmogu::Actions::ConsumeAreaTrigger, at, player);
579 }
580};
581
583{
584 explicit at_bg_temple_of_kotmogu_small_area(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
585
586 void OnUnitEnter(Unit* unit) override
587 {
588 if (Player* player = unit->ToPlayer())
589 {
590 if (!_totalTimeInAreaWithOrb.contains(player->GetGUID()))
591 _totalTimeInAreaWithOrb[player->GetGUID()] = 0;
592
593 player->CastSpell(player, TempleOfKotmogu::Spells::SmallAura, true);
594 }
595 }
596
597 void OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) override
598 {
600 }
601
602 void OnUpdate(uint32 diff) override
603 {
604 for (ObjectGuid const& guid : at->GetInsideUnits())
605 {
606 if (Player* player = ObjectAccessor::FindPlayer(guid))
607 {
609 {
610 _totalTimeInAreaWithOrb[player->GetGUID()] += diff;
611 if (_totalTimeInAreaWithOrb[player->GetGUID()] >= 90000 && !player->HasAchieved(TempleOfKotmogu::Achievements::Powerball))
612 player->CastSpell(player, TempleOfKotmogu::Spells::PowerballCredit, true);
613 }
614 }
615 }
616 }
617
618private:
619 std::unordered_map<ObjectGuid, uint32 /*milliseconds*/> _totalTimeInAreaWithOrb;
620};
621
623{
624 explicit at_bg_temple_of_kotmogu_medium_area(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
625
626 void OnUnitEnter(Unit* unit) override
627 {
628 if (Player* player = unit->ToPlayer())
629 player->CastSpell(player, TempleOfKotmogu::Spells::MediumAura, true);
630 }
631
636};
637
AreaTriggerExitReason
Definition AreaTrigger.h:69
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
std::set< ObjectGuid > GuidSet
Definition ObjectGuid.h:432
std::vector< ObjectGuid > GuidVector
Definition ObjectGuid.h:434
Spells
Definition PlayerAI.cpp:32
#define RegisterBattlegroundMapScript(script_name, mapId)
Definition ScriptMgr.h:1447
#define RegisterAreaTriggerAI(ai_name)
Definition ScriptMgr.h:1428
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
#define RegisterSpellScriptWithArgs(spell_script, script_name,...)
Definition ScriptMgr.h:1382
SpellEffIndex
@ EFFECT_3
@ EFFECT_1
@ EFFECT_0
@ EFFECT_2
constexpr TeamId GetTeamIdForTeam(Team team)
@ TEAM_ALLIANCE
@ TEAM_HORDE
@ SPELL_EFFECT_DUMMY
@ TEAM_OTHER
@ ALLIANCE
@ HORDE
ChatMsg
@ CHAT_MSG_BG_SYSTEM_ALLIANCE
@ CHAT_MSG_BG_SYSTEM_HORDE
@ CHAT_MSG_BG_SYSTEM_NEUTRAL
@ GO_STATE_READY
@ SPELL_AURA_PERIODIC_DUMMY
#define SpellEffectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
Creatures
void AddSC_battleground_temple_of_kotmogu()
Achievements
AreaTrigger *const at
GuidUnorderedSet const & GetInsideUnits() const
static AreaTrigger * CreateAreaTrigger(AreaTriggerCreatePropertiesId areaTriggerCreatePropertiesId, Position const &pos, int32 duration, Unit *caster, Unit *target, SpellCastVisual spellVisual={ 0, 0 }, SpellInfo const *spellInfo=nullptr, Spell *spell=nullptr, AuraEffect const *aurEff=nullptr)
HookList< EffectPeriodicHandler > OnEffectPeriodic
AuraEffect * GetEffect(uint8 effIndex) const
Aura * GetAura() const
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
Battleground * battleground
BattlegroundMap * battlegroundMap
void UpdateWorldState(int32 worldStateId, int32 value, bool hidden=false) const
void PlaySoundToAll(uint32 SoundID)
uint32 GetTeamScore(TeamId teamId) const
virtual void EndBattleground(Team winner)
void SendBroadcastText(uint32 id, ChatMsg msgType, WorldObject const *target=nullptr)
void SetTeamPoint(Team team, uint32 points=0)
void UpdatePvpStat(Player *player, uint32 pvpStatId, uint32 value)
static GameObject * CreateGameObject(uint32 entry, Map *map, Position const &pos, QuaternionData const &rotation, uint32 animProgress, GOState goState, uint32 artKit=0)
void UpdateSpawnGroupConditions()
Definition Map.cpp:2506
bool AddToMap(T *)
Definition Map.cpp:517
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:3552
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:3542
bool IsGameObject() const
Definition ObjectGuid.h:372
uint32 GetEntry() const
Definition ObjectGuid.h:334
Player * ToPlayer()
Definition Object.h:126
AreaTrigger * ToAreaTrigger()
Definition Object.h:146
uint32 GetEntry() const
Definition Object.h:89
Battleground * GetBattleground() const
Definition Player.cpp:25719
Team GetBGTeam() const
Definition Player.cpp:24358
Player * GetHitPlayer() const
HookList< HitHandler > OnHit
HookList< EffectHandler > OnEffectHitTarget
TaskContext & Repeat(TaskScheduler::duration_t duration)
TaskScheduler & Schedule(duration_t time, task_handler_t task)
TaskScheduler & Update()
Update the scheduler to the current time.
Definition Unit.h:635
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3974
Map * GetMap() const
Definition Object.h:411
ZoneScript * FindZoneScript() const
Definition Object.cpp:1365
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
ZoneScript * GetZoneScript() const
Definition Object.h:417
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
static constexpr std::array< Position, 4 > HealingBuffs
static constexpr uint32 AllianceInsigniaVisual
static constexpr uint32 PowerOrbImmunityPeriodic
static constexpr uint32 PowerOrbScalePeriodic
static constexpr std::array< StaticOrbData, 4 > Orbs
TC_GAME_API void SetValue(int32 worldStateId, int32 value, bool hidden, Map *map)
TC_GAME_API int32 GetValue(int32 worldStateId, Map const *map)
constexpr float GetOrientation() const
Definition Position.h:90
static QuaternionData fromEulerAnglesZYX(float Z, float Y, float X)
constexpr StaticOrbData(Position spawnPosition, uint32 entry, uint32 broadcastText, uint8 triggerText, int32 worldStateInBase, int32 worldStateHorde, int32 worldStateAlliance)
void OnUnitExit(Unit *unit, AreaTriggerExitReason) override
std::unordered_map< ObjectGuid, uint32 > _totalTimeInAreaWithOrb
void OnUnitExit(Unit *unit, AreaTriggerExitReason) override
static constexpr TempleOfKotmogu::StaticOrbData const * GetOrbData(uint32 orbEntry)
void OnCreatureCreate(Creature *creature) override
void SpawnOrb(TempleOfKotmogu::StaticOrbData const *orbData) const
void OnFlagDropped(ObjectGuid const &flagGuid, Player *player) override
void OnGameObjectCreate(GameObject *gameobject) override
void HandleConsumeAreaTrigger(AreaTrigger *trigger, Player *player)
void DoAction(uint32 actionId, WorldObject *source, WorldObject *target) override
void OnFlagTaken(GameObject *flag, Player *player) override