mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-08 18:22:26 +00:00
Fixed defensive procs so they now only trigger once per attack round like live.
Added live like proc chance modifer based on level difference to target. "Anything above your level will receive full mod. Starting 6 levels below PC level there is a negative 10 % mod applied each level until it reaches 0 and will not proc on anything 15 levels below you or lower." Thanks to Huffin from PEQ for the parse data
This commit is contained in:
parent
a99befebfe
commit
b369bb1793
@ -2,6 +2,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
== 03/25/2016 ==
|
== 03/25/2016 ==
|
||||||
Uleat: Fix for heal rotation 'Stack Overflow' error
|
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 ==
|
== 03/24/2016 ==
|
||||||
Kayen: Fix for AE taunt to use correct range and hate modifier.
|
Kayen: Fix for AE taunt to use correct range and hate modifier.
|
||||||
|
|||||||
@ -1255,7 +1255,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
CommonBreakInvisibleFromCombat();
|
CommonBreakInvisibleFromCombat();
|
||||||
|
|
||||||
if(GetTarget())
|
if(GetTarget())
|
||||||
TriggerDefensiveProcs(weapon, other, Hand, damage);
|
TriggerDefensiveProcs(other, Hand, true, damage);
|
||||||
|
|
||||||
if (damage > 0)
|
if (damage > 0)
|
||||||
return true;
|
return true;
|
||||||
@ -1822,7 +1822,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(GetHP() > 0 && !other->HasDied())
|
if(GetHP() > 0 && !other->HasDied())
|
||||||
TriggerDefensiveProcs(nullptr, other, Hand, damage);
|
TriggerDefensiveProcs(other, Hand, true, damage);
|
||||||
|
|
||||||
if (damage > 0)
|
if (damage > 0)
|
||||||
return true;
|
return true;
|
||||||
@ -3516,7 +3516,7 @@ float Mob::GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 h
|
|||||||
}
|
}
|
||||||
|
|
||||||
// argument 'weapon' not used
|
// argument 'weapon' not used
|
||||||
void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
|
void Mob::TryDefensiveProc(Mob *on, uint16 hand) {
|
||||||
|
|
||||||
if (!on) {
|
if (!on) {
|
||||||
SetTarget(nullptr);
|
SetTarget(nullptr);
|
||||||
@ -3524,29 +3524,37 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bDefensiveProc = HasDefensiveProcs();
|
if (!HasDefensiveProcs())
|
||||||
|
|
||||||
if (!bDefensiveProc)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float ProcChance, ProcBonus;
|
if (!on->HasDied() && on->GetHP() > 0){
|
||||||
on->GetDefensiveProcChances(ProcBonus, ProcChance, hand , this);
|
|
||||||
|
|
||||||
if(hand != MainPrimary)
|
float ProcChance, ProcBonus;
|
||||||
ProcChance /= 2;
|
on->GetDefensiveProcChances(ProcBonus, ProcChance, hand , this);
|
||||||
|
|
||||||
if (bDefensiveProc){
|
if(hand != MainPrimary)
|
||||||
for (int i = 0; i < MAX_PROCS; i++) {
|
ProcChance /= 2;
|
||||||
if (IsValidSpell(DefensiveProcs[i].spellID)) {
|
|
||||||
float chance = ProcChance * (static_cast<float>(DefensiveProcs[i].chance)/100.0f);
|
int level_penalty = 0;
|
||||||
if (zone->random.Roll(chance)) {
|
int level_diff = GetLevel() - on->GetLevel();
|
||||||
ExecWeaponProc(nullptr, DefensiveProcs[i].spellID, on);
|
if (level_diff > 6)//10% penalty per level if > 6 levels over target.
|
||||||
CheckNumHitsRemaining(NumHit::DefensiveSpellProcs, 0,
|
level_penalty = (level_diff - 6) * 10;
|
||||||
DefensiveProcs[i].base_spellID);
|
|
||||||
}
|
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) {
|
void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
|
||||||
|
|||||||
@ -2911,6 +2911,7 @@ void Bot::AI_Process() {
|
|||||||
DoClassAttacks(GetTarget());
|
DoClassAttacks(GetTarget());
|
||||||
if(attack_timer.Check()) {
|
if(attack_timer.Check()) {
|
||||||
Attack(GetTarget(), MainPrimary);
|
Attack(GetTarget(), MainPrimary);
|
||||||
|
TriggerDefensiveProcs(GetTarget(), MainPrimary, false);
|
||||||
ItemInst *wpn = GetBotItem(MainPrimary);
|
ItemInst *wpn = GetBotItem(MainPrimary);
|
||||||
TryWeaponProc(wpn, GetTarget(), MainPrimary);
|
TryWeaponProc(wpn, GetTarget(), MainPrimary);
|
||||||
bool tripleSuccess = false;
|
bool tripleSuccess = false;
|
||||||
@ -4865,7 +4866,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
|||||||
BuffFadeByEffect(SE_NegateIfCombat);
|
BuffFadeByEffect(SE_NegateIfCombat);
|
||||||
|
|
||||||
if(GetTarget())
|
if(GetTarget())
|
||||||
TriggerDefensiveProcs(weapon, other, Hand, damage);
|
TriggerDefensiveProcs(other, Hand, true, damage);
|
||||||
|
|
||||||
if (damage > 0)
|
if (damage > 0)
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -3399,12 +3399,13 @@ int Mob::GetSnaredAmount()
|
|||||||
return worst_snare;
|
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)
|
if (!on)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
on->TryDefensiveProc(weapon, this, hand);
|
if (!FromSkillProc)
|
||||||
|
on->TryDefensiveProc(this, hand);
|
||||||
|
|
||||||
//Defensive Skill Procs
|
//Defensive Skill Procs
|
||||||
if (damage < 0 && damage >= -4) {
|
if (damage < 0 && damage >= -4) {
|
||||||
|
|||||||
@ -152,7 +152,6 @@ public:
|
|||||||
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr, int special = 0) = 0;
|
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr, int special = 0) = 0;
|
||||||
int MonkSpecialAttack(Mob* other, uint8 skill_used);
|
int MonkSpecialAttack(Mob* other, uint8 skill_used);
|
||||||
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
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);
|
bool AvoidDamage(Mob* attacker, int32 &damage, int hand);
|
||||||
virtual bool CheckHitChance(Mob* attacker, SkillUseTypes skillinuse, int Hand, int16 chance_mod = 0);
|
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);
|
virtual void TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttackOptions *opts = nullptr);
|
||||||
@ -564,6 +563,7 @@ public:
|
|||||||
bool lookForAftArc = true);
|
bool lookForAftArc = true);
|
||||||
|
|
||||||
//Procs
|
//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 AddRangedProc(uint16 spell_id, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN);
|
||||||
bool RemoveRangedProc(uint16 spell_id, bool bAll = false);
|
bool RemoveRangedProc(uint16 spell_id, bool bAll = false);
|
||||||
bool HasRangedProcs() const;
|
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?
|
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 PassLimitToSkill(uint16 spell_id, uint16 skill);
|
||||||
bool PassLimitClass(uint32 Classes_, uint16 Class_);
|
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 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 TrySpellProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||||
void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);
|
void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||||
|
|||||||
@ -1107,6 +1107,7 @@ void Mob::AI_Process() {
|
|||||||
//try main hand first
|
//try main hand first
|
||||||
if(attack_timer.Check()) {
|
if(attack_timer.Check()) {
|
||||||
DoMainHandAttackRounds(target);
|
DoMainHandAttackRounds(target);
|
||||||
|
TriggerDefensiveProcs(target, MainPrimary, false);
|
||||||
|
|
||||||
bool specialed = false; // NPCs can only do one of these a round
|
bool specialed = false; // NPCs can only do one of these a round
|
||||||
if (GetSpecialAbility(SPECATK_FLURRY)) {
|
if (GetSpecialAbility(SPECATK_FLURRY)) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user