EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Development (https://www.eqemulator.org/forums/forumdisplay.php?f=590)
-   -   Mob::CheckDoubleAttack problems (https://www.eqemulator.org/forums/showthread.php?t=35608)

Kayen 08-02-2012 05:57 PM

Mob::CheckDoubleAttack problems
 
Code:

bool Client::CheckDoubleAttack(bool tripleAttack) {

        // If you don't have the double attack skill, return
        if(!HasSkill(DOUBLE_ATTACK) && !(GetClass() == BARD || GetClass() == BEASTLORD))
                return false;

        // You start with no chance of double attacking
        int chance = 0;

        // Used for maxSkill and triple attack calcs
        int8 classtype = GetClass();

        // The current skill level
        uint16 skill = GetSkill(DOUBLE_ATTACK);

        // Discipline bonuses give you 100% chance to double attack
        sint16 buffs = spellbonuses.DoubleAttackChance + itembonuses.DoubleAttackChance;

        // The maximum value for the Class based on the server rule of MaxLevel
        int16 maxSkill = MaxSkill(DOUBLE_ATTACK, classtype, RuleI(Character, MaxLevel));

        // AA bonuses for the melee classes
        int32 aaBonus =
                GetAA(aaBestialFrenzy) +
                GetAA(aaHarmoniousAttack) +
                GetAA(aaKnightsAdvantage)*10 +
                GetAA(aaFerocity)*10;

        // Bard Dance of Blades Double Attack bonus is not cumulative
        if(GetAA(aaDanceofBlades)) {
                aaBonus += 500;
        }

        // Half of Double Attack Skill used to check chance for Triple Attack
        if(tripleAttack) {
                // Only some Double Attack classes get Triple Attack
                if((classtype == MONK) || (classtype == WARRIOR) || (classtype == RANGER) || (classtype == BERSERKER)) {
                        // We only get half the skill, but should get all the bonuses
                        chance = (skill/2) + buffs + aaBonus;
                }
                else {
                        return false;
                }
        }
        else {
                // This is the actual Double Attack chance
                chance = skill + buffs + aaBonus;
        }

        // If your chance is greater than the RNG you are successful! Always have a 5% chance to fail at max skills+bonuses.
        if(chance > MakeRandomInt(0, (maxSkill + itembonuses.DoubleAttackChance + aaBonus)*1.05)) {
                return true;
        }

        return false;
}

While trying to properly implement the AA's for double attack, I came to conclusion the entire function is rather flawed but being such a vital part of the attack code, I don't want to change anything without bring it up for review in the event that I am really tired and missing something.

Essentially its written as you have at any skill level a 95% chance to double attack as long as your skill = maxskill for that level.

Ie at level 15, maxskill is 85, so if your 85/85 you hit 95%, therefore making the actual skill level irrelevant.

Beast/Bard skill level on live is capped at 25. However if we use our formula as long as your 25/25 your at 95%. Flawed.

Further more, this makes all AA and Worn Effects (ferocity) 100% null because they are canceled out in the calculation.

Finally it assumes any spell bonuses = 100% chance which is just totally incorrect because the ranges of spell values for double attack in the dbase range from 4% to 10000% ect.

The bottom line calculation is.

Skill + itembonus + AAbonus + spellbonus >
Rand(0,MaxSkill + itembonus + AAbonus *1.05)

As you can see item bonuses and AA bonuses are in all cases negated from both sides of the equation. Assuming you have no spellbonuses you are left with your 95% chance.

After doing some searching I found that live uses a formula:
(skill*skillmod) + level * (100 + totalfocus/100) / 500;

Unless there is some objection I would like to change it to use something like this.

Kayen 08-02-2012 07:34 PM

Function will probably end up looking something like this.

Code:

bool Client::CheckDoubleAttack(bool tripleAttack) {

        //Check for bonuses that give you a double attack chance regardless of skill (ie Bestial Frenzy/Harmonious Attack AA)
        uint16 bonusGiveDA = aabonuses.GiveDoubleAttack + spellbonuses.GiveDoubleAttack + itembonuses.GiveDoubleAttack;

        if(!HasSkill(DOUBLE_ATTACK) && !bonusGiveDA)
                return false;
       
        int chance = 0;
       
        int8 classtype = GetClass();
       
        uint16 skill = GetSkill(DOUBLE_ATTACK);

        sint16 bonusDA = aabonuses.DoubleAttackChance + spellbonuses.DoubleAttackChance + itembonuses.DoubleAttackChance;
        sint16 skillmod = 0; //TODO: Apply all worn skill mods, spell skill mods.

        //Use skill calculations otherwise, if you only have AA applied GiveDoubleAttack chance then use that value as the base.
        if (skill)
                chance = ( (skill*(100+skillmod/100) + GetLevel()) * (100+bonusDA+bonusGiveDA /100)) /500
        else
                chance = bonusGiveDA + (bonusGiveDA * (100+bonusDA/100));

        //Live now uses a static Triple Attack skill (lv 46 = 2% lv 60 = 20%) - We do not have this skill on EMU ATM.
        //A reasonable forumla would then be TA = 20% * chance
        if(tripleAttack) {
                // Only some Double Attack classes get Triple Attack [This is already checked in client_processes.cpp]
                sint16 triple_bonus = spellbonuses.TripleAttackChance + itembonuses.TripleAttackChance;
                chance *= 20 + triple_bonus /100;
        }
        else
                return false;
       
       
        if((MakeRandomInt(0, 100) < chance)))
                return true;
       
        return false;
}



All times are GMT -4. The time now is 02:04 PM.

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