mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-14 20:12:26 +00:00
Port EQMacEmu's Assist Aggro code
This code also allows you to toggle on Tick Pulling (Aggro:AllowTickPulling) which was a pulling technique (exploit) fixed sometime in 2006 This code also implements assist caps to cut down on trains (5 by default) Unsure if live what this number is (it exists) or if it's a per NPC basis An NPC with Assist Aggro will not call for help, only NPCs with Primary Aggro will
This commit is contained in:
parent
f8867ea73d
commit
03592e58f9
@ -459,6 +459,8 @@ RULE_BOOL(Combat, ProjectileDmgOnImpact, true) //If enabled, projectiles (ie arr
|
|||||||
RULE_BOOL(Combat, MeleePush, true) // enable melee push
|
RULE_BOOL(Combat, MeleePush, true) // enable melee push
|
||||||
RULE_INT(Combat, MeleePushChance, 50) // (NPCs) chance the target will be pushed. Made up, 100 actually isn't that bad
|
RULE_INT(Combat, MeleePushChance, 50) // (NPCs) chance the target will be pushed. Made up, 100 actually isn't that bad
|
||||||
RULE_BOOL(Combat, UseLiveCombatRounds, true) // turn this false if you don't want to worry about fixing up combat rounds for NPCs
|
RULE_BOOL(Combat, UseLiveCombatRounds, true) // turn this false if you don't want to worry about fixing up combat rounds for NPCs
|
||||||
|
RULE_INT(Combat, NPCAssistCap, 5) // Maxiumium number of NPCs that will assist another NPC at once
|
||||||
|
RULE_INT(Combat, NPCAssistCapTimer, 6000) // Time in milliseconds a NPC will take to clear assist aggro cap space
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(NPC)
|
RULE_CATEGORY(NPC)
|
||||||
@ -494,6 +496,7 @@ RULE_INT(Aggro, PetSpellAggroMod, 10)
|
|||||||
RULE_REAL(Aggro, TunnelVisionAggroMod, 0.75) //people not currently the top hate generate this much hate on a Tunnel Vision mob
|
RULE_REAL(Aggro, TunnelVisionAggroMod, 0.75) //people not currently the top hate generate this much hate on a Tunnel Vision mob
|
||||||
RULE_INT(Aggro, MaxScalingProcAggro, 400) // Set to -1 for no limit. Maxmimum amount of aggro that HP scaling SPA effect in a proc will add.
|
RULE_INT(Aggro, MaxScalingProcAggro, 400) // Set to -1 for no limit. Maxmimum amount of aggro that HP scaling SPA effect in a proc will add.
|
||||||
RULE_INT(Aggro, IntAggroThreshold, 75) // Int <= this will aggro regardless of level difference.
|
RULE_INT(Aggro, IntAggroThreshold, 75) // Int <= this will aggro regardless of level difference.
|
||||||
|
RULE_BOOL(Aggro, AllowTickPulling, false) // tick pulling is an exploit in an NPC's call for help fixed sometime in 2006 on live
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(TaskSystem)
|
RULE_CATEGORY(TaskSystem)
|
||||||
|
|||||||
@ -431,11 +431,20 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
|||||||
if (sender->GetPrimaryFaction() == 0 )
|
if (sender->GetPrimaryFaction() == 0 )
|
||||||
return; // well, if we dont have a faction set, we're gonna be indiff to everybody
|
return; // well, if we dont have a faction set, we're gonna be indiff to everybody
|
||||||
|
|
||||||
|
if (sender->HasAssistAggro())
|
||||||
|
return;
|
||||||
|
|
||||||
for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
|
for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
|
||||||
NPC *mob = it->second;
|
NPC *mob = it->second;
|
||||||
if (!mob)
|
if (!mob)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (mob->CheckAggro(attacker))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sender->NPCAssistCap() >= RuleI(Combat, NPCAssistCap))
|
||||||
|
break;
|
||||||
|
|
||||||
float r = mob->GetAssistRange();
|
float r = mob->GetAssistRange();
|
||||||
r = r * r;
|
r = r * r;
|
||||||
|
|
||||||
@ -477,6 +486,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
|||||||
sender->GetPosition()), fabs(sender->GetZ()+mob->GetZ()));
|
sender->GetPosition()), fabs(sender->GetZ()+mob->GetZ()));
|
||||||
#endif
|
#endif
|
||||||
mob->AddToHateList(attacker, 25, 0, false);
|
mob->AddToHateList(attacker, 25, 0, false);
|
||||||
|
sender->AddAssistCap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2422,6 +2422,11 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
|
|||||||
hate = 1;
|
hate = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iYellForHelp)
|
||||||
|
SetPrimaryAggro(true);
|
||||||
|
else
|
||||||
|
SetAssistAggro(true);
|
||||||
|
|
||||||
bool wasengaged = IsEngaged();
|
bool wasengaged = IsEngaged();
|
||||||
Mob* owner = other->GetOwner();
|
Mob* owner = other->GetOwner();
|
||||||
Mob* mypet = this->GetPet();
|
Mob* mypet = this->GetPet();
|
||||||
|
|||||||
@ -433,6 +433,9 @@ Mob::Mob(const char* in_name,
|
|||||||
|
|
||||||
emoteid = 0;
|
emoteid = 0;
|
||||||
endur_upkeep = false;
|
endur_upkeep = false;
|
||||||
|
PrimaryAggro = false;
|
||||||
|
AssistAggro = false;
|
||||||
|
npc_assist_cap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mob::~Mob()
|
Mob::~Mob()
|
||||||
@ -2693,6 +2696,8 @@ bool Mob::RemoveFromHateList(Mob* mob)
|
|||||||
{
|
{
|
||||||
AI_Event_NoLongerEngaged();
|
AI_Event_NoLongerEngaged();
|
||||||
zone->DelAggroMob();
|
zone->DelAggroMob();
|
||||||
|
if (IsNPC() && !RuleB(Aggro, AllowTickPulling))
|
||||||
|
ResetAssistCap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(GetTarget() == mob)
|
if(GetTarget() == mob)
|
||||||
|
|||||||
14
zone/mob.h
14
zone/mob.h
@ -504,6 +504,10 @@ public:
|
|||||||
Mob* GetHateRandom() { return hate_list.GetRandomEntOnHateList();}
|
Mob* GetHateRandom() { return hate_list.GetRandomEntOnHateList();}
|
||||||
Mob* GetHateMost() { return hate_list.GetEntWithMostHateOnList();}
|
Mob* GetHateMost() { return hate_list.GetEntWithMostHateOnList();}
|
||||||
bool IsEngaged() { return(!hate_list.IsHateListEmpty()); }
|
bool IsEngaged() { return(!hate_list.IsHateListEmpty()); }
|
||||||
|
bool HasPrimaryAggro() { return PrimaryAggro; }
|
||||||
|
bool HasAssistAggro() { return AssistAggro; }
|
||||||
|
void SetPrimaryAggro(bool value) { PrimaryAggro = value; if (value) AssistAggro = false; }
|
||||||
|
void SetAssistAggro(bool value) { AssistAggro = value; if (PrimaryAggro) AssistAggro = false; }
|
||||||
bool HateSummon();
|
bool HateSummon();
|
||||||
void FaceTarget(Mob* MobToFace = 0);
|
void FaceTarget(Mob* MobToFace = 0);
|
||||||
void SetHeading(float iHeading) { if(m_Position.w != iHeading) { pLastChange = Timer::GetCurrentTime();
|
void SetHeading(float iHeading) { if(m_Position.w != iHeading) { pLastChange = Timer::GetCurrentTime();
|
||||||
@ -993,6 +997,11 @@ public:
|
|||||||
void ApplyAABonuses(const AA::Rank &rank, StatBonuses* newbon);
|
void ApplyAABonuses(const AA::Rank &rank, StatBonuses* newbon);
|
||||||
bool CheckAATimer(int timer);
|
bool CheckAATimer(int timer);
|
||||||
|
|
||||||
|
int NPCAssistCap() { return npc_assist_cap; }
|
||||||
|
void AddAssistCap() { ++npc_assist_cap; }
|
||||||
|
void DelAssistCap() { --npc_assist_cap; }
|
||||||
|
void ResetAssistCap() { npc_assist_cap = 0; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic, int special = 0);
|
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic, int special = 0);
|
||||||
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||||
@ -1293,6 +1302,11 @@ protected:
|
|||||||
glm::vec4 m_CurrentWayPoint;
|
glm::vec4 m_CurrentWayPoint;
|
||||||
int cur_wp_pause;
|
int cur_wp_pause;
|
||||||
|
|
||||||
|
bool PrimaryAggro;
|
||||||
|
bool AssistAggro;
|
||||||
|
int npc_assist_cap;
|
||||||
|
Timer assist_cap_timer; // clear assist cap so more nearby mobs can be called for help
|
||||||
|
|
||||||
|
|
||||||
int patrol;
|
int patrol;
|
||||||
glm::vec3 m_FearWalkTarget;
|
glm::vec3 m_FearWalkTarget;
|
||||||
|
|||||||
@ -1735,8 +1735,10 @@ void Mob::AI_Event_Engaged(Mob* attacker, bool iYellForHelp) {
|
|||||||
if (iYellForHelp) {
|
if (iYellForHelp) {
|
||||||
if(IsPet()) {
|
if(IsPet()) {
|
||||||
GetOwner()->AI_Event_Engaged(attacker, iYellForHelp);
|
GetOwner()->AI_Event_Engaged(attacker, iYellForHelp);
|
||||||
} else {
|
} else if (!HasAssistAggro() && NPCAssistCap() < RuleI(Combat, NPCAssistCap)) {
|
||||||
entity_list.AIYellForHelp(this, attacker);
|
entity_list.AIYellForHelp(this, attacker);
|
||||||
|
if (NPCAssistCap() > 0 && !assist_cap_timer.Enabled())
|
||||||
|
assist_cap_timer.Start(RuleI(Combat, NPCAssistCapTimer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1787,6 +1789,8 @@ void Mob::AI_Event_NoLongerEngaged() {
|
|||||||
|
|
||||||
if(IsNPC())
|
if(IsNPC())
|
||||||
{
|
{
|
||||||
|
SetPrimaryAggro(false);
|
||||||
|
SetAssistAggro(false);
|
||||||
if(CastToNPC()->GetCombatEvent() && GetHP() > 0)
|
if(CastToNPC()->GetCombatEvent() && GetHP() > 0)
|
||||||
{
|
{
|
||||||
if(entity_list.GetNPCByID(this->GetID()))
|
if(entity_list.GetNPCByID(this->GetID()))
|
||||||
|
|||||||
12
zone/npc.cpp
12
zone/npc.cpp
@ -712,8 +712,18 @@ bool NPC::Process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Handle assists...
|
//Handle assists...
|
||||||
if(assist_timer.Check() && IsEngaged() && !Charmed()) {
|
if (assist_cap_timer.Check()) {
|
||||||
|
if (NPCAssistCap() > 0)
|
||||||
|
DelAssistCap();
|
||||||
|
else
|
||||||
|
assist_cap_timer.Disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assist_timer.Check() && IsEngaged() && !Charmed() && !HasAssistAggro() &&
|
||||||
|
NPCAssistCap() < RuleI(Combat, NPCAssistCap)) {
|
||||||
entity_list.AIYellForHelp(this, GetTarget());
|
entity_list.AIYellForHelp(this, GetTarget());
|
||||||
|
if (NPCAssistCap() > 0 && !assist_cap_timer.Enabled())
|
||||||
|
assist_cap_timer.Start(RuleI(Combat, NPCAssistCapTimer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(qGlobals)
|
if(qGlobals)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user