From 76ec6e4da236135d19187b5831a750f3f05c2e42 Mon Sep 17 00:00:00 2001 From: Michael Cook Date: Wed, 11 Dec 2013 01:49:51 -0500 Subject: [PATCH 1/2] Fixed crippling blow issues with berserker frenzy Also added two rules to control when to enter/exit berserker frenzy --- changelog.txt | 3 +++ common/ruletypes.h | 2 ++ zone/attack.cpp | 33 +++++++++++++-------------------- zone/client.h | 1 + zone/client_process.cpp | 8 ++++---- zone/mob.h | 1 + 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/changelog.txt b/changelog.txt index 6a6382e5f..ca2e11a1f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 12/11/2013 == +demonstar55: Fixed issue with crippling blow from berserker frenzy not actually doing anything + == 12/04/2013 == demonstar55: Fixed SpellType_Charm case in AICastSpell diff --git a/common/ruletypes.h b/common/ruletypes.h index bc10cbf9b..26083a583 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -371,6 +371,8 @@ RULE_INT ( Combat, ClientStunLevel, 55) //This is the level where client kicks a RULE_INT ( Combat, QuiverWRHasteDiv, 3) //Weight Reduction is divided by this to get haste contribution for quivers RULE_BOOL ( Combat, UseArcheryBonusRoll, false) //Make the 51+ archery bonus require an actual roll RULE_INT ( Combat, ArcheryBonusChance, 50) +RULE_INT ( Combat, BerserkerFrenzyStart, 35) +RULE_INT ( Combat, BerserkerFrenzyEnd, 45) RULE_CATEGORY_END() RULE_CATEGORY( NPC ) diff --git a/zone/attack.cpp b/zone/attack.cpp index 7cf35e2a2..4623661b5 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1173,7 +1173,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b if(weapon_damage > 0){ //Berserker Berserk damage bonus - if(berserk && GetClass() == BERSERKER){ + if(IsBerserk() && GetClass() == BERSERKER){ int bonus = 3 + GetLevel()/10; //unverified weapon_damage = weapon_damage * (100+bonus) / 100; mlog(COMBAT__DAMAGE, "Berserker damage bonus increases DMG to %d", weapon_damage); @@ -4102,19 +4102,15 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack //Warning: Do not define these rules if you want live like critical hits. critChance += RuleI(Combat, MeleeBaseCritChance); - if(IsClient()) + if (IsClient()) { critChance += RuleI(Combat, ClientBaseCritChance); - bool IsBerserk = false; - if(((GetClass() == WARRIOR || GetClass() == BERSERKER) && GetLevel() >= 12 && IsClient())) - { - if(CastToClient()->berserk){ - critChance += RuleI(Combat, BerserkBaseCritChance); - IsBerserk = true; + if ((GetClass() == WARRIOR || GetClass() == BERSERKER) && GetLevel() >= 12) { + if (IsBerserk()) + critChance += RuleI(Combat, BerserkBaseCritChance); + else + critChance += RuleI(Combat, WarBerBaseCritChance); } - - else - critChance += RuleI(Combat, WarBerBaseCritChance); } if(skill == SkillArchery && GetClass() == RANGER && GetSkill(SkillArchery) >= 65) @@ -4154,10 +4150,11 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack //Crippling Blow Chance: The percent value of the effect is applied //to the your Chance to Critical. (ie You have 10% chance to critical and you //have a 200% Chance to Critical Blow effect, therefore you have a 20% Chance to Critical Blow. - if (CripplingBlowChance){ - critChance *= float(CripplingBlowChance)/100.0f; + if (CripplingBlowChance || IsBerserk()) { + if (!IsBerserk()) + critChance *= float(CripplingBlowChance)/100.0f; - if(MakeRandomFloat(0, 1) < critChance){ + if (IsBerserk() || MakeRandomFloat(0, 1) < critChance) { critMod = 400; crip_success = true; } @@ -4166,8 +4163,7 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack critMod += GetCritDmgMob(skill) * 2; // To account for base crit mod being 200 not 100 damage = damage * critMod / 100; - if(IsBerserk || crip_success) - { + if (crip_success) { entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, CRIPPLING_BLOW, GetCleanName(), itoa(damage)); // Crippling blows also have a chance to stun //Kayen: Crippling Blow would cause a chance to interrupt for npcs < 55, with a staggers message. @@ -4175,10 +4171,7 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack defender->Emote("staggers."); defender->Stun(0); } - } - - else - { + } else { entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, CRITICAL_HIT, GetCleanName(), itoa(damage)); } } diff --git a/zone/client.h b/zone/client.h index 0209d422a..8e4a38c16 100644 --- a/zone/client.h +++ b/zone/client.h @@ -220,6 +220,7 @@ public: virtual bool HasGroup() { return (GetGroup() ? true : false); } virtual Raid* GetRaid() { return entity_list.GetRaidByClient(this); } virtual Group* GetGroup() { return entity_list.GetGroupByClient(this); } + virtual inline bool IsBerserk() { return berserk; } void AI_Init(); void AI_Start(uint32 iMoveDelay = 0); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 8bb3fd67c..9158f3bf2 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -464,13 +464,13 @@ bool Client::Process() { } if (GetClass() == WARRIOR || GetClass() == BERSERKER) { - if(!dead && !berserk && this->GetHPRatio() < 30) { + if (!dead && !IsBerserk() && GetHPRatio() < RuleI(Combat, BerserkerFrenzyStart)) { entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_START, GetName()); - this->berserk = true; + berserk = true; } - if (berserk && this->GetHPRatio() > 30) { + if (IsBerserk() && GetHPRatio() > RuleI(Combat, BerserkerFrenzyEnd)) { entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_END, GetName()); - this->berserk = false; + berserk = false; } } diff --git a/zone/mob.h b/zone/mob.h index 962bef3c8..2d58f0d79 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -126,6 +126,7 @@ public: void ApplyMeleeDamageBonus(uint16 skill, int32 &damage); virtual void MeleeMitigation(Mob *attacker, int32 &damage, int32 minhit, ExtraAttackOptions *opts = nullptr); bool CombatRange(Mob* other); + virtual inline bool IsBerserk() { return false; } // only clients //Appearance void SendLevelAppearance(); From c70ea4a621d9c0e0d29d413bc0d7956c431d24b6 Mon Sep 17 00:00:00 2001 From: Michael Cook Date: Wed, 11 Dec 2013 15:44:59 -0500 Subject: [PATCH 2/2] Fix haste caps Before these were mostly guess work, now based on what clients report since they do their own calculations so are most likely correct. --- changelog.txt | 1 + zone/client_mods.cpp | 49 ++++++++++++++++++++++---------------------- zone/mob.cpp | 41 +++++++++++++++++++++--------------- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/changelog.txt b/changelog.txt index ca2e11a1f..603481a32 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- == 12/11/2013 == demonstar55: Fixed issue with crippling blow from berserker frenzy not actually doing anything +demonstar55: Fix haste caps == 12/04/2013 == demonstar55: Fixed SpellType_Charm case in AICastSpell diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index 2cc26c3f7..45504510d 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -1340,45 +1340,46 @@ int16 Client::CalcCHA() { } int Client::CalcHaste() { - int h = spellbonuses.haste + spellbonuses.hastetype2 + itembonuses.haste; + int h = spellbonuses.haste + spellbonuses.hastetype2; int cap = 0; + int overhaste = 0; int level = GetLevel(); - /* - if(disc_inuse == discBlindingSpeed) { - if(!disc_elapse.Check(false)) { - h += 20; //this ammount is completely unknown - } else { - disc_inuse = discNone; - } - } */ - if(level < 30) { // Rogean: Are these caps correct? Will use for now. - cap = 50; - } else if(level < 50) { - cap = 74; - } else if(level < 55) { - cap = 84; - } else if(level < 60) { - cap = 94; - } else { + // 26+ no cap, 1-25 10 + if (level > 25) // 26+ + h += itembonuses.haste; + else // 1-25 + h += itembonuses.haste > 10 ? 10 : itembonuses.haste; + + // 60+ 100, 51-59 85, 1-50 level+25 + if (level > 59) // 60+ cap = RuleI(Character, HasteCap); - } + else if (level > 50) // 51-59 + cap = 85; + else // 1-50 + cap = level + 25; cap = mod_client_haste_cap(cap); - if(h > cap) h = cap; + if (h > cap) + h = cap; - h += spellbonuses.hastetype3; + // 51+ 25 (despite there being higher spells...), 1-50 10 + if (level > 50) // 51+ + overhaste = spellbonuses.hastetype3 > 25 ? 25 : spellbonuses.hastetype3; + else // 1-50 + overhaste = spellbonuses.hastetype3 > 10 ? 10 : spellbonuses.hastetype3; + + h += overhaste; h += ExtraHaste; //GM granted haste. h = mod_client_haste(h); - if (spellbonuses.inhibitmelee){ + if (spellbonuses.inhibitmelee) { if (h >= 0) h -= spellbonuses.inhibitmelee; - else - h -=((100+h)*spellbonuses.inhibitmelee/100); + h -= ((100 + h) * spellbonuses.inhibitmelee / 100); } Haste = h; diff --git a/zone/mob.cpp b/zone/mob.cpp index 820db7beb..632b0a16f 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2875,33 +2875,42 @@ uint32 Mob::GetZoneID() const { } int Mob::GetHaste() { - int h = spellbonuses.haste + spellbonuses.hastetype2 + itembonuses.haste; + int h = spellbonuses.haste + spellbonuses.hastetype2; int cap = 0; + int overhaste = 0; int level = GetLevel(); - if(level < 30) { // Rogean: Are these caps correct? Will use for now. - cap = 50; - } else if(level < 50) { - cap = 74; - } else if(level < 55) { - cap = 84; - } else if(level < 60) { - cap = 94; - } else { + // 26+ no cap, 1-25 10 + if (level > 25) // 26+ + h += itembonuses.haste; + else // 1-25 + h += itembonuses.haste > 10 ? 10 : itembonuses.haste; + + // 60+ 100, 51-59 85, 1-50 level+25 + if (level > 59) // 60+ cap = RuleI(Character, HasteCap); - } + else if (level > 50) // 51-59 + cap = 85; + else // 1-50 + cap = level + 25; - if(h > cap) h = cap; + if(h > cap) + h = cap; - h += spellbonuses.hastetype3; + // 51+ 25 (despite there being higher spells...), 1-50 10 + if (level > 50) // 51+ + overhaste = spellbonuses.hastetype3 > 25 ? 25 : spellbonuses.hastetype3; + else // 1-50 + overhaste = spellbonuses.hastetype3 > 10 ? 10 : spellbonuses.hastetype3; + + h += overhaste; h += ExtraHaste; //GM granted haste. - if (spellbonuses.inhibitmelee){ + if (spellbonuses.inhibitmelee) { if (h >= 0) h -= spellbonuses.inhibitmelee; - else - h -=((100+h)*spellbonuses.inhibitmelee/100); + h -= ((100 + h) * spellbonuses.inhibitmelee / 100); } return(h);