L L4D2node

CTerrorPlayer::CanBecomeGhost

0x009c6780 · 2741 bytes · __thiscall

_ZN13CTerrorPlayer14CanBecomeGhostEb

Decompiled

undefined (2 params)

/* CTerrorPlayer::CanBecomeGhost(bool) */

bool __thiscall CTerrorPlayer::CanBecomeGhost(CTerrorPlayer *this,bool param_1)

{
  CBaseEdict *pCVar1;
  code *pcVar2;
  CBaseEntity *pCVar3;
  short sVar4;
  bool bVar5;
  char cVar6;
  int iVar7;
  int iVar8;
  Vector *this_00;
  int *piVar9;
  undefined4 uVar10;
  CTerrorPlayer *this_01;
  int *piVar11;
  byte bVar12;
  longdouble lVar13;
  longdouble lVar14;
  longdouble lVar15;
  float fVar16;
  float fVar17;
  float local_70;
  float local_6c;
  int local_68;
  float local_60;
  int local_5c;
  undefined4 local_58;
  undefined4 local_54;
  float local_50;
  float local_4c;
  float local_48;
  float local_44;
  float local_40;
  float local_3c;
  int local_38;
  undefined4 local_34;
  undefined4 local_30;
  CBaseEntity *local_2c;
  undefined4 local_28;
  undefined4 local_24;
  undefined1 local_20;
  
  bVar12 = 0;
  iVar7 = CBaseEntity::GetTeamNumber((CBaseEntity *)this);
  if (iVar7 == 3) {
    cVar6 = (**(code **)(*(int *)this + 0x558))(this);
    if (cVar6 != '\0') goto LAB_009c67a6;
    cVar6 = (**(code **)(*(int *)this + 300))(this);
    if ((cVar6 == '\0') && (1 < *(int *)(this + 0x23bc) - 4U)) {
      if (*(int *)(DirectorNoSpecials._28_4_ + 0x30) == 0) {
        cVar6 = CDirector::IsFinale(TheDirector);
        sVar4 = (short)this;
        if ((cVar6 == '\0') && (*(char *)(*(int *)(TheDirector + 0x638) + 0x111) == '\0')) {
          if (((*(int *)(this + 0x2c14) != 0) && (!param_1)) &&
             (cVar6 = CTerrorGameRules::HasPlayerControlledZombies(), cVar6 == '\0')) {
            if ((this[0x2cce] == (CTerrorPlayer)0x0) &&
               (cVar6 = CDirectorScriptedEventManager::AreAllSurvivorsInBattlefield
                                  (*(CDirectorScriptedEventManager **)(TheDirector + 0x638)),
               cVar6 != '\0')) {
              if (*(int *)(this + 0x2ca8) != 4) {
                CServerNetworkProperty::NetworkStateChanged(sVar4 + 0x24);
                *(undefined4 *)(this + 0x2ca8) = 4;
              }
              goto LAB_009c67a6;
            }
            this[0x2cce] = (CTerrorPlayer)0x1;
          }
        }
        else {
          cVar6 = CDirector::AreGhostsAllowedInFinale();
          if (cVar6 == '\0') {
            if (*(int *)(this + 0x2ca8) != 0x40) {
              CServerNetworkProperty::NetworkStateChanged(sVar4 + 0x24);
              *(undefined4 *)(this + 0x2ca8) = 0x40;
            }
            goto LAB_009c67a6;
          }
        }
        cVar6 = CDirector::IsFinaleWon(TheDirector);
        if ((cVar6 == '\0') &&
           (cVar6 = CDirector::IsFinaleEscapeInProgress(TheDirector), cVar6 == '\0')) {
          cVar6 = CDirector::HasAnySurvivorLeftSafeArea(TheDirector);
          if ((cVar6 != '\0') ||
             (cVar6 = CDirectorChallengeMode::TankRun
                                (*(CDirectorChallengeMode **)(TheDirector + 0x648)), cVar6 == '\0'))
          {
            if ((param_1) ||
               (cVar6 = CDirector::HasAnySurvivorLeftSafeArea(TheDirector), cVar6 == '\0')) {
              if (*(int *)(this + 0x2ca8) == 0) {
                return true;
              }
              CServerNetworkProperty::NetworkStateChanged(sVar4 + 0x24);
              *(undefined4 *)(this + 0x2ca8) = 0;
              return true;
            }
            lVar13 = (longdouble)
                     CDirector::GetScriptValue
                               (TheDirector,"ZombieGhostDelayMin",
                                *(float *)(DirectorPrivate_DirectorZombieGhostDelayMin._28_4_ + 0x2c
                                          ));
            lVar14 = (longdouble)
                     CDirector::GetScriptValue
                               (TheDirector,"ZombieGhostDelayMax",
                                *(float *)(DirectorPrivate_DirectorZombieGhostDelayMax._28_4_ + 0x2c
                                          ));
            local_60 = (float)lVar14;
            cVar6 = CTerrorGameRules::IsSurvivalMode();
            if (cVar6 == '\0') {
              lVar14 = (longdouble)GetScrimmageSphereRadius(this);
              fVar16 = (float)lVar14;
              piVar9 = (int *)GetScrimmageSphereCenter(this);
              iVar7 = *(int *)(this + 0x2ca8);
              piVar11 = &local_5c;
              for (iVar8 = 3; iVar8 != 0; iVar8 = iVar8 + -1) {
                *piVar11 = *piVar9;
                piVar9 = piVar9 + (uint)bVar12 * -2 + 1;
                piVar11 = piVar11 + (uint)bVar12 * -2 + 1;
              }
              if (iVar7 != 0) {
                CServerNetworkProperty::NetworkStateChanged(sVar4 + 0x24);
                *(undefined4 *)(this + 0x2ca8) = 0;
              }
              local_2c = (CBaseEntity *)0x0;
              local_38 = local_5c;
              local_28 = 0xbf800000;
              local_34 = local_58;
              local_24 = 0;
              local_30 = local_54;
              local_20 = 1;
              ForEachSurvivor<FarthestSurvivorScan>((FarthestSurvivorScan *)&local_38);
              pCVar3 = local_2c;
              if (local_2c != (CBaseEntity *)0x0) {
                if (local_2c[0x1a90] == (CBaseEntity)0x0) {
                  iVar7 = (**(code **)(*g_pGameRules + 0x7c))(g_pGameRules);
                  if (((byte)pCVar3[0x14d] & 8) != 0) {
                    CBaseEntity::CalcAbsolutePosition(pCVar3);
                  }
                  local_4c = *(float *)(iVar7 + 0x10) + *(float *)(pCVar3 + 0x2e4);
                  local_48 = *(float *)(iVar7 + 0x14) + *(float *)(pCVar3 + 0x2e8);
                  local_50 = *(float *)(iVar7 + 0xc) + *(float *)(pCVar3 + 0x2e0);
                  iVar7 = (**(code **)(*g_pGameRules + 0x7c))(g_pGameRules);
                  if (((byte)pCVar3[0x14d] & 8) != 0) {
                    CBaseEntity::CalcAbsolutePosition(pCVar3);
                  }
                  local_40 = *(float *)(iVar7 + 0x1c) + *(float *)(pCVar3 + 0x2e4);
                  local_3c = *(float *)(iVar7 + 0x20) + *(float *)(pCVar3 + 0x2e8);
                  local_44 = *(float *)(iVar7 + 0x18) + *(float *)(pCVar3 + 0x2e0);
                }
                else {
                  iVar7 = (**(code **)(*g_pGameRules + 0x7c))();
                  if (((byte)pCVar3[0x14d] & 8) != 0) {
                    CBaseEntity::CalcAbsolutePosition(pCVar3);
                  }
                  local_4c = *(float *)(iVar7 + 0x28) + *(float *)(pCVar3 + 0x2e4);
                  local_48 = *(float *)(iVar7 + 0x2c) + *(float *)(pCVar3 + 0x2e8);
                  local_50 = *(float *)(iVar7 + 0x24) + *(float *)(pCVar3 + 0x2e0);
                  iVar7 = (**(code **)(*g_pGameRules + 0x7c))(g_pGameRules);
                  if (((byte)pCVar3[0x14d] & 8) != 0) {
                    CBaseEntity::CalcAbsolutePosition(pCVar3);
                  }
                  local_40 = *(float *)(iVar7 + 0x34) + *(float *)(pCVar3 + 0x2e4);
                  local_3c = *(float *)(iVar7 + 0x38) + *(float *)(pCVar3 + 0x2e8);
                  local_44 = *(float *)(iVar7 + 0x30) + *(float *)(pCVar3 + 0x2e0);
                }
                lVar14 = (longdouble)Vector::DistTo((Vector *)&local_50,(Vector *)&local_44);
                this_00 = (Vector *)(**(code **)(*(int *)pCVar3 + 0x288))(pCVar3);
                lVar15 = (longdouble)Vector::DistTo(this_00,(Vector *)&local_5c);
                fVar17 = (float)lVar14 * 0.5 + (float)lVar15;
                if (fVar16 - fVar17 != *(float *)(this + 0x2c1c)) {
                  CServerNetworkProperty::NetworkStateChanged(sVar4 + 0x24);
                  *(float *)(this + 0x2c1c) = fVar16 - fVar17;
                }
                if (fVar16 == 0.0) {
                  local_60 = (float)(~-(uint)(fVar17 < 0.0) & (uint)(float)lVar13 |
                                    (uint)local_60 & -(uint)(fVar17 < 0.0));
                }
                else {
                  fVar17 = fVar17 / fVar16;
                  if (1.0 <= fVar17) {
                    fVar17 = 1.0;
                  }
                  if (fVar17 <= 0.0) {
                    fVar17 = 0.0;
                  }
                  local_60 = fVar17 * ((float)lVar13 - local_60) + local_60;
                }
              }
            }
            else {
              lVar13 = (longdouble)CDirector::GetSpecialRespawnInterval(TheDirector);
              local_60 = (float)lVar13;
            }
            iVar7 = CDirector::GetPlayerCount(TheDirector,3,0);
            iVar8 = (**(code **)(*(int *)TheDirector + 0x30))(TheDirector);
            local_6c = 0.0;
            if (iVar7 < iVar8) {
              fVar16 = ((float)iVar7 / (float)iVar8) * local_60;
              if (fVar16 <= *(float *)(ZombieGhostMinSpawnTime._28_4_ + 0x2c)) {
                fVar16 = *(float *)(ZombieGhostMinSpawnTime._28_4_ + 0x2c);
              }
              local_6c = local_60 - fVar16;
              local_60 = fVar16;
              if (local_6c <= 0.0) {
                local_6c = 0.0;
              }
            }
            if ((((((*(float *)(ZombieGhostRunnerSpawnMultiplier._28_4_ + 0x2c) != 0.0) &&
                   (*(int *)(TheDirector + 0x1c0) < 1)) && (*(int *)(TheDirector + 0x1bc) < 1)) &&
                 ((cVar6 = CDirector::IsFinale(TheDirector), cVar6 == '\0' &&
                  (*(char *)(*(int *)(TheDirector + 0x638) + 0x111) == '\0')))) &&
                ((this_01 = (CTerrorPlayer *)
                            CDirectorTacticalServices::GetHighestFlowSurvivor
                                      (*(CDirectorTacticalServices **)(TheDirector + 0x628),0),
                 this_01 != (CTerrorPlayer *)0x0 &&
                 ((cVar6 = (**(code **)(*(int *)this_01 + 0x7e8))(this_01), cVar6 == '\0' &&
                  (cVar6 = IsDominatedBySpecialInfected(this_01), cVar6 == '\0')))))) &&
               (this_01[0x39f1] == (CTerrorPlayer)0x0)) {
              local_38 = 0;
              local_34 = 0;
              local_30 = 0;
              local_2c = (CBaseEntity *)0x0;
              local_28 = 0;
                    /* try { // try from 009c7037 to 009c717d has its CatchHandler @ 009c71bf */
              ForEachSurvivor<AmbulatorySurvivorCollector>((AmbulatorySurvivorCollector *)&local_38)
              ;
              if (1 < (int)local_2c) {
                bVar5 = true;
                for (local_68 = 0; local_68 < (int)local_2c; local_68 = local_68 + 1) {
                  pCVar3 = *(CBaseEntity **)(local_38 + local_68 * 4);
                  if (this_01 != (CTerrorPlayer *)pCVar3) {
                    iVar7 = *(int *)(pCVar3 + 0x100);
                    lVar13 = (longdouble)(**(code **)(*(int *)pCVar3 + 0x7e4))(pCVar3);
                    if (5.0 < (float)lVar13 + (float)iVar7) {
                      bVar5 = false;
                    }
                    iVar7 = (**(code **)(*(int *)this_01 + 0x52c))(this_01);
                    if (iVar7 == 0) {
                      local_70 = -9999.0;
                    }
                    else {
                      local_70 = *(float *)(iVar7 + 0x154);
                    }
                    iVar7 = (**(code **)(*(int *)pCVar3 + 0x52c))(pCVar3);
                    if (iVar7 == 0) {
                      fVar16 = -9999.0;
                    }
                    else {
                      fVar16 = *(float *)(iVar7 + 0x154);
                    }
                    if (local_70 - fVar16 <
                        *(float *)(ZombieGhostRunnerSpawnMultiplierDist._28_4_ + 0x2c))
                    goto LAB_009c71a9;
                    if (((byte)pCVar3[0x14d] & 8) != 0) {
                      CBaseEntity::CalcAbsolutePosition(pCVar3);
                    }
                    if (((byte)this_01[0x14d] & 8) != 0) {
                      CBaseEntity::CalcAbsolutePosition((CBaseEntity *)this_01);
                    }
                    if ((*(float *)(this_01 + 0x2e0) - *(float *)(pCVar3 + 0x2e0)) *
                        (*(float *)(this_01 + 0x2e0) - *(float *)(pCVar3 + 0x2e0)) +
                        (*(float *)(this_01 + 0x2e4) - *(float *)(pCVar3 + 0x2e4)) *
                        (*(float *)(this_01 + 0x2e4) - *(float *)(pCVar3 + 0x2e4)) +
                        (*(float *)(this_01 + 0x2e8) - *(float *)(pCVar3 + 0x2e8)) *
                        (*(float *)(this_01 + 0x2e8) - *(float *)(pCVar3 + 0x2e8)) < 1.44e+06)
                    goto LAB_009c71a9;
                  }
                }
                if (!bVar5) {
                  local_60 = local_60 * *(float *)(ZombieGhostRunnerSpawnMultiplier._28_4_ + 0x2c);
                  if (local_60 <= *(float *)(ZombieGhostMinSpawnTime._28_4_ + 0x2c)) {
                    local_60 = *(float *)(ZombieGhostMinSpawnTime._28_4_ + 0x2c);
                  }
                }
              }
LAB_009c71a9:
              CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>>::~CUtlVector
                        ((CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>> *)&local_38);
            }
            cVar6 = CDirectorChallengeMode::TankRun
                              (*(CDirectorChallengeMode **)(TheDirector + 0x648));
            if (cVar6 != '\0') {
              lVar13 = (longdouble)
                       CDirector::GetScriptValue
                                 (TheDirector,"TankRunSpawnDelay",
                                  *(float *)(DirectorPrivate_DirectorTankRunSpawnDelay._28_4_ + 0x2c
                                            ));
              local_60 = (float)lVar13;
            }
            if (*(float *)(this + 0x2c00) == -1.0) {
              SetBecomeGhostAt(this,local_60 + *(float *)(gpGlobals + 0xc));
              CDirector::DelayNextSpecialBotSpawn(TheDirector,local_6c);
              piVar9 = (int *)(**(code **)(*gameeventmanager + 0x1c))
                                        (gameeventmanager,"ghost_spawn_time",0,0);
              if (piVar9 != (int *)0x0) {
                pcVar2 = *(code **)(*piVar9 + 0x30);
                uVar10 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(this + 0x30));
                (*pcVar2)(piVar9,"userid",uVar10);
                (**(code **)(*piVar9 + 0x30))(piVar9,"spawntime",(int)local_60);
                (**(code **)(*gameeventmanager + 0x20))(gameeventmanager,piVar9,0);
              }
              if (*(int *)(this + 0x2c14) != 0) {
                CServerNetworkProperty::NetworkStateChanged(sVar4 + 0x24);
                *(undefined4 *)(this + 0x2c14) = 0;
              }
              iVar7 = gpGlobals;
              if (*(int *)(this + 0x2ca8) != 0) {
                CServerNetworkProperty::NetworkStateChanged(sVar4 + 0x24);
                iVar7 = gpGlobals;
                *(undefined4 *)(this + 0x2ca8) = 0;
              }
            }
            else {
              iVar7 = gpGlobals;
              if (3.0 < (*(float *)(this + 0x2c00) - *(float *)(gpGlobals + 0xc)) - local_60) {
                SetBecomeGhostAt(this,*(float *)(gpGlobals + 0xc) + local_60);
                iVar7 = gpGlobals;
              }
            }
            return *(float *)(this + 0x2c00) <= *(float *)(iVar7 + 0xc) &&
                   *(float *)(iVar7 + 0xc) != *(float *)(this + 0x2c00);
          }
          if (*(int *)(this + 0x2ca8) != 2) {
            CServerNetworkProperty::NetworkStateChanged(sVar4 + 0x24);
            *(undefined4 *)(this + 0x2ca8) = 2;
          }
        }
        else if (*(int *)(this + 0x2ca8) != 0x10) {
          if (this[0x6c] == (CTerrorPlayer)0x0) {
            pCVar1 = *(CBaseEdict **)(this + 0x30);
            if (pCVar1 != (CBaseEdict *)0x0) {
              *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
              iVar7 = CBaseEdict::GetChangeAccessor(pCVar1);
              *(undefined2 *)(iVar7 + 2) = 0;
            }
          }
          else {
            this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
          }
          *(undefined4 *)(this + 0x2ca8) = 0x10;
        }
      }
      else if (*(int *)(this + 0x2ca8) != 1) {
        if (this[0x6c] == (CTerrorPlayer)0x0) {
          pCVar1 = *(CBaseEdict **)(this + 0x30);
          if (pCVar1 != (CBaseEdict *)0x0) {
            *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
            iVar7 = CBaseEdict::GetChangeAccessor(pCVar1);
            *(undefined2 *)(iVar7 + 2) = 0;
          }
        }
        else {
          this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
        }
        *(undefined4 *)(this + 0x2ca8) = 1;
      }
      goto LAB_009c67a6;
    }
  }
  if (*(int *)(this + 0x2ca8) != 0) {
    if (this[0x6c] == (CTerrorPlayer)0x0) {
      pCVar1 = *(CBaseEdict **)(this + 0x30);
      if (pCVar1 != (CBaseEdict *)0x0) {
        *(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
        iVar7 = CBaseEdict::GetChangeAccessor(pCVar1);
        *(undefined2 *)(iVar7 + 2) = 0;
      }
      *(undefined4 *)(this + 0x2ca8) = 0;
    }
    else {
      this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
      *(undefined4 *)(this + 0x2ca8) = 0;
    }
  }
LAB_009c67a6:
  SetBecomeGhostAt(this,-1.0);
  return false;
}

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)