EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Development (https://www.eqemulator.org/forums/forumdisplay.php?f=590)
-   -   Double Attack change (https://www.eqemulator.org/forums/showthread.php?t=26340)

Congdar 09-26-2008 06:31 PM

Double Attack change
 
I think the Client::CheckDoubleAttack() method needs some modifications. Here it is currently:
Code:

bool Client::CheckDoubleAttack(bool AAadd, bool Triple) {
        int skill = 0;
        if (Triple)
        {
                if(!HasSkill(DOUBLE_ATTACK))
                        return(false);
               
                if (GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER)
                {
                        skill = GetSkill(DOUBLE_ATTACK)/2;
                } else {
                        return(false);
                }
        }
        else
        {
               
                //should these stack with skill, or does that ever even happen?
                int aaskill = GetAA(aaBestialFrenzy)*25 + GetAA(aaHarmoniousAttack)*25
                        + GetAA(aaKnightsAdvantage)*25 + GetAA(aaFerocity)*25;
                       
                if (!aaskill && !HasSkill(DOUBLE_ATTACK))
                {
                        return false;
                }
                skill = GetSkill(DOUBLE_ATTACK) + aaskill;
               
                //discipline effects
                skill += (spellbonuses.DoubleAttackChance + itembonuses.DoubleAttackChance) * 3;
               
                if(skill < 300)        //only gain if we arnt garunteed
                        CheckIncreaseSkill(DOUBLE_ATTACK);
        }
        if(MakeRandomInt(0, 299) < skill)
        {
                return true;
        }
        return false;
}

The first thing needing changes is the first argument bool AAadd, it doesn't get used anywhere in the method.
Next is the aa bonus *25 is too high. Max double attack skill for a 65 warrior is 255. In the following check if(skill < 300) if a warrior had only 225 skill + all 3 Ferocity AA's, the warrior would never skill up past 225 to max but would always double attack anyway in the random check below that. The magic number 299 is used there. If max skill and max ferocity, the warrior would always double attack. I think with the bonuses you should get real close to always, but not 100%. Rogue and Bards get a discipline that gives the a 10000% bonus so that's the only guarantee I know of.

Here's how I've rewritten the mentod. What do you think?
Code:

bool Client::CheckDoubleAttack(bool TripleAttack) {

        // If you don't have the double attack skill, return
        if(!HasSkill(DOUBLE_ATTACK))
                return false;

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

        // Used for maxSkill and triple attack calcs
        int class = GetClass();

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

        // Discipline bonuses give you 100% chance to double attack
        int buffs = (spellbonuses.DoubleAttackChance + itembonuses.DoubleAttackChance) * 3;

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

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


        // Half of Double Attack Skill used to check chance for Triple Attack
        if(TripleAttack) {
                // Only some Double Attack classes get Triple Attack
                if(class == MONK || class == WARRIOR || class == RANGER || class == 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;

                // You can gain skill even if you don't successfully double attack,
                // but put it here so you don't skill up on triple attacks
                CheckIncreaseSkill(DOUBLE_ATTACK);
        }

        // If your chance is greater than the RNG you are successful!
        if(chance > MakeRandomInt(0, maxSkill*.92)) {
                return true;
        }

        return false;
}


AndMetal 09-26-2008 07:12 PM

Quote:

Originally Posted by Congdar (Post 157013)
Code:

        // If your chance is greater than the RNG you are successful!
        if(chance > MakeRandomInt(0, maxSkill*.92)) {
                return true;
        }


Just to make sure I'm understanding correctly, that means the last 8% of skill-ups before the max cap would always land, since chance will equal at least the skill level of the character, not including any mods, right?

If that's the case, I think we may want to rethink this, especially in the scenario of newer levels. For example, a Monk on a progression server levels up to 50, so their max skill would be 240, so they would start double attacking 100% of the time after 220.8 (so starting at 221) skill. Say the player stops playing & the level cap has been raised to 65 (PoP I think?). They may have 240 skill, but the minimum to double attack 100% of the time (max being 265) is now 243.8 (so have to have 244+). The character hasn't changed, the rules of the server haven't changed, just the max level, but they won't be hitting like before. Granted, in that scenario, it's only a difference of about 9.5%, but that can still be significant.

Imo, I think it should be a static value, possibly set as a Rule. If it was set as a rule, would allow us to have a default value, similar to Live (which 300 sounds about right), but if you want to tune it for Progression-type servers, etc, you can.

Thoughts?

ChaosSlayer 09-26-2008 07:16 PM

AndMetal is right, value should be static, otherwise everytime max cap increses - your char sudenly becomes weaker out of the blue
make sure it will also work beyond lev 80 :D

Congdar 09-26-2008 07:22 PM

heh, right after I posted that I saw the *.92 I used to test and knew it wasn't right.

Congdar 09-26-2008 07:35 PM

Quote:

Originally Posted by AndMetal (Post 157017)
Imo, I think it should be a static value, possibly set as a Rule. If it was set as a rule, would allow us to have a default value, similar to Live (which 300 sounds about right), but if you want to tune it for Progression-type servers, etc, you can.
Thoughts?

300 isn't the right number either. Once Tribute goes in the warrior will have scores of up to 310 I think it was. I was hoping somebody would get the math right for me ;) but I think it needs to scale with the rule for max level as it is now but maybe add in the bonus to maxSkill too? Just a guess:
Code:

if(chance > MakeRandomInt(0, maxSkill + itembonuses.DoubleAttackChance + aaBonus)) {
This line is a bit off too. The Rogue and Bard disciplines adds 10000 to spellbonuses so then *3 + itembonuses is overkill in the calcs.
Code:

int buffs = (spellbonuses.DoubleAttackChance + itembonuses.DoubleAttackChance) * 3;

ChaosSlayer 09-26-2008 07:41 PM

two words: diminishing returns

let say with 300 you have 90% chance
next +10 gives you +1%
next +10 give you +0.5%
next +10 give you +0.25%
etc
or whatever numbers you want to use.

BUT at the very end leave soem sort of gap so there is NEVER a 100% chance even if your level is 200 and skill is 1k+

Congdar 09-26-2008 08:03 PM

so lets work up a calculation. if it should be a static value.. no static % then lets say you can never get more than 95% chance to double attack through bonuses. That means you always have a 5% chance to fail no matter how good you are. So if the best skill value available is a result of maxSkill + aaBonus + itembonuses.DoubleAttackChance then

if(chance > ((maxSkill + aaBonus + itembonuses.DoubleAttackChance)*1.05))

because you could only get 5% less than what is needed for max.

Is 95% the right number?

Congdar 09-26-2008 09:15 PM

almost forgot the change needed for client.h
Code:

bool        CheckDoubleAttack(bool TripleAttack = false);

Congdar 09-26-2008 09:21 PM

I totally missed the makerandom part
Code:


if(chance > MakeRandomInt(0, ((maxSkill + aaBonus + itembonuses.DoubleAttackChance)*1.05))


Congdar 09-28-2008 09:09 PM

To help with cut/paste:

find client.h line 645
Code:

        bool        CheckDoubleAttack(bool AAadd = false, bool Triple = false);
change to
Code:

        bool        CheckDoubleAttack(bool tripleAttack = false);
find client_process.cpp lines 288-291
Code:

                                        //triple attack: rangers, monks, warriors, berserkers over level 60
                                        if((((GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER)
                                                && GetLevel() >= 60) || SpecAttacks[SPECATK_TRIPLE])
                                          && CheckDoubleAttack(false,true))

change to
Code:

                                        //triple attack: rangers, monks, warriors, berserkers over level 60
                                        if((((GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER)
                                                && GetLevel() >= 60) || SpecAttacks[SPECATK_TRIPLE])
                                          && CheckDoubleAttack(true))

find client_process.cpp lines 297-298
Code:

                                        //quad attack, does this belong here??
                                        if(SpecAttacks[SPECATK_QUAD] && CheckDoubleAttack(false,true))

change to
Code:

                                        //quad attack, does this belong here??
                                        if(SpecAttacks[SPECATK_QUAD] && CheckDoubleAttack(true))

find attack.cpp line 2716 Delete the entire method Client::CheckDoubleAttack() and replace with this, it is completely rewritten.
Code:

bool Client::CheckDoubleAttack(bool tripleAttack) {

        // If you don't have the double attack skill, return
        if(!HasSkill(DOUBLE_ATTACK))
                return false;
       
        // You start with no chance of double attacking
        int chance = 0;
       
        // Used for maxSkill and triple attack calcs
        int classtype = GetClass();
       
        // The current skill level
        int skill = GetSkill(DOUBLE_ATTACK);
       
        // Discipline bonuses give you 100% chance to double attack
        int buffs = (spellbonuses.DoubleAttackChance + itembonuses.DoubleAttackChance) * 3;
       
        // The maximum value for the Class based on the database entry for level
        int maxSkill = MaxSkill(DOUBLE_ATTACK, classtype, GetLevel());
       
        // AA bonuses for the melee classes
        int aaBonus =
                (GetAA(aaBestialFrenzy)*10) +
                (GetAA(aaHarmoniousAttack)*10) +
                (GetAA(aaKnightsAdvantage)*10) +
                (GetAA(aaFerocity)*10) +
                (GetAA(aaDanceofBlades)*10);
       
        // 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;

                // You can gain skill even if you don't successfully double attack,
                // but put it here so you don't skill up on triple attacks
                CheckIncreaseSkill(DOUBLE_ATTACK);
        }
       
        // If your chance is greater than the RNG you are successful! Always have a 5% chance to fail.
        if(chance > MakeRandomInt(0, ((maxSkill + itembonuses.DoubleAttackChance + aaBonus)*1.05))) {
                return true;
        }

        return false;
}


Congdar 09-29-2008 12:30 PM

Can you move this to Submissions forum Trev, Cave?

AndMetal 09-29-2008 02:54 PM

Done. I'll merge it into SVN so everyone can start testing it out & comment out the old stuff just in case some want to utilize the older code.


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

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