diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 9ace76873..b2dbc8175 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1660,6 +1660,7 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { sp[tempid].directional_end = static_cast(atoi(row[195])); sp[tempid].sneak = atoi(row[196]) != 0; sp[tempid].not_focusable = atoi(row[197]) != 0; + sp[tempid].no_detrimental_spell_aggro = atoi(row[198]) != 0; sp[tempid].suspendable = atoi(row[200]) != 0; sp[tempid].viral_range = atoi(row[201]); sp[tempid].songcap = atoi(row[202]); diff --git a/common/spdat.cpp b/common/spdat.cpp index bb6097566..02803b173 100644 --- a/common/spdat.cpp +++ b/common/spdat.cpp @@ -1092,6 +1092,14 @@ bool DetrimentalSpellAllowsRest(uint16 spell_id) return false; } +bool NoDetrimentalSpellAggro(uint16 spell_id) +{ + if (IsValidSpell(spell_id)) + return spells[spell_id].no_detrimental_spell_aggro; + + return false; +} + uint32 GetNimbusEffect(uint16 spell_id) { if (IsValidSpell(spell_id)) diff --git a/common/spdat.h b/common/spdat.h index 76515ae42..b70be171a 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -745,7 +745,8 @@ struct SPDat_Spell_Struct /* 195 */ float directional_end; // Cone End Angle: /* 196 */ bool sneak; // effect can only be used if sneaking (rogue 'Daggerfall' ect) /* 197 */ bool not_focusable; //prevents focus effects from being applied to spell -/* 198- 199 */ +/* 198 */ bool no_detrimental_spell_aggro; +/* 199 */ /* 200 */ bool suspendable; // buff is suspended in suspended buff zones /* 201 */ int viral_range; /* 202 */ int songcap; // individual song cap @@ -764,7 +765,7 @@ struct SPDat_Spell_Struct /* 215 - 216 */ /* 217 */ int override_crit_chance; //Places a cap on the max chance to critical /* 218 */ int aemaxtargets; //Is used for various AE effects -/* 219 */ int no_heal_damage_item_mod; //Is used for beam and ring spells for target # limits (not implemented) +/* 219 */ int no_heal_damage_item_mod; /* 220 - 223 */ /* 224 */ bool persistdeath; // buff doesn't get stripped on death /* 225 - 226 */ @@ -880,6 +881,7 @@ uint32 GetPartialMeleeRuneReduction(uint32 spell_id); uint32 GetPartialMagicRuneReduction(uint32 spell_id); uint32 GetPartialMeleeRuneAmount(uint32 spell_id); uint32 GetPartialMagicRuneAmount(uint32 spell_id); +bool NoDetrimentalSpellAggro(uint16 spell_id); int CalcPetHp(int levelb, int classb, int STA = 75); const char *GetRandPetName(); diff --git a/zone/aggro.cpp b/zone/aggro.cpp index 09f173ac5..574ac335d 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -960,6 +960,9 @@ bool Mob::CheckLosFN(float posX, float posY, float posZ, float mobSize) { //offensive spell aggro int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc) { + if (NoDetrimentalSpellAggro(spell_id)) + return 0; + int32 AggroAmount = 0; int32 nonModifiedAggro = 0; uint16 slevel = GetLevel(); diff --git a/zone/attack.cpp b/zone/attack.cpp index 7a62aaff4..3089aa573 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2410,7 +2410,7 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack return true; } -void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, bool iYellForHelp /*= true*/, bool bFrenzy /*= false*/, bool iBuffTic /*= false*/) +void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, bool iYellForHelp /*= true*/, bool bFrenzy /*= false*/, bool iBuffTic /*= false*/, uint16 spell_id) { if(!other) return; @@ -2466,6 +2466,9 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b if(IsFamiliar() || GetSpecialAbility(IMMUNE_AGGRO)) return; + if (spell_id != SPELL_UNKNOWN && NoDetrimentalSpellAggro(spell_id)) + return; + if (other == myowner) return; @@ -3139,15 +3142,15 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons if(!RuleB(Combat, EXPFromDmgShield)) { // Damage shield damage shouldn't count towards who gets EXP if(!attacker->CastToClient()->GetFeigned() && !FromDamageShield) - AddToHateList(attacker, 0, damage, true, false, iBuffTic); + AddToHateList(attacker, 0, damage, true, false, iBuffTic, spell_id); } else { if(!attacker->CastToClient()->GetFeigned()) - AddToHateList(attacker, 0, damage, true, false, iBuffTic); + AddToHateList(attacker, 0, damage, true, false, iBuffTic, spell_id); } } else - AddToHateList(attacker, 0, damage, true, false, iBuffTic); + AddToHateList(attacker, 0, damage, true, false, iBuffTic, spell_id); } if(damage > 0) { @@ -3172,7 +3175,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons { if (!pet->IsHeld()) { Log.Out(Logs::Detail, Logs::Aggro, "Sending pet %s into battle due to attack.", pet->GetName()); - pet->AddToHateList(attacker, 1); + pet->AddToHateList(attacker, 1,0, true, false, false, spell_id); pet->SetTarget(attacker); Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName()); } diff --git a/zone/mob.h b/zone/mob.h index 651065296..e48eda680 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -489,7 +489,7 @@ public: inline uint32 GetLevelCon(uint8 iOtherLevel) const { return this ? GetLevelCon(GetLevel(), iOtherLevel) : CON_GREEN; } virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true, - bool bFrenzy = false, bool iBuffTic = false); + bool bFrenzy = false, bool iBuffTic = false, uint16 spell_id = SPELL_UNKNOWN); bool RemoveFromHateList(Mob* mob); void SetHateAmountOnEnt(Mob* other, int32 hate = 0, int32 damage = 0) { hate_list.SetHateAmountOnEnt(other,hate,damage);} void HalveAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHateAmountOnEnt(other, (in_hate > 1 ? in_hate / 2 : 1)); } diff --git a/zone/spells.cpp b/zone/spells.cpp index 6967598d0..ce45b6d83 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -4067,7 +4067,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(aggro > 0) { AddToHateList(caster, aggro); } else { - AddToHateList(caster, 1); + AddToHateList(caster, 1,0,true,false,false,spell_id); } return true; } @@ -4094,7 +4094,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(aggro > 0) { AddToHateList(caster, aggro); } else { - AddToHateList(caster, 1); + AddToHateList(caster, 1,0,true,false,false,spell_id); } return true; } @@ -4110,7 +4110,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(aggro > 0) { AddToHateList(caster, aggro); } else { - AddToHateList(caster, 1); + AddToHateList(caster, 1,0,true,false,false,spell_id); } return true; } else if(IsClient() && caster->IsClient() && (caster->CastToClient()->GetGM() == false)) @@ -4127,7 +4127,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if (aggro > 0) { AddToHateList(caster, aggro); } else { - AddToHateList(caster, 1); + AddToHateList(caster, 1,0,true,false,false,spell_id); } return true; } @@ -4150,7 +4150,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(aggro > 0) { AddToHateList(caster, aggro); } else { - AddToHateList(caster, 1); + AddToHateList(caster, 1,0,true,false,false,spell_id); } return true; } @@ -4190,7 +4190,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(aggro > 0) { AddToHateList(caster, aggro); } else { - AddToHateList(caster, 1); + AddToHateList(caster, 1,0,true,false,false,spell_id); } return true; }