TrinityCore
zone_dalaran.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/* Script Data Start
19SDName: Dalaran
20SDAuthor: WarHead, MaXiMiUS
21SD%Complete: 99%
22SDComment: For what is 63990+63991? Same function but don't work correct...
23SDCategory: Dalaran
24Script Data End */
25
26#include "ScriptMgr.h"
27#include "BattlegroundDS.h"
28#include "Containers.h"
29#include "DatabaseEnv.h"
30#include "Mail.h"
31#include "Map.h"
32#include "MotionMaster.h"
33#include "Player.h"
34#include "ScriptedCreature.h"
35
36/*******************************************************
37 * npc_mageguard_dalaran
38 *******************************************************/
39
41{
44
49};
50
51enum NPCs // All outdoor guards are within 35.0f of these NPCs
52{
57};
58
60{
61 npc_mageguard_dalaran(Creature* creature) : ScriptedAI(creature) { }
62
63 void Reset() override { }
64
65 void JustEngagedWith(Unit* /*who*/) override { }
66
67 void AttackStart(Unit* /*who*/) override { }
68
69 void MoveInLineOfSight(Unit* who) override
70 {
71 if (!who || !who->IsInWorld() || who->GetZoneId() != 4395)
72 return;
73
74 if (!me->IsWithinDist(who, 65.0f, false))
75 return;
76
78
79 if (!player || player->IsGameMaster() || player->IsBeingTeleported() ||
80 // If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass
83 // If player has already been teleported, don't try to teleport again
85 return;
86
87 switch (me->GetEntry())
88 {
90 if (player->GetTeam() == HORDE) // Horde unit found in Alliance area
91 {
93 {
94 if (me->isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me
95 DoCast(who, SPELL_TRESPASSER_A); // Teleport the Horde unit out
96 }
97 else // In my line of sight, and "indoors"
98 DoCast(who, SPELL_TRESPASSER_A); // Teleport the Horde unit out
99 }
100 break;
102 if (player->GetTeam() == ALLIANCE) // Alliance unit found in Horde area
103 {
105 {
106 if (me->isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me
107 DoCast(who, SPELL_TRESPASSER_H); // Teleport the Alliance unit out
108 }
109 else // In my line of sight, and "indoors"
110 DoCast(who, SPELL_TRESPASSER_H); // Teleport the Alliance unit out
111 }
112 break;
113 }
114 return;
115 }
116
117 void UpdateAI(uint32 /*diff*/) override { }
118};
119
121{
123
127
136
141
143{
145 {
146 me->setActive(true);
147 }
148
149 void Reset() override
150 {
152 me->SetVisible(false);
154 }
155
156 void GetPlayersInDalaran(std::vector<Player*>& playerList) const
157 {
158 Map::PlayerList const& players = me->GetMap()->GetPlayers();
159 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
160 if (Player* player = itr->GetSource()->ToPlayer())
161 if (player->GetZoneId() == ZONE_DALARAN && !player->IsFlying() && !player->IsMounted() && !player->IsGameMaster())
162 playerList.push_back(player);
163 }
164
165 static Player* SelectTargetInDalaran(std::vector<Player*>& PlayerInDalaranList)
166 {
167 if (PlayerInDalaranList.empty())
168 return nullptr;
169
170 return Trinity::Containers::SelectRandomContainerElement(PlayerInDalaranList);
171 }
172
173 void SendMailToPlayer(Player* player) const
174 {
175 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
178 CharacterDatabase.CommitTransaction(trans);
179 }
180
181 void UpdateAI(uint32 diff) override
182 {
183 events.Update(diff);
184
185 while (uint32 eventId = events.ExecuteEvent())
186 {
187 switch (eventId)
188 {
190 {
191 std::vector<Player*> PlayerInDalaranList;
192 GetPlayersInDalaran(PlayerInDalaranList);
193
194 // Increases chance of event based on player count in Dalaran (100 players or more = 100% else player count%)
195 if (PlayerInDalaranList.empty() || urand(1, 100) > PlayerInDalaranList.size())
197
198 me->SetVisible(true);
200 if (Player* player = SelectTargetInDalaran(PlayerInDalaranList))
201 {
202 playerGuid = player->GetGUID();
203 Position pos = player->GetPosition();
204 float dist = frand(10.0f, 30.0f);
205 float angle = frand(0.0f, 1.0f) * M_PI * 2.0f;
206 player->MovePositionToFirstCollision(pos, dist, angle);
208 }
210 break;
211 }
212 case EVENT_LAUGH_1:
215 break;
216 case EVENT_WANDER:
219 break;
220 case EVENT_PAUSE:
223 break;
224 case EVENT_CAST:
225 if (Player* player = me->GetMap()->GetPlayer(playerGuid))
226 {
227 DoCast(player, SPELL_MANABONKED);
228 SendMailToPlayer(player);
229 }
230 else
232
234 break;
235 case EVENT_LAUGH_2:
238 break;
239 case EVENT_BLINK:
242 break;
243 case EVENT_DESPAWN:
245 break;
246 default:
247 break;
248 }
249 }
250 }
251
252private:
255};
256
258{
259public:
260 at_ds_pipe_knockback() : AreaTriggerScript("at_ds_pipe_knockback") { }
261
262 void Trigger(Player* player) const
263 {
264 if (Battleground* battleground = player->GetBattleground())
265 {
266 if (battleground->GetStatus() != STATUS_IN_PROGRESS)
267 return;
268
269 // Remove effects of Demonic Circle Summon
271
272 // Someone has get back into the pipes and the knockback has already been performed,
273 // so we reset the knockback count for kicking the player again into the arena.
275 battleground->SetData(BG_DS_DATA_PIPE_KNOCKBACK_COUNT, 0);
276 }
277 }
278
279 bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override
280 {
281 Trigger(player);
282 return true;
283 }
284
285 bool OnExit(Player* player, AreaTriggerEntry const* /*trigger*/) override
286 {
287 Trigger(player);
288 return true;
289 }
290};
291
293{
297}
@ SPELL_WARL_DEMONIC_CIRCLE
@ BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT
constexpr uint32 BG_DS_DATA_PIPE_KNOCKBACK_COUNT
@ STATUS_IN_PROGRESS
Definition: Battleground.h:167
@ MINUTE
Definition: Common.h:29
#define M_PI
Definition: Common.h:115
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
int16_t int16
Definition: Define.h:139
uint64_t uint64
Definition: Define.h:141
uint32_t uint32
Definition: Define.h:142
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
@ MAIL_CHECK_MASK_NONE
Definition: Mail.h:52
@ MAIL_CREATURE
Definition: Mail.h:41
Spells
Definition: PlayerAI.cpp:32
float frand(float min, float max)
Definition: Random.cpp:55
int32 irand(int32 min, int32 max)
Definition: Random.cpp:35
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
#define RegisterCreatureAI(ai_name)
Definition: ScriptMgr.h:1380
Creature * GetClosestCreatureWithEntry(WorldObject *source, uint32 entry, float maxSearchRange, bool alive=true)
@ EMOTE_ONESHOT_LAUGH_NO_SHEATHE
@ ALLIANCE
@ HORDE
Creature *const me
Definition: CreatureAI.h:61
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
void SendMailTo(CharacterDatabaseTransaction trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
Definition: Mail.cpp:192
iterator end()
Definition: MapRefManager.h:35
iterator begin()
Definition: MapRefManager.h:34
Player * GetPlayer(ObjectGuid const &guid)
Definition: Map.cpp:3469
PlayerList const & GetPlayers() const
Definition: Map.h:367
void MoveRandom(float wanderDistance=0.0f, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_DEFAULT)
bool IsInWorld() const
Definition: Object.h:154
uint32 GetEntry() const
Definition: Object.h:161
static Player * ToPlayer(Object *o)
Definition: Object.h:213
Battleground * GetBattleground() const
Definition: Player.cpp:24976
bool IsGameMaster() const
Definition: Player.h:1178
bool IsBeingTeleported() const
Definition: Player.h:2219
Team GetTeam() const
Definition: Player.h:2235
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void SetVisible(bool x)
Definition: Unit.cpp:8351
bool isInBackInMap(Unit const *target, float distance, float arc=float(M_PI)) const
Definition: Unit.cpp:3160
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void NearTeleportTo(Position const &pos, bool casting=false)
Definition: Unit.cpp:12327
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition: Unit.cpp:1598
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
Map * GetMap() const
Definition: Object.h:624
void setActive(bool isActiveObject)
Definition: Object.cpp:922
void AddObjectToRemoveList()
Definition: Object.cpp:1824
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Object.cpp:2252
uint32 GetZoneId() const
Definition: Object.h:545
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition: Object.cpp:1142
bool OnExit(Player *player, AreaTriggerEntry const *) override
void Trigger(Player *player) const
bool OnTrigger(Player *player, AreaTriggerEntry const *) override
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:109
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
constexpr float GetOrientation() const
Definition: Position.h:79
constexpr float GetPositionZ() const
Definition: Position.h:78
void Reset() override
npc_mageguard_dalaran(Creature *creature)
void JustEngagedWith(Unit *) override
void UpdateAI(uint32) override
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
void MoveInLineOfSight(Unit *who) override
void SendMailToPlayer(Player *player) const
static Player * SelectTargetInDalaran(std::vector< Player * > &PlayerInDalaranList)
void Reset() override
void GetPlayersInDalaran(std::vector< Player * > &playerList) const
npc_minigob_manabonk(Creature *creature)
void UpdateAI(uint32 diff) override
@ SPELL_SUNREAVER_DISGUISE_MALE
@ SPELL_SILVER_COVENANT_DISGUISE_FEMALE
@ SPELL_TRESPASSER_H
@ SPELL_SILVER_COVENANT_DISGUISE_MALE
@ SPELL_TRESPASSER_A
@ SPELL_SUNREAVER_DISGUISE_FEMALE
void AddSC_dalaran()
@ NPC_SWEETBERRY_H
@ NPC_SILVER_COVENANT_GUARDIAN_MAGE
@ NPC_SUNREAVER_GUARDIAN_MAGE
@ NPC_APPLEBOUGH_A
MinigobData
@ EVENT_BLINK
@ MAIL_DELIVER_DELAY_MIN
@ SPELL_MANABONKED
@ MAIL_DELIVER_DELAY_MAX
@ ZONE_DALARAN
@ EVENT_DESPAWN
@ EVENT_PAUSE
@ EVENT_LAUGH_2
@ MAIL_MINIGOB_ENTRY
@ EVENT_SELECT_TARGET
@ EVENT_LAUGH_1
@ SPELL_TELEPORT_VISUAL
@ EVENT_WANDER
@ EVENT_CAST
@ SPELL_IMPROVED_BLINK