L L4D2node

CTerrorPlayer::OnPreThinkGhostState

0x009c2a20 · 2831 bytes · __thiscall

_ZN13CTerrorPlayer20OnPreThinkGhostStateEv

Decompiled

undefined (1 param)

/* CTerrorPlayer::OnPreThinkGhostState() */

void __thiscall CTerrorPlayer::OnPreThinkGhostState(CTerrorPlayer *this)

{
  CBaseEdict *pCVar1;
  code *pcVar2;
  char cVar3;
  bool bVar4;
  int iVar5;
  CNavArea *this_00;
  Checkpoint *this_01;
  int iVar6;
  CDirector *this_02;
  undefined1 *puVar7;
  int *piVar8;
  uint uVar9;
  uint uVar10;
  longdouble lVar11;
  CTerrorPlayer *local_e8;
  char local_e4;
  float local_e0;
  float local_dc;
  float local_d8;
  float local_d4;
  float local_cc;
  float local_c8;
  float local_c4;
  undefined4 local_bc;
  undefined4 local_b8;
  undefined4 local_b4;
  float local_ac;
  float local_a8;
  float local_a4;
  float local_9c;
  float local_98;
  float local_94;
  undefined4 local_8c;
  undefined1 local_88;
  undefined1 local_87;
  float local_70;
  float local_6c;
  float local_68;
  Vector local_64 [36];
  uint local_40;
  int local_24;
  
  cVar3 = CDirector::IsInTransition(TheDirector);
  if (cVar3 != '\0') {
    return;
  }
  lVar11 = (longdouble)CountdownTimer::Now();
  puVar7 = &stack0xfffffef4;
  if (*(float *)(this + 0x2cbc) <= (float)lVar11) {
    lVar11 = (longdouble)CountdownTimer::Now();
    if ((float)lVar11 + 0.25 != *(float *)(this + 0x2cbc)) {
      (**(code **)(*(int *)(this + 0x2cb4) + 4))();
      *(float *)(this + 0x2cbc) = (float)lVar11 + 0.25;
    }
    if (*(float *)(this + 0x2cb8) != 0.25) {
      (**(code **)(*(int *)(this + 0x2cb4) + 4))();
      *(undefined4 *)(this + 0x2cb8) = 0x3e800000;
    }
    if (*(int *)(this + 0x2ca8) != 0) {
      if (this[0x6c] == (CTerrorPlayer)0x0) {
        pCVar1 = *(CBaseEdict **)(this + 0x30);
        if (pCVar1 != (CBaseEdict *)0x0) {
          *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
          iVar5 = CBaseEdict::GetChangeAccessor(pCVar1);
          *(undefined2 *)(iVar5 + 2) = 0;
        }
      }
      else {
        this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
      }
      *(undefined4 *)(this + 0x2ca8) = 0;
    }
    if ((*(int *)(DirectorNoSpecials._28_4_ + 0x30) != 0) &&
       (uVar9 = *(uint *)(this + 0x2ca8) | 1, *(uint *)(this + 0x2ca8) != uVar9)) {
      if (this[0x6c] == (CTerrorPlayer)0x0) {
        pCVar1 = *(CBaseEdict **)(this + 0x30);
        if (pCVar1 != (CBaseEdict *)0x0) {
          *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
          iVar5 = CBaseEdict::GetChangeAccessor(pCVar1);
          *(undefined2 *)(iVar5 + 2) = 0;
        }
      }
      else {
        this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
      }
      *(uint *)(this + 0x2ca8) = uVar9;
    }
    this_02 = TheDirector;
    if (((*(int *)(TheDirector + 0x194) - 2U < 2) &&
        (*(int *)(ZombieGhostCooldown._28_4_ + 0x30) != 0)) &&
       (uVar9 = *(uint *)(this + 0x2ca8) | 0x20, *(uint *)(this + 0x2ca8) != uVar9)) {
      if (this[0x6c] == (CTerrorPlayer)0x0) {
        pCVar1 = *(CBaseEdict **)(this + 0x30);
        if (pCVar1 != (CBaseEdict *)0x0) {
          *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
          iVar5 = CBaseEdict::GetChangeAccessor(pCVar1);
          *(undefined2 *)(iVar5 + 2) = 0;
          this_02 = TheDirector;
        }
      }
      else {
        this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
      }
      *(uint *)(this + 0x2ca8) = uVar9;
    }
    cVar3 = CDirector::HasAnySurvivorLeftSafeArea(this_02);
    if (((cVar3 == '\0') && (*(int *)(ZombieGhostsSpawnInStart._28_4_ + 0x30) == 0)) &&
       ((this[0x2ccd] == (CTerrorPlayer)0x0 &&
        (uVar9 = *(uint *)(this + 0x2ca8) | 2, *(uint *)(this + 0x2ca8) != uVar9)))) {
      if (this[0x6c] == (CTerrorPlayer)0x0) {
        pCVar1 = *(CBaseEdict **)(this + 0x30);
        if (pCVar1 != (CBaseEdict *)0x0) {
          *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
          iVar5 = CBaseEdict::GetChangeAccessor(pCVar1);
          *(undefined2 *)(iVar5 + 2) = 0;
        }
      }
      else {
        this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
      }
      *(uint *)(this + 0x2ca8) = uVar9;
    }
    cVar3 = CTerrorGameRules::IsSurvivalMode();
    if (((cVar3 != '\0') && (**(char **)(TheDirector + 0x640) == '\0')) &&
       (uVar9 = *(uint *)(this + 0x2ca8) | 4, *(uint *)(this + 0x2ca8) != uVar9)) {
      if (this[0x6c] == (CTerrorPlayer)0x0) {
        pCVar1 = *(CBaseEdict **)(this + 0x30);
        if (pCVar1 != (CBaseEdict *)0x0) {
          *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
          iVar5 = CBaseEdict::GetChangeAccessor(pCVar1);
          *(undefined2 *)(iVar5 + 2) = 0;
        }
      }
      else {
        this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
      }
      *(uint *)(this + 0x2ca8) = uVar9;
    }
    cVar3 = CTerrorGameRules::IsScavengeMode();
    if ((((cVar3 == '\0') && (cVar3 = CTerrorGameRules::IsSurvivalMode(), cVar3 == '\0')) &&
        (cVar3 = CDirector::IsFinale(TheDirector), cVar3 == '\0')) &&
       (*(char *)(*(int *)(TheDirector + 0x638) + 0x111) == '\0')) {
      local_70 = (float)CONCAT31(local_70._1_3_,1);
      bVar4 = ForEachTerrorPlayer<SurvivorsInBattlefieldScan>
                        ((SurvivorsInBattlefieldScan *)&local_70);
      if ((bVar4) && (local_70._0_1_ == (Vector)0x0)) {
        if ((this[0x2cce] == (CTerrorPlayer)0x0) &&
           (uVar9 = *(uint *)(this + 0x2ca8) | 4, *(uint *)(this + 0x2ca8) != uVar9)) {
          if (this[0x6c] == (CTerrorPlayer)0x0) {
            pCVar1 = *(CBaseEdict **)(this + 0x30);
            if (pCVar1 != (CBaseEdict *)0x0) {
              *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
              iVar5 = CBaseEdict::GetChangeAccessor(pCVar1);
              *(undefined2 *)(iVar5 + 2) = 0;
            }
          }
          else {
            this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
          }
          *(uint *)(this + 0x2ca8) = uVar9;
        }
      }
      else {
        this[0x2cce] = (CTerrorPlayer)0x1;
      }
    }
    cVar3 = CDirector::IsFinaleWon(TheDirector);
    if (cVar3 == '\0') {
      cVar3 = CDirector::IsFinale(TheDirector);
      if (((cVar3 != '\0') && (cVar3 = CDirector::AreGhostsAllowedInFinale(), cVar3 == '\0')) &&
         (uVar9 = *(uint *)(this + 0x2ca8) | 0x40, *(uint *)(this + 0x2ca8) != uVar9))
      goto LAB_009c2c5a;
    }
    else {
      uVar9 = *(uint *)(this + 0x2ca8) | 0x10;
      if (*(uint *)(this + 0x2ca8) != uVar9) {
LAB_009c2c5a:
        if (this[0x6c] == (CTerrorPlayer)0x0) {
          pCVar1 = *(CBaseEdict **)(this + 0x30);
          if (pCVar1 != (CBaseEdict *)0x0) {
            *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
            iVar5 = CBaseEdict::GetChangeAccessor(pCVar1);
            *(undefined2 *)(iVar5 + 2) = 0;
          }
        }
        else {
          this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
        }
        *(uint *)(this + 0x2ca8) = uVar9;
      }
    }
    if (*(int *)(this + 0x2cac) < 1) {
      lVar11 = (longdouble)CDirector::GetTimeUntilNextGhostWave(TheDirector,0.0);
      iVar5 = (int)lVar11;
      if (iVar5 != *(int *)(this + 0x2cac)) {
        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 + 0x2cac) = iVar5;
      }
      if (*(int *)(this + 0x2cb0) != iVar5) goto LAB_009c3259;
    }
    else if ((0 < *(int *)(this + 0x2cb0)) &&
            (uVar9 = GetGhostPausedSpawnState(this), (uVar9 & 2) == 0)) {
      iVar5 = *(int *)(this + 0x2cb0) + -1;
LAB_009c3259:
      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 + 0x2cb0) = iVar5;
    }
    iVar5 = GetGhostPausedSpawnState(this);
    if (((iVar5 == 0) && (0 < *(int *)(this + 0x2cac))) && (*(int *)(this + 0x2cb0) == 0)) {
      cVar3 = (**(code **)(*(int *)this + 0x778))();
      if (cVar3 != '\0') {
        (**(code **)(*(int *)this + 0x544))();
        cVar3 = ZombieManager::GetRandomPZSpawnPosition();
        if (cVar3 != '\0') {
          CBaseEntity::SetAbsOrigin((CBaseEntity *)this,(Vector *)&local_70);
        }
      }
    }
    else {
      (**(code **)(*(int *)this + 0x778))();
    }
    this_00 = (CNavArea *)(**(code **)(*(int *)this + 0x52c))();
    if (this_00 != (CNavArea *)0x0) {
      if (((byte)this[0x14d] & 8) != 0) {
        CBaseEntity::CalcAbsolutePosition((CBaseEntity *)this);
      }
      cVar3 = CNavArea::IsOverlapping(this_00,(Vector *)(this + 0x2e0),100.0);
      if (cVar3 == '\0') {
        this_00 = (CNavArea *)0x0;
      }
    }
    cVar3 = CDirectorTacticalServices::IsVisibleToTeam
                      (*(CDirectorTacticalServices **)(TheDirector + 0x628),(CBaseEntity *)this,2,1,
                       0.0,(TerrorNavArea *)this_00);
    if ((cVar3 != '\0') &&
       (uVar9 = *(uint *)(this + 0x2ca8) | 0x80, *(uint *)(this + 0x2ca8) != uVar9)) {
      if (this[0x6c] == (CTerrorPlayer)0x0) {
        pCVar1 = *(CBaseEdict **)(this + 0x30);
        if (pCVar1 != (CBaseEdict *)0x0) {
          *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
          iVar5 = CBaseEdict::GetChangeAccessor(pCVar1);
          *(undefined2 *)(iVar5 + 2) = 0;
        }
      }
      else {
        this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
      }
      *(uint *)(this + 0x2ca8) = uVar9;
    }
    local_e8 = this;
    local_e4 = '\0';
    cVar3 = CDirector::IsFinale(TheDirector);
    if (((cVar3 == '\0') || (**(int **)(TheDirector + 0x638) - 3U < 2)) ||
       (**(int **)(TheDirector + 0x638) == 1)) {
      local_e0 = *(float *)(ZombieSpawnSafetyRange._28_4_ + 0x2c);
    }
    else {
      local_e0 = *(float *)(ZombieFinaleSpawnSafetyRangeOverride._28_4_ + 0x2c);
      if (local_e0 <= 0.0) {
        local_e0 = *(float *)(ZombieFinaleSpawnSafetyRange._28_4_ + 0x2c);
      }
    }
    ForEachSurvivor<GhostProximityScan>((GhostProximityScan *)&local_e8);
    if ((local_e4 != '\0') &&
       (uVar9 = *(uint *)(this + 0x2ca8) | 0x100, *(uint *)(this + 0x2ca8) != uVar9)) {
      if (this[0x6c] == (CTerrorPlayer)0x0) {
        pCVar1 = *(CBaseEdict **)(this + 0x30);
        if (pCVar1 != (CBaseEdict *)0x0) {
          *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
          iVar5 = CBaseEdict::GetChangeAccessor(pCVar1);
          *(undefined2 *)(iVar5 + 2) = 0;
        }
      }
      else {
        this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
      }
      *(uint *)(this + 0x2ca8) = uVar9;
    }
    if (this_00 != (CNavArea *)0x0) {
      uVar9 = *(uint *)(this_00 + 300);
      if ((uVar9 & 0x800) == 0) {
LAB_009c2e72:
        if ((uVar9 & 0x18000) == 0) goto LAB_009c2e7d;
      }
      else {
        cVar3 = CTerrorGameRules::IsScavengeMode();
        if (cVar3 != '\0') {
          uVar9 = *(uint *)(this_00 + 300);
          goto LAB_009c2e72;
        }
        this_01 = (Checkpoint *)TerrorNavMesh::GetLastCheckpoint(TheNavMesh);
        if (((this_01 == (Checkpoint *)0x0) ||
            (cVar3 = Checkpoint::ContainsArea(this_01,(TerrorNavArea *)this_00), cVar3 == '\0')) &&
           (TheDirector[0x161] != (CDirector)0x0)) goto LAB_009c2e7d;
      }
      uVar9 = *(uint *)(this + 0x2ca8) | 0x200;
      if (*(uint *)(this + 0x2ca8) != uVar9) {
        if (this[0x6c] == (CTerrorPlayer)0x0) {
          pCVar1 = *(CBaseEdict **)(this + 0x30);
          if (pCVar1 != (CBaseEdict *)0x0) {
            *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
            iVar5 = CBaseEdict::GetChangeAccessor(pCVar1);
            *(undefined2 *)(iVar5 + 2) = 0;
          }
        }
        else {
          this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
        }
        *(uint *)(this + 0x2ca8) = uVar9;
      }
    }
LAB_009c2e7d:
    (**(code **)(*(int *)this + 0x5b4))();
    (**(code **)(*(int *)this + 0x5b0))();
    if ((((byte)this[0x14d] & 8) != 0) &&
       (CBaseEntity::CalcAbsolutePosition((CBaseEntity *)this), ((byte)this[0x14d] & 8) != 0)) {
      CBaseEntity::CalcAbsolutePosition((CBaseEntity *)this);
    }
    local_87 = 0;
    local_bc = 0;
    local_b8 = 0;
    local_b4 = 0;
    local_8c = 0;
    local_9c = (local_dc - local_70) * 0.5;
    local_98 = (local_d8 - local_6c) * 0.5;
    local_94 = (local_d4 - local_68) * 0.5;
    local_ac = (local_dc + local_70) * 0.5;
    local_a4 = (local_d4 + local_68) * 0.5;
    local_a8 = (local_d8 + local_6c) * 0.5;
    local_c4 = *(float *)(this + 0x2e8) + local_a4;
    local_cc = *(float *)(this + 0x2e0) + local_ac;
    local_ac = -local_ac;
    local_c8 = *(float *)(this + 0x2e4) + local_a8;
    local_a8 = -local_a8;
    local_a4 = -local_a4;
    local_88 = local_9c * local_9c + local_98 * local_98 + local_94 * local_94 < 1e-06;
    (**(code **)(*(int *)this + 0x7a0))();
    CTraceFilterSimple::CTraceFilterSimple
              ((CTraceFilterSimple *)&local_dc,(IHandleEntity *)this,8,
               (_func_bool_IHandleEntity_ptr_int *)0x0);
    (**(code **)(*enginetrace + 0x14))();
    if (*(int *)(r_visualizetraces._28_4_ + 0x30) != 0) {
      DebugDrawLine((Vector *)&local_70,local_64,0xff,0,0,true,-1.0);
    }
    uVar9 = (**(code **)(*(int *)this + 0x7a0))();
    puVar7 = &stack0xfffffeec;
    if (((uVar9 & local_40) != 0) && (puVar7 = &stack0xfffffeec, local_24 != 0)) {
      uVar9 = *(uint *)(this + 0x2ca8);
      uVar10 = uVar9 | 0x400;
      piVar8 = (int *)&stack0xfffffeec;
      if (uVar9 != uVar10) {
        if (this[0x6c] == (CTerrorPlayer)0x0) {
          pCVar1 = *(CBaseEdict **)(this + 0x30);
          if (pCVar1 != (CBaseEdict *)0x0) {
            *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
            iVar5 = CBaseEdict::GetChangeAccessor(pCVar1);
            *(undefined2 *)(iVar5 + 2) = 0;
          }
        }
        else {
          this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
        }
        *(uint *)(this + 0x2ca8) = uVar10;
        uVar9 = uVar10;
        piVar8 = (int *)&stack0xfffffeec;
      }
      goto LAB_009c2a7b;
    }
  }
  uVar9 = *(uint *)(this + 0x2ca8);
  piVar8 = (int *)puVar7;
LAB_009c2a7b:
  if (uVar9 != 0) {
    return;
  }
  if (*(int *)(this + 0x2cac) < 1) {
    return;
  }
  if (*(int *)(this + 0x2cb0) != 0) {
    return;
  }
  if (((byte)this[0x1cb8] & 1) == 0) {
    iVar5 = *(int *)this;
    *piVar8 = (int)this;
    pcVar2 = *(code **)(iVar5 + 0x778);
    piVar8[-1] = 0x9c319b;
    cVar3 = (*pcVar2)();
    if (cVar3 == '\0') {
      return;
    }
    *piVar8 = (int)(this + 0x2cc0);
    piVar8[-1] = 0x9c31b1;
    lVar11 = (longdouble)CountdownTimer::Now();
    if ((float)lVar11 < *(float *)(this + 0x2cc8)) {
      return;
    }
  }
  *piVar8 = (int)this;
  piVar8[-1] = 0x9c2aa8;
  MaterializeFromGhost((CTerrorPlayer *)*piVar8);
  return;
}

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)