diff --git a/common/spdat.h b/common/spdat.h index a427349aa..36aef716e 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -838,7 +838,7 @@ typedef enum { //#define SE_Ff_Endurance_Max 493 // //#define SE_Pet_Add_Atk 494 // //#define SE_Ff_DurationMax 495 // -//#define SE_Critical_Melee_Damage_Mod_Max 496 // +#define SE_Critical_Melee_Damage_Mod_Max 496 // implemented - //#define SE_Ff_FocusCastProcNoBypass 497 // //#define SE_AddExtraAttackPct_1h_Primary 498 // //#define SE_AddExtraAttackPct_1h_Secondary 499 // @@ -851,24 +851,24 @@ typedef enum { //#define SE_Damage_Taken_Position_Amt 506 // //#define SE_Fc_Amplify_Mod 507 // //#define SE_Fc_Amplify_Amt 508 // -#define SE_Health_Transfer 509 // +#define SE_Health_Transfer 509 // implemented - //#define SE_Fc_ResistIncoming 510 // //#define SE_Ff_FocusTimerMin 511 // //#define SE_Proc_Timer_Modifier 512 // //#define SE_Mana_Max_Percent 513 // //#define SE_Endurance_Max_Percent 514 // -//#define SE_AC_Avoidance_Max_Percent 515 // 515 is before 172 TotalEffect(515) * static_cast(avoidance_ac) * 0.0001 that value is then rounded with a +/- 0.5 -//#define SE_AC_Mitigation_Max_Percent 516 // 516 is after AGI bonus +#define SE_AC_Avoidance_Max_Percent 515 // implemented - 515 is before 172 +#define SE_AC_Mitigation_Max_Percent 516 // implemented - 516 is after AGI bonus //#define SE_Attack_Offense_Max_Percent 517 // Requires too much rewrite of code. -#define SE_Attack_Accuracy_Max_Percent 518 // +#define SE_Attack_Accuracy_Max_Percent 518 // implemented - //#define SE_Luck_Amount 519 // //#define SE_Luck_Percent 520 // -#define SE_Endurance_Absorb_Pct_Damage 521 // -#define SE_Instant_Mana_Pct 522 // -#define SE_Instant_Endurance_Pct 523 // -#define SE_Duration_HP_Pct 524 // -#define SE_Duration_Mana_Pct 525 // -#define SE_Duration_Endurance_Pct 526 // +#define SE_Endurance_Absorb_Pct_Damage 521 // implemented - +#define SE_Instant_Mana_Pct 522 // implemented - +#define SE_Instant_Endurance_Pct 523 // implemented - +#define SE_Duration_HP_Pct 524 // implemented - +#define SE_Duration_Mana_Pct 525 // implemented - +#define SE_Duration_Endurance_Pct 526 // implemented - // LAST diff --git a/zone/attack.cpp b/zone/attack.cpp index 5b87af1ed..aff6ac9fa 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -190,8 +190,8 @@ int Mob::GetTotalToHit(EQ::skills::SkillType skill, int chance_mod) //518 Increase ATK accuracy by percentage, stackable auto atkhit_bonus = itembonuses.Attack_Accuracy_Max_Percent + aabonuses.Attack_Accuracy_Max_Percent + spellbonuses.Attack_Accuracy_Max_Percent; - - accuracy += (accuracy * atkhit_bonus) / 10000; + if (atkhit_bonus) + accuracy += round(static_cast(accuracy) * static_cast(atkhit_bonus) * 0.0001); // 216 Melee Accuracy Amt aka SE_Accuracy -- flat bonus accuracy += itembonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] + @@ -238,6 +238,11 @@ int Mob::compute_defense() if (IsClient()) defense += CastToClient()->GetHeroicAGI() / 10; + //516 SE_AC_Mitigation_Max_Percent + auto ac_bonus = itembonuses.AC_Mitigation_Max_Percent + aabonuses.AC_Mitigation_Max_Percent + spellbonuses.AC_Mitigation_Max_Percent; + if (ac_bonus) + defense += round(static_cast(defense) * static_cast(ac_bonus) * 0.0001); + defense += itembonuses.AvoidMeleeChance; // item mod2 if (IsNPC()) defense += CastToNPC()->GetAvoidanceRating(); @@ -260,7 +265,12 @@ 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) + avoidance += round(static_cast(avoidance) * static_cast(ac_aviodance_bonus) * 0.0001); + // 172 Evasion aka SE_AvoidMeleeChance evasion_bonus += itembonuses.AvoidMeleeChanceEffect + aabonuses.AvoidMeleeChanceEffect; // item bonus here isn't mod2 avoidance diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index fef8f23fc..e8ca2ebce 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -1102,6 +1102,19 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon) break; } + case SE_Critical_Melee_Damage_Mod_Max: + { + // Bad data or unsupported new skill + if (base2 > EQ::skills::HIGHEST_SKILL) + break; + int skill = base2 == ALL_SKILLS ? EQ::skills::HIGHEST_SKILL + 1 : base2; + if (base1 < 0 && newbon->CritDmgModNoStack[skill] > base1) + newbon->CritDmgModNoStack[skill] = base1; + else if (base1 > 0 && newbon->CritDmgModNoStack[skill] < base1) + newbon->CritDmgModNoStack[skill] = base1; + break; + } + case SE_CriticalSpellChance: { newbon->CriticalSpellChance += base1; @@ -1491,6 +1504,14 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon) newbon->Attack_Accuracy_Max_Percent += base1; break; + case SE_AC_Mitigation_Max_Percent: + newbon->AC_Mitigation_Max_Percent += base1; + break; + + case SE_AC_Avoidance_Max_Percent: + newbon->AC_Avoidance_Max_Percent += base1; + break; + // to do case SE_PetDiscipline: break; @@ -2489,6 +2510,20 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne break; } + case SE_Critical_Melee_Damage_Mod_Max: + { + // Bad data or unsupported new skill + if (base2 > EQ::skills::HIGHEST_SKILL) + break; + int skill = base2 == ALL_SKILLS ? EQ::skills::HIGHEST_SKILL + 1 : base2; + if (effect_value < 0 && new_bonus->CritDmgModNoStack[skill] > effect_value) + new_bonus->CritDmgModNoStack[skill] = effect_value; + else if (effect_value > 0 && new_bonus->CritDmgModNoStack[skill] < effect_value) { + new_bonus->CritDmgModNoStack[skill] = effect_value; + } + break; + } + case SE_ReduceSkillTimer: { if(new_bonus->SkillReuseTime[base2] < effect_value) @@ -3266,6 +3301,17 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne case SE_Attack_Accuracy_Max_Percent: new_bonus->Attack_Accuracy_Max_Percent += effect_value; break; + + + case SE_AC_Mitigation_Max_Percent: + new_bonus->AC_Mitigation_Max_Percent += effect_value; + break; + + case SE_AC_Avoidance_Max_Percent: + new_bonus->AC_Avoidance_Max_Percent += effect_value; + break; + + //Special custom cases for loading effects on to NPC from 'npc_spels_effects' table if (IsAISpellEffect) { @@ -4274,6 +4320,17 @@ void Mob::NegateSpellsBonuses(uint16 spell_id) break; } + case SE_Critical_Melee_Damage_Mod_Max: + { + for (int e = 0; e < EQ::skills::HIGHEST_SKILL + 1; e++) + { + spellbonuses.CritDmgModNoStack[e] = effect_value; + aabonuses.CritDmgModNoStack[e] = effect_value; + itembonuses.CritDmgModNoStack[e] = effect_value; + } + break; + } + case SE_SkillDamageAmount: { for (int e = 0; e < EQ::skills::HIGHEST_SKILL + 1; e++) @@ -4790,6 +4847,25 @@ void Mob::NegateSpellsBonuses(uint16 spell_id) aabonuses.IllusionPersistence = false; break; + case SE_Attack_Accuracy_Max_Percent: + spellbonuses.Attack_Accuracy_Max_Percent = effect_value; + itembonuses.Attack_Accuracy_Max_Percent = effect_value; + aabonuses.Attack_Accuracy_Max_Percent = effect_value; + break; + + + case SE_AC_Mitigation_Max_Percent: + spellbonuses.AC_Mitigation_Max_Percent = effect_value; + itembonuses.AC_Mitigation_Max_Percent = effect_value; + aabonuses.AC_Mitigation_Max_Percent = effect_value; + break; + + case SE_AC_Avoidance_Max_Percent: + spellbonuses.AC_Avoidance_Max_Percent = effect_value; + itembonuses.AC_Avoidance_Max_Percent = effect_value; + aabonuses.AC_Avoidance_Max_Percent = effect_value; + break; + case SE_SkillProcSuccess:{ for(int e = 0; e < MAX_SKILL_PROCS; e++) { diff --git a/zone/common.h b/zone/common.h index 3d9e93e3d..5b43b2e1d 100644 --- a/zone/common.h +++ b/zone/common.h @@ -461,6 +461,7 @@ struct StatBonuses { uint32 SpellOnKill[MAX_SPELL_TRIGGER*3]; // Chance to proc after killing a mob uint32 SpellOnDeath[MAX_SPELL_TRIGGER*2]; // Chance to have effect cast when you die int32 CritDmgMod[EQ::skills::HIGHEST_SKILL + 2]; // All Skills + -1 + int32 CritDmgModNoStack[EQ::skills::HIGHEST_SKILL + 2];// Critical melee damage modifier by percent, does not stack. int32 SkillReuseTime[EQ::skills::HIGHEST_SKILL + 1]; // Reduces skill timers int32 SkillDamageAmount[EQ::skills::HIGHEST_SKILL + 2]; // All Skills + -1 int32 TwoHandBluntBlock; // chance to block when wielding two hand blunt weapon @@ -525,6 +526,8 @@ struct StatBonuses { uint32 PC_Pet_Rampage[2]; // 0= % chance to rampage, 1=damage modifier uint32 PC_Pet_Flurry; // Percent chance flurry from double attack int32 Attack_Accuracy_Max_Percent; // Increase ATK accuracy by percent. + int32 AC_Mitigation_Max_Percent; // Increase AC mitigation by percent + int32 AC_Avoidance_Max_Percent; // Increase AC avoidance by percent // AAs int8 Packrat; //weight reduction for items, 1 point = 10% diff --git a/zone/mob.cpp b/zone/mob.cpp index 1ba1a0221..cf1ca5032 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -4624,10 +4624,13 @@ int16 Mob::GetCritDmgMod(uint16 skill) { int critDmg_mod = 0; - // All skill dmg mod + Skill specific + // All skill dmg mod + Skill specific [SPA 330 and 496] critDmg_mod += itembonuses.CritDmgMod[EQ::skills::HIGHEST_SKILL + 1] + spellbonuses.CritDmgMod[EQ::skills::HIGHEST_SKILL + 1] + aabonuses.CritDmgMod[EQ::skills::HIGHEST_SKILL + 1] + itembonuses.CritDmgMod[skill] + spellbonuses.CritDmgMod[skill] + aabonuses.CritDmgMod[skill]; - + Shout("Mod 1 %i", critDmg_mod); + critDmg_mod += itembonuses.CritDmgModNoStack[EQ::skills::HIGHEST_SKILL + 1] + spellbonuses.CritDmgModNoStack[EQ::skills::HIGHEST_SKILL + 1] + aabonuses.CritDmgModNoStack[EQ::skills::HIGHEST_SKILL + 1] + + itembonuses.CritDmgModNoStack[skill] + spellbonuses.CritDmgModNoStack[skill] + aabonuses.CritDmgModNoStack[skill]; + Shout("Mod 2 %i", critDmg_mod); return critDmg_mod; } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 0e655026b..1695a5a4e 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -3122,6 +3122,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove case SE_Duration_Mana_Pct: case SE_Duration_Endurance_Pct: case SE_Endurance_Absorb_Pct_Damage: + case SE_AC_Mitigation_Max_Percent: + case SE_AC_Avoidance_Max_Percent: + case SE_Attack_Accuracy_Max_Percent: + case SE_Critical_Melee_Damage_Mod_Max: { break; }