diff --git a/common/ruletypes.h b/common/ruletypes.h index edc770a2b..f506a8b64 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -451,7 +451,8 @@ RULE_BOOL(Spells, Jun182014HundredHandsRevamp, false, "This should be true for i RULE_BOOL(Spells, SwarmPetTargetLock, false, "Use old method of swarm pets target locking till target dies then despawning") RULE_BOOL(Spells, NPC_UseFocusFromSpells, true, "Allow NPC to use most spell derived focus effects") RULE_BOOL(Spells, NPC_UseFocusFromItems, false, "Allow NPC to use most item derived focus effects") -RULE_BOOL(Spells, UseAdditiveFocusFromWornSlot, false, "Allows an additive focus effect to be calculated from worn slot") +RULE_BOOL(Spells, UseAdditiveFocusFromWornSlot, false, "Allows an additive focus effect to be calculated from worn slot. Does not apply limits checks. Can only have one additive focus rule be true.") +RULE_BOOL(Spells, UseAdditiveFocusFromWornSlotWithLimits, false, "Allows an additive focus effect to be calculated from worn slot. Applies normal limit checks. Can only have one additive focus rule be true.") RULE_BOOL(Spells, AlwaysSendTargetsBuffs, false, "Ignore Leadership Alternate Abilities level if true") RULE_BOOL(Spells, FlatItemExtraSpellAmt, false, "Allow SpellDmg stat to affect all spells, regardless of cast time/cooldown/etc") RULE_BOOL(Spells, IgnoreSpellDmgLvlRestriction, false, "Ignore the 5 level spread on applying SpellDmg") diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 86ccde198..e34913676 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -2090,7 +2090,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne if (focus) { if (WornType){ - if (RuleB(Spells, UseAdditiveFocusFromWornSlot)) { + if (RuleB(Spells, UseAdditiveFocusFromWornSlotWithLimits)) { + new_bonus->FocusEffectsWornWithLimits[focus] = spells[spell_id].effect_id[i]; + } + else if (RuleB(Spells, UseAdditiveFocusFromWornSlot)) { new_bonus->FocusEffectsWorn[focus] += spells[spell_id].base_value[i]; } } diff --git a/zone/common.h b/zone/common.h index db56c41cf..b3b1815ac 100644 --- a/zone/common.h +++ b/zone/common.h @@ -445,7 +445,8 @@ struct StatBonuses { int32 SongRange; // increases range of beneficial bard songs uint32 HPToManaConvert; // Uses HP to cast spells at specific conversion int32 FocusEffects[HIGHEST_FOCUS+1]; // Stores the focus effectid for each focustype you have. - int16 FocusEffectsWorn[HIGHEST_FOCUS+1]; // Optional to allow focus effects to be applied additively from worn slot + int16 FocusEffectsWorn[HIGHEST_FOCUS+1]; // Optional to allow focus effects to be applied additively from worn slot, limits do not apply + int32 FocusEffectsWornWithLimits[HIGHEST_FOCUS + 1];// Optional to allow focus effects to be applied additively from worn slot, limits apply bool NegateEffects; // Check if you contain a buff with negate effect. (only spellbonuses) int32 SkillDamageAmount2[EQ::skills::HIGHEST_SKILL + 2]; // Adds skill specific damage uint32 NegateAttacks[3]; // 0 = bool HasEffect 1 = Buff Slot 2 = Max damage absorbed per hit diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index b8059d0f6..4f57c90ee 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -6801,9 +6801,53 @@ int64 Mob::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster, bool fro //Summon Spells that require reagents are typically imbue type spells, enchant metal, sacrifice and shouldn't be affected //by reagent conservation for obvious reasons. - //Non-Live like feature to allow for an additive focus bonus to be applied from foci that are placed in worn slot. (No limit checks) + int32 worneffect_bonus = 0; - if (RuleB(Spells, UseAdditiveFocusFromWornSlot)) { + //Non-Live like feature to allow for an additive focus bonus to be applied from foci that are placed in worn slot. (Limit Checks) + if (RuleB(Spells, UseAdditiveFocusFromWornSlotWithLimits)) { + //Check if item focus effect exists for the mob. + if (itembonuses.FocusEffectsWornWithLimits[type]) { + const EQ::ItemData* temporary_item = nullptr; + const EQ::ItemData* used_item = nullptr; + + //item focus + for (int x = EQ::invslot::EQUIPMENT_BEGIN; x <= EQ::invslot::EQUIPMENT_END; x++) { + temporary_item = nullptr; + EQ::ItemInstance* ins = GetInv().GetItem(x); + if (!ins) { + continue; + } + + temporary_item = ins->GetItem(); + if (temporary_item && IsValidSpell(temporary_item->Worn.Effect)) { + if (rand_effectiveness) { + worneffect_bonus += CalcFocusEffect(type, temporary_item->Worn.Effect, spell_id, true); + } + else { + worneffect_bonus += CalcFocusEffect(type, temporary_item->Worn.Effect, spell_id); + } + } + + for (int y = EQ::invaug::SOCKET_BEGIN; y <= EQ::invaug::SOCKET_END; ++y) { + EQ::ItemInstance* aug = nullptr; + aug = ins->GetAugment(y); + if (aug) { + const EQ::ItemData* temporary_item_augment = aug->GetItem(); + if (temporary_item_augment && IsValidSpell(temporary_item_augment->Worn.Effect)) { + if (rand_effectiveness) { + worneffect_bonus += CalcFocusEffect(type, temporary_item_augment->Worn.Effect, spell_id, true); + } + else { + worneffect_bonus += CalcFocusEffect(type, temporary_item_augment->Worn.Effect, spell_id); + } + } + } + } + } + } + } + //Non-Live like feature to allow for an additive focus bonus to be applied from foci that are placed in worn slot. (No limit checks) + else if (RuleB(Spells, UseAdditiveFocusFromWornSlot)) { worneffect_bonus = itembonuses.FocusEffectsWorn[type]; }