mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 19:51:29 +00:00
[Rule] Add rule for bard aggro cap (#3909)
BardAggroCap - Default 40 Allows adjustment of per song bard aggro cap.
This commit is contained in:
parent
98928aee74
commit
8f34bd998f
@ -625,6 +625,7 @@ RULE_REAL(Aggro, PetAttackRange, 40000.0, "Maximum squared range /pet attack wor
|
|||||||
RULE_BOOL(Aggro, NPCAggroMaxDistanceEnabled, true, "If enabled, NPC's will drop aggro beyond 600 units or what is defined at the zone level")
|
RULE_BOOL(Aggro, NPCAggroMaxDistanceEnabled, true, "If enabled, NPC's will drop aggro beyond 600 units or what is defined at the zone level")
|
||||||
RULE_BOOL(Aggro, AggroPlayerPets, false, "If enabled, NPCs will aggro player pets")
|
RULE_BOOL(Aggro, AggroPlayerPets, false, "If enabled, NPCs will aggro player pets")
|
||||||
RULE_BOOL(Aggro, UndeadAlwaysAggro, true, "should undead always aggro?")
|
RULE_BOOL(Aggro, UndeadAlwaysAggro, true, "should undead always aggro?")
|
||||||
|
RULE_INT(Aggro, BardAggroCap, 40, "per song bard aggro cap.")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(TaskSystem)
|
RULE_CATEGORY(TaskSystem)
|
||||||
|
|||||||
118
zone/aggro.cpp
118
zone/aggro.cpp
@ -1181,47 +1181,52 @@ bool Mob::CheckLosFN(glm::vec3 posWatcher, float sizeWatcher, glm::vec3 posTarge
|
|||||||
}
|
}
|
||||||
|
|
||||||
//offensive spell aggro
|
//offensive spell aggro
|
||||||
int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc)
|
int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool is_proc)
|
||||||
{
|
{
|
||||||
if (IsNoDetrimentalSpellAggroSpell(spell_id))
|
if (IsNoDetrimentalSpellAggroSpell(spell_id)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int32 AggroAmount = 0;
|
int32 aggro_amount = 0;
|
||||||
int32 nonModifiedAggro = 0;
|
int32 non_modified_aggro = 0;
|
||||||
uint16 slevel = GetLevel();
|
uint16 mob_level = GetLevel();
|
||||||
bool dispel = false;
|
bool dispel = false;
|
||||||
bool on_hatelist = target ? target->CheckAggro(this) : false;
|
bool on_hatelist = target ? target->CheckAggro(this) : false;
|
||||||
int proc_cap = RuleI(Aggro, MaxScalingProcAggro);
|
int proc_cap = RuleI(Aggro, MaxScalingProcAggro);
|
||||||
int64 hate_cap = isproc && proc_cap != -1 ? proc_cap : 1200;
|
int64 hate_cap = is_proc && proc_cap != -1 ? proc_cap : 1200;
|
||||||
|
|
||||||
int64 target_hp = target ? target->GetMaxHP() : 18000; // default to max
|
int64 target_hp = target ? target->GetMaxHP() : 18000; // default to max
|
||||||
int64 default_aggro = 25;
|
int64 default_aggro = 25;
|
||||||
if (target_hp >= 18000) // max
|
if (target_hp >= 18000) { // max
|
||||||
default_aggro = hate_cap;
|
default_aggro = hate_cap;
|
||||||
else if (target_hp >= 390) // min, 390 is the first number with int division that is 26
|
} else if (target_hp >= 390) { // min, 390 is the first number with int division that is 26
|
||||||
default_aggro = target_hp / 15;
|
default_aggro = target_hp / 15;
|
||||||
|
}
|
||||||
|
|
||||||
for (int o = 0; o < EFFECT_COUNT; o++) {
|
for (int o = 0; o < EFFECT_COUNT; o++) {
|
||||||
switch (spells[spell_id].effect_id[o]) {
|
switch (spells[spell_id].effect_id[o]) {
|
||||||
case SE_CurrentHPOnce:
|
case SE_CurrentHPOnce:
|
||||||
case SE_CurrentHP: {
|
case SE_CurrentHP: {
|
||||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], slevel, spell_id);
|
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||||
if(val < 0)
|
if(val < 0) {
|
||||||
AggroAmount -= val;
|
aggro_amount -= val;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_MovementSpeed: {
|
case SE_MovementSpeed: {
|
||||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], slevel, spell_id);
|
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||||
if (val < 0)
|
if (val < 0) {
|
||||||
AggroAmount += default_aggro;
|
aggro_amount += default_aggro;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_AttackSpeed:
|
case SE_AttackSpeed:
|
||||||
case SE_AttackSpeed2:
|
case SE_AttackSpeed2:
|
||||||
case SE_AttackSpeed3: {
|
case SE_AttackSpeed3: {
|
||||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], slevel, spell_id);
|
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||||
if (val < 100)
|
if (val < 100) {
|
||||||
AggroAmount += default_aggro;
|
aggro_amount += default_aggro;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_Stun:
|
case SE_Stun:
|
||||||
@ -1230,16 +1235,17 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc)
|
|||||||
case SE_Charm:
|
case SE_Charm:
|
||||||
case SE_Fear:
|
case SE_Fear:
|
||||||
case SE_Fearstun:
|
case SE_Fearstun:
|
||||||
AggroAmount += default_aggro;
|
aggro_amount += default_aggro;
|
||||||
break;
|
break;
|
||||||
case SE_Root:
|
case SE_Root:
|
||||||
AggroAmount += 10;
|
aggro_amount += 10;
|
||||||
break;
|
break;
|
||||||
case SE_ACv2:
|
case SE_ACv2:
|
||||||
case SE_ArmorClass: {
|
case SE_ArmorClass: {
|
||||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], slevel, spell_id);
|
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||||
if (val < 0)
|
if (val < 0) {
|
||||||
AggroAmount += default_aggro;
|
aggro_amount += default_aggro;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_ATK:
|
case SE_ATK:
|
||||||
@ -1255,31 +1261,34 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc)
|
|||||||
case SE_INT:
|
case SE_INT:
|
||||||
case SE_WIS:
|
case SE_WIS:
|
||||||
case SE_CHA: {
|
case SE_CHA: {
|
||||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], slevel, spell_id);
|
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||||
if (val < 0)
|
if (val < 0) {
|
||||||
AggroAmount += 10;
|
aggro_amount += 10;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_ResistAll: {
|
case SE_ResistAll: {
|
||||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], slevel, spell_id);
|
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||||
if (val < 0)
|
if (val < 0) {
|
||||||
AggroAmount += 50;
|
aggro_amount += 50;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_AllStats: {
|
case SE_AllStats: {
|
||||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], slevel, spell_id);
|
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||||
if (val < 0)
|
if (val < 0) {
|
||||||
AggroAmount += 70;
|
aggro_amount += 70;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_BardAEDot:
|
case SE_BardAEDot:
|
||||||
AggroAmount += 10;
|
aggro_amount += 10;
|
||||||
break;
|
break;
|
||||||
case SE_SpinTarget:
|
case SE_SpinTarget:
|
||||||
case SE_Amnesia:
|
case SE_Amnesia:
|
||||||
case SE_Silence:
|
case SE_Silence:
|
||||||
case SE_Destroy:
|
case SE_Destroy:
|
||||||
AggroAmount += default_aggro;
|
aggro_amount += default_aggro;
|
||||||
break;
|
break;
|
||||||
// unsure -- leave them this for now
|
// unsure -- leave them this for now
|
||||||
case SE_Harmony:
|
case SE_Harmony:
|
||||||
@ -1301,7 +1310,7 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc)
|
|||||||
case SE_DamageShield:
|
case SE_DamageShield:
|
||||||
case SE_SpellDamageShield:
|
case SE_SpellDamageShield:
|
||||||
case SE_ReverseDS: {
|
case SE_ReverseDS: {
|
||||||
AggroAmount += slevel * 2;
|
aggro_amount += mob_level * 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// unsure -- leave them this for now
|
// unsure -- leave them this for now
|
||||||
@ -1309,9 +1318,10 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc)
|
|||||||
case SE_ManaRegen_v2:
|
case SE_ManaRegen_v2:
|
||||||
case SE_ManaPool:
|
case SE_ManaPool:
|
||||||
case SE_CurrentEndurance: {
|
case SE_CurrentEndurance: {
|
||||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], slevel, spell_id);
|
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||||
if (val < 0)
|
if (val < 0) {
|
||||||
AggroAmount -= val * 2;
|
aggro_amount -= val * 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_CancelMagic:
|
case SE_CancelMagic:
|
||||||
@ -1321,37 +1331,41 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc)
|
|||||||
break;
|
break;
|
||||||
case SE_ReduceHate:
|
case SE_ReduceHate:
|
||||||
case SE_InstantHate:
|
case SE_InstantHate:
|
||||||
nonModifiedAggro = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], slevel, spell_id);
|
non_modified_aggro = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsBardSong(spell_id) && AggroAmount > 40)
|
if (IsBardSong(spell_id) && aggro_amount > RuleI(Aggro, BardAggroCap)) {
|
||||||
AggroAmount = 40; // bard songs seem to cap to 40 for most of their spells?
|
aggro_amount = RuleI(Aggro, BardAggroCap);
|
||||||
|
}
|
||||||
|
|
||||||
if (dispel && target && target->GetHateAmount(this) < 100)
|
if (dispel && target && target->GetHateAmount(this) < 100) {
|
||||||
AggroAmount += 50;
|
aggro_amount += 50;
|
||||||
|
}
|
||||||
|
|
||||||
if (spells[spell_id].hate_added != 0) // overrides the hate (ex. tash), can be negative.
|
if (spells[spell_id].hate_added != 0) { // overrides the hate (ex. tash), can be negative.
|
||||||
AggroAmount = spells[spell_id].hate_added;
|
aggro_amount = spells[spell_id].hate_added;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetOwner() && IsPet() && AggroAmount > 0)
|
if (GetOwner() && IsPet() && aggro_amount > 0) {
|
||||||
AggroAmount = AggroAmount * RuleI(Aggro, PetSpellAggroMod) / 100;
|
aggro_amount = aggro_amount * RuleI(Aggro, PetSpellAggroMod) / 100;
|
||||||
|
}
|
||||||
|
|
||||||
// hate focus ignored on first action for some reason
|
// hate focus ignored on first action for some reason
|
||||||
if (!on_hatelist && AggroAmount > 0) {
|
if (!on_hatelist && aggro_amount > 0) {
|
||||||
int HateMod = RuleI(Aggro, SpellAggroMod);
|
int HateMod = RuleI(Aggro, SpellAggroMod);
|
||||||
HateMod += GetFocusEffect(focusSpellHateMod, spell_id);
|
HateMod += GetFocusEffect(focusSpellHateMod, spell_id);
|
||||||
|
aggro_amount = (aggro_amount * HateMod) / 100;
|
||||||
AggroAmount = (AggroAmount * HateMod) / 100;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// initial aggro gets a bonus 100 besides for dispel or hate override
|
// initial aggro gets a bonus 100 besides for dispel or hate override
|
||||||
// We add this 100 in AddToHateList so we need to account for the oddities here
|
// We add this 100 in AddToHateList so we need to account for the oddities here
|
||||||
if (dispel && spells[spell_id].hate_added > 0 && !on_hatelist)
|
if (dispel && spells[spell_id].hate_added > 0 && !on_hatelist) {
|
||||||
AggroAmount -= 100;
|
aggro_amount -= 100;
|
||||||
|
}
|
||||||
|
|
||||||
return AggroAmount + spells[spell_id].bonus_hate + nonModifiedAggro;
|
return aggro_amount + spells[spell_id].bonus_hate + non_modified_aggro;
|
||||||
}
|
}
|
||||||
|
|
||||||
//healing and buffing aggro
|
//healing and buffing aggro
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user