After reviewing code and what i wrote i thought id redo and clean up a bit and try to explain more.
Heres WHY i did the changes to original code.
1. Original code used factors such as str/dex/agi which is incorrect.
the only thing that effects chance to hit are levels and weapon
skills.
2. Orginal caps on to hit were way to high/low in relation to live
3. Was not weighting weapon skill enough in chance to hit imho.
Basically in eqlive the following is true regarding to-hit values..
1. Level is the single biggest factor in to-hit rolls.
2. Offense skill and Weapon skill are the only other factors figured.
3. Attack buffs do NOT change it, stats do NOT change it
If the code below is terrible please let me know and perhaps i can give the forms outta here to someone that can code better.
2 known problems are
1. Weapon skill is checked off PRIMARY hand for BOTH weapons.
i THINK this is a bug someplace before my code when it calls
calls for weapon skill.
2. I am using educated guessing on the 35 min cap.
I based my work off some of the following links...
http://www.thesteelwarrior.org/forum...;threadid=3803
http://www.eqbeastlord.com/forums/viewtopic.php?t=10317
And more pages like that in general...
Anyhow here is the code... Line 156 is starting number in attack.cpp
Code:
////////////////////////////////////////////////////////
// To hit calcs go here goes here
////////////////////////////////////////////////////////
#ifdef IPC
if (other->IsNPC() && !other->CastToNPC()->IsInteractive()){
#else
if (other->IsNPC()) {
#endif
int8 chancetohit = 0;
int8 otherlevel = this->GetLevel();
int8 mylevel = other->GetLevel();
otherlevel = otherlevel ? otherlevel : 1;
mylevel = mylevel ? mylevel : 1;
int8 leveldif = (mylevel-otherlevel);
// chance to hit from behind the mob with equal levels should be around 60 percent
chancetohit = 60 + leveldif;
// cap the max/min to 73 percent and 35 percent respectively
if (chancetohit >= 73) {
chancetohit = 73;
}
else if (chancetohit <= 35) {
chancetohit = 35;
}
float tohit_roll = ((float)rand()/RAND_MAX)*100;
// Reposte discipline
if (IsClient() && CastToClient()->disc_inuse == 6) {
damage = -3;
return false;
}
if (tohit_roll > chancetohit){
#if EQDEBUG>=5
LogFile->write(EQEMuLog::Debug, "%s::AvoidDamage(%s) NPC missed %f:%f", GetName(), other->GetName(), tohit_roll, chancetohit);
#endif
damage = 0;
return false;
}
}
else if (other->IsNPC()){
int8 chancetohit = 0;
int8 otherlevel = this->GetLevel();
int8 mylevel = other->GetLevel();
otherlevel = otherlevel ? otherlevel : 1;
mylevel = mylevel ? mylevel : 1;
int8 leveldif = (mylevel-otherlevel);
// chance to hit from behind the mob with equal levels should be around 60 percent
chancetohit = 60 + leveldif;
// cap the max/min to 73 percent and 35 percent respectively
if (chancetohit >= 73) {
chancetohit = 73;
}
else if (chancetohit <= 35) {
chancetohit = 35;
}
float tohit_roll = ((float)rand()/RAND_MAX)*100;
if (tohit_roll > chancetohit){
damage = 0;
return false;
}
}
else if (other->IsClient()){
int8 chancetohit = 0;
int8 otherlevel = this->GetLevel();
int8 mylevel = other->GetLevel();
otherlevel = otherlevel ? otherlevel : 1;
mylevel = mylevel ? mylevel : 1;
int16 skillval = ((float)other->CastToClient()->GetSkill(attack_skill));
int16 offval = ((float)other->CastToClient()->GetSkill(OFFENSE));
int16 combo = (skillval + offval);
int16 leveldif = (mylevel-otherlevel);
int16 skilind = (combo/mylevel);
// Given that levels are equal and given that clients skills are maxxed for his/her level
// this will give very close to a 60 percent chance to hit from behind again.
// skillind is basically an index of how skilled for clients level is he/she.
// this should reflect live behavior in ceratin skill peaks and valleys that happen from 40-50 and 60-65.
chancetohit = (52 + leveldif + skilind);
// The below caps the skills again, in most parses i have seen 73 percent
// was max hit rate against a level 1 by a 65 level char so seems appropriate.
if (chancetohit >= 73) {
chancetohit = 73;
}
else if (chancetohit <= 35) {
chancetohit = 35;
}
///Check if it's a hit or miss
float tohit_roll = ((float)rand()/RAND_MAX)*100;
if (tohit_roll > chancetohit && other->CastToClient()->disc_inuse != 16){
damage = 0;
return false;
}
}
else {
LogFile->write(EQEMuLog::Error, "Unknown entity type: %s", this->GetName());
}
Any feedback is appreciated on this please