TrinityCore
Loading...
Searching...
No Matches
zone_westfall.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 "CombatAI.h"
19#include "Containers.h"
20#include "CreatureAIImpl.h"
21#include "ObjectAccessor.h"
22#include "Player.h"
23#include "ScriptedCreature.h"
24#include "ScriptedGossip.h"
25#include "ScriptMgr.h"
26#include "SpellAuraEffects.h"
27#include "SpellScript.h"
28#include "SharedDefines.h"
29
31{
32namespace Creatures
33{
34 static constexpr uint32 EnergizedHarvestReaper = 42342;
35 static constexpr uint32 OverloadedHarvestGolem = 42601;
36 static constexpr uint32 JangolodeMineGlubtok = 42492;
37 static constexpr uint32 JangolodeMineFigure = 42515;
38 static constexpr uint32 HomelessStormwindCitizen1 = 42386;
39 static constexpr uint32 HomelessStormwindCitizen2 = 42384;
40 static constexpr uint32 WestPlainDrifter = 42391;
41 static constexpr uint32 Transient = 42383;
42}
43
44namespace Quests
45{
46 static constexpr uint32 MurderWasTheCaseThatTheyGaveMe = 26209;
47}
48
49namespace Spells
50{
51 static constexpr uint32 JangolodeMineSummonFigure = 79265;
52 static constexpr uint32 JangolodeMineSummonGlubtok = 79263;
53 static constexpr uint32 HoboInformation1 = 79181;
54 static constexpr uint32 HoboInformation2 = 79182;
55 static constexpr uint32 HoboInformation3 = 79183;
56 static constexpr uint32 HoboInformation4 = 79184;
57 static constexpr uint32 SummonRagamuffinLooter = 79169;
58 static constexpr uint32 SummonRagamuffinLooter1 = 79170;
59 static constexpr uint32 SummonRagamuffinLooter2 = 79171;
60 static constexpr uint32 SummonRagamuffinLooter3 = 79172;
61 static constexpr uint32 SummonRagamuffinLooter4 = 79173;
62 static constexpr uint32 HoboAggro = 79168;
63}
64
65namespace Gossip
66{
67 namespace GossipOption
68 {
69 static constexpr uint32 GossipOption0 = 0;
70 static constexpr uint32 GossipOption1 = 1;
71 }
72}
73
74namespace Events
75{
76 namespace ItsAlive
77 {
78 static constexpr uint32 CheckArea = 1;
79 static constexpr uint32 DespawnHarvester = 2;
80 }
81
82 namespace MurderWasTheCaseThatTheyGaveMe
83 {
84 static constexpr uint32 HoboTalk = 1;
85 static constexpr uint32 JackpotIntro = 2;
86 static constexpr uint32 HoboCry = 3;
87 static constexpr uint32 PropertyRage = 4;
88 static constexpr uint32 JackpotMiddle = 5;
89 static constexpr uint32 JackpotEnd = 6;
90 static constexpr uint32 ResumeMove = 7;
91 static constexpr uint32 GroupOOC = 1;
92 }
93}
94
95namespace Actions
96{
97 namespace MurderWasTheCaseThatTheyGaveMe
98 {
99 static constexpr uint32 HoboAggroAction = 1;
100 static constexpr uint32 HoboAggroActionDone = 2;
101 }
102}
103
104namespace Text
105{
106 namespace HarvestGolem
107 {
108 static constexpr uint32 AnnounceOutOfArea = 0;
109 }
110
111 namespace HoboText
112 {
113 static constexpr uint32 HoboSayClue1 = 0;
114 static constexpr uint32 HoboSayClue2 = 1;
115 static constexpr uint32 HoboSayClue3 = 2;
116 static constexpr uint32 HoboSayClue4 = 3;
117 static constexpr uint32 HoboAggroBribe = 4;
118 static constexpr uint32 HoboAggroConvince = 5;
119 static constexpr uint32 HoboEvent = 6;
120 static constexpr uint32 HoboJackpotIntro = 7;
121 static constexpr uint32 HoboJackpotEnd = 8;
122 static constexpr uint32 HoboPropertyRage = 9;
123 static constexpr uint32 HoboFlee = 10;
124 }
125}
126
127namespace Area
128{
129 static constexpr uint32 TheMoestFarm = 918;
130}
131
132// 79084 - Unbound Energy
134{
135 void FilterTargets(std::list<WorldObject*>& targets)
136 {
137 if (targets.empty())
138 return;
139
140 Unit* caster = GetCaster();
141 targets.remove_if([caster](WorldObject const* target) -> bool
142 {
143 return caster->ToWorldObject() == target;
144 });
145
146 if (targets.size() > 1)
148 }
149
154};
155
156// 42601 - Overloaded Harvest Golem
158{
160
161 void JustAppeared() override
162 {
164 }
165
166 void PassengerBoarded(Unit* /*passenger*/, int8 /*seatId*/, bool apply) override
167 {
168 if (!apply)
170 }
171
172 void UpdateAI(uint32 diff) override
173 {
174 _events.Update(diff);
175 while (uint32 eventId = _events.ExecuteEvent())
176 {
177 switch (eventId)
178 {
181 {
182 if (Unit* owner = me->GetCharmerOrOwner())
185 }
186 else
187 _events.Repeat(1s);
188 break;
192 else
194 break;
195 default:
196 break;
197 }
198 }
199 }
200
201private:
203};
204
205// 79425 - Reaping Blows
207{
208 bool Validate(SpellInfo const* spellInfo) override
209 {
210 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } }) && ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_1).TriggerSpell) });
211 }
212
213 void HandlePeriodic(AuraEffect const* /*aurEff*/)
214 {
215 // HACK
216 // periodic ticks are forcing to cast the spell onto himself instead of target
217 // ref AuraEffect::HandlePeriodicTriggerSpellAuraTick
219 if (Creature* reaper = GetTarget()->FindNearestCreature(Creatures::EnergizedHarvestReaper, 5.f, true))
220 GetTarget()->CastSpell(reaper, GetSpellInfo()->GetEffect(EFFECT_1).TriggerSpell, true);
221 }
222
227};
228
229// 79436 - Wake Harvest Golem
231{
233 {
234 Unit* target = GetExplTargetUnit();
235 if (!target || !target->IsCreature())
237
238 return SPELL_CAST_OK;
239 }
240
242 {
243 Unit* caster = GetCaster();
244 if (!caster || !caster->IsPlayer())
245 return;
246
247 if (Creature* target = GetHitCreature())
248 {
250 target->DespawnOrUnsummon(100ms);
251 }
252 }
253
259};
260
261// 79262 - Summon Lou's House
276
277// 79275 - Quest Credit: Jangolde Event
290
291// 79290 - General Trigger 1: Glubtok
292// 79292 - General Trigger 2: Glubtok
293// 79294 - General Trigger 3: Glubtok
294// 79297 - General Trigger 4: Glubtok
296{
297 void FilterTargets(std::list<WorldObject*>& targets)
298 {
299 Player* player = Object::ToPlayer(GetCaster());
300 if (!player)
301 return;
302
303 targets.clear();
304 if (Creature* creature = player->FindNearestCreatureWithOptions(50.0f, { .CreatureId = Creatures::JangolodeMineGlubtok, .OwnerGuid = player->GetGUID() }))
305 targets.push_back(creature);
306 }
307
312};
313
314// 79279 - General Trigger 1: Figure
315// 79283 - General Trigger 2: Figure
316// 79284 - General Trigger 3: Figure
317// 79287 - General Trigger 4: Figure
319{
320 void FilterTargets(std::list<WorldObject*>& targets)
321 {
322 Player* player = Object::ToPlayer(GetCaster());
323 if (!player)
324 return;
325
326 targets.clear();
327 if (Creature* creature = player->FindNearestCreatureWithOptions(50.0f, { .CreatureId = Creatures::JangolodeMineFigure, .OwnerGuid = player->GetGUID() }))
328 targets.push_back(creature);
329 }
330
335};
336
337// 79273 - Despawn Jangolode Actor
339{
340 void FilterTargets(std::list<WorldObject*>& targets)
341 {
342 Player* player = Object::ToPlayer(GetCaster());
343 if (!player)
344 return;
345
346 targets.clear();
347 if (Creature* creature = player->FindNearestCreatureWithOptions(50.0f, { .CreatureId = Creatures::JangolodeMineGlubtok, .OwnerGuid = player->GetGUID() }))
348 targets.push_back(creature);
349
350 if (Creature* creature = player->FindNearestCreatureWithOptions(50.0f, { .CreatureId = Creatures::JangolodeMineFigure, .OwnerGuid = player->GetGUID() }))
351 targets.push_back(creature);
352 }
353
358};
359
360// 42386 - Homeless Stormwind Citizen
361// 42384 - Homeless Stormwind Citizen
362// 42384 - West Plain Drifter
363// 42383 - Transient
365{
366 npc_westfall_hobo_witness(Creature* creature) : ScriptedAI(creature), _bribeFailed(false), _hoboRage(false), _flee(false) {}
367
373
381
382 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
383 {
384 uint8 clueGainChance = 0;
385 switch (gossipListId)
386 {
388 {
389 clueGainChance = 25;
390 break;
391 }
393 {
394 clueGainChance = 75;
395 _bribeFailed = true;
396 break;
397 }
398 default:
399 return true;
400 }
401
403 CloseGossipMenuFor(player);
404 if (roll_chance(clueGainChance))
405 GiveClue(player);
406 else
407 {
408 me->SetImmuneToPC(false);
409 AttackStart(player);
410 }
411
412 return false;
413 }
414
415 void GiveClue(Player* player)
416 {
418 me->SetFacingToObject(player);
419
421
422 for (uint8 i = 0; i < HoboClues.size(); i++)
423 {
424 if (player->GetQuestSlotCounter(slot, i) == 0)
425 {
426 HoboClueData const& data = HoboClues[i];
427
428 player->CastSpell(player, data.SpellID);
429 Talk(data.TextID, player);
430
431 me->DespawnOrUnsummon(12s);
432 return;
433 }
434 }
435 }
436
447
448 void DamageTaken(Unit* /*killer*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
449 {
450 if (!_flee && me->HealthBelowPctDamaged(20, damage))
451 {
452 _flee = true;
455 }
456 }
457
458 void JustDied(Unit* who) override
459 {
460 if (Creature* creature = who->ToCreature())
463 }
464
476
477 void DoAction(int32 action) override
478 {
479 switch (action)
480 {
483 {
484 _hoboRage = true;
486 me->PauseMovement();
487 me->SetFacingToObject(target);
488 AttackStart(target);
489 }
490 break;
492 _hoboRage = false;
493 break;
494 default:
495 return;
496 }
497 }
498
499 void SetGUID(ObjectGuid const& guid, int32 /*id*/) override
500 {
501 _targetGUID = guid;
502 }
503
504 void UpdateAI(uint32 diff) override
505 {
506 _events.Update(diff);
507 while (uint32 eventId = _events.ExecuteEvent())
508 {
509 switch (eventId)
510 {
512 me->PauseMovement();
515 break;
517 me->PauseMovement();
520 break;
522 me->SetAIAnimKitId(648);
525 break;
527 me->SetAIAnimKitId(0);
529 break;
532 me->PauseMovement();
534 break;
536 {
538 if (Creature* creature = GetClosestCreatureWithEntry(me, creatureId, 25.0f))
539 {
540 if (!creature->IsAlive() || creature->IsInCombat())
541 {
543 return;
544 }
545 _hoboRage = true;
548 me->PauseMovement();
549 me->CastSpell(creature, Spells::HoboAggro, true);
550 me->SetFacingToObject(creature);
551 }
552 else
554 break;
555 }
558 if (roll_chance(50)) // prevent spam
559 {
560 if (roll_chance(70)) // chance to trigger simple talk event
562 else
564 }
565 else
566 _events.Repeat(30s, 80s);
567 break;
568 default:
569 break;
570 }
571 }
572
573 if (!_hoboRage)
574 if (!UpdateVictim())
575 return;
576 }
577
578private:
583 bool _flee;
584};
585
586// 79169 - Summon Ragamuffin Looter
614
615// 79168 - Hobo Aggro
617{
618 void HandleDummy(SpellEffIndex /*effIndex*/)
619 {
620 if (Creature* creature = GetHitCreature())
621 {
622 creature->AI()->SetGUID(GetCaster()->GetGUID(), 0);
624 }
625 }
626
631};
632}
633
First const & RAND(First const &first, Second const &second, Rest const &... rest)
uint8_t uint8
Definition Define.h:156
int8_t int8
Definition Define.h:152
int32_t int32
Definition Define.h:150
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
Spells
Definition PlayerAI.cpp:32
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
bool roll_chance(T chance)
Definition Random.h:55
#define RegisterCreatureAI(ai_name)
Definition ScriptMgr.h:1392
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
Creature * GetClosestCreatureWithEntry(WorldObject *source, uint32 entry, float maxSearchRange, bool alive=true)
void CloseGossipMenuFor(Player *player)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ TARGET_UNIT_SRC_AREA_ENTRY
@ EMOTE_ONESHOT_CRY
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
SpellCastResult
@ SPELL_FAILED_BAD_TARGETS
@ SPELL_CAST_OK
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
#define SpellCheckCastFn(F)
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
@ UNIT_NPC_FLAG_GOSSIP
DamageEffectType
Creatures
void PreventDefaultAction()
HookList< EffectPeriodicHandler > OnEffectPeriodic
SpellInfo const * GetSpellInfo() const
AuraEffect * GetEffect(uint8 effIndex) const
Unit * GetTarget() const
bool IsCreature() const
Definition BaseEntity.h:172
bool IsPlayer() const
Definition BaseEntity.h:173
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
void SetImmuneToPC(bool apply) override
Definition Creature.h:184
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void DoFleeToGetAssistance()
uint32 ExecuteEvent()
Definition EventMap.cpp:77
void Update(uint32 time)
Definition EventMap.h:61
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
void CancelEventGroup(uint32 group)
Definition EventMap.cpp:157
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:40
void Reset()
Definition EventMap.cpp:25
Player * ToPlayer()
Definition Object.h:126
WorldObject * ToWorldObject()
Definition Object.h:106
Creature * ToCreature()
Definition Object.h:121
void KilledMonsterCredit(uint32 entry, ObjectGuid guid=ObjectGuid::Empty)
Definition Player.cpp:16679
uint16 GetQuestSlotCounter(uint16 slot, uint8 counter) const
Definition Player.cpp:16399
uint16 FindQuestSlot(uint32 quest_id) const
Definition Player.cpp:16383
uint32 TriggerSpell
Definition SpellInfo.h:234
uint32 const Id
Definition SpellInfo.h:328
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:588
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
HookList< CheckCastHandler > OnCheckCast
Creature * GetHitCreature() const
Unit * GetCaster() const
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
HookList< EffectHandler > OnEffectLaunch
Unit * GetExplTargetUnit() const
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
virtual void Reset()
Definition UnitAI.h:64
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:160
Definition Unit.h:635
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition Unit.cpp:13307
void ResumeMovement(uint32 timer=0, uint8 slot=0)
Definition Unit.cpp:10707
void PauseMovement(uint32 timer=0, uint8 slot=0, bool forced=true)
Definition Unit.cpp:10695
void RemoveNpcFlag(NPCFlags flags)
Definition Unit.h:998
Unit * GetCharmerOrOwner() const
Definition Unit.h:1221
void SetNpcFlag(NPCFlags flags)
Definition Unit.h:997
bool HealthBelowPctDamaged(float pct, uint32 damage) const
Definition Unit.h:793
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition Unit.cpp:1657
void SetAIAnimKitId(uint16 animKitId)
Definition Unit.cpp:11174
virtual void ExitVehicle(Position const *exitPosition=nullptr)
Definition Unit.cpp:12835
Creature * FindNearestCreatureWithOptions(float range, FindCreatureOptions const &options) const
Definition Object.cpp:1526
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
uint32 GetAreaId() const
Definition Object.h:333
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
static constexpr uint32 MurderWasTheCaseThatTheyGaveMe
static constexpr uint32 SummonRagamuffinLooter4
static constexpr uint32 SummonRagamuffinLooter3
static constexpr uint32 SummonRagamuffinLooter1
static constexpr uint32 JangolodeMineSummonGlubtok
static constexpr uint32 JangolodeMineSummonFigure
static constexpr uint32 SummonRagamuffinLooter2
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:67
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
void SetGUID(ObjectGuid const &guid, int32) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
static constexpr std::array< HoboClueData, 4 > HoboClues
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
void PassengerBoarded(Unit *, int8, bool apply) override
== Fields =======================================
void AddSC_westfall()