PDA

View Full Version : Mob::CheckDoubleAttack problems


Kayen
08-02-2012, 05:57 PM
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.

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;
}