TrinityCore
zone_wintergrasp.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 "ScriptMgr.h"
19#include "Battlefield.h"
20#include "BattlefieldMgr.h"
22#include "DB2Stores.h"
23#include "GameObject.h"
24#include "GameObjectAI.h"
25#include "GameTime.h"
26#include "ObjectMgr.h"
27#include "Player.h"
28#include "ScriptedCreature.h"
29#include "ScriptedGossip.h"
30#include "ScriptSystem.h"
31#include "SpellAuras.h"
32#include "SpellAuraEffects.h"
33#include "SpellScript.h"
34#include "Vehicle.h"
35#include "WorldSession.h"
36
37#define GOSSIP_HELLO_DEMO1 "Build catapult."
38#define GOSSIP_HELLO_DEMO2 "Build demolisher."
39#define GOSSIP_HELLO_DEMO3 "Build siege engine."
40#define GOSSIP_HELLO_DEMO4 "I cannot build more!"
41
43{
51};
52
54{
55 // Demolisher engineers spells
62
64};
65
67{
70
72
74};
75
77{
84
92
98
105};
106
108
110{
115};
116
118{
120
121 bool OnGossipHello(Player* player) override
122 {
123 if (me->IsQuestGiver())
124 player->PrepareQuestMenu(me->GetGUID());
125
126 if (CanBuild())
127 {
128 if (player->HasAura(SPELL_CORPORAL))
130 else if (player->HasAura(SPELL_LIEUTENANT))
131 {
135 }
136 }
137 else
139
140 SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID());
141 return true;
142 }
143
144 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
145 {
146 uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
147 CloseGossipMenuFor(player);
148
149 if (CanBuild())
150 {
151 switch (action - GOSSIP_ACTION_INFO_DEF)
152 {
153 case 0:
154 DoCast(player, SPELL_BUILD_CATAPULT_FORCE, true);
155 break;
156 case 1:
158 break;
159 case 2:
161 break;
162 }
163 if (Creature* controlArms = me->FindNearestCreature(NPC_WINTERGRASP_CONTROL_ARMS, 30.0f, true))
164 DoCast(controlArms, SPELL_ACTIVATE_CONTROL_ARMS, true);
165 }
166 return true;
167 }
168
169private:
170 bool CanBuild() const
171 {
172 Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(me->GetMap(), BATTLEFIELD_BATTLEID_WG);
173 if (!wintergrasp)
174 return false;
175
176 switch (me->GetEntry())
177 {
182 default:
183 return false;
184 }
185 }
186};
187
189{
190 npc_wg_spirit_guide(Creature* creature) : ScriptedAI(creature) { }
191
192 bool OnGossipHello(Player* player) override
193 {
194 if (me->IsQuestGiver())
195 player->PrepareQuestMenu(me->GetGUID());
196
197 Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(me->GetMap(), BATTLEFIELD_BATTLEID_WG);
198 if (!wintergrasp)
199 return true;
200
201 GraveyardVect graveyard = wintergrasp->GetGraveyardVector();
202 for (uint8 i = 0; i < graveyard.size(); i++)
203 if (graveyard[i]->GetControlTeamId() == player->GetTeamId())
205
206 SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID());
207 return true;
208 }
209
210 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
211 {
212 uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
213 CloseGossipMenuFor(player);
214
215 Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(me->GetMap(), BATTLEFIELD_BATTLEID_WG);
216 if (wintergrasp)
217 {
218 GraveyardVect gy = wintergrasp->GetGraveyardVector();
219 for (uint8 i = 0; i < gy.size(); i++)
220 if (action - GOSSIP_ACTION_INFO_DEF == i && gy[i]->GetControlTeamId() == player->GetTeamId())
221 if (WorldSafeLocsEntry const* safeLoc = sObjectMgr->GetWorldSafeLoc(gy[i]->GetGraveyardId()))
222 player->TeleportTo(safeLoc->Loc);
223 }
224 return true;
225 }
226};
227
229{
230 SPELL_FROST_ARMOR = 12544
232
234{
235 npc_wg_queue(Creature* creature) : ScriptedAI(creature)
236 {
238 }
239
241
242 void Reset() override
243 {
245 }
246
247 void JustEngagedWith(Unit* /*who*/) override { }
248
249 void UpdateAI(uint32 diff) override
250 {
251 if (FrostArmor_Timer <= diff)
252 {
254 FrostArmor_Timer = 180000;
255 }
256 else FrostArmor_Timer -= diff;
257 }
258
259 bool OnGossipHello(Player* player) override
260 {
261 if (me->IsQuestGiver())
262 player->PrepareQuestMenu(me->GetGUID());
263
264 Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(me->GetMap(), BATTLEFIELD_BATTLEID_WG);
265 if (!wintergrasp)
266 return true;
267
268 if (wintergrasp->IsWarTime())
269 {
272 }
273 else
274 {
275 uint32 timer = wintergrasp->GetTimer() / 1000;
276 player->SendUpdateWorldState(4354, GameTime::GetGameTime() + timer);
277 if (timer < 15 * MINUTE)
278 {
281 }
282 else
284 }
285 return true;
286 }
287
288 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
289 {
290 CloseGossipMenuFor(player);
291
292 Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(me->GetMap(), BATTLEFIELD_BATTLEID_WG);
293 if (!wintergrasp)
294 return true;
295
296 if (wintergrasp->IsWarTime())
297 wintergrasp->InvitePlayerToWar(player);
298 else
299 {
300 uint32 timer = wintergrasp->GetTimer() / 1000;
301 if (timer < 15 * MINUTE)
302 wintergrasp->InvitePlayerToQueue(player);
303 }
304 return true;
305 }
306};
307
309{
311
312 bool IsFriendly(Unit* passenger)
313 {
314 return ((me->GetFaction() == FACTION_HORDE_GENERIC_WG && passenger->GetFaction() == HORDE) ||
315 (me->GetFaction() == FACTION_ALLIANCE_GENERIC_WG && passenger->GetFaction() == ALLIANCE));
316 }
317
319 {
321 if (Vehicle* vehicle = cVeh->GetVehicleKit())
322 if (Unit* passenger = vehicle->GetPassenger(0))
323 if (IsFriendly(passenger))
324 if (Creature* teleportTrigger = passenger->SummonTrigger(me->GetPositionX()-60.0f, me->GetPositionY(), me->GetPositionZ()+1.0f, cVeh->GetOrientation(), 1s))
325 return teleportTrigger;
326
327 return nullptr;
328 }
329
330 void UpdateAI(uint32 diff) override
331 {
332 _checkTimer += diff;
333 if (_checkTimer >= 1000)
334 {
335 for (uint8 i = 0; i < MAX_WINTERGRASP_VEHICLES; i++)
336 if (Creature* vehicleCreature = me->FindNearestCreature(vehiclesList[i], 3.0f, true))
337 if (Creature* teleportTrigger = GetValidVehicle(vehicleCreature))
338 teleportTrigger->CastSpell(vehicleCreature, SPELL_VEHICLE_TELEPORT, true);
339
340 _checkTimer = 0;
341 }
342 }
343
344private:
346};
347
348/* 49899 - Activate Robotic Arms
349 56659 - Build Demolisher (Force)
350 56662 - Build Siege Vehicle (Force)
351 56664 - Build Catapult (Force)
352 61409 - Build Siege Vehicle (Force) */
354{
355 bool Validate(SpellInfo const* /*spell*/) override
356 {
357 return ValidateSpellInfo(
358 {
363 });
364 }
365
367 {
368 PreventHitDefaultEffect(effIndex);
370 }
371
372 void Register() override
373 {
375 }
376};
377
378// 61178 - Grab Passenger
380{
381 void HandleScript(SpellEffIndex /*effIndex*/)
382 {
383 if (Player* target = GetHitPlayer())
384 target->CastSpell(GetCaster(), SPELL_RIDE_WG_VEHICLE, false);
385 }
386
387 void Register() override
388 {
390 }
391};
392
394{
395public:
396 achievement_wg_didnt_stand_a_chance() : AchievementCriteriaScript("achievement_wg_didnt_stand_a_chance") { }
397
398 bool OnCheck(Player* source, Unit* target) override
399 {
400 if (!target)
401 return false;
402
403 if (Player* victim = target->ToPlayer())
404 {
405 if (!victim->IsMounted())
406 return false;
407
408 if (Vehicle* vehicle = source->GetVehicle())
409 if (vehicle->GetVehicleInfo()->ID == 244) // Wintergrasp Tower Cannon
410 return true;
411 }
412
413 return false;
414 }
415};
416
418{
420};
421
422// 54640 - Teleport
424{
426 {
427 if (Player* target = GetExplTargetUnit()->ToPlayer())
428 if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(target->GetMap(), BATTLEFIELD_BATTLEID_WG))
429 // check if we are in Wintergrasp at all, SotA uses same teleport spells
430 if ((target->GetZoneId() == AREA_WINTERGRASP && target->GetTeamId() != wg->GetDefenderTeam()) || target->HasAura(SPELL_WINTERGRASP_TELEPORT_TRIGGER))
432 return SPELL_CAST_OK;
433 }
434
435 void Register() override
436 {
438 }
439};
440
441// 54643 - Teleport
443{
444 void HandleDummy(SpellEffIndex /*effindex*/)
445 {
446 if (Unit* target = GetHitUnit())
447 {
448 WorldLocation loc = target->GetWorldLocation();
450 }
451 }
452
453 void Register() override
454 {
456 }
457
458};
459
460// 58549 - Tenacity
461// 59911 - Tenacity
463{
464 bool Validate(SpellInfo const* spellInfo) override
465 {
466 if (!ValidateSpellEffect({ { spellInfo->Id, EFFECT_2 } }))
467 return false;
468 uint32 triggeredSpellId = spellInfo->GetEffect(EFFECT_2).CalcValue();
469 return !triggeredSpellId || ValidateSpellInfo({ triggeredSpellId });
470 }
471
472 void Refresh(AuraEffect const* aurEff)
473 {
475
476 if (uint32 triggeredSpellId = aurEff->GetSpellEffectInfo().CalcValue())
477 {
478 int32 bp = 0;
479 if (AuraEffect const* healEffect = GetEffect(EFFECT_0))
480 bp = healEffect->GetAmount();
481
482 CastSpellExtraArgs args(aurEff);
483 args
486 GetTarget()->CastSpell(nullptr, triggeredSpellId, args);
487 }
488
490 }
491
492 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
493 {
494 if (uint32 triggeredSpellId = aurEff->GetSpellEffectInfo().CalcValue())
495 GetTarget()->RemoveAurasDueToSpell(triggeredSpellId);
496 }
497
498 void Register() override
499 {
502 }
503};
504
506{
507public:
508 condition_is_wintergrasp_horde() : ConditionScript("condition_is_wintergrasp_horde") { }
509
510 bool OnConditionCheck(Condition const* /* condition */, ConditionSourceInfo& sourceInfo)
511 {
512 if (!sourceInfo.mConditionMap)
513 return false;
514 Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(sourceInfo.mConditionMap, BATTLEFIELD_BATTLEID_WG);
515 if (wintergrasp->IsEnabled() && wintergrasp->GetDefenderTeam() == TEAM_HORDE)
516 return true;
517 return false;
518 }
519};
520
522{
523public:
524 condition_is_wintergrasp_alliance() : ConditionScript("condition_is_wintergrasp_alliance") { }
525
526 bool OnConditionCheck(Condition const* /* condition */, ConditionSourceInfo& sourceInfo)
527 {
528 if (!sourceInfo.mConditionMap)
529 return false;
530 Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(sourceInfo.mConditionMap, BATTLEFIELD_BATTLEID_WG);
531 if (wintergrasp->IsEnabled() && wintergrasp->GetDefenderTeam() == TEAM_ALLIANCE)
532 return true;
533 return false;
534 }
535};
536
538{
551}
#define sBattlefieldMgr
@ NPC_WINTERGRASP_SIEGE_ENGINE_HORDE
@ NPC_WINTERGRASP_CATAPULT
@ NPC_WINTERGRASP_DEMOLISHER
@ NPC_WINTERGRASP_SIEGE_ENGINE_ALLIANCE
@ SPELL_CORPORAL
Definition: BattlefieldWG.h:40
@ SPELL_LIEUTENANT
Definition: BattlefieldWG.h:41
@ BATTLEFIELD_WG_DATA_VEHICLE_A
Definition: BattlefieldWG.h:88
@ BATTLEFIELD_WG_DATA_MAX_VEHICLE_A
Definition: BattlefieldWG.h:86
@ BATTLEFIELD_WG_DATA_VEHICLE_H
Definition: BattlefieldWG.h:89
@ BATTLEFIELD_WG_DATA_MAX_VEHICLE_H
Definition: BattlefieldWG.h:87
std::vector< BfGraveyard * > GraveyardVect
Definition: Battlefield.h:93
@ BATTLEFIELD_BATTLEID_WG
Definition: Battlefield.h:36
@ MINUTE
Definition: Common.h:29
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
#define sObjectMgr
Definition: ObjectMgr.h:1946
Spells
Definition: PlayerAI.cpp:32
#define RegisterCreatureAI(ai_name)
Definition: ScriptMgr.h:1380
#define RegisterGameObjectAI(ai_name)
Definition: ScriptMgr.h:1398
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
void AddGossipItemFor(Player *player, GossipOptionNpc optionNpc, std::string text, uint32 sender, uint32 action)
void SendGossipMenuFor(Player *player, uint32 npcTextID, ObjectGuid const &guid)
void CloseGossipMenuFor(Player *player)
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_0
Definition: SharedDefines.h:30
@ EFFECT_2
Definition: SharedDefines.h:32
@ TEAM_ALLIANCE
@ TEAM_HORDE
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ ALLIANCE
@ HORDE
SpellCastResult
@ SPELL_FAILED_BAD_TARGETS
@ SPELL_CAST_OK
@ FACTION_ALLIANCE_GENERIC_WG
@ FACTION_HORDE_GENERIC_WG
@ AREA_WINTERGRASP
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:197
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:196
#define SpellCheckCastFn(F)
Definition: SpellScript.h:830
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define AuraEffectPeriodicFn(F, I, N)
Definition: SpellScript.h:2046
#define AuraEffectRemoveFn(F, I, N, M)
Definition: SpellScript.h:2040
SpellEffectInfo const & GetSpellEffectInfo() const
void PreventDefaultAction()
HookList< EffectApplyHandler > AfterEffectRemove
Definition: SpellScript.h:2039
HookList< EffectPeriodicHandler > OnEffectPeriodic
Definition: SpellScript.h:2045
AuraEffect * GetEffect(uint8 effIndex) const
Unit * GetTarget() const
void RefreshDuration()
bool IsWarTime() const
Return true if battle is start, false if battle is not started.
Definition: Battlefield.h:189
GraveyardVect GetGraveyardVector() const
Definition: Battlefield.h:285
void InvitePlayerToQueue(Player *player)
void InvitePlayerToWar(Player *player)
TeamId GetDefenderTeam() const
Definition: Battlefield.h:219
uint32 GetTimer() const
Definition: Battlefield.h:287
virtual uint32 GetData(uint32 dataId) const override
Definition: Battlefield.h:214
bool IsEnabled() const
Return if battlefield is enable.
Definition: Battlefield.h:196
Creature *const me
Definition: CreatureAI.h:61
GameObject *const me
Definition: GameObjectAI.h:50
uint32 GetFaction() const override
Definition: GameObject.h:388
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, TeleportToOptions options=TELE_TO_NONE, Optional< uint32 > instanceId={})
Definition: Player.cpp:1250
WorldSession * GetSession() const
Definition: Player.h:2101
TeamId GetTeamId() const
Definition: Player.h:2236
void PrepareQuestMenu(ObjectGuid guid)
Definition: Player.cpp:14474
void SendUpdateWorldState(uint32 variable, uint32 value, bool hidden=false) const
Definition: Player.cpp:9174
uint32 GetGossipTextId(uint32 menuId, WorldObject *source)
Definition: Player.cpp:14367
std::unique_ptr< PlayerMenu > PlayerTalkClass
Definition: Player.h:2380
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
Definition: SpellInfo.cpp:495
uint32 const Id
Definition: SpellInfo.h:325
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition: SpellInfo.h:577
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
Definition: SpellScript.h:173
HookList< CheckCastHandler > OnCheckCast
Definition: SpellScript.h:829
Player * GetHitPlayer() const
Unit * GetCaster() const
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
int32 GetEffectValue() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
void SetExplTargetDest(WorldLocation const &loc)
Unit * GetExplTargetUnit() const
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
Vehicle * GetVehicle() const
Definition: Unit.h:1713
bool IsQuestGiver() const
Definition: Unit.h:994
uint32 GetFaction() const override
Definition: Unit.h:858
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
Vehicle * GetVehicleKit() const
Definition: Unit.h:1711
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
constexpr WorldLocation GetWorldLocation() const
Definition: Position.h:196
Map * GetMap() const
Definition: Object.h:624
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
Creature * SummonTrigger(float x, float y, float z, float ang, Milliseconds despawnTime, CreatureAI *(*GetAI)(Creature *)=nullptr)
Definition: Object.cpp:2106
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
char const * GetTrinityString(uint32 entry) const
bool OnCheck(Player *source, Unit *target) override
bool OnConditionCheck(Condition const *, ConditionSourceInfo &sourceInfo)
bool OnConditionCheck(Condition const *, ConditionSourceInfo &sourceInfo)
void HandleScript(SpellEffIndex effIndex)
bool Validate(SpellInfo const *) override
void OnRemove(AuraEffect const *aurEff, AuraEffectHandleModes)
bool Validate(SpellInfo const *spellInfo) override
void Refresh(AuraEffect const *aurEff)
time_t GetGameTime()
Definition: GameTime.cpp:44
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
Definition: SpellDefines.h:474
Map const * mConditionMap
Definition: ConditionMgr.h:221
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr float GetOrientation() const
Definition: Position.h:79
constexpr float GetPositionZ() const
Definition: Position.h:78
go_wg_vehicle_teleporter(GameObject *gameObject)
Creature * GetValidVehicle(Creature *cVeh)
bool IsFriendly(Unit *passenger)
void UpdateAI(uint32 diff) override
bool OnGossipHello(Player *player) override
npc_wg_demolisher_engineer(Creature *creature)
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
bool OnGossipSelect(Player *player, uint32, uint32) override
npc_wg_queue(Creature *creature)
void UpdateAI(uint32 diff) override
void Reset() override
bool OnGossipHello(Player *player) override
void JustEngagedWith(Unit *) override
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
bool OnGossipHello(Player *player) override
npc_wg_spirit_guide(Creature *creature)
uint32 const vehiclesList[MAX_WINTERGRASP_VEHICLES]
#define GOSSIP_HELLO_DEMO4
#define GOSSIP_HELLO_DEMO2
@ SPELL_WINTERGRASP_TELEPORT_TRIGGER
WGqueuenpctext
@ WG_NPCQUEUE_TEXT_H_WAR
@ WG_NPCQUEUE_TEXTOPTION_JOIN
@ WG_NPCQUEUE_TEXT_H_NOWAR
@ WG_NPCQUEUE_TEXT_A_WAR
@ WG_NPCQUEUE_TEXT_A_QUEUE
@ WG_NPCQUEUE_TEXT_H_QUEUE
@ WG_NPCQUEUE_TEXT_A_NOWAR
@ SPELL_BUILD_DEMOLISHER_FORCE
@ SPELL_VEHICLE_TELEPORT
@ SPELL_RIDE_WG_VEHICLE
@ SPELL_ACTIVATE_CONTROL_ARMS
@ SPELL_BUILD_SIEGE_VEHICLE_FORCE_ALLIANCE
@ SPELL_BUILD_SIEGE_VEHICLE_FORCE_HORDE
@ SPELL_BUILD_CATAPULT_FORCE
uint8 const MAX_WINTERGRASP_VEHICLES
@ QUEST_HEALING_WITH_ROSES_HORDE_DEF
@ QUEST_DEFEND_THE_SIEGE_HORDE_ATT
@ QUEST_SHOUTHERN_SABOTAGE_ALLIANCE_DEF
@ QUEST_SLAY_THEM_ALL_HORDE_DEF
@ QUEST_FUELING_THE_DEMOLISHERS_HORDE_DEF
@ QUEST_A_RARE_HERB_ALLIANCE_DEF
@ QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT
@ QUEST_SLAY_THEM_ALL_HORDE_ATT
@ QUEST_STOP_THE_SIEGE_HORDE_DEF
@ QUEST_WARDING_THE_WALLS_HORDE_DEF
@ QUEST_BONES_AND_ARROWS_ALLIANCE_DEF
@ QUEST_A_RARE_HERB_ALLIANCE_ATT
@ QUEST_HEALING_WITH_ROSES_HORDE_ATT
@ QUEST_BONES_AND_ARROWS_ALLIANCE_ATT
@ QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_ATT
@ QUEST_STOP_THE_SIEGE_ALLIANCE_DEF
@ QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_DEF
@ QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT
@ QUEST_TOPPLING_THE_TOWERS_HORDE_DEF
@ QUEST_BONES_AND_ARROWS_HORDE_DEF
@ QUEST_WARDING_THE_WARRIORS_ALLIANCE_DEF
@ QUEST_BONES_AND_ARROWS_HORDE_ATT
@ QUEST_DEFEND_THE_SIEGE_ALLIANCE_ATT
@ QUEST_JINXING_THE_WALLS_HORDE_ATT
@ NPC_GOBLIN_MECHANIC
@ NPC_WINTERGRASP_CONTROL_ARMS
@ NPC_WORLD_TRIGGER_LARGE_AOI_NOT_IMMUNE_PC_NPC
@ NPC_GNOMISH_ENGINEER
void AddSC_wintergrasp()
#define GOSSIP_HELLO_DEMO3
@ SPELL_FROST_ARMOR
#define GOSSIP_HELLO_DEMO1