Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Development

Development::Development Forum for development topics and for those interested in EQEMu development. (Not a support forum)

Reply
 
Thread Tools Display Modes
  #1  
Old 08-02-2012, 05:57 PM
Kayen
Developer
 
Join Date: Mar 2009
Location: -
Posts: 228
Default 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.
Reply With Quote
  #2  
Old 08-02-2012, 07:34 PM
Kayen
Developer
 
Join Date: Mar 2009
Location: -
Posts: 228
Default

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;
}
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 05:30 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3