mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-09 08:17:56 +00:00
fix(Scripts/World): Precious and Simone use safer calls (#25728)
This commit is contained in:
@@ -70,14 +70,14 @@ Player* NPCStaveQuestAI::GetGossipPlayer()
|
|||||||
return ObjectAccessor::GetPlayer(*me, gossipPlayerGUID);
|
return ObjectAccessor::GetPlayer(*me, gossipPlayerGUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NPCStaveQuestAI::IsAllowedEntry(uint32 entry)
|
bool NPCStaveQuestAI::IsAllowedEntry(uint32 entry) const
|
||||||
{
|
{
|
||||||
uint32 allowedEntries[4] = { 0, 12999, 19833, 19921 }; //player, World Invisible Trigger(traps) and snake trap snakes
|
uint32 allowedEntries[4] = { 0, 12999, 19833, 19921 }; //player, World Invisible Trigger(traps) and snake trap snakes
|
||||||
bool isAllowed = std::find(std::begin(allowedEntries), std::end(allowedEntries), entry) != std::end(allowedEntries);
|
bool isAllowed = std::find(std::begin(allowedEntries), std::end(allowedEntries), entry) != std::end(allowedEntries);
|
||||||
return isAllowed;
|
return isAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NPCStaveQuestAI::UnitIsUnfair(Unit* unit)
|
bool NPCStaveQuestAI::UnitIsUnfair(Unit* unit) const
|
||||||
{
|
{
|
||||||
if (!unit || playerGUID.IsEmpty())
|
if (!unit || playerGUID.IsEmpty())
|
||||||
{
|
{
|
||||||
@@ -108,7 +108,7 @@ bool NPCStaveQuestAI::UnitIsUnfair(Unit* unit)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NPCStaveQuestAI::IsFairFight()
|
bool NPCStaveQuestAI::IsFairFight() const
|
||||||
{
|
{
|
||||||
for (ThreatReference const* ref : me->GetThreatMgr().GetUnsortedThreatList())
|
for (ThreatReference const* ref : me->GetThreatMgr().GetUnsortedThreatList())
|
||||||
{
|
{
|
||||||
@@ -128,12 +128,10 @@ bool NPCStaveQuestAI::IsFairFight()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NPCStaveQuestAI::ValidThreatlist()
|
bool NPCStaveQuestAI::ValidThreatlist() const
|
||||||
{
|
{
|
||||||
if (me->GetThreatMgr().GetThreatListSize() == 1)
|
if (me->GetThreatMgr().GetThreatListSize() == 1)
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
bool isFair = IsFairFight();
|
bool isFair = IsFairFight();
|
||||||
|
|
||||||
@@ -463,10 +461,10 @@ public:
|
|||||||
|
|
||||||
struct npc_preciousAI : public NPCStaveQuestAI
|
struct npc_preciousAI : public NPCStaveQuestAI
|
||||||
{
|
{
|
||||||
npc_preciousAI(Creature *creature) : NPCStaveQuestAI(creature) { }
|
explicit npc_preciousAI(Creature *creature) : NPCStaveQuestAI(creature) { }
|
||||||
|
|
||||||
EventMap events;
|
EventMap events;
|
||||||
bool flaggedForDespawn;
|
bool flaggedForDespawn{};
|
||||||
|
|
||||||
void InitializeAI() override
|
void InitializeAI() override
|
||||||
{
|
{
|
||||||
@@ -512,6 +510,37 @@ public:
|
|||||||
{
|
{
|
||||||
flaggedForDespawn = true;
|
flaggedForDespawn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 GetData(uint32 type) const override
|
||||||
|
{
|
||||||
|
if (type == DATA_SIMONE_VALID_THREATLIST)
|
||||||
|
return ValidThreatlist() ? 1 : 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetData(uint32 type, uint32 data) override
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DATA_SIMONE_REVEAL:
|
||||||
|
if (data)
|
||||||
|
RevealForm();
|
||||||
|
break;
|
||||||
|
case DATA_SIMONE_PREPARE_ENCOUNTER:
|
||||||
|
PrepareForEncounter();
|
||||||
|
break;
|
||||||
|
case DATA_SIMONE_SET_HOME:
|
||||||
|
SetHomePosition();
|
||||||
|
break;
|
||||||
|
case DATA_SIMONE_CORPSE_REMOVED:
|
||||||
|
EnterEvadeMode();
|
||||||
|
FlagForDespawn();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -527,7 +556,7 @@ public:
|
|||||||
|
|
||||||
struct npc_simoneAI : public NPCStaveQuestAI
|
struct npc_simoneAI : public NPCStaveQuestAI
|
||||||
{
|
{
|
||||||
npc_simoneAI(Creature *creature) : NPCStaveQuestAI(creature) { }
|
explicit npc_simoneAI(Creature *creature) : NPCStaveQuestAI(creature) { }
|
||||||
|
|
||||||
EventMap events;
|
EventMap events;
|
||||||
ObjectGuid preciousGUID;
|
ObjectGuid preciousGUID;
|
||||||
@@ -535,39 +564,18 @@ public:
|
|||||||
void SetPreciousGUID()
|
void SetPreciousGUID()
|
||||||
{
|
{
|
||||||
if (CreatureGroup* formation = me->GetFormation())
|
if (CreatureGroup* formation = me->GetFormation())
|
||||||
{
|
for ([[maybe_unused]] auto const& [member, info] : formation->GetMembers())
|
||||||
const CreatureGroup::CreatureGroupMemberType& members = formation->GetMembers();
|
if (member && member->GetOriginalEntry() == PRECIOUS_NORMAL_ENTRY)
|
||||||
for (CreatureGroup::CreatureGroupMemberType::const_iterator itr = members.begin(); itr != members.end(); ++itr)
|
preciousGUID = member->GetGUID();
|
||||||
{
|
|
||||||
if (itr->first && itr->first->GetOriginalEntry() == PRECIOUS_NORMAL_ENTRY)
|
|
||||||
{
|
|
||||||
preciousGUID = itr->first->GetGUID();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Creature* Precious()
|
Creature* Precious()
|
||||||
{
|
{
|
||||||
if (preciousGUID.IsEmpty())
|
if (preciousGUID.IsEmpty())
|
||||||
{
|
|
||||||
SetPreciousGUID();
|
SetPreciousGUID();
|
||||||
}
|
|
||||||
|
|
||||||
if (!preciousGUID.IsEmpty())
|
if (!preciousGUID.IsEmpty())
|
||||||
{
|
|
||||||
return ObjectAccessor::GetCreature(*me, preciousGUID);
|
return ObjectAccessor::GetCreature(*me, preciousGUID);
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
npc_precious::npc_preciousAI* PreciousAI()
|
|
||||||
{
|
|
||||||
if (Precious())
|
|
||||||
{
|
|
||||||
return CAST_AI(npc_precious::npc_preciousAI, Precious()->AI());
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -632,21 +640,20 @@ public:
|
|||||||
|
|
||||||
void CorpseRemoved(uint32& /*respawnDelay*/) override
|
void CorpseRemoved(uint32& /*respawnDelay*/) override
|
||||||
{
|
{
|
||||||
if (!Precious())
|
Creature* creature = Precious();
|
||||||
{
|
if (!creature)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (Precious()->IsInCombat())
|
if (creature->IsInCombat())
|
||||||
{
|
{
|
||||||
// If Simone corpse is removed but pet is InCombat, EnterEvadeMode and auto despawn on pet reaching home
|
// If Simone corpse is removed but pet is InCombat, ask pet AI to enter evade and flag for despawn
|
||||||
PreciousAI()->EnterEvadeMode();
|
if (creature->AI())
|
||||||
PreciousAI()->FlagForDespawn();
|
creature->AI()->SetData(DATA_SIMONE_CORPSE_REMOVED, 1);
|
||||||
|
else
|
||||||
|
creature->DespawnOrUnsummon(0ms);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
creature->DespawnOrUnsummon(0ms);
|
||||||
Precious()->DespawnOrUnsummon(0ms);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
@@ -704,10 +711,9 @@ public:
|
|||||||
break;
|
break;
|
||||||
case EVENT_REVEAL:
|
case EVENT_REVEAL:
|
||||||
RevealForm();
|
RevealForm();
|
||||||
if (PreciousAI())
|
if (Creature* creature = Precious())
|
||||||
{
|
if (creature->AI())
|
||||||
PreciousAI()->RevealForm();
|
creature->AI()->SetData(DATA_SIMONE_REVEAL, 1);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
// Prevent hunters from figthing Simone alone
|
// Prevent hunters from figthing Simone alone
|
||||||
case SIMONE_EVENT_CHECK_PET_STATE:
|
case SIMONE_EVENT_CHECK_PET_STATE:
|
||||||
@@ -721,6 +727,8 @@ public:
|
|||||||
events.ScheduleEvent(SIMONE_EVENT_CHECK_PET_STATE, 1s);
|
events.ScheduleEvent(SIMONE_EVENT_CHECK_PET_STATE, 1s);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UpdateVictim())
|
if (UpdateVictim())
|
||||||
@@ -760,23 +768,32 @@ public:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EVENT_UNFAIR_FIGHT:
|
case EVENT_UNFAIR_FIGHT:
|
||||||
if (!ValidThreatlist() || (PreciousAI() && !PreciousAI()->ValidThreatlist()))
|
{
|
||||||
|
Creature* creature = Precious();
|
||||||
|
bool isPreciousThreatListValid = creature && creature->AI() && creature->AI()->GetData(DATA_SIMONE_VALID_THREATLIST) == 1;
|
||||||
|
|
||||||
|
if (!ValidThreatlist() || !isPreciousThreatListValid)
|
||||||
{
|
{
|
||||||
SetHomePosition();
|
SetHomePosition();
|
||||||
PreciousAI()->SetHomePosition();
|
me->DespawnOrUnsummon(5s);
|
||||||
|
|
||||||
Precious()->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1);
|
|
||||||
Precious()->SetImmuneToAll(true);
|
|
||||||
me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1);
|
me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1);
|
||||||
me->SetImmuneToAll(true);
|
me->SetImmuneToAll(true);
|
||||||
|
|
||||||
Precious()->DespawnOrUnsummon(5s);
|
if (creature)
|
||||||
|
{
|
||||||
|
if (creature->AI())
|
||||||
|
creature->AI()->SetData(DATA_SIMONE_SET_HOME, 1);
|
||||||
|
|
||||||
|
creature->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1);
|
||||||
|
creature->SetImmuneToAll(true);
|
||||||
|
creature->DespawnOrUnsummon(5s);
|
||||||
|
}
|
||||||
|
|
||||||
me->DespawnOrUnsummon(5s);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
events.Repeat(2s);
|
events.Repeat(2s);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SIMONE_EVENT_CHAIN_LIGHTNING:
|
case SIMONE_EVENT_CHAIN_LIGHTNING:
|
||||||
me->CastSpell(me->GetVictim(), SIMONE_SPELL_CHAIN_LIGHTNING, false);
|
me->CastSpell(me->GetVictim(), SIMONE_SPELL_CHAIN_LIGHTNING, false);
|
||||||
events.Repeat(7s);
|
events.Repeat(7s);
|
||||||
@@ -785,6 +802,8 @@ public:
|
|||||||
me->CastSpell(me->GetVictim(), SIMONE_SPELL_TEMPTRESS_KISS, false);
|
me->CastSpell(me->GetVictim(), SIMONE_SPELL_TEMPTRESS_KISS, false);
|
||||||
events.Repeat(45s);
|
events.Repeat(45s);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
@@ -805,10 +824,10 @@ public:
|
|||||||
void ScheduleEncounterStart(ObjectGuid playerGUID)
|
void ScheduleEncounterStart(ObjectGuid playerGUID)
|
||||||
{
|
{
|
||||||
PrepareForEncounter();
|
PrepareForEncounter();
|
||||||
if (PreciousAI())
|
if (Creature* creature = Precious())
|
||||||
{
|
if (creature->AI())
|
||||||
PreciousAI()->PrepareForEncounter();
|
creature->AI()->SetData(DATA_SIMONE_PREPARE_ENCOUNTER, 1);
|
||||||
}
|
|
||||||
gossipPlayerGUID = playerGUID;
|
gossipPlayerGUID = playerGUID;
|
||||||
events.ScheduleEvent(EVENT_ENCOUNTER_START, 1s);
|
events.ScheduleEvent(EVENT_ENCOUNTER_START, 1s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,6 +88,15 @@ enum NPCPrecious
|
|||||||
PRECIOUS_EVIL_ENTRY = 14538
|
PRECIOUS_EVIL_ENTRY = 14538
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SimoneAIData
|
||||||
|
{
|
||||||
|
DATA_SIMONE_REVEAL = 1,
|
||||||
|
DATA_SIMONE_PREPARE_ENCOUNTER = 2,
|
||||||
|
DATA_SIMONE_VALID_THREATLIST = 3,
|
||||||
|
DATA_SIMONE_SET_HOME = 4,
|
||||||
|
DATA_SIMONE_CORPSE_REMOVED = 5
|
||||||
|
};
|
||||||
|
|
||||||
enum NPCNelson
|
enum NPCNelson
|
||||||
{
|
{
|
||||||
NELSON_EVENT_DREADFUL_FRIGHT = 6,
|
NELSON_EVENT_DREADFUL_FRIGHT = 6,
|
||||||
@@ -189,10 +198,10 @@ struct NPCStaveQuestAI : public ScriptedAI
|
|||||||
void RevealForm();
|
void RevealForm();
|
||||||
void StorePlayerGUID();
|
void StorePlayerGUID();
|
||||||
Player* GetGossipPlayer();
|
Player* GetGossipPlayer();
|
||||||
bool IsAllowedEntry(uint32 /*entry*/);
|
bool IsAllowedEntry(uint32 /*entry*/) const;
|
||||||
bool UnitIsUnfair(Unit* unit);
|
bool UnitIsUnfair(Unit* unit) const;
|
||||||
bool IsFairFight();
|
bool IsFairFight() const;
|
||||||
bool ValidThreatlist();
|
bool ValidThreatlist() const;
|
||||||
void SetHomePosition();
|
void SetHomePosition();
|
||||||
void PrepareForEncounter();
|
void PrepareForEncounter();
|
||||||
void ClearLootIfUnfair(Unit* killer);
|
void ClearLootIfUnfair(Unit* killer);
|
||||||
|
|||||||
Reference in New Issue
Block a user