MajorMUD Dodge Formula

General MajorMUD Discussion
Post Reply
User avatar
syntax
Site Admin
Posts: 530
Joined: Tue Jun 02, 2009 10:02 am

MajorMUD Dodge Formula

Post by syntax »

There are a few posts on here about this on here and bunch of speculation on charm, encumbrance, etc. This post was pretty close, but I believe I have deciphered the actual dodge formula:

Code: Select all

nDodge = Fix(nCharLevel / 5)
nDodge = nDodge + Fix((nCharm - 50) / 5)
nDodge = nDodge + Fix((nAgility - 50) / 3)
nDodge = nDodge + nPlusDodge '[cumulative dodge from: abilities + auras + race + class + items]

If nCurrentEncum > 0 And nMaxEncum > 0 Then
    nEncumPct = Fix((nCurrentEncum / nMaxEncum) * 100)
End If
If nEncumPct < 33 Then
    nDodge = nDodge + 10 - Fix(nEncumPct / 10)
End If
From these snippets in the dll...

Code: Select all

function _move_player_to_fighter

arg2[8] = _get_user_ability_value(0x22, 0xffffffff, USER_RECORD, 0, nullptr);
arg2[8] += ((USER_RECORD + 0xac) - 50) / 5 + (USER_RECORD + 0x94) / 5 + ((USER_RECORD + 0xaa) - 50) / 3;

[... later in code]

if ((USER_RECORD + 0x708) < 33 && (USER_RECORD + 0xb0) > 0) {
    arg2[8] += 10 - (USER_RECORD + 0x708) / 10;
}
Note that dodge is checked only after the AC check and determined a hit. Therefore, sometimes the perceived dodge percentage fluctuates depending on the mob.


User avatar
syntax
Site Admin
Posts: 530
Joined: Tue Jun 02, 2009 10:02 am

Re: MajorMUD Dodge Formula

Post by syntax »

Side note after some further testing...
  • Dodge is not initially capped at 95%.
  • Upon each attack, the mob's accuracy is checked. If the mob's accuracy <= 8, the dodge chance is reduced to 0.
  • Otherwise, the dodge value as calculated above is multiplied by 10 and divided by the mob's accuracy divided by 8. e.g. (nUserDodge * 10) / (nMobAttackAccuracy / 8)
  • The result of that is then capped at 95%.
  • Finally, if the attack is a backstab, the dodge chance from there is divided by 5.

Code: Select all

//_calculate_attack function

int32_t ebx_1; //establish temp variable ebx_1

if (*(uint32_t*)arg1 <= 8) { //take the first 4 bytes of the argument array, which is the accuracy of the attacker's attack
    ebx_1 = 0; //dodge = 0
} else {
    int32_t edx_30 = *(uint32_t*)arg1; //put accuracy of the attacker's attack into edx_30
    
    if (edx_30 < 0) { //from the way I read this, this will never evaluate to true because the above would have evaluated to true before this one
        edx_30 += 7;
    }
    
    //arg2 + 32 is the current calculated dodge value
    //edx_30 >> 3 is a bitshift which effectively means divide by 8
    ebx_1 = (int64_t)(*(uint32_t*)((char*)arg2 + 32) * 10) / (edx_30 >> 3);
}

if (ebx_1 > 95) { //cap dodge at 95
    ebx_1 = 95;
}

if (ATTACK_TYPE == 4) { //is it a backstab?
    ebx_1 = (int64_t)ebx_1 / 5; //if so divide by 5
}


//generate random number between 0 and 100 and if the dodge value is greater... we dodge
if (*(uint32_t*)((char*)arg2 + 0x20) > 0 && ebx_1 > _genrdn(0, 100)) {
    data_495fd0 = 3;
    data_495fd4 = 0;
    return &data_495fd0;
}


Post Reply