#11
|
|||
|
You know how you know someone is an engineer?
They'll tell you!
__________________
Realtime auction logger: http://ahungry.com/eqauctions/
| ||
|
#12
|
|||
|
Code:
//o-------------------------------------------------------------- //| GetHitChance; Yeahlight, Nov 24, 2008 //o-------------------------------------------------------------- //| Returns the chance to hit between attacker and defender //o-------------------------------------------------------------- int16 Mob::GetHitChance(Mob* attacker, Mob* defender, int skill_num) { bool debugFlag = true; //Yeahlight: If the target is sitting, the chance to hit them is 100% if(defender->GetAppearance() == SittingAppearance) return 999; sint16 ATKadjustment = (attacker->GetLevel() - defender->GetLevel()) * 3; sint16 hitRateAdjustment = (attacker->GetLevel() - defender->GetLevel()); int16 hitChance = 70; int16 weaponSkill = 0; if(ATKadjustment < 0) ATKadjustment = 0; if(attacker->IsClient()) weaponSkill = attacker->CastToClient()->GetSkill(skill_num); else weaponSkill = attacker->GetSkill(skill_num); int16 accuracyATK = (int)((float)weaponSkill * 2.70f) + 5 + ATKadjustment; if(accuracyATK == 0) accuracyATK = 1; int16 avoidanceAC = defender->GetAvoidanceAC(); //Yeahlight: 5% bonus evasion for defensive monks if(defender->GetClass() == MONK || defender->GetClass() == MONKGM) hitChance = hitChance - 5; //Yeahlight: 5% bonus accuracy for offensive rogues if(attacker->GetClass() == ROGUE || attacker->GetClass() == ROGUEGM) hitChance = hitChance + 5; //Yeahlight: As the attacker falls further under the level of the defender, it becomes harder to land a hit // Note: This will become a major tweak for class balancing! We must keep this on par with spell casting level penalties if(hitRateAdjustment < 0) { hitRateAdjustment = abs(hitRateAdjustment); if(hitRateAdjustment > 15) hitRateAdjustment = 15; float tempAdjustment = (float)hitRateAdjustment * 2.00f / 3.00f; hitRateAdjustment = (int)tempAdjustment; hitChance = hitChance - hitRateAdjustment; } //Yeahlight: Adjust hit rate based on the gap between accuracy and avoidance AC sint16 gapPercent = (sint16)(((float)(accuracyATK - avoidanceAC) / (float)(accuracyATK)) * 100.00f); sint16 gapAdjustment = ((float)gapPercent / 5.00f); if(gapAdjustment > 5) gapAdjustment = 5; else if(gapAdjustment < -5) gapAdjustment = -5; hitChance = hitChance + gapAdjustment; //Yeahlight: Debug messages if(debugFlag && defender->IsClient() && defender->CastToClient()->GetDebugMe()) defender->Message(LIGHTEN_BLUE, "Debug: %s's ATK accuracy: %i; Your AC evasion: %i; Hit rate: %i%s", attacker->GetName(), accuracyATK, avoidanceAC, hitChance, "%"); if(debugFlag && attacker->IsClient() && attacker->CastToClient()->GetDebugMe()) attacker->Message(LIGHTEN_BLUE, "Debug: Your ATK accuracy: %i; %s's AC evasion: %i; Hit rate: %i%s", accuracyATK, defender->GetName(), avoidanceAC, hitChance, "%"); CAST_CLIENT_DEBUG_PTR(attacker)->Log(CP_ATTACK, "Mob::GetHitChance: Your hit chance: %f", hitChance); CAST_CLIENT_DEBUG_PTR(defender)->Log(CP_ATTACK, "Mob::GetHitChance: %s's hit chance: %f", attacker->GetName(), hitChance); return hitChance; } | ||
|
#13
|
||||
|
Quote:
__________________
[52 Disciple] Downgrade (Human) <Azure Guard>
[31 Druid] Edarg (Halfling) | |||
|
#14
|
|||
|
Interesting code snippet. However, that doesn't tell us how ATK functions(in the eq sense uses it). The code you posted looks to be for hit rate %, which ATK doesn't affect.
| ||
|
#15
|
|||
|
Ok, so if I read this code right, then your percentage of landing blows is between 65% to 75% if you are >= target level.
And between 50% to 75% if your < target level. So the most you will ever hit a mob is 75% no matter what you do, and this is only based on level (and skill level which is based on level). | ||
|
#16
|
|||
|
Don't want to post all the code, but if you want to look...
https://github.com/EQEmu/Server/blob...one/attack.cpp | ||
|
#17
|
|||
|
I was just about to post that (was reading attack.cpp myself).
Important part: Code:
// This is called when the Mob is the one being hit int32 Mob::GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating) { float d = 10.0; float mit_roll = MakeRandomFloat(0, mit_rating); float atk_roll = MakeRandomFloat(0, atk_rating); if (atk_roll > mit_roll) { float a_diff = atk_roll - mit_roll; float thac0 = atk_rating * RuleR(Combat, ACthac0Factor); float thac0cap = attacker->GetLevel() * 9 + 20; if (thac0 > thac0cap) thac0 = thac0cap; d -= 10.0 * (a_diff / thac0); } else if (mit_roll > atk_roll) { float m_diff = mit_roll - atk_roll; float thac20 = mit_rating * RuleR(Combat, ACthac20Factor); float thac20cap = GetLevel() * 9 + 20; if (thac20 > thac20cap) thac20 = thac20cap; d += 10.0 * (m_diff / thac20); } if (d < 0.0) d = 0.0; else if (d > 20.0) d = 20.0; float interval = (damage - minhit) / 20.0; damage -= ((int)d * interval); damage -= (minhit * itembonuses.MeleeMitigation / 100); damage -= (damage * spellbonuses.MeleeMitigation / 100); return damage; } Code:
if (GetClass() == WIZARD || GetClass() == MAGICIAN || GetClass() == NECROMANCER || GetClass() == ENCHANTER) mitigation_rating = ((GetSkill(SkillDefense) + itembonuses.HeroicAGI/10) / 4.0) + armor + 1; else mitigation_rating = ((GetSkill(SkillDefense) + itembonuses.HeroicAGI/10) / 3.0) + (armor * 1.333333) + 1; mitigation_rating *= 0.847; mitigation_rating = mod_mitigation_rating(mitigation_rating, attacker); if (attacker->IsClient()) attack_rating = (attacker->CastToClient()->CalcATK() + ((attacker->GetSTR()-66) * 0.9) + (attacker->GetSkill(SkillOffense)*1.345)); else attack_rating = (attacker->GetATK() + (attacker->GetSkill(SkillOffense)*1.345) + ((attacker->GetSTR()-66) * 0.9)); attack_rating = attacker->mod_attack_rating(attack_rating, this); damage = GetMeleeMitDmg(attacker, damage, minhit, mitigation_rating, attack_rating);
__________________
Realtime auction logger: http://ahungry.com/eqauctions/
| ||
|
#18
|
||||
|
Quote:
You are thinking of ATK as just one thing. There are two components to ATK (chance to hit and how hard I hit), just as there are two components to AC. The two values combined is your displayed ATK, just as the two combined AC components equal your displayed AC value. | |||
|
#19
|
|||
|
lol, haven't seen code with THAC0's in it for a while.
__________________
The Ancient Ranger
Awake again. | ||
|
#20
|
||||
|
Quote:
| |||
|
|
|