mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-02 02:23:49 +00:00
fix(Core/QuestNpc): Rework/fix the Stave of Ancients script (#7929)
* WIP Artorius the amiable * Add Artorius sql update * Splited npc script to stave of ancients script * Move reveal form to npcstaveqai * Change enum constant names * Refactor DoAction * Refactor feign death reset
This commit is contained in:
@@ -35,192 +35,6 @@ EndContentData */
|
||||
#include "ScriptMgr.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
// Ours
|
||||
enum eStaveQuest
|
||||
{
|
||||
QUEST_STAVE_OF_THE_ANCIENTS = 7636,
|
||||
|
||||
NPC_SIMONE_NORMAL = 14527,
|
||||
NPC_FRANKLIN_NORMAL = 14529,
|
||||
NPC_ARTORIUS_NORMAL = 14531,
|
||||
NPC_NELSON_NORMAL = 14536,
|
||||
NPC_PRECIOUS = 14528,
|
||||
|
||||
NPC_SIMONE_EVIL = 14533,
|
||||
NPC_FRANKLIN_EVIL = 14534,
|
||||
NPC_ARTORIUS_EVIL = 14535,
|
||||
NPC_NELSON_EVIL = 14530,
|
||||
NPC_PRECIOUS_EVIL = 14538,
|
||||
|
||||
EVENT_CHECK_PLAYER = 1,
|
||||
EVENT_SPELL_CHAIN_LIGHTNING = 23206,
|
||||
EVENT_SPELL_TEMPTRESS_KISS = 23205,
|
||||
EVENT_SPELL_DEMONIC_ENRAGE = 23257,
|
||||
EVENT_SPELL_ENTROPIC_STING = 23260,
|
||||
EVENT_SPELL_DEMONIC_DOOM = 23298,
|
||||
EVENT_SPELL_STINGING_TRAUMA = 23299,
|
||||
EVENT_SPELL_DREADFUL_FRIGHT = 23275,
|
||||
|
||||
SPELL_FOOLS_PLIGHT = 23504,
|
||||
SPELL_SOUL_FLAME = 23272,
|
||||
};
|
||||
|
||||
class npc_stave_of_the_ancients : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_stave_of_the_ancients() : CreatureScript("npc_stave_of_the_ancients") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_stave_of_the_ancientsAI(creature);
|
||||
}
|
||||
|
||||
struct npc_stave_of_the_ancientsAI : public ScriptedAI
|
||||
{
|
||||
npc_stave_of_the_ancientsAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
changeEntry = me->GetEntry();
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_SIMONE_NORMAL:
|
||||
changeEntry = NPC_SIMONE_EVIL;
|
||||
break;
|
||||
case NPC_FRANKLIN_NORMAL:
|
||||
changeEntry = NPC_FRANKLIN_EVIL;
|
||||
break;
|
||||
case NPC_ARTORIUS_NORMAL:
|
||||
changeEntry = NPC_ARTORIUS_EVIL;
|
||||
break;
|
||||
case NPC_NELSON_NORMAL:
|
||||
changeEntry = NPC_NELSON_EVIL;
|
||||
break;
|
||||
case NPC_PRECIOUS:
|
||||
changeEntry = NPC_PRECIOUS_EVIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectGuid playerGUID;
|
||||
EventMap events;
|
||||
uint32 changeEntry;
|
||||
bool damaged;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (me->GetOriginalEntry() != me->GetEntry())
|
||||
me->UpdateEntry(me->GetOriginalEntry());
|
||||
|
||||
events.Reset();
|
||||
playerGUID.Clear();
|
||||
damaged = false;
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32&, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (!damaged)
|
||||
{
|
||||
if (who && who->GetGUID() != playerGUID && (who->GetTypeId() == TYPEID_PLAYER || who->GetOwnerGUID().IsPlayer()))
|
||||
{
|
||||
damaged = true;
|
||||
me->CastSpell(who, SPELL_FOOLS_PLIGHT, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
damaged = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit*) override
|
||||
{
|
||||
switch (changeEntry)
|
||||
{
|
||||
case NPC_SIMONE_EVIL:
|
||||
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 3000);
|
||||
events.ScheduleEvent(EVENT_SPELL_TEMPTRESS_KISS, 1000);
|
||||
break;
|
||||
case NPC_FRANKLIN_EVIL:
|
||||
events.ScheduleEvent(EVENT_SPELL_DEMONIC_ENRAGE, 3000);
|
||||
events.ScheduleEvent(EVENT_SPELL_ENTROPIC_STING, 5000);
|
||||
break;
|
||||
case NPC_ARTORIUS_EVIL:
|
||||
events.ScheduleEvent(EVENT_SPELL_DEMONIC_DOOM, 3000);
|
||||
events.ScheduleEvent(EVENT_SPELL_STINGING_TRAUMA, 5000);
|
||||
break;
|
||||
case NPC_NELSON_EVIL:
|
||||
me->CastSpell(me, SPELL_SOUL_FLAME, true);
|
||||
events.ScheduleEvent(EVENT_SPELL_DREADFUL_FRIGHT, 5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (me->GetEntry() != changeEntry && who->GetTypeId() == TYPEID_PLAYER && who->ToPlayer()->GetQuestStatus(QUEST_STAVE_OF_THE_ANCIENTS) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
playerGUID = who->GetGUID();
|
||||
me->UpdateEntry(changeEntry);
|
||||
events.ScheduleEvent(EVENT_CHECK_PLAYER, 5000);
|
||||
return;
|
||||
}
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
uint32 eventId = events.ExecuteEvent();
|
||||
if (eventId == EVENT_CHECK_PLAYER)
|
||||
{
|
||||
Player* player = ObjectAccessor::GetPlayer(*me, playerGUID);
|
||||
if (!player || !player->IsWithinDist2d(me, 60.0f))
|
||||
EnterEvadeMode();
|
||||
else
|
||||
events.RepeatEvent(5000);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SPELL_CHAIN_LIGHTNING:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(7000);
|
||||
break;
|
||||
case EVENT_SPELL_TEMPTRESS_KISS:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(45000);
|
||||
break;
|
||||
case EVENT_SPELL_DEMONIC_ENRAGE:
|
||||
me->CastSpell(me, eventId, false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_ENTROPIC_STING:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_DEMONIC_DOOM:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(50000);
|
||||
break;
|
||||
case EVENT_SPELL_STINGING_TRAUMA:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_DREADFUL_FRIGHT:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Theirs
|
||||
/*######
|
||||
## npc_rivern_frostwind
|
||||
@@ -804,9 +618,6 @@ public:
|
||||
|
||||
void AddSC_winterspring()
|
||||
{
|
||||
// Ours
|
||||
new npc_stave_of_the_ancients();
|
||||
|
||||
// Theirs
|
||||
new npc_rivern_frostwind();
|
||||
new npc_ranshalla();
|
||||
|
||||
1213
src/server/scripts/World/npc_stave_of_ancients.cpp
Normal file
1213
src/server/scripts/World/npc_stave_of_ancients.cpp
Normal file
File diff suppressed because it is too large
Load Diff
212
src/server/scripts/World/npc_stave_of_ancients.h
Normal file
212
src/server/scripts/World/npc_stave_of_ancients.h
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NPC_STAVE_OF_ANCIENTS_H
|
||||
#define NPC_STAVE_OF_ANCIENTS_H
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
enum Common
|
||||
{
|
||||
// Gossip
|
||||
GOSSIP_EVENT_START_OPTION_ID = 0,
|
||||
|
||||
// Events
|
||||
EVENT_ENCOUNTER_START = 1,
|
||||
EVENT_REVEAL = 2,
|
||||
EVENT_FOOLS_PLIGHT = 3,
|
||||
EVENT_RANGE_CHECK = 4,
|
||||
EVENT_UNFAIR_FIGHT = 5,
|
||||
|
||||
QUEST_STAVE_OF_THE_ANCIENTS = 7636,
|
||||
|
||||
// Spells
|
||||
// Player
|
||||
SPELL_FEIGN_DEATH = 5384,
|
||||
// NPC
|
||||
SPELL_DEMONIC_ENRAGE = 23257,
|
||||
SPELL_FOOLS_PLIGHT = 23504,
|
||||
};
|
||||
|
||||
enum NPCArtorius
|
||||
{
|
||||
ARTORIUS_EVENT_DEMONIC_DOOM = 6,
|
||||
ARTORIUS_EVENT_DEMONIC_ENRAGE = 7,
|
||||
|
||||
ARTORIUS_WEAKNESS_EMOTE = 9786, // broadcast_text.ID "%s is stricken by a virulent poison."
|
||||
ARTORIUS_SAY = 9787, // broadcast_text.ID "Your soul is mine, weakling."
|
||||
|
||||
ARTORIUS_NORMAL_ENTRY = 14531, // creature_template.entry
|
||||
ARTORIUS_EVIL_ENTRY = 14535, // creature_template.entry
|
||||
|
||||
ARTORIUS_HEAD = 18955, // item_template.entry
|
||||
|
||||
ARTORIUS_SPELL_DEMONIC_DOOM = 23298,
|
||||
ARTORIUS_SPELL_STINGING_TRAUMA = 23299
|
||||
};
|
||||
|
||||
enum NPCSimone
|
||||
{
|
||||
SIMONE_EVENT_TALK = 6,
|
||||
SIMONE_EVENT_CHECK_PET_STATE = 7,
|
||||
SIMONE_EVENT_CHAIN_LIGHTNING = 8,
|
||||
SIMONE_EVENT_TEMPTRESS_KISS = 9,
|
||||
|
||||
SIMONE_EMOTE = 9759, // broadcast_text.ID "%s laughs at your foolish request."
|
||||
SIMONE_SAY = 9760, // broadcast_text.ID "As you wish, $c."
|
||||
SIMONE_WEAKNESS_EMOTE = 9762, // broadcast_text.ID "%s is silenced by the venomous sting."
|
||||
|
||||
SIMONE_NORMAL_ENTRY = 14527, // creature_template.entry
|
||||
SIMONE_EVIL_ENTRY = 14533, // creature_template.entry
|
||||
|
||||
SIMONE_HEAD = 18952, // item_template.entry
|
||||
|
||||
SIMONE_SPELL_WEAKNESS_VIPER_STING = 3034,
|
||||
SIMONE_SPELL_TEMPTRESS_KISS = 23205,
|
||||
SIMONE_SPELL_CHAIN_LIGHTNING = 23206,
|
||||
// Found 23207 using spell editor it matches the duration, it doesn't have animation and the id is close to the other simone spells
|
||||
SIMONE_SPELL_SILENCE = 23207
|
||||
};
|
||||
|
||||
enum NPCPrecious
|
||||
{
|
||||
PRECIOUS_NORMAL_ENTRY = 14528,
|
||||
PRECIOUS_EVIL_ENTRY = 14538
|
||||
};
|
||||
|
||||
enum NPCNelson
|
||||
{
|
||||
NELSON_EVENT_DREADFUL_FRIGHT = 6,
|
||||
NELSON_EVENT_CREEPING_DOOM = 7,
|
||||
|
||||
NELSON_SAY = 9782, // broadcast_text.ID "You dare challenge me? Prepare for an e..."
|
||||
NELSON_WEAKNESS_EMOTE = 9785, // breadcast_text.ID "%s is immobilized."
|
||||
NELSON_DESPAWN_SAY = 9815, // breadcast_text.ID "Only a fool would remain in this battle..."
|
||||
|
||||
NELSON_NORMAL_ENTRY = 14536, // creature_template.entry
|
||||
NELSON_EVIL_ENTRY = 14530, // creature_template.entry
|
||||
CREEPING_DOOM_ENTRY = 14761,
|
||||
|
||||
NELSON_HEAD = 18954, // item_template.entry
|
||||
|
||||
NELSON_WEAKNESS_WING_CLIP = 2974,
|
||||
NELSON_WEAKNESS_FROST_TRAP = 13810,
|
||||
|
||||
NELSON_SPELL_SOUL_FLAME = 23272,
|
||||
NELSON_SPELL_DREADFUL_FRIGHT = 23275,
|
||||
NELSON_SPELL_CRIPPLING_CLIP = 23279,
|
||||
NELSON_SPELL_CREEPING_DOOM = 23589
|
||||
};
|
||||
|
||||
enum NPCFranklin
|
||||
{
|
||||
FRANKLIN_EVENT_DEMONIC_ENRAGE = 6,
|
||||
|
||||
FRANKLIN_SAY = 9772, // broadcast_text.ID "I shall enjoy this, $c."
|
||||
FRANKLIN_ENRAGE_EMOTE = 9764, // broadcast_text.ID "%s goes into a killing frenzy!"
|
||||
FRANKLIN_DESPAWN_SAY = 9815, // breadcast_text.ID "Only a fool would remain in this battle..."
|
||||
|
||||
FRANKLIN_NORMAL_ENTRY = 14529,
|
||||
FRANKLIN_EVIL_ENTRY = 14534,
|
||||
|
||||
FRANKLIN_HEAD = 18953, // item_template.entry
|
||||
|
||||
FRANKLIN_WEAKNESS_SCORPID_STING = 3043,
|
||||
|
||||
FRANKLIN_SPELL_ENTROPIC_STING = 23260
|
||||
};
|
||||
|
||||
struct NPCStaveQuestAI : public ScriptedAI
|
||||
{
|
||||
NPCStaveQuestAI(Creature *creature) : ScriptedAI(creature) { }
|
||||
|
||||
ObjectGuid gossipPlayerGUID;
|
||||
ObjectGuid playerGUID;
|
||||
bool encounterStarted;
|
||||
ThreatContainer::StorageType const& threatList = me->getThreatMgr().getThreatList();
|
||||
|
||||
std::map<int, int> entryKeys = {
|
||||
{ ARTORIUS_NORMAL_ENTRY, 1 },
|
||||
{ ARTORIUS_EVIL_ENTRY, 1 },
|
||||
{ SIMONE_NORMAL_ENTRY, 2 },
|
||||
{ SIMONE_EVIL_ENTRY, 2 },
|
||||
{ PRECIOUS_NORMAL_ENTRY, 3 },
|
||||
{ PRECIOUS_EVIL_ENTRY, 3 },
|
||||
{ NELSON_NORMAL_ENTRY, 4 },
|
||||
{ NELSON_EVIL_ENTRY, 4 },
|
||||
{ FRANKLIN_NORMAL_ENTRY, 5 },
|
||||
{ FRANKLIN_EVIL_ENTRY, 5 }
|
||||
};
|
||||
std::map<int, std::map<std::string, int>> entryList = {
|
||||
{
|
||||
1, {
|
||||
{"normal", ARTORIUS_NORMAL_ENTRY},
|
||||
{"evil", ARTORIUS_EVIL_ENTRY}
|
||||
}
|
||||
},
|
||||
{
|
||||
2, {
|
||||
{"normal", SIMONE_NORMAL_ENTRY},
|
||||
{"evil", SIMONE_EVIL_ENTRY}
|
||||
}
|
||||
},
|
||||
{
|
||||
3, {
|
||||
{"normal", PRECIOUS_NORMAL_ENTRY},
|
||||
{"evil", PRECIOUS_EVIL_ENTRY}
|
||||
}
|
||||
},
|
||||
{
|
||||
4, {
|
||||
{"normal", NELSON_NORMAL_ENTRY},
|
||||
{"evil", NELSON_EVIL_ENTRY}
|
||||
}
|
||||
},
|
||||
{
|
||||
5, {
|
||||
{"normal", FRANKLIN_NORMAL_ENTRY},
|
||||
{"evil", FRANKLIN_EVIL_ENTRY}
|
||||
}
|
||||
}
|
||||
};
|
||||
std::vector<uint64> attackerGuids;
|
||||
|
||||
uint32 GetFormEntry(std::string /*type*/);
|
||||
bool InNormalForm();
|
||||
void RevealForm();
|
||||
void StorePlayerGUID();
|
||||
Player* GetGossipPlayer();
|
||||
bool IsAllowedEntry(uint32 /*entry*/);
|
||||
bool UnitIsUnfair(Unit* unit);
|
||||
bool IsFairFight();
|
||||
bool ValidThreatlist();
|
||||
void SetHomePosition();
|
||||
void PrepareForEncounter();
|
||||
void ClearLootIfUnfair(Unit* killer);
|
||||
bool PlayerEligibleForReward(Unit* killer);
|
||||
void StoreAttackerGuidValue(Unit* attacker);
|
||||
bool QuestIncomplete(Unit* unit, uint32 questItem);
|
||||
void ResetState(uint32 /*aura*/);
|
||||
void EvadeOnFeignDeath();
|
||||
|
||||
virtual void AttackStart(Unit* /*target*/);
|
||||
virtual void AttackedBy(Unit* /*attacker*/);
|
||||
virtual void JustDied(Unit* /*killer*/);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -31,6 +31,7 @@ void AddSC_chat_log(); // location: scripts\World\chat_log.cpp
|
||||
void AddSC_character_creation();
|
||||
void AddSC_action_ip_logger(); // location: scripts\World\action_ip_logger.cpp
|
||||
void AddSC_player_scripts();
|
||||
void AddSC_npc_stave_of_ancients();
|
||||
|
||||
// The name of this function should match:
|
||||
// void Add${NameOfDirectory}Scripts()
|
||||
@@ -51,4 +52,5 @@ void AddWorldScripts()
|
||||
AddSC_character_creation();
|
||||
AddSC_action_ip_logger(); // location: scripts\World\action_ip_logger.cpp
|
||||
AddSC_player_scripts();
|
||||
AddSC_npc_stave_of_ancients();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user