diff --git a/common/spdat.h b/common/spdat.h index de7a0433a..019ea2289 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -916,7 +916,7 @@ typedef enum { #define SE_AttackSpeed3 119 // implemented #define SE_HealRate 120 // implemented - reduces healing by a % #define SE_ReverseDS 121 // implemented -//#define SE_ReduceSkill 122 // not implemented TODO: Now used on live, decreases skills by percent +#define SE_ReduceSkill 122 // implemented - base: skill id, limit: none, max: none, formula: % skill is reduced (positive) #define SE_Screech 123 // implemented Spell Blocker(If have buff with value +1 will block any effect with -1) #define SE_ImprovedDamage 124 // implemented #define SE_ImprovedHeal 125 // implemented diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index f796160d0..56be60079 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -2789,6 +2789,25 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne break; } + case SE_ReduceSkill: { + // Bad data or unsupported new skill + if (spells[spell_id].base_value[i] > EQ::skills::HIGHEST_SKILL) { + break; + } + //cap skill reducation at 100% + uint32 skill_reducation_percent = spells[spell_id].formula[i]; + if (spells[spell_id].formula[i] > 100) { + skill_reducation_percent = 100; + } + + if (spells[spell_id].base_value[i] <= EQ::skills::HIGHEST_SKILL) { + if (new_bonus->ReduceSkill[spells[spell_id].base_value[i]] < skill_reducation_percent) { + new_bonus->ReduceSkill[spells[spell_id].base_value[i]] = skill_reducation_percent; + } + } + break; + } + case SE_StunResist: { if(new_bonus->StunResist < effect_value) diff --git a/zone/client.cpp b/zone/client.cpp index 890f224a8..494b3f82b 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -12414,3 +12414,34 @@ std::vector Client::GetRaidOrGroupOrSelf(bool clients_only) return v; } + +uint16 Client::GetSkill(EQ::skills::SkillType skill_id) const +{ + if (skill_id <= EQ::skills::HIGHEST_SKILL) { + + if (spellbonuses.ReduceSkill[skill_id] > 0) { + + if (itembonuses.skillmod[skill_id] > 0) { + + if (itembonuses.skillmodmax[skill_id] > 0) { + return std::min(m_pp.skills[skill_id] + itembonuses.skillmodmax[skill_id], m_pp.skills[skill_id] + ((m_pp.skills[skill_id] * (itembonuses.skillmod[skill_id] - spellbonuses.ReduceSkill[skill_id])) / 100)); + } + return m_pp.skills[skill_id] + ((m_pp.skills[skill_id] * (itembonuses.skillmod[skill_id] - spellbonuses.ReduceSkill[skill_id])) / 100); + } + return m_pp.skills[skill_id] - ((m_pp.skills[skill_id] * spellbonuses.ReduceSkill[skill_id]) / 100); + } + + if (itembonuses.skillmod[skill_id] > 0) { + + if (itembonuses.skillmodmax[skill_id] > 0){ + + if (itembonuses.skillmodmax[skill_id] > 0) { + return std::min(m_pp.skills[skill_id] + itembonuses.skillmodmax[skill_id], m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100); + } + return m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100; + } + return m_pp.skills[skill_id]; + } + return 0; + } +} diff --git a/zone/client.h b/zone/client.h index 1f890bd82..24ce3a002 100644 --- a/zone/client.h +++ b/zone/client.h @@ -830,7 +830,7 @@ public: void IncreaseSkill(int skill_id, int value = 1) { if (skill_id <= EQ::skills::HIGHEST_SKILL) { m_pp.skills[skill_id] += value; } } void IncreaseLanguageSkill(uint8 language_id, uint8 increase = 1); - virtual uint16 GetSkill(EQ::skills::SkillType skill_id) const { if (skill_id <= EQ::skills::HIGHEST_SKILL) { return(itembonuses.skillmod[skill_id] > 0 ? (itembonuses.skillmodmax[skill_id] > 0 ? std::min(m_pp.skills[skill_id] + itembonuses.skillmodmax[skill_id], m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id]); } return 0; } + virtual uint16 GetSkill(EQ::skills::SkillType skill_id) const; uint32 GetRawSkill(EQ::skills::SkillType skill_id) const { if (skill_id <= EQ::skills::HIGHEST_SKILL) { return(m_pp.skills[skill_id]); } return 0; } bool HasSkill(EQ::skills::SkillType skill_id) const; bool CanHaveSkill(EQ::skills::SkillType skill_id) const; diff --git a/zone/common.h b/zone/common.h index a139dfb13..c35530c72 100644 --- a/zone/common.h +++ b/zone/common.h @@ -503,8 +503,10 @@ struct StatBonuses { uint8 invisibility_verse_undead; // IVU level uint8 invisibility_verse_animal; // IVA level int32 ShieldTargetSpa[2]; // [0] base = % mitigation amount, [1] buff slot + uint32 ReduceSkill[EQ::skills::HIGHEST_SKILL + 2]; //reduce value of a skill by percentage int64 FlatMaxHPChange; // base: Max HP change by a flat amount value from spell effect/item worn effect/aa + // AAs int32 TrapCircumvention; // reduce chance to trigger a trap. uint16 SecondaryForte; // allow a second skill to be specialized with a cap of this value. diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 94d877909..85b21a318 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -3391,6 +3391,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove case SE_ImprovedInvisAnimals: case SE_InvisVsUndead: case SE_InvisVsUndead2: + case SE_Shield_Target: + case SE_ReduceSkill: { break; }