L L4D2node

CDirector::TryToTakeOverCharacter

0x00877e80 · 639 bytes · __thiscall

_ZN9CDirector22TryToTakeOverCharacterER23DirectorNewPlayerType_t21SurvivorCharacterType

Decompiled

undefined (3 params)

/* CDirector::TryToTakeOverCharacter(DirectorNewPlayerType_t&, SurvivorCharacterType) */

undefined4 __thiscall
CDirector::TryToTakeOverCharacter
          (CDirector *this,DirectorNewPlayerType_t *param_1,undefined4 param_3)

{
  uint uVar1;
  char cVar2;
  undefined4 uVar3;
  undefined4 uVar4;
  undefined4 uVar5;
  SurvivorBot *pSVar6;
  undefined4 uVar7;
  int iVar8;
  int *piVar9;
  CTerrorPlayer *pCVar10;
  undefined *puVar11;
  
  uVar3 = SurvivorCharacterName(param_3);
  iVar8 = 0;
  uVar1 = *(uint *)param_1;
  if (((uVar1 != 0xffffffff) &&
      (puVar11 = g_pEntityList + (uVar1 & 0xfff) * 0x10, puVar11 != (undefined *)0xfffffffc)) &&
     (*(uint *)(puVar11 + 8) == uVar1 >> 0xc)) {
    iVar8 = *(int *)(puVar11 + 4);
  }
  uVar4 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(iVar8 + 0x30));
  uVar1 = *(uint *)param_1;
  piVar9 = (int *)0x0;
  if (((uVar1 != 0xffffffff) &&
      (puVar11 = g_pEntityList + (uVar1 & 0xfff) * 0x10, puVar11 != (undefined *)0xfffffffc)) &&
     (*(uint *)(puVar11 + 8) == uVar1 >> 0xc)) {
    piVar9 = *(int **)(puVar11 + 4);
  }
  uVar5 = (**(code **)(*piVar9 + 0xb8))(piVar9);
  DevMsg(1,"[TAKEOVER]: %s (%d) wants to take over character %s\n",uVar5,uVar4,uVar3);
  piVar9 = (int *)CTerrorPlayer::GetPlayerByCharacter(param_3);
  if (piVar9 != (int *)0x0) {
    uVar3 = (**(code **)(*piVar9 + 0x778))(piVar9);
    if ((char)uVar3 == '\0') {
      uVar4 = (**(code **)(*engine + 0x40))(engine,piVar9[0xc]);
      uVar5 = (**(code **)(*piVar9 + 0xb8))(piVar9);
      uVar7 = SurvivorCharacterName(param_3);
      DevMsg(1,"[TAKEOVER]: %s is already posessed by %s (%d)\n",uVar7,uVar5,uVar4);
      return uVar3;
    }
    pSVar6 = (SurvivorBot *)__dynamic_cast(piVar9,&CTerrorPlayer::typeinfo,&SurvivorBot::typeinfo,0)
    ;
    if (pSVar6 != (SurvivorBot *)0x0) {
      if ((*(int *)(pSVar6 + 0x4308) != 0) &&
         (cVar2 = IsHumanSpectatorValid(this,pSVar6), cVar2 != '\0')) {
        return 0;
      }
      NewPlayerPossessBot(this,param_1,pSVar6);
      return uVar3;
    }
  }
  cVar2 = IsTeamFull(this,2,1);
  if (cVar2 == '\0') {
    pCVar10 = (CTerrorPlayer *)0x0;
    uVar1 = *(uint *)param_1;
    if (((uVar1 != 0xffffffff) &&
        (puVar11 = g_pEntityList + (uVar1 & 0xfff) * 0x10, puVar11 != (undefined *)0xfffffffc)) &&
       (*(uint *)(puVar11 + 8) == uVar1 >> 0xc)) {
      pCVar10 = *(CTerrorPlayer **)(puVar11 + 4);
    }
    CTerrorPlayer::SetDesiredCharacter(pCVar10,param_3);
    piVar9 = (int *)0x0;
    uVar1 = *(uint *)param_1;
    if (((uVar1 != 0xffffffff) &&
        (puVar11 = g_pEntityList + (uVar1 & 0xfff) * 0x10, puVar11 != (undefined *)0xfffffffc)) &&
       (*(uint *)(puVar11 + 8) == uVar1 >> 0xc)) {
      piVar9 = *(int **)(puVar11 + 4);
    }
    (**(code **)(*piVar9 + 0x194))(piVar9,2);
    return 1;
  }
  return 0;
}

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)