L L4D2node

CTerrorPlayer::ReplaceWithBot

0x009cb040 · 1375 bytes · __thiscall

_ZN13CTerrorPlayer14ReplaceWithBotEb

Decompiled

undefined (2 params)

/* WARNING: Type propagation algorithm not settling */
/* CTerrorPlayer::ReplaceWithBot(bool) */

SurvivorBot * __thiscall CTerrorPlayer::ReplaceWithBot(CTerrorPlayer *this,bool param_1)

{
  CBaseEdict *pCVar1;
  code *pcVar2;
  char cVar3;
  int iVar4;
  undefined4 uVar5;
  int iVar6;
  char *pcVar7;
  int *piVar8;
  CTerrorPlayer *pCVar9;
  ZombieReplacement local_248 [60];
  undefined4 local_20c;
  undefined4 local_208;
  undefined4 local_204;
  undefined4 local_200;
  undefined4 local_1fc;
  undefined4 local_1e8;
  undefined4 local_1e4;
  undefined4 local_1e0;
  undefined4 local_1dc;
  undefined4 local_1d8;
  undefined4 local_150;
  undefined4 local_14c;
  undefined4 local_148;
  undefined4 local_144;
  undefined4 local_140;
  undefined **local_10c;
  undefined4 local_108;
  undefined4 local_b8;
  undefined **local_9c;
  undefined4 local_98;
  undefined4 local_94;
  undefined **local_84;
  undefined4 local_80;
  undefined **local_6c;
  undefined4 local_68;
  undefined **local_5c;
  undefined4 local_58;
  undefined4 local_54;
  undefined **local_50;
  undefined4 local_4c;
  undefined4 local_3c;
  undefined4 local_38;
  undefined4 local_34;
  undefined4 local_30;
  undefined4 local_2c;
  undefined4 local_28;
  undefined4 local_24;
  undefined4 local_20;
  
  cVar3 = (**(code **)(*(int *)this + 0x778))(this);
  if ((cVar3 != '\0') && (!param_1)) {
    return (SurvivorBot *)0x0;
  }
  cVar3 = (**(code **)(*(int *)this + 300))(this);
  if (cVar3 == '\0') {
    iVar4 = CBaseEntity::GetTeamNumber((CBaseEntity *)this);
joined_r0x009cb18e:
    if (iVar4 == 3) {
      return (SurvivorBot *)0x0;
    }
  }
  else {
    cVar3 = (**(code **)(*(int *)this + 0x558))(this);
    if (cVar3 != '\0') {
      iVar4 = CBaseEntity::GetTeamNumber((CBaseEntity *)this);
      goto joined_r0x009cb18e;
    }
  }
  if (*(int *)(nav_edit._28_4_ + 0x30) != 0) {
    return (SurvivorBot *)0x0;
  }
  if (TheDirector[0x114] != (CDirector)0x0) {
    return (SurvivorBot *)0x0;
  }
  iVar4 = CBaseEntity::GetTeamNumber((CBaseEntity *)this);
  if (iVar4 == 2) {
    cVar3 = CDirector::NoSurvivorBots(TheDirector);
    if (cVar3 != '\0') {
      return (SurvivorBot *)0x0;
    }
    local_1e8 = 0;
    local_1e4 = 0;
    local_1e0 = 0;
    local_1dc = 0;
    local_1d8 = 0;
    local_144 = 0xffffffff;
    local_10c = &PTR_NetworkStateChanged_00c23e10;
    local_108 = 0xbf800000;
    local_b8 = 0xffffffff;
    local_9c = &PTR_NetworkStateChanged_00c0b6e0;
    local_98 = 0;
    local_94 = 0xbf800000;
    local_84 = &PTR_NetworkStateChanged_00c23e10;
    local_80 = 0xbf800000;
    local_6c = &PTR_NetworkStateChanged_00c23e10;
    local_68 = 0xbf800000;
    local_5c = &PTR_NetworkStateChanged_00c0b6e0;
    local_58 = 0;
    local_54 = 0xbf800000;
    local_50 = &PTR_NetworkStateChanged_00c23e10;
    local_4c = 0xbf800000;
    local_3c = 0xffffffff;
    local_38 = 0xffffffff;
    local_34 = 0;
    local_30 = 0;
    local_2c = 0;
    local_28 = 0;
    local_24 = 0;
    local_20 = 0xffffffff;
                    /* try { // try from 009cb2b7 to 009cb387 has its CatchHandler @ 009cb5b9 */
    SurvivorReplacement::Save((SurvivorReplacement *)local_248,this);
    iVar4 = *(int *)(this + 0x2ba0);
    if (iVar4 != 8) {
      if (this[0x6c] == (CTerrorPlayer)0x0) {
        pCVar1 = *(CBaseEdict **)(this + 0x30);
        if (pCVar1 != (CBaseEdict *)0x0) {
          *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
          iVar6 = CBaseEdict::GetChangeAccessor(pCVar1);
          *(undefined2 *)(iVar6 + 2) = 0;
        }
      }
      else {
        this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
      }
      *(undefined4 *)(this + 0x2ba0) = 8;
    }
    (**(code **)(*(int *)this + 0x70))(this,*DAT_0101739c);
    pcVar7 = (char *)SurvivorCharacterDisplayName(iVar4);
    pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<SurvivorBot>(pcVar7);
    if (pCVar9 != (CTerrorPlayer *)0x0) {
      if (param_1) {
        (**(code **)(*(int *)this + 0x194))(this,1);
      }
      SurvivorReplacement::Restore((SurvivorReplacement *)local_248,this,pCVar9);
    }
    if (iVar4 != *(int *)(this + 0x2ba0)) {
      if (this[0x6c] == (CTerrorPlayer)0x0) {
        pCVar1 = *(CBaseEdict **)(this + 0x30);
        if (pCVar1 != (CBaseEdict *)0x0) {
          *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
          iVar6 = CBaseEdict::GetChangeAccessor(pCVar1);
          *(undefined2 *)(iVar6 + 2) = 0;
        }
      }
      else {
        this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
      }
      *(int *)(this + 0x2ba0) = iVar4;
    }
    local_28 = 0;
    CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_34);
    local_24 = local_34;
    CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_34);
    local_1dc = 0;
    CUtlMemory<CTerrorWeapon*,int>::Purge((CUtlMemory<CTerrorWeapon*,int> *)&local_1e8);
    local_1d8 = local_1e8;
    CUtlMemory<CTerrorWeapon*,int>::Purge((CUtlMemory<CTerrorWeapon*,int> *)&local_1e8);
    goto LAB_009cb3e6;
  }
  iVar4 = CBaseEntity::GetTeamNumber((CBaseEntity *)this);
  if (iVar4 != 3) {
    return (SurvivorBot *)0x0;
  }
  local_20c = 0;
  local_208 = 0;
  local_204 = 0;
  local_200 = 0;
  local_1fc = 0;
  local_150 = 0;
  local_14c = 0;
  local_148 = 0;
  local_144 = 0;
  local_140 = 0;
                    /* try { // try from 009cb14f to 009cb15e has its CatchHandler @ 009cb5dc */
  ZombieReplacement::Save(local_248,this);
  uVar5 = (**(code **)(*(int *)this + 0x544))(this);
  switch(uVar5) {
  default:
    pCVar9 = (CTerrorPlayer *)0x0;
    goto LAB_009cb4cc;
  case 1:
    pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Smoker>("Smoker");
    break;
  case 2:
    pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Boomer>("Boomer");
    break;
  case 3:
    pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Hunter>("Hunter");
    break;
  case 4:
    pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Spitter>("Spitter");
    break;
  case 5:
    pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Jockey>("Jockey");
    break;
  case 6:
    pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Charger>("Charger");
    break;
  case 8:
                    /* try { // try from 009cb4aa to 009cb589 has its CatchHandler @ 009cb5dc */
    pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Tank>("Tank");
  }
  if (pCVar9 != (CTerrorPlayer *)0x0) {
    ZombieReplacement::Restore(local_248,this,pCVar9);
  }
LAB_009cb4cc:
  local_144 = 0;
  CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_150);
  local_140 = local_150;
  CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_150);
  local_200 = 0;
  CUtlMemory<CTerrorWeapon*,int>::Purge((CUtlMemory<CTerrorWeapon*,int> *)&local_20c);
  local_1fc = local_20c;
  CUtlMemory<CTerrorWeapon*,int>::Purge((CUtlMemory<CTerrorWeapon*,int> *)&local_20c);
LAB_009cb3e6:
  if (pCVar9 == (CTerrorPlayer *)0x0) {
    return (SurvivorBot *)0x0;
  }
  piVar8 = (int *)(**(code **)(*gameeventmanager + 0x1c))(gameeventmanager,"player_bot_replace",0,0)
  ;
  if (piVar8 == (int *)0x0) {
    return (SurvivorBot *)pCVar9;
  }
  pcVar2 = *(code **)(*piVar8 + 0x30);
  uVar5 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(this + 0x30));
  (*pcVar2)(piVar8,"player",uVar5);
  pcVar2 = *(code **)(*piVar8 + 0x30);
  uVar5 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(pCVar9 + 0x30));
  (*pcVar2)(piVar8,"bot",uVar5);
  (**(code **)(*gameeventmanager + 0x20))(gameeventmanager,piVar8,0);
  return (SurvivorBot *)pCVar9;
}

SourceMod gamedata

paste into addons/sourcemod/gamedata/<your_plugin>.txt
used as the SourceMod key — change to fit your plugin's convention
SourceMod library name (server / engine / matchmaking)

Just a Signatures{} block, ready to drop into a gamedata file. Wire it up in your plugin however you like - SDKCall, DHooks, raw memory ops, or anything else.



        

        

          

Type inference is best-effort from the C signature - sanity-check the DHooks types before shipping.

Return-type handling cheatsheet (DHookReturn)