mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-16 01:01:30 +00:00
[Bug Fix] NPC Faction War prevention. (#3595)
* [Bug] NPC Faction War prevention. This should assist with prevention of NPC Faction waring. I have been using this code on my server for over 5 years with no coredumps or any noted bugs. This was brought up as users have reported a few events where they can trigger NPC's to fight each other. * Correct a few entries to line up with updated code. * Re-add missing RestTimer functionality
This commit is contained in:
parent
c0fe0f11f7
commit
f7780b0247
@ -42,15 +42,14 @@ HateList::~HateList()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void HateList::WipeHateList()
|
void HateList::WipeHateList(bool npc_only) {
|
||||||
{
|
|
||||||
auto iterator = list.begin();
|
auto iterator = list.begin();
|
||||||
|
while (iterator != list.end()) {
|
||||||
while (iterator != list.end())
|
|
||||||
{
|
|
||||||
Mob *m = (*iterator)->entity_on_hatelist;
|
Mob *m = (*iterator)->entity_on_hatelist;
|
||||||
if (m)
|
if (m && (m->IsClient() || (m->IsPet() && m->GetOwner()->IsClient())) && npc_only) {
|
||||||
{
|
iterator++;
|
||||||
|
} else {
|
||||||
|
if (m) {
|
||||||
if (parse->HasQuestSub(hate_owner->GetNPCTypeID(), EVENT_HATE_LIST)) {
|
if (parse->HasQuestSub(hate_owner->GetNPCTypeID(), EVENT_HATE_LIST)) {
|
||||||
parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), m, "0", 0);
|
parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), m, "0", 0);
|
||||||
}
|
}
|
||||||
@ -59,10 +58,10 @@ void HateList::WipeHateList()
|
|||||||
m->CastToClient()->DecrementAggroCount();
|
m->CastToClient()->DecrementAggroCount();
|
||||||
m->CastToClient()->RemoveXTarget(hate_owner, true);
|
m->CastToClient()->RemoveXTarget(hate_owner, true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
delete (*iterator);
|
delete (*iterator);
|
||||||
iterator = list.erase(iterator);
|
iterator = list.erase(iterator);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -88,7 +88,7 @@ public:
|
|||||||
void SetHateAmountOnEnt(Mob *other, int64 in_hate, uint64 in_damage);
|
void SetHateAmountOnEnt(Mob *other, int64 in_hate, uint64 in_damage);
|
||||||
void SetHateOwner(Mob *new_hate_owner) { hate_owner = new_hate_owner; }
|
void SetHateOwner(Mob *new_hate_owner) { hate_owner = new_hate_owner; }
|
||||||
void SpellCast(Mob *caster, uint32 spell_id, float range, Mob *ae_center = nullptr);
|
void SpellCast(Mob *caster, uint32 spell_id, float range, Mob *ae_center = nullptr);
|
||||||
void WipeHateList();
|
void WipeHateList(bool npc_only = false);
|
||||||
void RemoveStaleEntries(int time_ms, float dist);
|
void RemoveStaleEntries(int time_ms, float dist);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
14
zone/mob.cpp
14
zone/mob.cpp
@ -4888,16 +4888,14 @@ bool Mob::RemoveFromHateList(Mob* mob)
|
|||||||
return bFound;
|
return bFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::WipeHateList()
|
void Mob::WipeHateList(bool npc_only) {
|
||||||
{
|
if (IsEngaged()) {
|
||||||
if(IsEngaged())
|
hate_list.WipeHateList(npc_only);
|
||||||
{
|
if (hate_list.IsHateListEmpty()) {
|
||||||
hate_list.WipeHateList();
|
|
||||||
AI_Event_NoLongerEngaged();
|
AI_Event_NoLongerEngaged();
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
{
|
hate_list.WipeHateList(npc_only);
|
||||||
hate_list.WipeHateList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -767,7 +767,7 @@ public:
|
|||||||
void SetAssistAggro(bool value) { AssistAggro = value; if (PrimaryAggro) AssistAggro = false; }
|
void SetAssistAggro(bool value) { AssistAggro = value; if (PrimaryAggro) AssistAggro = false; }
|
||||||
bool HateSummon();
|
bool HateSummon();
|
||||||
void FaceTarget(Mob* mob_to_face = 0);
|
void FaceTarget(Mob* mob_to_face = 0);
|
||||||
void WipeHateList();
|
void WipeHateList(bool npc_only = false);
|
||||||
void AddFeignMemory(Mob* attacker);
|
void AddFeignMemory(Mob* attacker);
|
||||||
void RemoveFromFeignMemory(Mob* attacker);
|
void RemoveFromFeignMemory(Mob* attacker);
|
||||||
void ClearFeignMemory();
|
void ClearFeignMemory();
|
||||||
|
|||||||
@ -1062,6 +1062,10 @@ void Mob::AI_Process() {
|
|||||||
SetTarget(hate_list.GetClosestEntOnHateList(this));
|
SetTarget(hate_list.GetClosestEntOnHateList(this));
|
||||||
else {
|
else {
|
||||||
if (AI_target_check_timer->Check()) {
|
if (AI_target_check_timer->Check()) {
|
||||||
|
if (IsNPC() && (!IsPet() || (HasOwner() && GetOwner()->IsNPC())) && !CastToNPC()->WillAggroNPCs()) {
|
||||||
|
WipeHateList(true); // wipe NPCs from hate list to prevent faction war
|
||||||
|
}
|
||||||
|
|
||||||
if (IsFocused()) {
|
if (IsFocused()) {
|
||||||
if (!target) {
|
if (!target) {
|
||||||
SetTarget(hate_list.GetEntWithMostHateOnList(this));
|
SetTarget(hate_list.GetEntWithMostHateOnList(this));
|
||||||
|
|||||||
@ -3885,12 +3885,13 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
|
|||||||
|
|
||||||
if (IsDetrimentalSpell(buff.spellid)) {
|
if (IsDetrimentalSpell(buff.spellid)) {
|
||||||
if (caster->IsClient()) {
|
if (caster->IsClient()) {
|
||||||
if (!caster->CastToClient()->GetFeigned())
|
if (!caster->CastToClient()->GetFeigned()) {
|
||||||
AddToHateList(caster, -effect_value);
|
AddToHateList(caster, -effect_value);
|
||||||
} else if (!IsClient()) // Allow NPC's to generate hate if casted on other
|
}
|
||||||
// NPC's.
|
} else if (!IsClient()) { // Allow NPC's to generate hate if casted on other NPC's
|
||||||
AddToHateList(caster, -effect_value);
|
AddToHateList(caster, -effect_value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
effect_value = caster->GetActDoTDamage(buff.spellid, effect_value, this);
|
effect_value = caster->GetActDoTDamage(buff.spellid, effect_value, this);
|
||||||
|
|
||||||
@ -3990,6 +3991,12 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
|
|||||||
case SE_Charm: {
|
case SE_Charm: {
|
||||||
if (!caster || !PassCharismaCheck(caster, buff.spellid)) {
|
if (!caster || !PassCharismaCheck(caster, buff.spellid)) {
|
||||||
BuffFadeByEffect(SE_Charm);
|
BuffFadeByEffect(SE_Charm);
|
||||||
|
|
||||||
|
// Remove from hate list of any NPC's hate list and remove all NPCs this hate list
|
||||||
|
if (IsNPC()) {
|
||||||
|
entity_list.RemoveFromHateLists(this);
|
||||||
|
WipeHateList(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -4244,13 +4244,10 @@ bool Mob::SpellOnTarget(
|
|||||||
spelltar->DamageShield(this, true);
|
spelltar->DamageShield(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (!(spelltar->IsNPC() && IsNPC() && !(IsPet() && GetOwner()->IsClient()))) {
|
||||||
spelltar->IsAIControlled() &&
|
if (spelltar->IsAIControlled() && IsDetrimentalSpell(spell_id) && !IsHarmonySpell(spell_id)) {
|
||||||
IsDetrimentalSpell(spell_id) &&
|
|
||||||
!IsHarmonySpell(spell_id)
|
|
||||||
) {
|
|
||||||
auto aggro_amount = CheckAggroAmount(spell_id, spelltar, isproc);
|
auto aggro_amount = CheckAggroAmount(spell_id, spelltar, isproc);
|
||||||
LogSpells("Spell [{}] cast on [{}] generated [{}] hate", spell_id,
|
LogSpellsDetail("Spell {} cast on {} generated {} hate", spell_id,
|
||||||
spelltar->GetName(), aggro_amount);
|
spelltar->GetName(), aggro_amount);
|
||||||
if (aggro_amount > 0) {
|
if (aggro_amount > 0) {
|
||||||
spelltar->AddToHateList(this, aggro_amount);
|
spelltar->AddToHateList(this, aggro_amount);
|
||||||
@ -4280,6 +4277,7 @@ bool Mob::SpellOnTarget(
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// make sure spelltar is high enough level for the buff
|
// make sure spelltar is high enough level for the buff
|
||||||
if (!spelltar->CheckSpellLevelRestriction(this, spell_id)) {
|
if (!spelltar->CheckSpellLevelRestriction(this, spell_id)) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user