[Spells] Added constant labeling to all StatBonuses that use as arrays. (#1485)

* constexpr labels added

* more updates

* more updates

* completed

* Update common.h

* Namespace constants, few minor spelling tweaks

Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
KayenEQ 2021-08-01 14:13:14 -04:00 committed by GitHub
parent 72056ffba3
commit 38beb804a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 554 additions and 500 deletions

View File

@ -87,7 +87,7 @@ EQ::skills::SkillType Mob::AttackAnimation(int Hand, const EQ::ItemInstance* wea
break;
case EQ::item::ItemType2HBlunt: // 2H Blunt
skillinuse = EQ::skills::Skill2HBlunt;
type = RuleB(Combat, Classic2HBAnimation) ? anim2HWeapon : anim2HSlashing;
type = RuleB(Combat, Classic2HBAnimation) ? anim2HWeapon : anim2HSlashing;
break;
case EQ::item::ItemType2HPiercing: // 2H Piercing
if (IsClient() && CastToClient()->ClientVersion() < EQ::versions::ClientVersion::RoF2)
@ -265,7 +265,7 @@ int Mob::GetTotalDefense()
auto evasion_bonus = spellbonuses.AvoidMeleeChanceEffect; // we check this first since it has a special case
if (evasion_bonus >= 10000)
return -1;
// 515 SE_AC_Avoidance_Max_Percent
auto ac_aviodance_bonus = itembonuses.AC_Avoidance_Max_Percent + aabonuses.AC_Avoidance_Max_Percent + spellbonuses.AC_Avoidance_Max_Percent;
if (ac_aviodance_bonus)
@ -870,7 +870,7 @@ int Mob::GetBestMeleeSkill()
{ EQ::skills::Skill1HBlunt,
EQ::skills::Skill1HSlashing,
EQ::skills::Skill2HBlunt,
EQ::skills::Skill2HSlashing,
EQ::skills::Skill2HSlashing,
EQ::skills::SkillHandtoHand,
EQ::skills::Skill1HPiercing,
EQ::skills::Skill2HPiercing,
@ -1547,12 +1547,12 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
///////////////////////////////////////////////////////////
////// Send Attack Damage
///////////////////////////////////////////////////////////
if (my_hit.damage_done > 0 && aabonuses.SkillAttackProc[0] && aabonuses.SkillAttackProc[1] == my_hit.skill &&
IsValidSpell(aabonuses.SkillAttackProc[2])) {
float chance = aabonuses.SkillAttackProc[0] / 1000.0f;
if (my_hit.damage_done > 0 && aabonuses.SkillAttackProc[SBIndex::SKILLPROC_CHANCE] && aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SKILL] == my_hit.skill &&
IsValidSpell(aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SPELL_ID])) {
float chance = aabonuses.SkillAttackProc[SBIndex::SKILLPROC_CHANCE] / 1000.0f;
if (zone->random.Roll(chance))
SpellFinished(aabonuses.SkillAttackProc[2], other, EQ::spells::CastingSlot::Item, 0, -1,
spells[aabonuses.SkillAttackProc[2]].ResistDiff);
SpellFinished(aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SPELL_ID], other, EQ::spells::CastingSlot::Item, 0, -1,
spells[aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SPELL_ID]].ResistDiff);
}
other->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, my_hit.skill, true, -1, false, m_specialattacks);
@ -2746,9 +2746,9 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
if (damage > GetHP())
damage = GetHP();
if (spellbonuses.ImprovedTaunt[1] && (GetLevel() < spellbonuses.ImprovedTaunt[0])
&& other && (buffs[spellbonuses.ImprovedTaunt[2]].casterid != other->GetID()))
hate = (hate*spellbonuses.ImprovedTaunt[1]) / 100;
if (spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_AGGRO_MOD] && (GetLevel() < spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_MAX_LVL])
&& other && (buffs[spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_BUFFSLOT]].casterid != other->GetID()))
hate = (hate*spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_AGGRO_MOD]) / 100;
hate_list.AddEntToHateList(other, hate, damage, bFrenzy, !iBuffTic);
@ -2806,7 +2806,7 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
// owner must get on list, but he's not actually gained any hate yet
if (
!owner->GetSpecialAbility(IMMUNE_AGGRO) &&
!(this->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && owner->IsClient()) &&
!(this->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && owner->IsClient()) &&
!(this->GetSpecialAbility(IMMUNE_AGGRO_NPC) && owner->IsNPC())
) {
if (owner->IsClient() && !CheckAggro(owner))
@ -2818,9 +2818,9 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
if (mypet && !mypet->IsHeld() && !mypet->IsPetStop()) { // I have a pet, add other to it
if (
!mypet->IsFamiliar() &&
!mypet->IsFamiliar() &&
!mypet->GetSpecialAbility(IMMUNE_AGGRO) &&
!(mypet->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && this->IsClient()) &&
!(mypet->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && this->IsClient()) &&
!(mypet->GetSpecialAbility(IMMUNE_AGGRO_NPC) && this->IsNPC())
) {
mypet->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
@ -2828,9 +2828,9 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
}
else if (myowner) { // I am a pet, add other to owner if it's NPC/LD
if (
myowner->IsAIControlled() &&
myowner->IsAIControlled() &&
!myowner->GetSpecialAbility(IMMUNE_AGGRO) &&
!(this->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && myowner->IsClient()) &&
!(this->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && myowner->IsClient()) &&
!(this->GetSpecialAbility(IMMUNE_AGGRO_NPC) && myowner->IsNPC())
) {
myowner->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
@ -2907,7 +2907,7 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) {
int ds_mitigation = attacker->itembonuses.DSMitigation;
// Subtract mitigations because DS_Mitigation_Percentage is a negative value when reducing total, thus final value will be positive
ds_mitigation -= attacker->aabonuses.DS_Mitigation_Percentage + attacker->itembonuses.DS_Mitigation_Percentage + attacker->spellbonuses.DS_Mitigation_Percentage; //Negative value to reduce
DS -= DS * ds_mitigation / 100;
}
attacker->Damage(this, -DS, spellid, EQ::skills::SkillAbjuration/*hackish*/, false);
@ -3122,8 +3122,8 @@ int32 Mob::ReduceDamage(int32 damage)
int32 slot = -1;
bool DisableMeleeRune = false;
if (spellbonuses.NegateAttacks[0]) {
slot = spellbonuses.NegateAttacks[1];
if (spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_EXISTS]) {
slot = spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_BUFFSLOT];
if (slot >= 0) {
if (--buffs[slot].numhits == 0) {
@ -3131,21 +3131,21 @@ int32 Mob::ReduceDamage(int32 damage)
BuffFadeBySlot(slot, true);
}
if (spellbonuses.NegateAttacks[2] && (damage > spellbonuses.NegateAttacks[2]))
damage -= spellbonuses.NegateAttacks[2];
if (spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT] && (damage > spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT]))
damage -= spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT];
else
return DMG_RUNE;
}
}
//Only mitigate if damage is above the minimium specified.
if (spellbonuses.MeleeThresholdGuard[0]) {
slot = spellbonuses.MeleeThresholdGuard[1];
if (spellbonuses.MeleeThresholdGuard[SBIndex::THRESHOLDGUARD_MITIGATION_PERCENT]) {
slot = spellbonuses.MeleeThresholdGuard[SBIndex::THRESHOLDGUARD_BUFFSLOT];
if (slot >= 0 && (damage > spellbonuses.MeleeThresholdGuard[2]))
if (slot >= 0 && (damage > spellbonuses.MeleeThresholdGuard[SBIndex::THRESHOLDGUARD_MIN_DMG_TO_TRIGGER]))
{
DisableMeleeRune = true;
int damage_to_reduce = damage * spellbonuses.MeleeThresholdGuard[0] / 100;
int damage_to_reduce = damage * spellbonuses.MeleeThresholdGuard[SBIndex::THRESHOLDGUARD_MITIGATION_PERCENT] / 100;
if (damage_to_reduce >= buffs[slot].melee_rune)
{
LogSpells("Mob::ReduceDamage SE_MeleeThresholdGuard [{}] damage negated, [{}] damage remaining, fading buff", damage_to_reduce, buffs[slot].melee_rune);
@ -3162,16 +3162,16 @@ int32 Mob::ReduceDamage(int32 damage)
}
}
if (spellbonuses.MitigateMeleeRune[0] && !DisableMeleeRune) {
slot = spellbonuses.MitigateMeleeRune[1];
if (spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_PERCENT] && !DisableMeleeRune) {
slot = spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_BUFFSLOT];
if (slot >= 0)
{
int damage_to_reduce = damage * spellbonuses.MitigateMeleeRune[0] / 100;
int damage_to_reduce = damage * spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_PERCENT] / 100;
if (spellbonuses.MitigateMeleeRune[2] && (damage_to_reduce > spellbonuses.MitigateMeleeRune[2]))
damage_to_reduce = spellbonuses.MitigateMeleeRune[2];
if (spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_MAX_DMG_ABSORB_PER_HIT] && (damage_to_reduce > spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_MAX_DMG_ABSORB_PER_HIT]))
damage_to_reduce = spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_MAX_DMG_ABSORB_PER_HIT];
if (spellbonuses.MitigateMeleeRune[3] && (damage_to_reduce >= buffs[slot].melee_rune))
if (spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_MAX_HP_AMT] && (damage_to_reduce >= buffs[slot].melee_rune))
{
LogSpells("Mob::ReduceDamage SE_MitigateMeleeDamage [{}] damage negated, [{}] damage remaining, fading buff", damage_to_reduce, buffs[slot].melee_rune);
damage -= buffs[slot].melee_rune;
@ -3182,7 +3182,7 @@ int32 Mob::ReduceDamage(int32 damage)
{
LogSpells("Mob::ReduceDamage SE_MitigateMeleeDamage [{}] damage negated, [{}] damage remaining", damage_to_reduce, buffs[slot].melee_rune);
if (spellbonuses.MitigateMeleeRune[3])
if (spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_MAX_HP_AMT])
buffs[slot].melee_rune = (buffs[slot].melee_rune - damage_to_reduce);
damage -= damage_to_reduce;
@ -3193,7 +3193,7 @@ int32 Mob::ReduceDamage(int32 damage)
if (damage < 1)
return DMG_RUNE;
if (spellbonuses.MeleeRune[0] && spellbonuses.MeleeRune[1] >= 0)
if (spellbonuses.MeleeRune[SBIndex::RUNE_AMOUNT] && spellbonuses.MeleeRune[SBIndex::POSITIONAL_DAMAGE_MOD] >= 0)
damage = RuneAbsorb(damage, SE_Rune);
if (damage < 1)
@ -3211,8 +3211,8 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
int32 slot = -1;
// See if we block the spell outright first
if (!iBuffTic && spellbonuses.NegateAttacks[0]) {
slot = spellbonuses.NegateAttacks[1];
if (!iBuffTic && spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_EXISTS]) {
slot = spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_BUFFSLOT];
if (slot >= 0) {
if (--buffs[slot].numhits == 0) {
@ -3220,8 +3220,8 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
BuffFadeBySlot(slot, true);
}
if (spellbonuses.NegateAttacks[2] && (damage > spellbonuses.NegateAttacks[2]))
damage -= spellbonuses.NegateAttacks[2];
if (spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT] && (damage > spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT]))
damage -= spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT];
else
return 0;
}
@ -3231,16 +3231,16 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
if (iBuffTic) {
damage -= (damage * itembonuses.DoTShielding / 100);
if (spellbonuses.MitigateDotRune[0]) {
slot = spellbonuses.MitigateDotRune[1];
if (spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_PERCENT]) {
slot = spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_BUFFSLOT];
if (slot >= 0)
{
int damage_to_reduce = damage * spellbonuses.MitigateDotRune[0] / 100;
int damage_to_reduce = damage * spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_PERCENT] / 100;
if (spellbonuses.MitigateDotRune[2] && (damage_to_reduce > spellbonuses.MitigateDotRune[2]))
damage_to_reduce = spellbonuses.MitigateDotRune[2];
if (spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_MAX_DMG_ABSORB_PER_HIT] && (damage_to_reduce > spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_MAX_DMG_ABSORB_PER_HIT]))
damage_to_reduce = spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_MAX_DMG_ABSORB_PER_HIT];
if (spellbonuses.MitigateDotRune[3] && (damage_to_reduce >= buffs[slot].dot_rune))
if (spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_MAX_HP_AMT] && (damage_to_reduce >= buffs[slot].dot_rune))
{
damage -= buffs[slot].dot_rune;
if (!TryFadeEffect(slot))
@ -3248,7 +3248,7 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
}
else
{
if (spellbonuses.MitigateDotRune[3])
if (spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_MAX_HP_AMT])
buffs[slot].dot_rune = (buffs[slot].dot_rune - damage_to_reduce);
damage -= damage_to_reduce;
@ -3264,13 +3264,13 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
damage -= (damage * itembonuses.SpellShield / 100);
//Only mitigate if damage is above the minimium specified.
if (spellbonuses.SpellThresholdGuard[0]) {
slot = spellbonuses.SpellThresholdGuard[1];
if (spellbonuses.SpellThresholdGuard[SBIndex::THRESHOLDGUARD_MITIGATION_PERCENT]) {
slot = spellbonuses.SpellThresholdGuard[SBIndex::THRESHOLDGUARD_BUFFSLOT];
if (slot >= 0 && (damage > spellbonuses.MeleeThresholdGuard[2]))
if (slot >= 0 && (damage > spellbonuses.MeleeThresholdGuard[SBIndex::THRESHOLDGUARD_MIN_DMG_TO_TRIGGER]))
{
DisableSpellRune = true;
int damage_to_reduce = damage * spellbonuses.SpellThresholdGuard[0] / 100;
int damage_to_reduce = damage * spellbonuses.SpellThresholdGuard[SBIndex::THRESHOLDGUARD_MITIGATION_PERCENT] / 100;
if (damage_to_reduce >= buffs[slot].magic_rune)
{
damage -= buffs[slot].magic_rune;
@ -3286,16 +3286,16 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
}
// Do runes now.
if (spellbonuses.MitigateSpellRune[0] && !DisableSpellRune) {
slot = spellbonuses.MitigateSpellRune[1];
if (spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_PERCENT] && !DisableSpellRune) {
slot = spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_BUFFSLOT];
if (slot >= 0)
{
int damage_to_reduce = damage * spellbonuses.MitigateSpellRune[0] / 100;
int damage_to_reduce = damage * spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_PERCENT] / 100;
if (spellbonuses.MitigateSpellRune[2] && (damage_to_reduce > spellbonuses.MitigateSpellRune[2]))
damage_to_reduce = spellbonuses.MitigateSpellRune[2];
if (spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_MAX_DMG_ABSORB_PER_HIT] && (damage_to_reduce > spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_MAX_DMG_ABSORB_PER_HIT]))
damage_to_reduce = spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_MAX_DMG_ABSORB_PER_HIT];
if (spellbonuses.MitigateSpellRune[3] && (damage_to_reduce >= buffs[slot].magic_rune))
if (spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_MAX_HP_AMT] && (damage_to_reduce >= buffs[slot].magic_rune))
{
LogSpells("Mob::ReduceDamage SE_MitigateSpellDamage [{}] damage negated, [{}] damage remaining, fading buff", damage_to_reduce, buffs[slot].magic_rune);
damage -= buffs[slot].magic_rune;
@ -3306,7 +3306,7 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
{
LogSpells("Mob::ReduceDamage SE_MitigateMeleeDamage [{}] damage negated, [{}] damage remaining", damage_to_reduce, buffs[slot].magic_rune);
if (spellbonuses.MitigateSpellRune[3])
if (spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_MAX_HP_AMT])
buffs[slot].magic_rune = (buffs[slot].magic_rune - damage_to_reduce);
damage -= damage_to_reduce;
@ -3318,10 +3318,10 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
return 0;
//Regular runes absorb spell damage (except dots) - Confirmed on live.
if (spellbonuses.MeleeRune[0] && spellbonuses.MeleeRune[1] >= 0)
if (spellbonuses.MeleeRune[SBIndex::RUNE_AMOUNT] && spellbonuses.MeleeRune[SBIndex::POSITIONAL_DAMAGE_MOD] >= 0)
damage = RuneAbsorb(damage, SE_Rune);
if (spellbonuses.AbsorbMagicAtt[0] && spellbonuses.AbsorbMagicAtt[1] >= 0)
if (spellbonuses.AbsorbMagicAtt[SBIndex::RUNE_AMOUNT] && spellbonuses.AbsorbMagicAtt[SBIndex::POSITIONAL_DAMAGE_MOD] >= 0)
damage = RuneAbsorb(damage, SE_AbsorbMagicAtt);
if (damage < 1)
@ -3344,9 +3344,9 @@ int32 Mob::ReduceAllDamage(int32 damage)
}
}
if (spellbonuses.EnduranceAbsorbPercentDamage[0]) {
int32 damage_reduced = damage * spellbonuses.EnduranceAbsorbPercentDamage[0] / 10000; //If hit for 1000, at 10% then lower damage by 100;
int32 endurance_drain = damage_reduced * spellbonuses.EnduranceAbsorbPercentDamage[1] / 10000; //Reduce endurance by 0.05% per HP loss
if (spellbonuses.EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_MITIGIATION]) {
int32 damage_reduced = damage * spellbonuses.EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_MITIGIATION] / 10000; //If hit for 1000, at 10% then lower damage by 100;
int32 endurance_drain = damage_reduced * spellbonuses.EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_DRAIN_PER_HP] / 10000; //Reduce endurance by 0.05% per HP loss
if (endurance_drain < 1)
endurance_drain = 1;
@ -3529,7 +3529,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
// emote goes with every one ... even npcs
entity_list.MessageClose(this, true, RuleI(Range, SpellMessages), Chat::Emote, "%s beams a smile at %s", attacker->GetCleanName(), this->GetCleanName());
}
// If a client pet is damaged while sitting, stand, fix sit button,
// and remove sitting regen. Removes bug where client clicks sit
// during battle and gains pet hp-regen and bugs the sit button.
@ -3542,7 +3542,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
// fix GUI sit button to be unpressed and stop sitting regen
owner->CastToClient()->SetPetCommandState(PET_BUTTON_SIT, 0);
SetAppearance(eaStanding);
}
}
}
} //end `if there is some damage being done and theres anattacker person involved`
@ -3552,16 +3552,16 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
// pets that have Hold and no Focus will add NPCs if they're engaged
// pets that have Hold and Focus will not add NPCs
if (
pet &&
!pet->IsFamiliar() &&
!pet->GetSpecialAbility(IMMUNE_AGGRO) &&
!pet->IsEngaged() &&
attacker &&
!(pet->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && attacker->IsClient()) &&
!(pet->GetSpecialAbility(IMMUNE_AGGRO_NPC) && attacker->IsNPC()) &&
attacker != this &&
!attacker->IsCorpse() &&
!pet->IsGHeld() &&
pet &&
!pet->IsFamiliar() &&
!pet->GetSpecialAbility(IMMUNE_AGGRO) &&
!pet->IsEngaged() &&
attacker &&
!(pet->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && attacker->IsClient()) &&
!(pet->GetSpecialAbility(IMMUNE_AGGRO_NPC) && attacker->IsNPC()) &&
attacker != this &&
!attacker->IsCorpse() &&
!pet->IsGHeld() &&
!attacker->IsTrap()
) {
if (!pet->IsHeld()) {
@ -4384,12 +4384,12 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *
// 1: Try Slay Undead
if (defender->GetBodyType() == BT_Undead || defender->GetBodyType() == BT_SummonedUndead ||
defender->GetBodyType() == BT_Vampire) {
int SlayRateBonus = aabonuses.SlayUndead[0] + itembonuses.SlayUndead[0] + spellbonuses.SlayUndead[0];
int SlayRateBonus = aabonuses.SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] + itembonuses.SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] + spellbonuses.SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD];
if (SlayRateBonus) {
float slayChance = static_cast<float>(SlayRateBonus) / 10000.0f;
if (zone->random.Roll(slayChance)) {
int SlayDmgBonus = std::max(
{ aabonuses.SlayUndead[1], itembonuses.SlayUndead[1], spellbonuses.SlayUndead[1] });
{aabonuses.SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD], itembonuses.SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD], spellbonuses.SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] });
hit.damage_done = std::max(hit.damage_done, hit.base_damage) + 5;
hit.damage_done = (hit.damage_done * SlayDmgBonus) / 100;
@ -4560,18 +4560,18 @@ bool Mob::TryFinishingBlow(Mob *defender, int &damage)
if (defender && !defender->IsClient() && defender->GetHPRatio() < 10) {
uint32 FB_Dmg =
aabonuses.FinishingBlow[1] + spellbonuses.FinishingBlow[1] + itembonuses.FinishingBlow[1];
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] + spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] + itembonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG];
uint32 FB_Level = 0;
FB_Level = aabonuses.FinishingBlowLvl[0];
if (FB_Level < spellbonuses.FinishingBlowLvl[0])
FB_Level = spellbonuses.FinishingBlowLvl[0];
else if (FB_Level < itembonuses.FinishingBlowLvl[0])
FB_Level = itembonuses.FinishingBlowLvl[0];
FB_Level = aabonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX];
if (FB_Level < spellbonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX])
FB_Level = spellbonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX];
else if (FB_Level < itembonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX])
FB_Level = itembonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX];
// modern AA description says rank 1 (500) is 50% chance
int ProcChance =
aabonuses.FinishingBlow[0] + spellbonuses.FinishingBlow[0] + spellbonuses.FinishingBlow[0];
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] + spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] + spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE];
if (FB_Level && FB_Dmg && (defender->GetLevel() <= FB_Level) &&
(ProcChance >= zone->random.Int(1, 1000))) {
@ -4622,8 +4622,8 @@ void Mob::DoRiposte(Mob *defender)
return;
}
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[0] + defender->spellbonuses.GiveDoubleRiposte[0] +
defender->itembonuses.GiveDoubleRiposte[0];
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[SBIndex::DOUBLE_RIPOSTE_CHANCE] + defender->spellbonuses.GiveDoubleRiposte[SBIndex::DOUBLE_RIPOSTE_CHANCE] +
defender->itembonuses.GiveDoubleRiposte[SBIndex::DOUBLE_RIPOSTE_CHANCE];
// Live AA - Double Riposte
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
@ -4636,15 +4636,15 @@ void Mob::DoRiposte(Mob *defender)
// Double Riposte effect, allows for a chance to do RIPOSTE with a skill specific special attack (ie Return Kick).
// Coded narrowly: Limit to one per client. Limit AA only. [1 = Skill Attack Chance, 2 = Skill]
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[1];
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[SBIndex::DOUBLE_RIPOSTE_SKILL_ATK_CHANCE];
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
LogCombat("Preforming a return SPECIAL ATTACK ([{}] percent chance)", DoubleRipChance);
if (defender->GetClass() == MONK)
defender->MonkSpecialAttack(this, defender->aabonuses.GiveDoubleRiposte[2]);
defender->MonkSpecialAttack(this, defender->aabonuses.GiveDoubleRiposte[SBIndex::DOUBLE_RIPOSTE_SKILL]);
else if (defender->IsClient()) // so yeah, even if you don't have the skill you can still do the attack :P (and we don't crash anymore)
defender->CastToClient()->DoClassAttacks(this, defender->aabonuses.GiveDoubleRiposte[2], true);
defender->CastToClient()->DoClassAttacks(this, defender->aabonuses.GiveDoubleRiposte[SBIndex::DOUBLE_RIPOSTE_SKILL], true);
}
}
@ -5067,13 +5067,13 @@ bool Mob::TryRootFadeByDamage(int buffslot, Mob* attacker) {
- Root break chance values obtained from live parses.
*/
if (!attacker || !spellbonuses.Root[0] || spellbonuses.Root[1] < 0)
if (!attacker || !spellbonuses.Root[SBIndex::ROOT_EXISTS] || spellbonuses.Root[SBIndex::ROOT_BUFFSLOT] < 0)
return false;
if (IsDetrimentalSpell(spellbonuses.Root[1]) && spellbonuses.Root[1] != buffslot) {
if (IsDetrimentalSpell(spellbonuses.Root[SBIndex::ROOT_BUFFSLOT]) && spellbonuses.Root[SBIndex::ROOT_BUFFSLOT] != buffslot) {
int BreakChance = RuleI(Spells, RootBreakFromSpells);
BreakChance -= BreakChance*buffs[spellbonuses.Root[1]].RootBreakChance / 100;
BreakChance -= BreakChance * buffs[spellbonuses.Root[SBIndex::ROOT_BUFFSLOT]].RootBreakChance / 100;
int level_diff = attacker->GetLevel() - GetLevel();
//Use baseline if level difference <= 1 (ie. If target is (1) level less than you, or equal or greater level)
@ -5092,8 +5092,8 @@ bool Mob::TryRootFadeByDamage(int buffslot, Mob* attacker) {
if (zone->random.Roll(BreakChance)) {
if (!TryFadeEffect(spellbonuses.Root[1])) {
BuffFadeBySlot(spellbonuses.Root[1]);
if (!TryFadeEffect(spellbonuses.Root[SBIndex::ROOT_BUFFSLOT])) {
BuffFadeBySlot(spellbonuses.Root[SBIndex::ROOT_BUFFSLOT]);
LogCombat("Spell broke root! BreakChance percent chance");
return true;
}
@ -5109,7 +5109,7 @@ int32 Mob::RuneAbsorb(int32 damage, uint16 type)
uint32 buff_max = GetMaxTotalSlots();
if (type == SE_Rune) {
for (uint32 slot = 0; slot < buff_max; slot++) {
if (slot == spellbonuses.MeleeRune[1] && spellbonuses.MeleeRune[0] && buffs[slot].melee_rune && IsValidSpell(buffs[slot].spellid)) {
if (slot == spellbonuses.MeleeRune[SBIndex::POSITIONAL_DAMAGE_MOD] && spellbonuses.MeleeRune[SBIndex::RUNE_AMOUNT] && buffs[slot].melee_rune && IsValidSpell(buffs[slot].spellid)) {
int melee_rune_left = buffs[slot].melee_rune;
if (melee_rune_left > damage)
@ -5133,7 +5133,7 @@ int32 Mob::RuneAbsorb(int32 damage, uint16 type)
else {
for (uint32 slot = 0; slot < buff_max; slot++) {
if (slot == spellbonuses.AbsorbMagicAtt[1] && spellbonuses.AbsorbMagicAtt[0] && buffs[slot].magic_rune && IsValidSpell(buffs[slot].spellid)) {
if (slot == spellbonuses.AbsorbMagicAtt[SBIndex::POSITIONAL_DAMAGE_MOD] && spellbonuses.AbsorbMagicAtt[SBIndex::RUNE_AMOUNT] && buffs[slot].magic_rune && IsValidSpell(buffs[slot].spellid)) {
int magic_rune_left = buffs[slot].magic_rune;
if (magic_rune_left > damage)
{
@ -5255,7 +5255,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
spec_mod = mod;
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) {
//SE_PC_Pet_Rampage SPA 464 on pet, damage modifier
int spell_mod = spellbonuses.PC_Pet_Rampage[1] + itembonuses.PC_Pet_Rampage[1] + aabonuses.PC_Pet_Rampage[1];
int spell_mod = spellbonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] + itembonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] + aabonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD];
if (spell_mod > spec_mod)
spec_mod = spell_mod;
}
@ -5266,7 +5266,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
spec_mod = mod;
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) {
//SE_PC_Pet_AE_Rampage SPA 465 on pet, damage modifier
int spell_mod = spellbonuses.PC_Pet_AE_Rampage[1] + itembonuses.PC_Pet_AE_Rampage[1] + aabonuses.PC_Pet_AE_Rampage[1];
int spell_mod = spellbonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] + itembonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] + aabonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD];
if (spell_mod > spec_mod)
spec_mod = spell_mod;
}
@ -5483,24 +5483,24 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell)
CheckIncreaseSkill(EQ::skills::SkillDoubleAttack, target, -10);
if (CheckDoubleAttack()) {
Attack(target, hand, false, false, IsFromSpell);
if (hand == EQ::invslot::slotPrimary) {
if (HasTwoHanderEquipped()) {
auto extraattackchance = aabonuses.ExtraAttackChance[0] + spellbonuses.ExtraAttackChance[0] +
itembonuses.ExtraAttackChance[0];
auto extraattackchance = aabonuses.ExtraAttackChance[SBIndex::EXTRA_ATTACK_CHANCE] + spellbonuses.ExtraAttackChance[SBIndex::EXTRA_ATTACK_CHANCE] +
itembonuses.ExtraAttackChance[SBIndex::EXTRA_ATTACK_CHANCE];
if (extraattackchance && zone->random.Roll(extraattackchance)) {
auto extraattackamt = std::max({ aabonuses.ExtraAttackChance[1], spellbonuses.ExtraAttackChance[1], itembonuses.ExtraAttackChance[1] });
auto extraattackamt = std::max({aabonuses.ExtraAttackChance[SBIndex::EXTRA_ATTACK_NUM_ATKS], spellbonuses.ExtraAttackChance[SBIndex::EXTRA_ATTACK_NUM_ATKS], itembonuses.ExtraAttackChance[SBIndex::EXTRA_ATTACK_NUM_ATKS] });
for (int i = 0; i < extraattackamt; i++) {
Attack(target, hand, false, false, IsFromSpell);
}
}
}
else {
auto extraattackchance_primary = aabonuses.ExtraAttackChancePrimary[0] + spellbonuses.ExtraAttackChancePrimary[0] +
itembonuses.ExtraAttackChancePrimary[0];
auto extraattackchance_primary = aabonuses.ExtraAttackChancePrimary[SBIndex::EXTRA_ATTACK_CHANCE] + spellbonuses.ExtraAttackChancePrimary[SBIndex::EXTRA_ATTACK_CHANCE] +
itembonuses.ExtraAttackChancePrimary[SBIndex::EXTRA_ATTACK_CHANCE];
if (extraattackchance_primary && zone->random.Roll(extraattackchance_primary)) {
auto extraattackamt_primary = std::max({ aabonuses.ExtraAttackChancePrimary[1], spellbonuses.ExtraAttackChancePrimary[1], itembonuses.ExtraAttackChancePrimary[1] });
auto extraattackamt_primary = std::max({aabonuses.ExtraAttackChancePrimary[SBIndex::EXTRA_ATTACK_NUM_ATKS], spellbonuses.ExtraAttackChancePrimary[SBIndex::EXTRA_ATTACK_NUM_ATKS], itembonuses.ExtraAttackChancePrimary[SBIndex::EXTRA_ATTACK_NUM_ATKS] });
for (int i = 0; i < extraattackamt_primary; i++) {
Attack(target, hand, false, false, IsFromSpell);
}
@ -5509,10 +5509,10 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell)
}
if (hand == EQ::invslot::slotSecondary) {
auto extraattackchance_secondary = aabonuses.ExtraAttackChanceSecondary[0] + spellbonuses.ExtraAttackChanceSecondary[0] +
itembonuses.ExtraAttackChanceSecondary[0];
auto extraattackchance_secondary = aabonuses.ExtraAttackChanceSecondary[SBIndex::EXTRA_ATTACK_CHANCE] + spellbonuses.ExtraAttackChanceSecondary[SBIndex::EXTRA_ATTACK_CHANCE] +
itembonuses.ExtraAttackChanceSecondary[SBIndex::EXTRA_ATTACK_CHANCE];
if (extraattackchance_secondary && zone->random.Roll(extraattackchance_secondary)) {
auto extraattackamt_secondary = std::max({ aabonuses.ExtraAttackChanceSecondary[1], spellbonuses.ExtraAttackChanceSecondary[1], itembonuses.ExtraAttackChanceSecondary[1] });
auto extraattackamt_secondary = std::max({aabonuses.ExtraAttackChanceSecondary[SBIndex::EXTRA_ATTACK_NUM_ATKS], spellbonuses.ExtraAttackChanceSecondary[SBIndex::EXTRA_ATTACK_NUM_ATKS], itembonuses.ExtraAttackChanceSecondary[SBIndex::EXTRA_ATTACK_NUM_ATKS] });
for (int i = 0; i < extraattackamt_secondary; i++) {
Attack(target, hand, false, false, IsFromSpell);
}

File diff suppressed because it is too large Load Diff

View File

@ -328,10 +328,10 @@ int32 Client::CalcMaxHP()
if (current_hp > max_hp) {
current_hp = max_hp;
}
int hp_perc_cap = spellbonuses.HPPercCap[0];
int hp_perc_cap = spellbonuses.HPPercCap[SBIndex::RESOURCE_PERCENT_CAP];
if (hp_perc_cap) {
int curHP_cap = (max_hp * hp_perc_cap) / 100;
if (current_hp > curHP_cap || (spellbonuses.HPPercCap[1] && current_hp > spellbonuses.HPPercCap[1])) {
if (current_hp > curHP_cap || (spellbonuses.HPPercCap[SBIndex::RESOURCE_AMOUNT_CAP] && current_hp > spellbonuses.HPPercCap[SBIndex::RESOURCE_AMOUNT_CAP])) {
current_hp = curHP_cap;
}
@ -591,10 +591,10 @@ int32 Client::CalcMaxMana()
if (current_mana > max_mana) {
current_mana = max_mana;
}
int mana_perc_cap = spellbonuses.ManaPercCap[0];
int mana_perc_cap = spellbonuses.ManaPercCap[SBIndex::RESOURCE_PERCENT_CAP];
if (mana_perc_cap) {
int curMana_cap = (max_mana * mana_perc_cap) / 100;
if (current_mana > curMana_cap || (spellbonuses.ManaPercCap[1] && current_mana > spellbonuses.ManaPercCap[1])) {
if (current_mana > curMana_cap || (spellbonuses.ManaPercCap[SBIndex::RESOURCE_AMOUNT_CAP] && current_mana > spellbonuses.ManaPercCap[SBIndex::RESOURCE_AMOUNT_CAP])) {
current_mana = curMana_cap;
}
}
@ -1614,10 +1614,10 @@ void Client::CalcMaxEndurance()
if (current_endurance > max_end) {
current_endurance = max_end;
}
int end_perc_cap = spellbonuses.EndPercCap[0];
int end_perc_cap = spellbonuses.EndPercCap[SBIndex::RESOURCE_PERCENT_CAP];
if (end_perc_cap) {
int curEnd_cap = (max_end * end_perc_cap) / 100;
if (current_endurance > curEnd_cap || (spellbonuses.EndPercCap[1] && current_endurance > spellbonuses.EndPercCap[1])) {
if (current_endurance > curEnd_cap || (spellbonuses.EndPercCap[SBIndex::RESOURCE_AMOUNT_CAP] && current_endurance > spellbonuses.EndPercCap[SBIndex::RESOURCE_AMOUNT_CAP])) {
current_endurance = curEnd_cap;
}
}

View File

@ -503,8 +503,8 @@ struct StatBonuses {
uint32 MitigateDotRune[4]; // 0 = Mitigation value 1 = Buff Slot 2 = Max mitigation per tick 3 = Rune Amt
bool TriggerMeleeThreshold; // Has Melee Threshhold
bool TriggerSpellThreshold; // Has Spell Threshhold
uint32 ManaAbsorbPercentDamage; // 0 = Mitigation value
int32 EnduranceAbsorbPercentDamage[2]; // 0 = Mitigation value 1 = Percent Endurance drain per HP lost
uint32 ManaAbsorbPercentDamage; // 0 = Mitigation value
int32 EnduranceAbsorbPercentDamage[2]; // 0 = Mitigation value 1 = Percent Endurance drain per HP lost
int32 ShieldBlock; // Chance to Shield Block
int32 BlockBehind; // Chance to Block Behind (with our without shield)
bool CriticalRegenDecay; // increase critical regen chance, decays based on spell level cast
@ -512,7 +512,7 @@ struct StatBonuses {
bool CriticalDotDecay; // increase critical dot chance, decays based on spell level cast
bool DivineAura; // invulnerability
bool DistanceRemoval; // Check if Cancle if Moved effect is present
int32 ImprovedTaunt[3]; // 0 = Max Level 1 = Aggro modifier 2 = buffid
int32 ImprovedTaunt[3]; // 0 = Max Level 1 = Aggro modifier 2 = buff slot
int8 Root[2]; // The lowest buff slot a root can be found. [0] = Bool if has root [1] = buff slot
int32 FrenziedDevastation; // base1= AArank(used) base2= chance increase spell criticals + all DD spells 2x mana.
uint32 AbsorbMagicAtt[2]; // 0 = magic rune value 1 = buff slot
@ -616,6 +616,58 @@ struct StatBonuses {
bool hunger; // Song of Sustenance -- min caps to 3500
};
// StatBonus Indexes
namespace SBIndex {
constexpr uint16 BUFFSTACKER_EXISTS = 0; // SPA 446-449
constexpr uint16 BUFFSTACKER_VALUE = 1; // SPA 446-449
constexpr uint16 EXTRA_ATTACK_CHANCE = 0; // SPA 266,498,499
constexpr uint16 EXTRA_ATTACK_NUM_ATKS = 1; // SPA 266,498,499
constexpr uint16 DIVINE_SAVE_CHANCE = 0; // SPA 232
constexpr uint16 DIVINE_SAVE_SPELL_TRIGGER_ID = 1; // SPA 232
constexpr uint16 DEATH_SAVE_TYPE = 0; // SPA 150
constexpr uint16 DEATH_SAVE_BUFFSLOT = 1; // SPA 150
constexpr uint16 DEATH_SAVE_MIN_LEVEL_FOR_HEAL = 2; // SPA 150
constexpr uint16 DEATH_SAVE_HEAL_AMT = 3; // SPA 150
constexpr uint16 RESOURCE_PERCENT_CAP = 0; // SPA 408-410
constexpr uint16 RESOURCE_AMOUNT_CAP = 1; // SPA 408-419
constexpr uint16 NEGATE_ATK_EXISTS = 0; // SPA 163
constexpr uint16 NEGATE_ATK_BUFFSLOT = 1; // SPA 163
constexpr uint16 NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT = 2; // SPA 163
constexpr uint16 MITIGATION_RUNE_PERCENT = 0; // SPA 161,162,450
constexpr uint16 MITIGATION_RUNE_BUFFSLOT = 1; // SPA 161,162,450
constexpr uint16 MITIGATION_RUNE_MAX_DMG_ABSORB_PER_HIT = 2; // SPA 161,162,450
constexpr uint16 MITIGATION_RUNE_MAX_HP_AMT = 3; // SPA 161,162,450
constexpr uint16 THRESHOLDGUARD_MITIGATION_PERCENT = 0; // SPA 451,452
constexpr uint16 THRESHOLDGUARD_BUFFSLOT = 1; // SPA 451,452
constexpr uint16 THRESHOLDGUARD_MIN_DMG_TO_TRIGGER = 2; // SPA 451,452
constexpr uint16 ENDURANCE_ABSORD_MITIGIATION = 0; // SPA 521
constexpr uint16 ENDURANCE_ABSORD_DRAIN_PER_HP = 1; // SPA 521
constexpr uint16 IMPROVED_TAUNT_MAX_LVL = 0; // SPA 444
constexpr uint16 IMPROVED_TAUNT_AGGRO_MOD = 1; // SPA 444
constexpr uint16 IMPROVED_TAUNT_BUFFSLOT = 2; // SPA 444
constexpr uint16 ROOT_EXISTS = 0; // SPA 99
constexpr uint16 ROOT_BUFFSLOT = 1; // SPA 99
constexpr uint16 RUNE_AMOUNT = 0; // SPA 55
constexpr uint16 RUNE_BUFFSLOT = 1; // SPA 78
constexpr uint16 POSITIONAL_DAMAGE_MOD = 0; // SPA 503-506
constexpr uint16 POSITIONAL_LOCATION = 1; // SPA 503-506
constexpr uint16 PET_RAMPAGE_CHANCE = 0; // SPA 464,465
constexpr uint16 PET_RAMPAGE_DMG_MOD = 1; // SPA 465,465
constexpr uint16 SKILLPROC_CHANCE = 0; // SPA 427
constexpr uint16 SKILLPROC_SKILL = 1; // SPA 427
constexpr uint16 SKILLPROC_SPELL_ID = 2; // SPA 427
constexpr uint16 SLAYUNDEAD_RATE_MOD = 0; // SPA 219
constexpr uint16 SLAYUNDEAD_DMG_MOD = 1; // SPA 219
constexpr uint16 DOUBLE_RIPOSTE_CHANCE = 0; // SPA 223
constexpr uint16 DOUBLE_RIPOSTE_SKILL_ATK_CHANCE = 1; // SPA 223
constexpr uint16 DOUBLE_RIPOSTE_SKILL = 2; // SPA 223
constexpr uint16 FINISHING_EFFECT_PROC_CHANCE = 0; // SPA 278, 439, 217
constexpr uint16 FINISHING_EFFECT_DMG = 1; // SPA 278, 439, 217
constexpr uint16 FINISHING_EFFECT_LEVEL_MAX = 0; // SPA 440, 345, 346
constexpr uint16 FINISHING_EFFECT_LEVEL_CHANCE_BONUS = 1; // SPA 440, 345, 346
};
typedef struct
{
uint16 spellID;

View File

@ -862,10 +862,10 @@ int32 Merc::CalcMaxHP() {
if (current_hp > max_hp)
current_hp = max_hp;
int hp_perc_cap = spellbonuses.HPPercCap[0];
int hp_perc_cap = spellbonuses.HPPercCap[SBIndex::RESOURCE_PERCENT_CAP];
if(hp_perc_cap) {
int curHP_cap = (max_hp * hp_perc_cap) / 100;
if (current_hp > curHP_cap || (spellbonuses.HPPercCap[1] && current_hp > spellbonuses.HPPercCap[1]))
if (current_hp > curHP_cap || (spellbonuses.HPPercCap[SBIndex::RESOURCE_AMOUNT_CAP] && current_hp > spellbonuses.HPPercCap[SBIndex::RESOURCE_AMOUNT_CAP]))
current_hp = curHP_cap;
}
@ -904,10 +904,10 @@ int32 Merc::CalcMaxMana()
current_mana = max_mana;
}
int mana_perc_cap = spellbonuses.ManaPercCap[0];
int mana_perc_cap = spellbonuses.ManaPercCap[SBIndex::RESOURCE_PERCENT_CAP];
if(mana_perc_cap) {
int curMana_cap = (max_mana * mana_perc_cap) / 100;
if (current_mana > curMana_cap || (spellbonuses.ManaPercCap[1] && current_mana > spellbonuses.ManaPercCap[1]))
if (current_mana > curMana_cap || (spellbonuses.ManaPercCap[SBIndex::RESOURCE_AMOUNT_CAP] && current_mana > spellbonuses.ManaPercCap[SBIndex::RESOURCE_AMOUNT_CAP]))
current_mana = curMana_cap;
}
@ -999,10 +999,10 @@ void Merc::CalcMaxEndurance()
cur_end = max_end;
}
int end_perc_cap = spellbonuses.EndPercCap[0];
int end_perc_cap = spellbonuses.EndPercCap[SBIndex::RESOURCE_PERCENT_CAP];
if(end_perc_cap) {
int curEnd_cap = (max_end * end_perc_cap) / 100;
if (cur_end > curEnd_cap || (spellbonuses.EndPercCap[1] && cur_end > spellbonuses.EndPercCap[1]))
if (cur_end > curEnd_cap || (spellbonuses.EndPercCap[SBIndex::RESOURCE_AMOUNT_CAP] && cur_end > spellbonuses.EndPercCap[SBIndex::RESOURCE_AMOUNT_CAP]))
cur_end = curEnd_cap;
}
}
@ -1624,7 +1624,7 @@ void Merc::AI_Process() {
}
}
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance[0] + itembonuses.ExtraAttackChance[0] + aabonuses.ExtraAttackChance[0];
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance[SBIndex::EXTRA_ATTACK_CHANCE] + itembonuses.ExtraAttackChance[SBIndex::EXTRA_ATTACK_CHANCE] + aabonuses.ExtraAttackChance[SBIndex::EXTRA_ATTACK_CHANCE];
if (GetTarget() && ExtraAttackChanceBonus) {
if(zone->random.Roll(ExtraAttackChanceBonus))

View File

@ -3547,9 +3547,9 @@ bool Mob::TrySpellTrigger(Mob *target, uint32 spell_id, int effect)
return false;
/*The effects SE_SpellTrigger (SPA 340) and SE_Chance_Best_in_Spell_Grp (SPA 469) work as follows, you typically will have 2-3 different spells each with their own
chance to be triggered with all chances equaling up to 100 pct, with only 1 spell out of the group being ultimately cast.
(ie Effect1 trigger spellA with 30% chance, Effect2 triggers spellB with 20% chance, Effect3 triggers spellC with 50% chance).
The following function ensures a stastically accurate chance for each spell to be cast based on their chance values. These effects are also used in spells where there
chance to be triggered with all chances equaling up to 100 pct, with only 1 spell out of the group being ultimately cast.
(ie Effect1 trigger spellA with 30% chance, Effect2 triggers spellB with 20% chance, Effect3 triggers spellC with 50% chance).
The following function ensures a stastically accurate chance for each spell to be cast based on their chance values. These effects are also used in spells where there
is only 1 effect using the trigger effect. In those situations we simply roll a chance for that spell to be cast once.
Note: Both SPA 340 and 469 can be in same spell and both cummulative add up to 100 pct chances. SPA469 only difference being the spell cast will
be "best in spell group", instead of a defined spell_id.*/
@ -3558,7 +3558,7 @@ bool Mob::TrySpellTrigger(Mob *target, uint32 spell_id, int effect)
int total_chance = 0;
int effect_slot = effect;
bool CastSpell = false;
for (int i = 0; i < EFFECT_COUNT; i++)
{
if (spells[spell_id].effectid[i] == SE_SpellTrigger || spells[spell_id].effectid[i] == SE_Chance_Best_in_Spell_Grp)
@ -3743,7 +3743,7 @@ void Mob::TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id)
if (!IsValidSpell(spell_id))
return;
/*Apply damage from Lifeburn type effects on caster at end of spell cast.
/*Apply damage from Lifeburn type effects on caster at end of spell cast.
This allows for the AE spells to function without repeatedly killing caster
Damage or heal portion can be found as regular single use spell effect
*/
@ -3766,7 +3766,7 @@ void Mob::TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id)
int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
{
/*
Modifies incoming spell damage by percent, to increase or decrease damage, can be limited to specific resists.
Modifies incoming spell damage by percent, to increase or decrease damage, can be limited to specific resists.
Can be applied through quest function, spell focus or npc_spells_effects table. This function is run on the target of the spell.
*/
@ -3789,7 +3789,7 @@ int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
innate_mod = Vulnerability_Mod[HIGHEST_RESIST+1];
//[Apply spell derived vulnerabilities] Step 1: Check this focus effect exists on the mob.
if (spellbonuses.FocusEffects[focusSpellVulnerability]){
if (spellbonuses.FocusEffects[focusSpellVulnerability]){
int32 tmp_focus = 0;
int tmp_buffslot = -1;
@ -3903,8 +3903,8 @@ int32 Mob::GetPositionalDmgTaken(Mob *attacker)
int back_arc = 0;
int total_mod = 0;
back_arc += itembonuses.Damage_Taken_Position_Mod[0] + aabonuses.Damage_Taken_Position_Mod[0] + spellbonuses.Damage_Taken_Position_Mod[0];
front_arc += itembonuses.Damage_Taken_Position_Mod[1] + aabonuses.Damage_Taken_Position_Mod[1] + spellbonuses.Damage_Taken_Position_Mod[1];
back_arc += itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] + aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] + spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD];
front_arc += itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_LOCATION] + aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_LOCATION] + spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_LOCATION];
if (back_arc || front_arc) { //Do they have this bonus?
if (attacker->BehindMob(this, attacker->GetX(), attacker->GetY()))//Check if attacker is striking from behind
@ -4897,8 +4897,8 @@ int16 Mob::GetMeleeDmgPositionMod(Mob* defender)
int back_arc = 0;
int total_mod = 0;
back_arc += itembonuses.Melee_Damage_Position_Mod[0] + aabonuses.Melee_Damage_Position_Mod[0] + spellbonuses.Melee_Damage_Position_Mod[0];
front_arc += itembonuses.Melee_Damage_Position_Mod[1] + aabonuses.Melee_Damage_Position_Mod[1] + spellbonuses.Melee_Damage_Position_Mod[1];
back_arc += itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] + aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] + spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD];
front_arc += itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_LOCATION] + aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_LOCATION] + spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_LOCATION];
if (back_arc || front_arc) { //Do they have this bonus?
if (BehindMob(defender, GetX(), GetY()))//Check if attacker is striking from behind

View File

@ -1224,12 +1224,12 @@ void Mob::AI_Process() {
//SE_PC_Pet_Rampage SPA 464 on pet, chance modifier
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) {
int chance = spellbonuses.PC_Pet_Rampage[0] + itembonuses.PC_Pet_Rampage[0] + aabonuses.PC_Pet_Rampage[0];
int chance = spellbonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_CHANCE] + itembonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_CHANCE] + aabonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_CHANCE];
if (chance && zone->random.Roll(chance)) {
Rampage(nullptr);
}
}
if (GetSpecialAbility(SPECATK_RAMPAGE) && !specialed) {
int rampage_chance = GetSpecialAbilityParam(SPECATK_RAMPAGE, 0);
@ -1267,7 +1267,7 @@ void Mob::AI_Process() {
//SE_PC_Pet_Rampage SPA 465 on pet, chance modifier
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) {
int chance = spellbonuses.PC_Pet_AE_Rampage[0] + itembonuses.PC_Pet_AE_Rampage[0] + aabonuses.PC_Pet_AE_Rampage[0];
int chance = spellbonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_CHANCE] + itembonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_CHANCE] + aabonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_CHANCE];
if (chance && zone->random.Roll(chance)) {
Rampage(nullptr);
}

View File

@ -193,12 +193,12 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int32 bas
DoAttack(who, my_hit);
who->AddToHateList(this, hate, 0);
if (my_hit.damage_done > 0 && aabonuses.SkillAttackProc[0] && aabonuses.SkillAttackProc[1] == skill &&
IsValidSpell(aabonuses.SkillAttackProc[2])) {
float chance = aabonuses.SkillAttackProc[0] / 1000.0f;
if (my_hit.damage_done > 0 && aabonuses.SkillAttackProc[SBIndex::SKILLPROC_CHANCE] && aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SKILL] == skill &&
IsValidSpell(aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SPELL_ID])) {
float chance = aabonuses.SkillAttackProc[SBIndex::SKILLPROC_CHANCE] / 1000.0f;
if (zone->random.Roll(chance))
SpellFinished(aabonuses.SkillAttackProc[2], who, EQ::spells::CastingSlot::Item, 0, -1,
spells[aabonuses.SkillAttackProc[2]].ResistDiff);
SpellFinished(aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SPELL_ID], who, EQ::spells::CastingSlot::Item, 0, -1,
spells[aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SPELL_ID]].ResistDiff);
}
who->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, skill, false);
@ -996,21 +996,21 @@ void Mob::ProjectileAttack()
disable = false;
Mob *target = entity_list.GetMobID(ProjectileAtk[i].target_id);
if (target && target->IsMoving()) {
if (target && target->IsMoving()) {
/*
Only recalculate hit increment if target is moving.
Due to frequency that we need to check increment the targets position variables may not be
Due to frequency that we need to check increment the targets position variables may not be
updated even if moving. Do a simple check before calculating distance.
*/
if (ProjectileAtk[i].tlast_x != target->GetX() || ProjectileAtk[i].tlast_y != target->GetY()) {
ProjectileAtk[i].tlast_x = target->GetX();
ProjectileAtk[i].tlast_y = target->GetY();
//Recalculate from the original location the projectile was fired in relation to the current targets location.
float distance = target->CalculateDistance(ProjectileAtk[i].origin_x, ProjectileAtk[i].origin_y, ProjectileAtk[i].origin_z);
float distance_mod = 0.0f;
if (distance <= 125.0f) {
distance_mod = (ProjectileAtk[i].speed_mod - 4.0f) * -20.0f;
distance += distance * distance_mod / 100.0f;
@ -1022,14 +1022,14 @@ void Mob::ProjectileAttack()
distance = distance * 1.30f; //Add 30% to base distance if over 200 range to tighten up hit timing.
distance = 3.14f * (distance / 2.0f); //Get distance of arc to better reflect projectile path length
}
float hit = 1200.0f + (10 * distance / ProjectileAtk[i].speed_mod);
ProjectileAtk[i].hit_increment = static_cast<uint16>(hit);
}
}
// Check if we hit.
// Check if we hit.
if (ProjectileAtk[i].hit_increment <= ProjectileAtk[i].increment) {
if (target) {
if (IsNPC()) {
@ -2061,9 +2061,9 @@ int Mob::TryHeadShot(Mob *defender, EQ::skills::SkillType skillInUse)
// Only works on YOUR target.
if (defender && defender->GetBodyType() == BT_Humanoid && !defender->IsClient() &&
skillInUse == EQ::skills::SkillArchery && GetTarget() == defender) {
uint32 HeadShot_Dmg = aabonuses.HeadShot[1] + spellbonuses.HeadShot[1] + itembonuses.HeadShot[1];
uint32 HeadShot_Dmg = aabonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] + spellbonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] + itembonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG];
uint8 HeadShot_Level = 0; // Get Highest Headshot Level
HeadShot_Level = std::max({aabonuses.HSLevel[0], spellbonuses.HSLevel[0], itembonuses.HSLevel[0]});
HeadShot_Level = std::max({aabonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX], spellbonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX], itembonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX]});
if (HeadShot_Dmg && HeadShot_Level && (defender->GetLevel() <= HeadShot_Level)) {
int chance = GetDEX();
@ -2071,10 +2071,10 @@ int Mob::TryHeadShot(Mob *defender, EQ::skills::SkillType skillInUse)
if (IsClient())
chance += CastToClient()->GetHeroicDEX() / 25;
chance *= 10;
int norm = aabonuses.HSLevel[1];
int norm = aabonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS];
if (norm > 0)
chance = chance * norm / 100;
chance += aabonuses.HeadShot[0] + spellbonuses.HeadShot[0] + itembonuses.HeadShot[0];
chance += aabonuses.HeadShot[SBIndex::FINISHING_EFFECT_PROC_CHANCE] + spellbonuses.HeadShot[SBIndex::FINISHING_EFFECT_PROC_CHANCE] + itembonuses.HeadShot[SBIndex::FINISHING_EFFECT_PROC_CHANCE];
if (zone->random.Int(1, 1000) <= chance) {
entity_list.MessageCloseString(
this, false, 200, Chat::MeleeCrit, FATAL_BOW_SHOT,
@ -2097,7 +2097,7 @@ int Mob::TryAssassinate(Mob *defender, EQ::skills::SkillType skillInUse)
if (IsClient())
chance += CastToClient()->GetHeroicDEX();
chance *= 10;
int norm = aabonuses.AssassinateLevel[1];
int norm = aabonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS];
if (norm > 0)
chance = chance * norm / 100;
} else if (skillInUse == EQ::skills::SkillThrowing) {
@ -2107,14 +2107,14 @@ int Mob::TryAssassinate(Mob *defender, EQ::skills::SkillType skillInUse)
chance += 5;
}
chance += aabonuses.Assassinate[0] + spellbonuses.Assassinate[0] + itembonuses.Assassinate[0];
chance += aabonuses.Assassinate[SBIndex::FINISHING_EFFECT_PROC_CHANCE] + spellbonuses.Assassinate[SBIndex::FINISHING_EFFECT_PROC_CHANCE] + itembonuses.Assassinate[SBIndex::FINISHING_EFFECT_PROC_CHANCE];
uint32 Assassinate_Dmg =
aabonuses.Assassinate[1] + spellbonuses.Assassinate[1] + itembonuses.Assassinate[1];
aabonuses.Assassinate[SBIndex::FINISHING_EFFECT_DMG] + spellbonuses.Assassinate[SBIndex::FINISHING_EFFECT_DMG] + itembonuses.Assassinate[SBIndex::FINISHING_EFFECT_DMG];
uint8 Assassinate_Level = 0; // Get Highest Headshot Level
Assassinate_Level = std::max(
{aabonuses.AssassinateLevel[0], spellbonuses.AssassinateLevel[0], itembonuses.AssassinateLevel[0]});
{aabonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX], spellbonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX], itembonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX]});
// revamped AAs require AA line I believe?
if (!Assassinate_Level)
@ -2198,12 +2198,12 @@ void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQ::skills::Sk
}
other->AddToHateList(this, hate, 0);
if (damage > 0 && aabonuses.SkillAttackProc[0] && aabonuses.SkillAttackProc[1] == skillinuse &&
IsValidSpell(aabonuses.SkillAttackProc[2])) {
float chance = aabonuses.SkillAttackProc[0] / 1000.0f;
if (damage > 0 && aabonuses.SkillAttackProc[SBIndex::SKILLPROC_CHANCE] && aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SKILL] == skillinuse &&
IsValidSpell(aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SPELL_ID])) {
float chance = aabonuses.SkillAttackProc[SBIndex::SKILLPROC_CHANCE] / 1000.0f;
if (zone->random.Roll(chance))
SpellFinished(aabonuses.SkillAttackProc[2], other, EQ::spells::CastingSlot::Item, 0, -1,
spells[aabonuses.SkillAttackProc[2]].ResistDiff);
SpellFinished(aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SPELL_ID], other, EQ::spells::CastingSlot::Item, 0, -1,
spells[aabonuses.SkillAttackProc[SBIndex::SKILLPROC_SPELL_ID]].ResistDiff);
}
other->Damage(this, damage, SPELL_UNKNOWN, skillinuse);

View File

@ -2903,10 +2903,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if (zone->random.Roll(spells[spell_id].base[i]) && IsValidSpell(spells[spell_id].base2[i]))
caster->SpellFinished(spells[spell_id].base2[i], this, EQ::spells::CastingSlot::Item, 0, -1, spells[spells[spell_id].base2[i]].ResistDiff);
break;
}
case SE_Hatelist_To_Tail_Index: {
if (caster && zone->random.Roll(spells[spell_id].base[i]))
caster->SetBottomRampageList();
@ -2940,7 +2940,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
else
Stun(spells[spell_id].base[i]);
}
else
else
caster->MessageString(Chat::SpellFailure, FEAR_TOO_HIGH);
break;
}
@ -2949,7 +2949,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
buffs[buffslot].focusproclimit_procamt = spells[spell_id].base[i]; //Set max amount of procs before lockout timer
break;
}
case SE_PersistentEffect:
MakeAura(spell_id);
break;
@ -3928,11 +3928,11 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
int32 amt = abs(GetMaxHP() * effect_value / 100);
if (spells[buff.spellid].max[i] && amt > spells[buff.spellid].max[i])
amt = spells[buff.spellid].max[i];
if (effect_value < 0) {
if (effect_value < 0) {
Damage(this, amt, 0, EQ::skills::SkillEvocation, false);
}
else {
else {
HealDamage(amt);
}
break;
@ -3945,7 +3945,7 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
amt = spells[buff.spellid].max[i];
if (effect_value < 0) {
SetMana(GetMana() - amt);
}
else {
@ -6192,16 +6192,16 @@ bool Mob::TryDivineSave()
-If desired, additional spells can be triggered from the AA/item/spell effect, generally a heal.
*/
int32 SuccessChance = aabonuses.DivineSaveChance[0] + itembonuses.DivineSaveChance[0] + spellbonuses.DivineSaveChance[0];
int32 SuccessChance = aabonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_CHANCE] + itembonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_CHANCE] + spellbonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_CHANCE];
if (SuccessChance && zone->random.Roll(SuccessChance))
{
SetHP(1);
int32 EffectsToTry[] =
{
aabonuses.DivineSaveChance[1],
itembonuses.DivineSaveChance[1],
spellbonuses.DivineSaveChance[1]
aabonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_SPELL_TRIGGER_ID],
itembonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_SPELL_TRIGGER_ID],
spellbonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_SPELL_TRIGGER_ID]
};
//Fade the divine save effect here after saving the old effects off.
//That way, if desired, the effect could apply SE_DivineSave again.
@ -6236,10 +6236,10 @@ bool Mob::TryDeathSave() {
-In later expansions this SE_DeathSave was given a level limit and a heal value in its effect data.
*/
if (spellbonuses.DeathSave[0]){
if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE]){
int SuccessChance = 0;
int buffSlot = spellbonuses.DeathSave[1];
int buffSlot = spellbonuses.DeathSave[SBIndex::DEATH_SAVE_BUFFSLOT];
int32 UD_HealMod = 0;
int HealAmt = 300; //Death Pact max Heal
@ -6254,12 +6254,12 @@ bool Mob::TryDeathSave() {
if(zone->random.Roll(SuccessChance)) {
if(spellbonuses.DeathSave[0] == 2)
if(spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == 2)
HealAmt = RuleI(Spells, DivineInterventionHeal); //8000HP is how much LIVE Divine Intervention max heals
//Check if bonus Heal amount can be applied ([3] Bonus Heal [2] Level limit)
if (spellbonuses.DeathSave[3] && (GetLevel() >= spellbonuses.DeathSave[2]))
HealAmt += spellbonuses.DeathSave[3];
if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_HEAL_AMT] && (GetLevel() >= spellbonuses.DeathSave[SBIndex::DEATH_SAVE_MIN_LEVEL_FOR_HEAL]))
HealAmt += spellbonuses.DeathSave[SBIndex::DEATH_SAVE_HEAL_AMT];
if ((GetMaxHP() - GetHP()) < HealAmt)
HealAmt = GetMaxHP() - GetHP();
@ -6267,7 +6267,7 @@ bool Mob::TryDeathSave() {
SetHP((GetHP()+HealAmt));
Message(263, "The gods have healed you for %i points of damage.", HealAmt);
if(spellbonuses.DeathSave[0] == 2)
if(spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == 2)
entity_list.MessageCloseString(
this,
false,
@ -6291,12 +6291,12 @@ bool Mob::TryDeathSave() {
if(zone->random.Roll(SuccessChance)) {
if(spellbonuses.DeathSave[0] == 2)
if(spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == 2)
HealAmt = RuleI(Spells, DivineInterventionHeal);
//Check if bonus Heal amount can be applied ([3] Bonus Heal [2] Level limit)
if (spellbonuses.DeathSave[3] && (GetLevel() >= spellbonuses.DeathSave[2]))
HealAmt += spellbonuses.DeathSave[3];
if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_HEAL_AMT] && (GetLevel() >= spellbonuses.DeathSave[SBIndex::DEATH_SAVE_MIN_LEVEL_FOR_HEAL]))
HealAmt += spellbonuses.DeathSave[SBIndex::DEATH_SAVE_HEAL_AMT];
HealAmt = HealAmt*UD_HealMod/100;
@ -6306,7 +6306,7 @@ bool Mob::TryDeathSave() {
SetHP((GetHP()+HealAmt));
Message(263, "The gods have healed you for %i points of damage.", HealAmt);
if(spellbonuses.DeathSave[0] == 2)
if(spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == 2)
entity_list.MessageCloseString(
this,
false,
@ -6645,22 +6645,22 @@ bool Mob::TryDispel(uint8 caster_level, uint8 buff_level, int level_modifier){
bool Mob::ImprovedTaunt(){
if (spellbonuses.ImprovedTaunt[0]){
if (spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_MAX_LVL]){
if (GetLevel() > spellbonuses.ImprovedTaunt[0])
if (GetLevel() > spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_MAX_LVL])
return false;
if (spellbonuses.ImprovedTaunt[2] >= 0){
if (spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_BUFFSLOT] >= 0){
target = entity_list.GetMob(buffs[spellbonuses.ImprovedTaunt[2]].casterid);
target = entity_list.GetMob(buffs[spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_BUFFSLOT]].casterid);
if (target){
SetTarget(target);
return true;
}
else {
if(!TryFadeEffect(spellbonuses.ImprovedTaunt[2]))
BuffFadeBySlot(spellbonuses.ImprovedTaunt[2], true); //If caster killed removed effect.
if(!TryFadeEffect(spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_BUFFSLOT]))
BuffFadeBySlot(spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_BUFFSLOT], true); //If caster killed removed effect.
}
}
}
@ -7187,7 +7187,7 @@ void Mob::CastSpellOnLand(Mob* caster, int32 spell_id)
the CalcFocusEffect function if not 100pct.
ApplyFocusProcLimiter() function checks for SE_Proc_Timer_Modifier which allows for limiting how often a spell from effect can be triggered
for example, if set to base=1 and base2= 1500, then for everyone 1 successful trigger, you will be unable to trigger again for 1.5 seconds.
Live only has this focus in buffs/debuffs that can be placed on a target. TODO: Will consider adding support for it as AA and Item.
*/
if (!caster)
@ -7221,7 +7221,7 @@ void Mob::CastSpellOnLand(Mob* caster, int32 spell_id)
SpellFinished(trigger_spell_id, current_target, EQ::spells::CastingSlot::Item, 0, -1, spells[trigger_spell_id].ResistDiff);
}
}
if (i >= 0)
CheckNumHitsRemaining(NumHit::MatchingSpells, i);
}
@ -7237,13 +7237,13 @@ bool Mob::ApplyFocusProcLimiter(int32 spell_id, int buffslot)
//Do not allow spell cast if timer is active.
if (buffs[buffslot].focusproclimit_time > 0)
return false;
return false;
/*
SE_Proc_Timer_Modifier
SE_Proc_Timer_Modifier
base1= amount of total procs allowed until lock out timer is triggered, should be set to at least 1 in any spell for the effect to function.
base2= lock out timer, which prevents any more procs set in ms 1500 = 1.5 seconds
This system allows easy scaling for multiple different buffs with same effects each having seperate active individual timer checks. Ie.
This system allows easy scaling for multiple different buffs with same effects each having seperate active individual timer checks. Ie.
*/
if (IsValidSpell(spell_id)) {
@ -7270,7 +7270,7 @@ bool Mob::ApplyFocusProcLimiter(int32 spell_id, int buffslot)
if (!focus_proc_limit_timer.Enabled()) {
focus_proc_limit_timer.Start(250);
}
return true;
}
}

View File

@ -2945,31 +2945,33 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2,
}
}
/*Buff stacking prevention spell effects (446 - 449) works as follows... If B prevent A, if C prevent B, if D prevent C.
If checking same type ie A vs A, which ever effect base value is higher will take hold.
Special check is added to make sure the buffs stack properly when applied from fade on duration effect, since the buff
is not fully removed at the time of the trgger*/
if (spellbonuses.AStacker[0]) {
if ((effect2 == SE_AStacker) && (sp2.effectid[i] <= spellbonuses.AStacker[1]))
/*
Buff stacking prevention spell effects (446 - 449) works as follows... If B prevent A, if C prevent B, if D prevent C.
If checking same type ie A vs A, which ever effect base value is higher will take hold.
Special check is added to make sure the buffs stack properly when applied from fade on duration effect, since the buff
is not fully removed at the time of the trigger
*/
if (spellbonuses.AStacker[SBIndex::BUFFSTACKER_EXISTS]) {
if ((effect2 == SE_AStacker) && (sp2.effectid[i] <= spellbonuses.AStacker[SBIndex::BUFFSTACKER_VALUE]))
return -1;
}
if (spellbonuses.BStacker[0]) {
if ((effect2 == SE_BStacker) && (sp2.effectid[i] <= spellbonuses.BStacker[1]))
if (spellbonuses.BStacker[SBIndex::BUFFSTACKER_EXISTS]) {
if ((effect2 == SE_BStacker) && (sp2.effectid[i] <= spellbonuses.BStacker[SBIndex::BUFFSTACKER_VALUE]))
return -1;
if ((effect2 == SE_AStacker) && (!IsCastonFadeDurationSpell(spellid1) && buffs[buffslot].ticsremaining != 1 && IsEffectInSpell(spellid1, SE_BStacker)))
return -1;
}
if (spellbonuses.CStacker[0]) {
if ((effect2 == SE_CStacker) && (sp2.effectid[i] <= spellbonuses.CStacker[1]))
if (spellbonuses.CStacker[SBIndex::BUFFSTACKER_EXISTS]) {
if ((effect2 == SE_CStacker) && (sp2.effectid[i] <= spellbonuses.CStacker[SBIndex::BUFFSTACKER_VALUE]))
return -1;
if ((effect2 == SE_BStacker) && (!IsCastonFadeDurationSpell(spellid1) && buffs[buffslot].ticsremaining != 1 && IsEffectInSpell(spellid1, SE_CStacker)))
return -1;
}
if (spellbonuses.DStacker[0]) {
if ((effect2 == SE_DStacker) && (sp2.effectid[i] <= spellbonuses.DStacker[1]))
if (spellbonuses.DStacker[SBIndex::BUFFSTACKER_EXISTS]) {
if ((effect2 == SE_DStacker) && (sp2.effectid[i] <= spellbonuses.DStacker[SBIndex::BUFFSTACKER_VALUE]))
return -1;
if ((effect2 == SE_CStacker) && (!IsCastonFadeDurationSpell(spellid1) && buffs[buffslot].ticsremaining != 1 && IsEffectInSpell(spellid1, SE_DStacker)))
return -1;
@ -3786,7 +3788,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
MessageString(Chat::SpellFailure, SPELL_NO_EFFECT);
return false;
}
// Block next spell effect should be used up first(since its blocking the next spell)
if(CanBlockSpell()) {
int buff_count = GetMaxTotalSlots();