Merge pull request #508 from KayenEQ/Development

Defensive proc rate fix
This commit is contained in:
KayenEQ 2016-03-25 13:04:21 -04:00
commit 1e795c0199
6 changed files with 37 additions and 24 deletions

View File

@ -2,6 +2,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 03/25/2016 ==
Uleat: Fix for heal rotation 'Stack Overflow' error
Kayen: Defensive procs will now only proc once per attack round (instead of every attack chance).
Live like modifier added that decreases defensive proc chance if you are higher level then your attacker.
== 03/24/2016 ==
Kayen: Fix for AE taunt to use correct range and hate modifier.

View File

@ -1255,7 +1255,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
CommonBreakInvisibleFromCombat();
if(GetTarget())
TriggerDefensiveProcs(weapon, other, Hand, damage);
TriggerDefensiveProcs(other, Hand, true, damage);
if (damage > 0)
return true;
@ -1822,7 +1822,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
}
if(GetHP() > 0 && !other->HasDied())
TriggerDefensiveProcs(nullptr, other, Hand, damage);
TriggerDefensiveProcs(other, Hand, true, damage);
if (damage > 0)
return true;
@ -3516,7 +3516,7 @@ float Mob::GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 h
}
// argument 'weapon' not used
void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
void Mob::TryDefensiveProc(Mob *on, uint16 hand) {
if (!on) {
SetTarget(nullptr);
@ -3524,29 +3524,37 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
return;
}
bool bDefensiveProc = HasDefensiveProcs();
if (!bDefensiveProc)
if (!HasDefensiveProcs())
return;
float ProcChance, ProcBonus;
on->GetDefensiveProcChances(ProcBonus, ProcChance, hand , this);
if (!on->HasDied() && on->GetHP() > 0){
if(hand != MainPrimary)
ProcChance /= 2;
float ProcChance, ProcBonus;
on->GetDefensiveProcChances(ProcBonus, ProcChance, hand , this);
if (bDefensiveProc){
for (int i = 0; i < MAX_PROCS; i++) {
if (IsValidSpell(DefensiveProcs[i].spellID)) {
float chance = ProcChance * (static_cast<float>(DefensiveProcs[i].chance)/100.0f);
if (zone->random.Roll(chance)) {
ExecWeaponProc(nullptr, DefensiveProcs[i].spellID, on);
CheckNumHitsRemaining(NumHit::DefensiveSpellProcs, 0,
DefensiveProcs[i].base_spellID);
}
if(hand != MainPrimary)
ProcChance /= 2;
int level_penalty = 0;
int level_diff = GetLevel() - on->GetLevel();
if (level_diff > 6)//10% penalty per level if > 6 levels over target.
level_penalty = (level_diff - 6) * 10;
ProcChance -= ProcChance*level_penalty/100;
if (ProcChance < 0)
return;
for (int i = 0; i < MAX_PROCS; i++) {
if (IsValidSpell(DefensiveProcs[i].spellID)) {
float chance = ProcChance * (static_cast<float>(DefensiveProcs[i].chance)/100.0f);
if (zone->random.Roll(chance)) {
ExecWeaponProc(nullptr, DefensiveProcs[i].spellID, on);
CheckNumHitsRemaining(NumHit::DefensiveSpellProcs, 0,DefensiveProcs[i].base_spellID);
}
}
}
}
}
void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {

View File

@ -2911,6 +2911,7 @@ void Bot::AI_Process() {
DoClassAttacks(GetTarget());
if(attack_timer.Check()) {
Attack(GetTarget(), MainPrimary);
TriggerDefensiveProcs(GetTarget(), MainPrimary, false);
ItemInst *wpn = GetBotItem(MainPrimary);
TryWeaponProc(wpn, GetTarget(), MainPrimary);
bool tripleSuccess = false;
@ -4865,7 +4866,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
BuffFadeByEffect(SE_NegateIfCombat);
if(GetTarget())
TriggerDefensiveProcs(weapon, other, Hand, damage);
TriggerDefensiveProcs(other, Hand, true, damage);
if (damage > 0)
return true;

View File

@ -3399,12 +3399,13 @@ int Mob::GetSnaredAmount()
return worst_snare;
}
void Mob::TriggerDefensiveProcs(const ItemInst* weapon, Mob *on, uint16 hand, int damage)
void Mob::TriggerDefensiveProcs(Mob *on, uint16 hand, bool FromSkillProc, int damage)
{
if (!on)
return;
on->TryDefensiveProc(weapon, this, hand);
if (!FromSkillProc)
on->TryDefensiveProc(this, hand);
//Defensive Skill Procs
if (damage < 0 && damage >= -4) {

View File

@ -152,7 +152,6 @@ public:
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr, int special = 0) = 0;
int MonkSpecialAttack(Mob* other, uint8 skill_used);
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
void TriggerDefensiveProcs(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary, int damage = 0);
bool AvoidDamage(Mob* attacker, int32 &damage, int hand);
virtual bool CheckHitChance(Mob* attacker, SkillUseTypes skillinuse, int Hand, int16 chance_mod = 0);
virtual void TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttackOptions *opts = nullptr);
@ -564,6 +563,7 @@ public:
bool lookForAftArc = true);
//Procs
void TriggerDefensiveProcs(Mob *on, uint16 hand = MainPrimary, bool SkillProc=false, int damage = 0);
bool AddRangedProc(uint16 spell_id, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN);
bool RemoveRangedProc(uint16 spell_id, bool bAll = false);
bool HasRangedProcs() const;
@ -1142,7 +1142,7 @@ protected:
void TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success = false, uint16 hand = 0, bool IsDefensive = false); // hand = MainCharm?
bool PassLimitToSkill(uint16 spell_id, uint16 skill);
bool PassLimitClass(uint32 Classes_, uint16 Class_);
void TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);
void TryDefensiveProc(Mob *on, uint16 hand = MainPrimary);
void TryWeaponProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = MainPrimary);
void TrySpellProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = MainPrimary);
void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);

View File

@ -1107,6 +1107,7 @@ void Mob::AI_Process() {
//try main hand first
if(attack_timer.Check()) {
DoMainHandAttackRounds(target);
TriggerDefensiveProcs(target, MainPrimary, false);
bool specialed = false; // NPCs can only do one of these a round
if (GetSpecialAbility(SPECATK_FLURRY)) {