EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Server Code Submissions (https://www.eqemulator.org/forums/forumdisplay.php?f=669)
-   -   COMMITTED: Heroics - Extended (https://www.eqemulator.org/forums/showthread.php?t=32438)

Caryatis 11-08-2010 04:18 AM

COMMITTED: Heroics - Extended
 
The base of heroics have been in for a while but there are a number of effects that were not supported:
EQ Forums

Quote:

- Heroic Intelligence: For intelligence-based casters, increases mana pool, mana regen, and the maximum amount of mana regen a character can have.
- Heroic Wisdom: For wisdom-based casters, increases mana pool, mana regen, and the maximum amount of mana regen a character can have.
- Heroic Strength: Increases endurance pool, endurance regen, and the maximum amount of endurance regen a character can have. Also increases damage done by melee attacks and improves the bonus granted to armor class while using a shield.
- Heroic Stamina: Increases hit point pool, hit point regen, and the maximum amount of hit point regen a character can have. Also increases endurance pool, endurance regen, and the maximum amount of endurance regen a character can have.
- Heroic Agility: Increases endurance pool, endurance regen, and the maximum amount of endurance regen a character can have. Also increases the chance to dodge an attack, grants a bonus to defense skill, and reduces falling damage.
- Heroic Dexterity: Increases endurance pool, endurance regen, and the maximum amount of endurance regen a character can have. Also increases damage done by ranged attacks, improves chance to successfully assassinate or headshot, and improves the chance to riposte, block, and parry incoming attacks.
- Heroic Charisma: Improves reaction rolls with some NPCs and increases the amount of faction you gain or lose when faction is adjusted.
I have added support for all that was missing except for the falling damage part since AFAIK that is handled by the client.

New Rule
Code:

INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Character:ItemEnduranceRegenCap', '15', 'Endurance cap from items');
Code:

Index: EQEmuServer/common/ruletypes.h
===================================================================
--- EQEmuServer/common/ruletypes.h        (revision 1715)
+++ EQEmuServer/common/ruletypes.h        (working copy)
@@ -60,6 +60,7 @@
 RULE_INT ( Character, ItemStunResistCap, 35)
 RULE_INT ( Character, ItemStrikethroughCap, 35)
 RULE_INT ( Character, ItemATKCap, 250)
+RULE_INT ( Character, ItemEnduranceRegenCap, 15)
 RULE_INT ( Character, SkillUpModifier, 100) //skill ups are at 100%
 RULE_BOOL ( Character, SharedBankPlat, false) //off by default to prevent duping for now
 RULE_BOOL ( Character, BindAnywhere, false)
Index: EQEmuServer/zone/aggro.cpp
===================================================================
--- EQEmuServer/zone/aggro.cpp        (revision 1715)
+++ EQEmuServer/zone/aggro.cpp        (working copy)
@@ -316,6 +316,9 @@
        // Are they kos?
        // Are we stupid or are they green
        // and they don't have their gm flag on
+        int heroicCHA_mod = mob->itembonuses.HeroicCHA/25; // 800 Heroic CHA cap
+        if(heroicCHA_mod > THREATENLY_ARRGO_CHANCE)
+                heroicCHA_mod = THREATENLY_ARRGO_CHANCE;
        if
        (
        //old InZone check taken care of above by !mob->CastToClient()->Connected()
@@ -334,7 +337,7 @@
                        ||
                        (
                                fv == FACTION_THREATENLY
-                                && MakeRandomInt(0,99) < THREATENLY_ARRGO_CHANCE
+                                && MakeRandomInt(0,99) < THREATENLY_ARRGO_CHANCE - heroicCHA_mod
                        )
                )
        )
Index: EQEmuServer/zone/attack.cpp
===================================================================
--- EQEmuServer/zone/attack.cpp        (revision 1715)
+++ EQEmuServer/zone/attack.cpp        (working copy)
@@ -435,7 +435,7 @@
                if (!ghit) {        //if they are not using a garunteed hit discipline
                        bonus = 2.0 + skill/60.0 + (GetDEX()/200);
                        bonus = bonus * (100 + defender->spellbonuses.RiposteChance + defender->itembonuses.RiposteChance) / 100.0f;
-                        RollTable[0] = bonus;
+                        RollTable[0] = bonus + (itembonuses.HeroicDEX / 25); // 25 heroic = 1%, applies to ripo, parry, block
                }
        }
       
@@ -542,7 +542,7 @@
                if (!ghit) {        //if they are not using a garunteed hit discipline
                        bonus = 2.0 + skill/60.0 + (GetAGI()/200);
                        bonus = bonus * (100 + defender->spellbonuses.DodgeChance + defender->itembonuses.DodgeChance) / 100.0f;
-                        RollTable[3] = RollTable[2] + bonus;
+                        RollTable[3] = RollTable[2] + bonus - (itembonuses.HeroicDEX / 25) + (itembonuses.HeroicAGI / 25); // Remove the dex as it doesnt count for dodge
                }
        }
        else{
@@ -671,11 +671,11 @@
                mitigation_rating = 0.0;
                if(GetClass() == WIZARD || GetClass() == MAGICIAN || GetClass() == NECROMANCER || GetClass() == ENCHANTER)
                {
-                        mitigation_rating = (GetSkill(DEFENSE) / 4.0) + armor + 1;
+                        mitigation_rating = ((GetSkill(DEFENSE) + itembonuses.HeroicAGI/10) / 4.0) + armor + 1;
                }
                else
                {
-                        mitigation_rating = (GetSkill(DEFENSE) / 3.0) + (armor * 1.333333) + 1;
+                        mitigation_rating = ((GetSkill(DEFENSE) + itembonuses.HeroicAGI/10) / 3.0) + (armor * 1.333333) + 1;
                }
                mitigation_rating *= 0.847;
 
@@ -1270,6 +1270,7 @@
                        other->AvoidDamage(this, damage);
                        other->MeleeMitigation(this, damage, min_hit);
                        ApplyMeleeDamageBonus(skillinuse, damage);
+                        damage += itembonuses.HeroicSTR / 10;
                        damage = GetSkillDmgTaken(skillinuse, damage);
                        TryCriticalHit(other, skillinuse, damage);
                        mlog(COMBAT__DAMAGE, "Final damage after all reductions: %d", damage);
Index: EQEmuServer/zone/bonuses.cpp
===================================================================
--- EQEmuServer/zone/bonuses.cpp        (revision 1715)
+++ EQEmuServer/zone/bonuses.cpp        (working copy)
@@ -152,14 +152,22 @@
                        continue;
                AddItemBonuses(inst, newbon, false, true);
        }
+        // Caps
+        if(newbon->HPRegen > RuleI(Character, ItemHealthRegenCap) + (itembonuses.HeroicSTA/25))
+                newbon->HPRegen = RuleI(Character, ItemHealthRegenCap) + (itembonuses.HeroicSTA/25);
+
+        if(GetCasterClass() == 'I') {
+                if(newbon->ManaRegen > RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind) + (itembonuses.HeroicINT / 25))
+                        newbon->ManaRegen = RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind) + (itembonuses.HeroicINT / 25);
+        }
+        else if(GetCasterClass() == 'W') {
+                if(newbon->ManaRegen > RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind) + (itembonuses.HeroicWIS / 25))
+                        newbon->ManaRegen = RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind) + (itembonuses.HeroicWIS / 25);
+        }
       
-        //caps
-        if(newbon->ManaRegen > (RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind)))
-                newbon->ManaRegen = RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind);
-        if(newbon->HPRegen > RuleI(Character, ItemHealthRegenCap))
-                newbon->HPRegen = RuleI(Character, ItemHealthRegenCap);
-       
-       
+        if(newbon->EnduranceRegen > RuleI(Character, ItemEnduranceRegenCap) + itembonuses.HeroicSTR/25 + itembonuses.HeroicDEX/25 + itembonuses.HeroicAGI/25 + itembonuses.HeroicSTA/25)
+                        newbon->EnduranceRegen = RuleI(Character, ItemEnduranceRegenCap) + itembonuses.HeroicSTR/25 + itembonuses.HeroicDEX/25 + itembonuses.HeroicAGI/25 + itembonuses.HeroicSTA/25;
+                       
        SetAttackTimer();
 }
               
@@ -294,12 +302,15 @@
        if(newbon->haste < (sint8)item->Haste) {
                newbon->haste = item->Haste;
        }
-        if(item->Regen > 0) {
+        if(item->Regen > 0)
                newbon->HPRegen += item->Regen;
-        }
-        if(item->ManaRegen > 0) {
+
+        if(item->ManaRegen > 0)
                newbon->ManaRegen += item->ManaRegen;
-        }
+       
+        if(item->EnduranceRegen > 0)
+                newbon->EnduranceRegen += item->EnduranceRegen;
+
        if(item->Attack > 0) {
                if((newbon->ATK + item->Attack) > RuleI(Character, ItemATKCap))
                {
@@ -310,9 +321,6 @@
                        newbon->ATK += item->Attack;
                }
        }
-        if(item->EnduranceRegen > 0){
-                newbon->EnduranceRegen += item->EnduranceRegen;
-        }
        if(item->DamageShield > 0) {
                if((newbon->DamageShield + item->DamageShield) > RuleI(Character, ItemDamageShieldCap))
                        newbon->DamageShield = RuleI(Character, ItemDamageShieldCap);
Index: EQEmuServer/zone/client_mods.cpp
===================================================================
--- EQEmuServer/zone/client_mods.cpp        (revision 1715)
+++ EQEmuServer/zone/client_mods.cpp        (working copy)
@@ -213,10 +213,9 @@
 }
 
 sint32 Client::CalcHPRegen() {
-        sint32 regen = LevelRegen() + itembonuses.HPRegen + spellbonuses.HPRegen;
+        sint32 regen = LevelRegen() + itembonuses.HPRegen + spellbonuses.HPRegen + (itembonuses.HeroicSTA / 25);
        //AAs
        regen += GetAA(aaInnateRegeneration)
-                //+ GetAA(aaInnateRegeneration2) //not currently in the AA table anymore, so why bother?
                + GetAA(aaNaturalHealing)
                + GetAA(aaBodyAndMindRejuvenation)
                + GetAA(aaConvalescence)
@@ -847,8 +846,7 @@
 sint16 Client::CalcAC() {
 
        // new formula
-        int avoidance = 0;
-        avoidance = (acmod() + ((GetSkill(DEFENSE)*16)/9));
+        int avoidance = (acmod() + ((GetSkill(DEFENSE) + itembonuses.HeroicAGI/10)*16)/9);
        if (avoidance < 0)
                avoidance = 0;
 
@@ -856,12 +854,12 @@
        if (m_pp.class_ == WIZARD || m_pp.class_ == MAGICIAN || m_pp.class_ == NECROMANCER || m_pp.class_ == ENCHANTER) {
                //something is wrong with this, naked casters have the wrong natural AC
 //                mitigation = (spellbonuses.AC/3) + (GetSkill(DEFENSE)/2) + (itembonuses.AC+1);
-                mitigation = GetSkill(DEFENSE)/4 + (itembonuses.AC+1);
+                mitigation = (GetSkill(DEFENSE) + itembonuses.HeroicAGI/10)/4 + (itembonuses.AC+1);
                //this might be off by 4..
                mitigation -= 4;
        } else {
 //                mitigation = (spellbonuses.AC/4) + (GetSkill(DEFENSE)/3) + ((itembonuses.AC*4)/3);
-                mitigation = GetSkill(DEFENSE)/3 + ((itembonuses.AC*4)/3);
+                mitigation = (GetSkill(DEFENSE) + itembonuses.HeroicAGI/10)/3 + ((itembonuses.AC*4)/3);
                if(m_pp.class_ == MONK)
                        mitigation += GetLevel() * 13/10;        //the 13/10 might be wrong, but it is close...
        }
@@ -879,6 +877,16 @@
                        displayed += iksarlevel * 12 / 10;
        }
       
+        // Shield AC bonus for HeroicSTR
+        if(itembonuses.HeroicSTR) {
+                bool equiped = CastToClient()->m_inv.GetItem(14);
+                if(equiped) {
+                        uint8 shield = CastToClient()->m_inv.GetItem(14)->GetItem()->ItemType;
+                        if(shield == ItemTypeShield)
+                                displayed += itembonuses.HeroicSTR/2;
+                }
+        }
+       
        //spell AC bonuses are added directly to natural total
        displayed += spellbonuses.AC;
       
@@ -1051,6 +1059,11 @@
                regen = 2 + spellbonuses.ManaRegen + itembonuses.ManaRegen + (clevel / 5);
        }
 
+        if(GetCasterClass() == 'I')
+                regen += (itembonuses.HeroicINT / 25);
+        else
+                regen += (itembonuses.HeroicWIS / 25);
+       
        //AAs
        regen += GetAA(aaMentalClarity) + GetAA(aaBodyAndMindRejuvenation);
 
@@ -1886,7 +1899,7 @@
 
 sint32 Client::CalcEnduranceRegen() {
        sint32 regen = sint32(GetLevel() * 4 / 10) + 2;
-        regen += spellbonuses.EnduranceRegen + itembonuses.EnduranceRegen;
+        regen += spellbonuses.EnduranceRegen + itembonuses.EnduranceRegen + itembonuses.HeroicSTR/25 + itembonuses.HeroicSTA/25 + itembonuses.HeroicDEX/25 + itembonuses.HeroicAGI/25;
        regen = (regen * RuleI(Character, EnduranceRegenMultiplier)) / 100;
        return regen;
 }
Index: EQEmuServer/zone/faction.cpp
===================================================================
--- EQEmuServer/zone/faction.cpp        (revision 1715)
+++ EQEmuServer/zone/faction.cpp        (working copy)
@@ -540,6 +540,17 @@
                        // Get the characters current value with that faction
                        current_value = GetCharacterFactionLevel(faction_id[i]);
                       
+                        if(this->itembonuses.HeroicCHA) {
+                                int faction_mod = itembonuses.HeroicCHA / 5;
+                                // If our result isn't truncated to 0, then just do that
+                                if(npc_value[i] * faction_mod / 100 != 0)
+                                        npc_value[i] += npc_value[i] * faction_mod / 100;
+                                // If our result is truncated, then double a mob's value every once and a while to equal what they would have got
+                                else {
+                                        if(MakeRandomInt(0, 100) < faction_mod)
+                                                npc_value[i] *= 2;
+                                }
+                        }
                        //figure out their modifier
                        mod = fm.base + fm.class_mod + fm.race_mod + fm.deity_mod;
                        if(mod > MAX_FACTION)
Index: EQEmuServer/zone/special_attacks.cpp
===================================================================
--- EQEmuServer/zone/special_attacks.cpp        (revision 1715)
+++ EQEmuServer/zone/special_attacks.cpp        (working copy)
@@ -542,7 +542,7 @@
                }
 
                // solar - chance to assassinate
-                float chance = (10.0+(GetDEX()/10)); //18.5% chance at 85 dex 40% chance at 300 dex
+                int chance = 10 + (GetDEX()/10) + (itembonuses.HeroicDEX/10); //18.5% chance at 85 dex 40% chance at 300 dex
                if(
                        level >= 60 && // player is 60 or higher
                        other->GetLevel() <= 45 && // mob 45 or under
@@ -869,6 +869,8 @@
                                else
                                        TotalDmg = MakeRandomInt(1, MaxDmg);
 
+                                TotalDmg += itembonuses.HeroicDEX; //think this adds like this since archery hits less often than melee
+                               
                                int minDmg = 1;
                                if(GetLevel() > 25){
                                        //twice, for ammo and weapon
@@ -1895,8 +1897,8 @@
                        if((GetLevelCon(GetLevel(), defender->GetLevel()) == CON_LIGHTBLUE || GetLevelCon(GetLevel(), defender->GetLevel()) == CON_GREEN) && defender->GetLevel() <= 60 && !defender->IsClient()) {
                                // WildcardX: These chance formula's below are arbitrary. If someone has a better formula that is more
                                // consistent with live, feel free to update these.
-                                float AttackerChance = 0.20f + ((float)(GetLevel() - 51) * 0.005f);
-                                float DefenderChance = (float)MakeRandomFloat(0.00f, 1.00f);
+                                int AttackerChance = 20 + ((GetLevel() - 51) / 2) + (itembonuses.HeroicDEX / 10);
+                                int DefenderChance = MakeRandomInt(0, 100);
                                if(AttackerChance > DefenderChance) {
                                        mlog(COMBAT__ATTACKS, "Landed a headshot: Attacker chance was %f and Defender chance was %f.", AttackerChance, DefenderChance);
                                        // WildcardX: At the time I wrote this, there wasnt a string id for something like HEADSHOT_BLOW


Akkadius 11-08-2010 04:32 AM

Quote:

Originally Posted by Caryatis (Post 194031)
The base of heroics have been in for a while but there are a number of effects that were not supported:
EQ Forums



I have added support for all that was missing except for the falling damage part since AFAIK that is handled by the client.

New Rule
Code:

INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Character:ItemEnduranceRegenCap', '15', 'Endurance cap from items');


Code:

Index: EQEmuServer/common/ruletypes.h
===================================================================
--- EQEmuServer/common/ruletypes.h        (revision 1715)
+++ EQEmuServer/common/ruletypes.h        (working copy)
@@ -60,6 +60,7 @@
 RULE_INT ( Character, ItemStunResistCap, 35)
 RULE_INT ( Character, ItemStrikethroughCap, 35)
 RULE_INT ( Character, ItemATKCap, 250)
+RULE_INT ( Character, ItemEnduranceRegenCap, 15)
 RULE_INT ( Character, SkillUpModifier, 100) //skill ups are at 100%
 RULE_BOOL ( Character, SharedBankPlat, false) //off by default to prevent duping for now
 RULE_BOOL ( Character, BindAnywhere, false)
Index: EQEmuServer/zone/aggro.cpp
===================================================================
--- EQEmuServer/zone/aggro.cpp        (revision 1715)
+++ EQEmuServer/zone/aggro.cpp        (working copy)
@@ -316,6 +316,9 @@
        // Are they kos?
        // Are we stupid or are they green
        // and they don't have their gm flag on
+        int heroicCHA_mod = mob->itembonuses.HeroicCHA/25; // 800 Heroic CHA cap
+        if(heroicCHA_mod > THREATENLY_ARRGO_CHANCE)
+                heroicCHA_mod = THREATENLY_ARRGO_CHANCE;
        if
        (
        //old InZone check taken care of above by !mob->CastToClient()->Connected()
@@ -334,7 +337,7 @@
                        ||
                        (
                                fv == FACTION_THREATENLY
-                                && MakeRandomInt(0,99) < THREATENLY_ARRGO_CHANCE
+                                && MakeRandomInt(0,99) < THREATENLY_ARRGO_CHANCE - heroicCHA_mod
                        )
                )
        )
Index: EQEmuServer/zone/attack.cpp
===================================================================
--- EQEmuServer/zone/attack.cpp        (revision 1715)
+++ EQEmuServer/zone/attack.cpp        (working copy)
@@ -435,7 +435,7 @@
                if (!ghit) {        //if they are not using a garunteed hit discipline
                        bonus = 2.0 + skill/60.0 + (GetDEX()/200);
                        bonus = bonus * (100 + defender->spellbonuses.RiposteChance + defender->itembonuses.RiposteChance) / 100.0f;
-                        RollTable[0] = bonus;
+                        RollTable[0] = bonus + (itembonuses.HeroicDEX / 25); // 25 heroic = 1%, applies to ripo, parry, block
                }
        }
       
@@ -542,7 +542,7 @@
                if (!ghit) {        //if they are not using a garunteed hit discipline
                        bonus = 2.0 + skill/60.0 + (GetAGI()/200);
                        bonus = bonus * (100 + defender->spellbonuses.DodgeChance + defender->itembonuses.DodgeChance) / 100.0f;
-                        RollTable[3] = RollTable[2] + bonus;
+                        RollTable[3] = RollTable[2] + bonus - (itembonuses.HeroicDEX / 25) + (itembonuses.HeroicAGI / 25); // Remove the dex as it doesnt count for dodge
                }
        }
        else{
@@ -671,11 +671,11 @@
                mitigation_rating = 0.0;
                if(GetClass() == WIZARD || GetClass() == MAGICIAN || GetClass() == NECROMANCER || GetClass() == ENCHANTER)
                {
-                        mitigation_rating = (GetSkill(DEFENSE) / 4.0) + armor + 1;
+                        mitigation_rating = ((GetSkill(DEFENSE) + itembonuses.HeroicAGI/10) / 4.0) + armor + 1;
                }
                else
                {
-                        mitigation_rating = (GetSkill(DEFENSE) / 3.0) + (armor * 1.333333) + 1;
+                        mitigation_rating = ((GetSkill(DEFENSE) + itembonuses.HeroicAGI/10) / 3.0) + (armor * 1.333333) + 1;
                }
                mitigation_rating *= 0.847;
 
@@ -1270,6 +1270,7 @@
                        other->AvoidDamage(this, damage);
                        other->MeleeMitigation(this, damage, min_hit);
                        ApplyMeleeDamageBonus(skillinuse, damage);
+                        damage += itembonuses.HeroicSTR / 10;
                        damage = GetSkillDmgTaken(skillinuse, damage);
                        TryCriticalHit(other, skillinuse, damage);
                        mlog(COMBAT__DAMAGE, "Final damage after all reductions: %d", damage);
Index: EQEmuServer/zone/bonuses.cpp
===================================================================
--- EQEmuServer/zone/bonuses.cpp        (revision 1715)
+++ EQEmuServer/zone/bonuses.cpp        (working copy)
@@ -152,14 +152,22 @@
                        continue;
                AddItemBonuses(inst, newbon, false, true);
        }
+        // Caps
+        if(newbon->HPRegen > RuleI(Character, ItemHealthRegenCap) + (itembonuses.HeroicSTA/25))
+                newbon->HPRegen = RuleI(Character, ItemHealthRegenCap) + (itembonuses.HeroicSTA/25);
+
+        if(GetCasterClass() == 'I') {
+                if(newbon->ManaRegen > RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind) + (itembonuses.HeroicINT / 25))
+                        newbon->ManaRegen = RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind) + (itembonuses.HeroicINT / 25);
+        }
+        else if(GetCasterClass() == 'W') {
+                if(newbon->ManaRegen > RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind) + (itembonuses.HeroicWIS / 25))
+                        newbon->ManaRegen = RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind) + (itembonuses.HeroicWIS / 25);
+        }
       
-        //caps
-        if(newbon->ManaRegen > (RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind)))
-                newbon->ManaRegen = RuleI(Character, ItemManaRegenCap) + GetAA(aaExpansiveMind);
-        if(newbon->HPRegen > RuleI(Character, ItemHealthRegenCap))
-                newbon->HPRegen = RuleI(Character, ItemHealthRegenCap);
-       
-       
+        if(newbon->EnduranceRegen > RuleI(Character, ItemEnduranceRegenCap) + itembonuses.HeroicSTR/25 + itembonuses.HeroicDEX/25 + itembonuses.HeroicAGI/25 + itembonuses.HeroicSTA/25)
+                        newbon->EnduranceRegen = RuleI(Character, ItemEnduranceRegenCap) + itembonuses.HeroicSTR/25 + itembonuses.HeroicDEX/25 + itembonuses.HeroicAGI/25 + itembonuses.HeroicSTA/25;
+                       
        SetAttackTimer();
 }
               
@@ -294,12 +302,15 @@
        if(newbon->haste < (sint8)item->Haste) {
                newbon->haste = item->Haste;
        }
-        if(item->Regen > 0) {
+        if(item->Regen > 0)
                newbon->HPRegen += item->Regen;
-        }
-        if(item->ManaRegen > 0) {
+
+        if(item->ManaRegen > 0)
                newbon->ManaRegen += item->ManaRegen;
-        }
+       
+        if(item->EnduranceRegen > 0)
+                newbon->EnduranceRegen += item->EnduranceRegen;
+
        if(item->Attack > 0) {
                if((newbon->ATK + item->Attack) > RuleI(Character, ItemATKCap))
                {
@@ -310,9 +321,6 @@
                        newbon->ATK += item->Attack;
                }
        }
-        if(item->EnduranceRegen > 0){
-                newbon->EnduranceRegen += item->EnduranceRegen;
-        }
        if(item->DamageShield > 0) {
                if((newbon->DamageShield + item->DamageShield) > RuleI(Character, ItemDamageShieldCap))
                        newbon->DamageShield = RuleI(Character, ItemDamageShieldCap);
Index: EQEmuServer/zone/client_mods.cpp
===================================================================
--- EQEmuServer/zone/client_mods.cpp        (revision 1715)
+++ EQEmuServer/zone/client_mods.cpp        (working copy)
@@ -213,10 +213,9 @@
 }
 
 sint32 Client::CalcHPRegen() {
-        sint32 regen = LevelRegen() + itembonuses.HPRegen + spellbonuses.HPRegen;
+        sint32 regen = LevelRegen() + itembonuses.HPRegen + spellbonuses.HPRegen + (itembonuses.HeroicSTA / 25);
        //AAs
        regen += GetAA(aaInnateRegeneration)
-                //+ GetAA(aaInnateRegeneration2) //not currently in the AA table anymore, so why bother?
                + GetAA(aaNaturalHealing)
                + GetAA(aaBodyAndMindRejuvenation)
                + GetAA(aaConvalescence)
@@ -847,8 +846,7 @@
 sint16 Client::CalcAC() {
 
        // new formula
-        int avoidance = 0;
-        avoidance = (acmod() + ((GetSkill(DEFENSE)*16)/9));
+        int avoidance = (acmod() + ((GetSkill(DEFENSE) + itembonuses.HeroicAGI/10)*16)/9);
        if (avoidance < 0)
                avoidance = 0;
 
@@ -856,12 +854,12 @@
        if (m_pp.class_ == WIZARD || m_pp.class_ == MAGICIAN || m_pp.class_ == NECROMANCER || m_pp.class_ == ENCHANTER) {
                //something is wrong with this, naked casters have the wrong natural AC
 //                mitigation = (spellbonuses.AC/3) + (GetSkill(DEFENSE)/2) + (itembonuses.AC+1);
-                mitigation = GetSkill(DEFENSE)/4 + (itembonuses.AC+1);
+                mitigation = (GetSkill(DEFENSE) + itembonuses.HeroicAGI/10)/4 + (itembonuses.AC+1);
                //this might be off by 4..
                mitigation -= 4;
        } else {
 //                mitigation = (spellbonuses.AC/4) + (GetSkill(DEFENSE)/3) + ((itembonuses.AC*4)/3);
-                mitigation = GetSkill(DEFENSE)/3 + ((itembonuses.AC*4)/3);
+                mitigation = (GetSkill(DEFENSE) + itembonuses.HeroicAGI/10)/3 + ((itembonuses.AC*4)/3);
                if(m_pp.class_ == MONK)
                        mitigation += GetLevel() * 13/10;        //the 13/10 might be wrong, but it is close...
        }
@@ -879,6 +877,16 @@
                        displayed += iksarlevel * 12 / 10;
        }
       
+        // Shield AC bonus for HeroicSTR
+        if(itembonuses.HeroicSTR) {
+                bool equiped = CastToClient()->m_inv.GetItem(14);
+                if(equiped) {
+                        uint8 shield = CastToClient()->m_inv.GetItem(14)->GetItem()->ItemType;
+                        if(shield == ItemTypeShield)
+                                displayed += itembonuses.HeroicSTR/2;
+                }
+        }
+       
        //spell AC bonuses are added directly to natural total
        displayed += spellbonuses.AC;
       
@@ -1051,6 +1059,11 @@
                regen = 2 + spellbonuses.ManaRegen + itembonuses.ManaRegen + (clevel / 5);
        }
 
+        if(GetCasterClass() == 'I')
+                regen += (itembonuses.HeroicINT / 25);
+        else
+                regen += (itembonuses.HeroicWIS / 25);
+       
        //AAs
        regen += GetAA(aaMentalClarity) + GetAA(aaBodyAndMindRejuvenation);
 
@@ -1886,7 +1899,7 @@
 
 sint32 Client::CalcEnduranceRegen() {
        sint32 regen = sint32(GetLevel() * 4 / 10) + 2;
-        regen += spellbonuses.EnduranceRegen + itembonuses.EnduranceRegen;
+        regen += spellbonuses.EnduranceRegen + itembonuses.EnduranceRegen + itembonuses.HeroicSTR/25 + itembonuses.HeroicSTA/25 + itembonuses.HeroicDEX/25 + itembonuses.HeroicAGI/25;
        regen = (regen * RuleI(Character, EnduranceRegenMultiplier)) / 100;
        return regen;
 }
Index: EQEmuServer/zone/faction.cpp
===================================================================
--- EQEmuServer/zone/faction.cpp        (revision 1715)
+++ EQEmuServer/zone/faction.cpp        (working copy)
@@ -540,6 +540,17 @@
                        // Get the characters current value with that faction
                        current_value = GetCharacterFactionLevel(faction_id[i]);
                       
+                        if(this->itembonuses.HeroicCHA) {
+                                int faction_mod = itembonuses.HeroicCHA / 5;
+                                // If our result isn't truncated to 0, then just do that
+                                if(npc_value[i] * faction_mod / 100 != 0)
+                                        npc_value[i] += npc_value[i] * faction_mod / 100;
+                                // If our result is truncated, then double a mob's value every once and a while to equal what they would have got
+                                else {
+                                        if(MakeRandomInt(0, 100) < faction_mod)
+                                                npc_value[i] *= 2;
+                                }
+                        }
                        //figure out their modifier
                        mod = fm.base + fm.class_mod + fm.race_mod + fm.deity_mod;
                        if(mod > MAX_FACTION)
Index: EQEmuServer/zone/special_attacks.cpp
===================================================================
--- EQEmuServer/zone/special_attacks.cpp        (revision 1715)
+++ EQEmuServer/zone/special_attacks.cpp        (working copy)
@@ -542,7 +542,7 @@
                }
 
                // solar - chance to assassinate
-                float chance = (10.0+(GetDEX()/10)); //18.5% chance at 85 dex 40% chance at 300 dex
+                int chance = 10 + (GetDEX()/10) + (itembonuses.HeroicDEX/10); //18.5% chance at 85 dex 40% chance at 300 dex
                if(
                        level >= 60 && // player is 60 or higher
                        other->GetLevel() <= 45 && // mob 45 or under
@@ -869,6 +869,8 @@
                                else
                                        TotalDmg = MakeRandomInt(1, MaxDmg);
 
+                                TotalDmg += itembonuses.HeroicDEX; //think this adds like this since archery hits less often than melee
+                               
                                int minDmg = 1;
                                if(GetLevel() > 25){
                                        //twice, for ammo and weapon
@@ -1895,8 +1897,8 @@
                        if((GetLevelCon(GetLevel(), defender->GetLevel()) == CON_LIGHTBLUE || GetLevelCon(GetLevel(), defender->GetLevel()) == CON_GREEN) && defender->GetLevel() <= 60 && !defender->IsClient()) {
                                // WildcardX: These chance formula's below are arbitrary. If someone has a better formula that is more
                                // consistent with live, feel free to update these.
-                                float AttackerChance = 0.20f + ((float)(GetLevel() - 51) * 0.005f);
-                                float DefenderChance = (float)MakeRandomFloat(0.00f, 1.00f);
+                                int AttackerChance = 20 + ((GetLevel() - 51) / 2) + (itembonuses.HeroicDEX / 10);
+                                int DefenderChance = MakeRandomInt(0, 100);
                                if(AttackerChance > DefenderChance) {
                                        mlog(COMBAT__ATTACKS, "Landed a headshot: Attacker chance was %f and Defender chance was %f.", AttackerChance, DefenderChance);
                                        // WildcardX: At the time I wrote this, there wasnt a string id for something like HEADSHOT_BLOW


Keep up the good work bro. Wish I had the time to get involved with source.


All times are GMT -4. The time now is 08:11 AM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.