I will paste my translations of several resist function decompiles here for convenience. These and more are found on my public Google Drive.
Code:
// CheckResistSpell() from February 16 1999 client. (original launch CD) Decompiled with Ghidra
// Note that many of the subclass references and NULL checks were removed for readability
// Also note that the compiler reuses variables. I have renamed some variables with multiple names for readability
// A return of 100 means full resist. 0 means full hit
// param_1 = spell_data
// param_2 = caster level
// param_3 = no_resist_floor
// param_4 = caster_object
// param_5 = spell ID
// this + 0x38 = level
// uVar5 = roll
// uVar6 = final_resist
// sVar7 = level_diff
// 0x94 = IsNPC()
// iVar10 = start_resist
uint __thiscall
FUN_00416fd0(int this, int spell_data, byte caster_level, int no_resist_floor, undefined4 caster_object, int spell_id)
{
char cVar1;
byte level;
int iVar3;
int iVar4;
uint roll;
uint final_resist;
short level_diff;
int iVar8;
int iVar9;
int start_resist;
int local_4;
level = caster_level;
start_resist = 0;
level_diff = this->GetLevel() - caster_level;
temp_resist = 0;
local_4 = -1;
if (spell_data == nullptr) {
return 100;
}
iVar8 = -1;
if (*(int *)(this + 0xa0) == nullptr) {
return 100;
}
do {
if (((iVar8 != -1) ||
((iVar3 = FUN_00416f50(spell_data,start_resist), iVar9 = start_resist, iVar3 == 0 && (iVar9 = iVar8, false)
))) && (iVar4 = FUN_00416f50(spell_data,start_resist), iVar9 = iVar8, iVar3 = start_resist, iVar4 != 0))
break;
start_resist = start_resist + 1; // compiler optimizer reusing variables; this is basically 'i' for this loop
iVar8 = iVar9;
iVar3 = local_4; // -1
} while (start_resist < 4); // only 4 spell slots max in this era
local_4 = iVar3;
if (iVar9 == -1) {
return 100; // no valid spell slots
}
switch(*(undefined *)(spell_data + 0x1f9)) { // spell resist type
case SPELL_RESIST_TYPE_1_MAGIC:
start_resist = GetMR(level); // attacker's level; needed to modify resist by level difference
break;
case SPELL_RESIST_TYPE_2_FIRE:
start_resist = GetFR(level);
break;
case SPELL_RESIST_TYPE_3_COLD:
start_resist = GetCR(level);
break;
case SPELL_RESIST_TYPE_4_POISON:
start_resist = GetPR(level);
break;
case SPELL_RESIST_TYPE_5_DISEASE:
start_resist = GetDR(level);
break;
default:
goto LAB_LAND_SPELL;
}
iVar8 = *(int *)(this + 0xa0); // used in IsNPC() lines that I removed for readability
if (!IsNPC()) {
if (start_resist > 99) {
start_resist = 99; // players capped at 99
}
}
else if (start_resist > 150) {
return 100; // guaranteed full resist if resist > 150
}
temp_resist = temp_resist + start_resist;
if (true) {
switch(*(undefined *)(iVar9 + 0x1fa + spell_data)) { // first spell slot effect
case SE_0_CURRENTHP:
case SE_79_CURRENT_HP_ONCE:
if (IsNPC() && level_diff > 0 && this->GetLevel() > 16) {
temp_resist = temp_resist + level_diff * 2;
}
break;
case SE_22_CHARM:
ModResistCHA(&temp_resist,caster_object);
case SE_3_MOVEMENTSPEED:
case SE_20_BLIND:
case SE_23_FEAR:
if (no_resist_floor == 0 && temp_resist < 5) {
temp_resist = 5;
}
break;
case SE_31_MEZ:
case SE_34_CONFUSE:
case SE_63_BLUR:
ModResistCHA(&temp_resist,caster_object);
break;
case SE_44_LYCANTHROPY:
temp_resist = temp_resist + 30;
}
}
// NPC target resist floors
if (IsNPC()) {
if (level_diff > -11 && this->GetLevel() > 14 && temp_resist < 10) {
temp_resist = 10;
}
if ((level_diff < -20) || this->GetLevel() < 15)) {
if (temp_resist < 2) {
temp_resist = 2;
}
}
else if (temp_resist < 5) {
temp_resist = 5;
}
}
else if (temp_resist < 1) {
temp_resist = 1; // player targets floor at 1
}
if (temp_resist > 100) {
temp_resist = 100; // resist capped at 100 here for everything
}
final_resist = temp_resist;
roll = RandNum(0,100); // roll a number from 0 to 99 inclusive
if (roll < 99 && roll <= final_resist)
{
if (local_4 != -1 && // -1 means there is only one valid spell effect
(cVar1 = *(char *)(iVar9 + 0x1fa + spell_data), cVar1 == SE_0_CURRENTHP || cVar1 == SE_79_CURRENT_HP_ONCE))
{
return 100; // if there are multiple effects in the spell, and the first effect is damage, then full resist
}
cVar1 = *(char *)(iVar9 + 0x1fa + spell_data); // get first spell effect
if (cVar1 == SE_0_CURRENTHP || cVar1 == SE_79_CURRENT_HP_ONCE) // only pure DD spells may partial hit
{
// calculate possible partial damage; still may full resist. Only single effect spells with SE 0 or 79 end up here
final_resist = (final_resist * 100 + roll * -100) / final_resist;
if (IsNPC())
{
if (level_diff > 0 && this->GetLevel() > 16) {
final_resist = final_resist + 5; // yellows and reds resist more
}
level = this->GetLevel(); // target's level
if (level > 29) {
final_resist = (final_resist - 25) + level; // level 30+ mobs resist more; the higher the level the more it resists
}
if (level < 15) {
final_resist = final_resist - 5; // newbie mobs resist less
}
}
if (spell_id == SPELL_88_HARM_TOUCH) {
final_resist = final_resist - 15;
}
if (final_resist < 0) {
final_resist = 0;
}
if (final_resist < 101) {
return final_resist;
}
}
return 100; // 100 means zero damage/full resist
}
LAB_LAND_SPELL:
return 0; // 0 means full damage
}