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)

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #13  
Old 06-05-2025, 04:23 AM
Torven
Sarnak
 
Join Date: Aug 2014
Posts: 76
Default

Code:
// CheckResistSpell() from March 21 2000 client. (a month before Kunark launch)  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

uint __fastcall
FUN_0041a9a0(int param_1_00, undefined4 param_2_00, int spell_data, byte caster_level, int param_3, int caster, int spell_id)
{
  char cVar1;
  byte bVar2;
  undefined4 in_EAX;
  int iVar3;
  int iVar4;
  uint roll_result;
  uint charm_level_limit;
  byte bVarLevel;
  int iVar8;
  int iVar9;
  int iVar10;
  short sVar11;
  uint temp_resist;
  int local_10;
  int local_c;
  int level_diff;
  int local_4;
  
  level_diff = CONCAT22((short)((uint)in_EAX >> 0x10),GetLevel()) -
            (CONCAT31((int3)((uint)param_2_00 >> 8),caster_level) & 0xffff00ff);
  iVar10 = 0;
  iVar8 = -1;
  temp_resist = 0;
  local_c = 0xffffffff;
  local_4 = -1;
  if (spell_id == SPELL_982_CAZIC_TOUCH) {
    return 0;
  }
  if (spell_data == 0) {
    return 100;
  }
  if (*(int *)(param_1_00 + 0xa0) == 0) {
    return 100;
  }
  local_10 = param_1_00;
  bVarLevel = caster_level;
  if ((caster != 0) && (*(int *)(caster + 0xf0) == 27)) {		// probably body type.  27 is elementals
    caster_level = caster_level + 5;
    bVarLevel = caster_level;
  }
  do {
    if (((iVar8 != -1) ||
        ((iVar3 = FUN_0041a8d0(spell_data,iVar10), iVar9 = iVar10, iVar3 == 0 && (iVar9 = iVar8, false)
         ))) && (iVar4 = FUN_0041a8d0(spell_data,iVar10), iVar9 = iVar8, iVar3 = iVar10, iVar4 != 0))
    break;
    iVar10 = iVar10 + 1;
    iVar8 = iVar9;
    iVar3 = local_4;
  } while (iVar10 < 4);
  local_4 = iVar3;
  if (iVar9 == -1) {
    return 100;
  }
  local_c = iVar9;
  switch(*(undefined *)(spell_data + 0x1f9)) {
  case SPELL_RESIST_TYPE_1_MAGIC:
    iVar8 = FUN_004155e0(caster_level);
    if (((bVarLevel > 34) && (caster != 0)) && caster->GetClass() == WIZARD)) {
      if (*(char *)(spell_data + 0x1fa) == SPELL_EFFECT_TYPE_0_HP) goto LAB_0041ab3e;
      if (*(char *)(spell_data + 0x1fa) == SPELL_EFFECT_TYPE_79_INSTANTHP) {
        iVar8 = iVar8 + -10;
      }
    }
    break;
  case SPELL_RESIST_TYPE_2_FIRE:
    iVar8 = FUN_004156d0(caster_level);
    if (((bVarLevel > 34) && (caster != 0)) && caster->GetClass() == WIZARD)) {
      iVar8 = iVar8 + -10;
    }
    break;
  case SPELL_RESIST_TYPE_3_COLD:
    iVar8 = FUN_004157d0(caster_level);
    if (((bVarLevel > 34) && (caster != 0)) && caster->GetClass() == WIZARD)) {
LAB_0041ab3e:
      iVar8 = iVar8 + -10;
    }
    break;
  case SPELL_RESIST_TYPE_4_POISON:
    iVar8 = FUN_00415960(caster_level);
    break;
  case SPELL_RESIST_TYPE_5_DISEASE:
    iVar8 = FUN_004158a0(caster_level);
    break;
  default:
    goto LAB_LAND_SPELL;
  }
  cVar1 = *(char *)(iVar9 + 0x1fa + spell_data);
  if (cVar1 == SE_23_FEAR && IsNPC() && GetLevel() > 52)
  {
    return 100;
  }
  if (cVar1 == SE_22_CHARM && caster != 0 && !caster->IsNPC())
  {
    bVar2 = *(byte *)(spell_data + 0x204 + (uint)*(byte *)(caster + 0x95));		// level the caster gets this charm spell
    switch(GetRace()) {
    case RACE_44_FREEPORT_GUARD:
    case RACE_67_HIGHPASS_CITIZEN:
    case RACE_71_QEYNOS_CITIZEN:
    case RACE_77_NERIAK_CITIZEN:
    case RACE_78_ERUDITE_CITIZEN:
    case RACE_81_RIVERVALE_CITIZEN:
    case RACE_88_CLOCKWORK_GNOME:
    case RACE_90_HALAS_CITIIZEN:
    case RACE_92_GROB_CITIZEN:
    case RACE_93_OGGOK_CITIZEN:
    case RACE_94_KALADIM_CITIZEN:
    case RACE_106_FELGUARD:
    case RACE_112_FAYGUARD:
    case RACE_139_IKSAR_CITIZEN:
      goto LAB_RESIST_SPELL;			// guards are immune to charm casted by players
    case 0x2d:	// 45
    case 0x2e:
    case 0x2f:
    case 0x30:
    case 0x31:
    case 0x32:
    case 0x33:
    case 0x34:
    case 0x35:
    case 0x36:
    case 0x37:
    case 0x38:
    case 0x39:
    case 0x3a:
    case 0x3b:
    case 0x3c:
    case 0x3d:
    case 0x3e:
    case 0x3f:
    case 0x40:
    case 0x41:
    case 0x42:
    case 0x44:
    case 0x45:
    case 0x46:
    case 0x48:
    case 0x49:
    case 0x4a:
    case 0x4b:
    case 0x4c:
    case 0x4f:
    case 0x50:
    case 0x52:
    case 0x53:
    case 0x54:
    case 0x55:
    case 0x56:
    case 0x57:
    case 0x59:
    case 0x5b:
    case 0x5f:
    case 0x60:
    case 0x61:
    case 0x62:
    case 99:
    case 100:
    case 0x65:
    case 0x66:
    case 0x67:
    case 0x68:
    case 0x69:
    case 0x6b:
    case 0x6c:
    case 0x6d:
    case 0x6e:
    case 0x6f:
    case 0x71:
    case 0x72:
    case 0x73:
    case 0x74:
    case 0x75:
    case 0x76:
    case 0x77:
    case 0x78:
    case 0x79:
    case 0x7a:
    case 0x7b:
    case 0x7c:
    case 0x7d:
    case 0x7e:
    case 0x7f:
    case 0x80:
    case 0x81:
    case 0x82:
    case 0x83:
    case 0x84:
    case 0x85:
    case 0x86:
    case 0x87:
    case 0x88:
    case 0x89:
    case 0x8a:	// race 138 Yeti;  highest Kunark race is 167 though?
      bVarLevel = caster_level;		// this doesn't appear to do anything.  maybe vestigial
    }
    if (bVar2 > 50) {
      bVar2 = caster->GetLevel() / 2;
    }
    charm_level_limit = bVar2;
    if (caster->GetClass() != ENCHANTER) {
      bVar2 = *(byte *)(spell_data + 0x212);		// level enchanter gets the spell
      if (bVar2 != 0 && bVar2 < 51) {
        charm_level_limit = bVar2;
      }
    }
    charm_level_limit = (charm_level_limit * 15) / 10;
    if (charm_level_limit < 24) {
      charm_level_limit = 24;
    }
    if (spell_id < 183) {
      if (spell_id == SPELL_182_BEGUILE) {
LAB_0041acde:
        charm_level_limit = 37;
      }
      else if (spell_id == SPELL_141_BEGUILE_ANIMALS) {
        charm_level_limit = 43;
      }
      else if (spell_id == SPELL_142_ALLURE_OF_THE_WILD) {
        charm_level_limit = 51;
      }
    }
    else if (spell_id < 197) {
      if (spell_id == SPELL_196_DOMINATE_UNDEAD) {
        charm_level_limit = 32;
      }
      else {
        iVar10 = spell_id - 183;
LAB_0041acb4:
        if (iVar10 == 0) {				// Cajoling Whispers is spell ID 183;  Beguile Undead is 197
          charm_level_limit = 46;
        }
        else if (iVar10 == 1) {			// Allure is spell ID 184;  Cajole Undead is 198
          charm_level_limit = 51;
        }
      }
    }
    else if (spell_id < 261) {
      if (spell_id != SPELL_260_CHARM_ANIMALS) {
        iVar10 = spell_id - 197;
        goto LAB_0041acb4;
      }
      charm_level_limit = 33;
    }
    else if (spell_id < 1554) {
      if (spell_id == SPELL_1553_CALL_OF_KARANA) {
switchD_0041acf9_caseD_658:
        charm_level_limit = 51;
      }
      else if (spell_id == SPELL_725_SOLONS_SONG_OF_THE_SIRENS) goto LAB_0041acde;
    }
    else if (true) {
      switch(spell_id) {
      case SPELL_1556_TUNARES_REQUEST:
        charm_level_limit = 35;
        break;
      case SPELL_1624_THRALL_OF_BONES:
      case SPELL_1705_BOLTRANS_AGACERIE:
        goto switchD_0041acf9_caseD_658;
      case SPELL_1629_ENSLAVE_DEATH:
      case SPELL_1707_DICTATE:
        charm_level_limit = 52;
      }
    }
    if (charm_level_limit > 51) {
      charm_level_limit = 51;
    }
    iVar9 = local_c;
    if (charm_level_limit < GetLevel()) {
      if (*(int *)(caster + 0x74) != 0) {	// presumably some kind of IsClient() subclass check
        FUN_004ca2a0(*(int *)(caster + 0x74),s_Target_Too_High_level_for_your_c_005a8b14,0xd);
        return 100;
      }
      return 100;
    }
  }
  
  if (!IsNPC()) {
    if (iVar8 > 99) {
      iVar8 = 99;
    }
  }
  else if (iVar8 > 150) {
    return 100;
  }
  
  if (spell_id == SPELL_127_INVOKE_FEAR || spell_id == SPELL_59_PANIC_THE_DEAD || spell_id == SPELL_514_TERRORIZE_ANIMAL)
  {
    if (bVarLevel < GetLevel()) {
      iVar10 = -5;
    }
    else {
      iVar10 = -(uint)(caster_level >> 1);
    }
    iVar8 = iVar8 + iVar10;
    if (iVar8 < 5) {
      iVar8 = 5;
    }
  }
  
  if (spell_id == SPELL_1527_TREPIDATION || spell_id == SPELL_1550_REPULSE_ANIMAL || spell_id == SPELL_1532_DREAD_OF_NIGHT)
  {
    if (bVarLevel < GetLevel()) {
      iVar10 = -15;
    }
    else {
      iVar10 = -5 - caster_level / 2;
    }
    iVar8 = iVar8 + iVar10;
    if (iVar8 < 5) {
      iVar8 = 5;
    }
  }
  
  sVar11 = (short)iVar8;
  if (spell_id == SPELL_1544_ENFORCED_REVERENCE || spell_id == SPELL_1553_CALL_OF_KARANA || spell_id == SPELL_1624_THRALL_OF_BONES 
	|| spell_id == SPELL_1690_FASCINATION || spell_id == SPELL_1691_GLAMOUR_OF_KINTAZ || spell_id == SPELL_1705_BOLTRANS_AGACERIE)
  {
    sVar11 = sVar11 - 10;
  }
  
  iVar8 = IsUnresistableSpell(spell_data,spell_id);
  if (iVar8 == 0 && *(char *)(spell_data + 0x1fe) != 13) {		// spell type 13 (lifetap) will be false here and land
    temp_resist = temp_resist + (int)sVar11;
    if (true) {
      switch(*(undefined *)(iVar9 + 0x1fa + spell_data)) {
      case SE_0_CURRENTHP:
      case SE_79_CURRENT_HP_ONCE:
        if (IsNPC() && level_diff > 0 && GetLevel() > 16) {
          temp_resist = temp_resist + level_diff * 2;
        }
        break;
      case SE_22_CHARM:
        CharismaMod(&temp_resist,caster);
      case SE_3_MOVEMENTSPEED:
      case SE_20_BLIND:
      case SE_23_FEAR:
        if (param_3 == 0 && temp_resist < 5) {
          temp_resist = 5;
        }
        break;
      case SE_31_MEZ:
      case SE_34_CONFUSE:
      case SE_63_BLUR:
        CharismaMod(&temp_resist,caster);
        break;
      case SE_44_LYCANTHROPY:
        temp_resist = temp_resist + 0x1e;
      }
    }
    iVar8 = local_10;
    if (spell_id == SPELL_676_TASHAN || spell_id == SPELL_677_TASHANI || spell_id == SPELL_678_TASHANIA) {
      temp_resist = temp_resist * 2 / 3;
    }
	
	// resist floors
    if (IsNPC()) {
      if (level_diff > -11 && GetLevel() > 14 && (temp_resist < 10)) {
        temp_resist = 10;
      }
      if (level_diff < -20 || 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;
    }
    if (temp_resist > 100) {
      temp_resist = 100;
    }
	
    iVar10 = IsLullSpell(spell_id);
    if (iVar10 != 0) {
      if (spell_id == SPELL_728_KELINS_LUGUBRIOUS_LAMENT) {
        temp_resist = temp_resist / 2;
        if (temp_resist < 5) {
          temp_resist = 5;
        }
        effective_resist = 5;			// note: the decompile code reuses the charm_level_limit variable for this
      }									// but I renamed it starting from here for readability
      else {
        bVarLevel = GetLevel();
        if (bVarLevel < 15) {
          effective_resist = 10;
        }
        else if (bVarLevel < 25) {
          effective_resist = 20;
        }
        else if (bVarLevel < 35) {
          effective_resist = 33;
        }
        else if (bVarLevel < 40) {
          effective_resist = 42;
        }
        else {
          effective_resist = (-(uint)(bVarLevel < 50) & 0xffffffd2) + 100;
        }
      }
      if (temp_resist < effective_resist) {
        temp_resist = effective_resist;
      }
    }
	
    if (caster != nullptr && caster->IsNPC()) &&
       (caster->GetClass() == ENCHANTER || caster->GetClass() == CLASS_30_ENCHANTER_GM) &&
       caster->GetLevel() > 24)
	{
      effective_resist = GetLevel();
      if (effective_resist < temp_resist) {
        temp_resist = effective_resist;
      }
      if (temp_resist > 40) {
        temp_resist = 40;
      }
    }
    effective_resist = temp_resist;
    roll_result = Roll0(0,100);
	
    if (roll_result < 99 && roll_result <= effective_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)) ||
           (*(byte *)(spell_data + 0x212) < 13)))) || (*(char *)(local_4 + 0x1fa + spell_data) == SE_27_CANCELMAGIC)
         )
	  {
        cVar1 = *(char *)(iVar9 + 0x1fa + spell_data);		// first spell effect
        if (cVar1 != SE_0_CURRENTHP && cVar1 != SE_79_CURRENT_HP_ONCE) {
          return 100;
        }
        effective_resist = (effective_resist * 100 + roll_result * -100) / effective_resist;
        if (IsNPC()) {
          if (level_diff > 0 && GetLevel() > 16) {
            effective_resist = effective_resist + 5;
          }
          bVarLevel = GetLevel();
          if (bVarLevel > 29) {
            effective_resist = (effective_resist - 25) + bVarLevel;
          }
          if (bVarLevel < 15) {
            effective_resist = effective_resist - 5;
          }
        }
        if (spell_id == SPELL_88_HARM_TOUCH) {
          effective_resist = effective_resist - 45;
        }
        if (effective_resist < 0) {
          effective_resist = 0;
        }
        if (effective_resist > 100) {
          return 100;
        }
        return effective_resist;
      }
LAB_RESIST_SPELL:
      return 100;
    }
  }
LAB_LAND_SPELL:
  return 0;
}
Reply With Quote
 


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 07:38 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 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3