diff --git a/common/ruletypes.h b/common/ruletypes.h index b2de14baa..a4a199400 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -681,6 +681,7 @@ RULE_BOOL(NPC, DisableLastNames, false, "Enable to disable NPC Last Names") RULE_BOOL(NPC, NPCIgnoreLevelBasedHasteCaps, false, "Ignores hard coded level based haste caps.") RULE_INT(NPC, NPCHasteCap, 150, "Haste cap for non-v3(over haste) haste") RULE_INT(NPC, NPCHastev3Cap, 25, "Haste cap for v3(over haste) haste") +RULE_STRING(NPC, ExcludedFaceTargetRaces, "52,72,73,141,233,328,329,372,376,377,378,379,380,381,382,383,404,422,423,424,425,426,428,429,445,449,460,462,463,500,501,502,503,504,505,506,507,508,509,510,511,513,514,515,516,533,534,535,536,537,538,539,540,541,542,543,544,545,546,550,551,552,553,554,555,556,557,567,573,577,586,589,590,591,592,593,595,596,599,601,616,619,621,628,629,630,633,634,635,636,665,683,684,685,691,692,693,694,702,703,705,706,707,710,711,714,720,2250,2254", "Race IDs excluded from facing target when hailed") RULE_CATEGORY_END() RULE_CATEGORY(Aggro) diff --git a/zone/npc.cpp b/zone/npc.cpp index f1260cd9c..38f597e63 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -3297,16 +3297,28 @@ uint32 NPC::GetSpawnKillCount() return(0); } -void NPC::DoQuestPause(Mob *other) { - if(IsMoving() && !IsOnHatelist(other)) { - PauseWandering(RuleI(NPC, SayPauseTimeInSec)); - if (other && !other->sneaking) - FaceTarget(other); - } else if(!IsMoving()) { - if (other && !other->sneaking && GetAppearance() != eaSitting && GetAppearance() != eaDead) - FaceTarget(other); +void NPC::DoQuestPause(Mob* m) +{ + if (!m) { + return; } + if (IsMoving() && !IsOnHatelist(m)) { + PauseWandering(RuleI(NPC, SayPauseTimeInSec)); + + if (FacesTarget() && !m->sneaking) { + FaceTarget(m); + } + } else if (!IsMoving()) { + if ( + FacesTarget() && + !m->sneaking && + GetAppearance() != eaSitting && + GetAppearance() != eaDead + ) { + FaceTarget(m); + } + } } void NPC::ChangeLastName(std::string last_name) @@ -4238,3 +4250,17 @@ void NPC::DoNpcToNpcAggroScan() false ); } + +bool NPC::FacesTarget() +{ + const std::string& excluded_races_rule = RuleS(NPC, ExcludedFaceTargetRaces); + + if (excluded_races_rule.empty()) { + return true; + } + + const auto& v = Strings::Split(excluded_races_rule, ","); + + return std::find(v.begin(), v.end(), std::to_string(GetBaseRace())) == v.end(); +} + diff --git a/zone/npc.h b/zone/npc.h index 20b6f74f6..a20d975b1 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -482,7 +482,8 @@ public: NPC_Emote_Struct* GetNPCEmote(uint32 emote_id, uint8 event_); void DoNPCEmote(uint8 event_, uint32 emote_id, Mob* t = nullptr); bool CanTalk(); - void DoQuestPause(Mob *other); + void DoQuestPause(Mob* m); + bool FacesTarget(); inline void SetSpellScale(float amt) { spellscale = amt; } inline float GetSpellScale() { return spellscale; }