L L4D2node

ZombieManager::CollectSpawnAreas

0x00a5da20 · 2665 bytes · __thiscall

_ZNK13ZombieManager17CollectSpawnAreasENS_15MobLocationTypeE15ZombieClassType

Decompiled

undefined (3 params)

/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
/* ZombieManager::CollectSpawnAreas(ZombieManager::MobLocationType, ZombieClassType) const */

ZombieManager * __thiscall
ZombieManager::CollectSpawnAreas(ZombieManager *this,int param_2,undefined4 param_3)

{
  CDirectorScriptedEventManager *pCVar1;
  CBaseEntity *this_00;
  char cVar2;
  int iVar3;
  uint *puVar4;
  ZombieManager *pZVar5;
  int iVar6;
  bool bVar7;
  longdouble lVar8;
  CDirectorScriptedEventManager *this_01;
  char *pcVar9;
  undefined4 uVar10;
  float local_60;
  undefined4 local_54;
  undefined4 local_50;
  undefined4 local_4c;
  undefined4 local_48;
  int local_44;
  float local_40;
  float local_3c;
  undefined4 local_38;
  undefined4 local_34;
  uint local_30 [8];
  
  local_54 = 0;
  local_50 = 0;
  if (_towlower == 0) {
    local_44 = 0;
  }
  else {
    (**(code **)(_towlower + 0x50))
              (_towlower,&local_54,0,0,0,0,"/data/src/game/server/terror/zombiemanager.cpp",0x71a,
               &CollectSpawnAreas(ZombieManager::MobLocationType,ZombieClassType)::tm_fmt,"(%s)%s",
               "ZOMBIE","ZombieManager::CollectSpawnAreas");
    local_44 = _towlower;
  }
  iVar6 = _DAT_0105db00;
  local_4c = local_54;
  local_48 = local_50;
                    /* try { // try from 00a5dba6 to 00a5dc06 has its CatchHandler @ 00a5e528 */
  if (((_DAT_0105d154 != 0) || (DAT_0105d158 == '\0')) &&
     (iVar3 = ThreadGetCurrentId(), iVar6 == iVar3)) {
    if ((char *)*_DAT_0105d15c != "ZombieManager::CollectSpawnAreas") {
      _DAT_0105d15c =
           (int *)CVProfNode::GetSubNode((char *)_DAT_0105d15c,0xd29924,(char *)0x0,0xc0db47);
    }
    puVar4 = (uint *)(_DAT_0105d1e8 + 4 + _DAT_0105d15c[0x1c] * 8);
    *puVar4 = *puVar4 | 4;
    CVProfNode::EnterScope();
    DAT_0105d158 = '\0';
  }
  iVar6 = param_2 * 0xc;
  pCVar1 = (CDirectorScriptedEventManager *)(this + iVar6 + 0x14c);
  this_01 = pCVar1;
                    /* try { // try from 00a5dae9 to 00a5daed has its CatchHandler @ 00a5e4f8 */
  lVar8 = (longdouble)CountdownTimer::Now();
  if ((float)lVar8 < *(float *)(this + iVar6 + 0x154)) {
    pZVar5 = this + param_2 * 0x14 + 0x70;
    goto LAB_00a5db0a;
  }
  pZVar5 = this + param_2 * 0x14 + 0x70;
                    /* try { // try from 00a5dc25 to 00a5dc79 has its CatchHandler @ 00a5e4f8 */
  lVar8 = (longdouble)CountdownTimer::Now();
  if ((float)lVar8 + 2.0 != *(float *)(this + iVar6 + 0x154)) {
    (**(code **)(*(int *)(this + iVar6 + 0x14c) + 4))(pCVar1,this + iVar6 + 0x154);
    *(float *)(this + iVar6 + 0x154) = (float)lVar8 + 2.0;
  }
  if (*(float *)(this + iVar6 + 0x150) != 2.0) {
    (**(code **)(*(int *)(this + iVar6 + 0x14c) + 4))(pCVar1,this + iVar6 + 0x150);
    *(undefined4 *)(this + iVar6 + 0x150) = 0x40000000;
  }
  bVar7 = param_2 == *(int *)(ZombieDebugSpawnSet._28_4_ + 0x30);
  cVar2 = CDirectorChallengeMode::TankRun(*(CDirectorChallengeMode **)(TheDirector + 0x648));
  switch(param_2) {
  default:
    local_60 = -1.0;
    break;
  case 1:
    if (cVar2 == '\0') {
      local_40 = 1e+09;
      local_3c = 2.8026e-45;
      local_38 = 0;
      local_34 = 0;
      local_30[0] = 0;
      ForEachTerrorPlayer<LowestFlowDistance>((LowestFlowDistance *)&local_40);
    }
    else {
      local_40 = -9999.0;
      local_3c = 2.8026e-45;
      local_38 = 0;
      local_34 = 0;
      local_30[0] = 1;
      local_30[1] = 0;
      ForEachTerrorPlayer<HighestFlowDistance>((HighestFlowDistance *)&local_40);
    }
    local_60 = local_40;
    lVar8 = (longdouble)
            CDirector::GetScriptValue
                      (TheDirector,"SpawnBehindSurvivorsDistance",
                       *(float *)(DirectorPrivate_DirectorSpawnBehindSurvivorsDistance._28_4_ + 0x2c
                                 ));
    if (local_60 - (float)lVar8 <= 0.0) {
      local_60 = 0.0;
    }
    else {
      lVar8 = (longdouble)
              CDirector::GetScriptValue
                        (TheDirector,"SpawnBehindSurvivorsDistance",
                         *(float *)(DirectorPrivate_DirectorSpawnBehindSurvivorsDistance._28_4_ +
                                   0x2c));
      local_60 = local_60 - (float)lVar8;
    }
    break;
  case 2:
    local_3c = 1e+09;
    local_38 = 0;
    local_40 = (float)((uint)local_40 & 0xffffff00);
    ForEachSurvivor<MostRecentITFlowDistance>((MostRecentITFlowDistance *)&local_40);
    local_60 = local_3c;
    break;
  case 3:
  case 7:
    local_40 = -9999.0;
    local_30[0] = (uint)(param_2 == 3);
    local_3c = 2.8026e-45;
    local_38 = 0;
    local_34 = 0;
    local_30[1] = 0;
                    /* try { // try from 00a5dd8c to 00a5df2d has its CatchHandler @ 00a5e4f8 */
    ForEachTerrorPlayer<HighestFlowDistance>((HighestFlowDistance *)&local_40);
    local_60 = local_40;
    break;
  case 6:
    local_30[0] = 0;
    local_30[1] = 0;
    local_30[2] = 0;
    local_30[3] = 0;
    local_30[4] = 0;
    local_40 = 2.8026e-45;
    local_3c = 2.8026e-45;
    local_38 = 3;
    local_34 = 9;
                    /* try { // try from 00a5dce5 to 00a5dd52 has its CatchHandler @ 00a5e519 */
    ForEachPlayer<PlayerCollector>((PlayerCollector *)&local_40);
    if ((int)local_30[3] < 1) {
      local_60 = -1e+08;
    }
    else {
      iVar6 = 0;
      local_60 = -1e+08;
      do {
        this_00 = *(CBaseEntity **)(local_30[0] + iVar6 * 4);
        if (((byte)this_00[0x14d] & 8) != 0) {
          CBaseEntity::CalcAbsolutePosition(this_00);
        }
        if ((local_60 < *(float *)(this_00 + 0x2e8)) &&
           (local_60 = *(float *)(this_00 + 0x2e8), ((byte)this_00[0x14d] & 8) != 0)) {
                    /* try { // try from 00a5df53 to 00a5df57 has its CatchHandler @ 00a5e519 */
          CBaseEntity::CalcAbsolutePosition(this_00);
          local_60 = *(float *)(this_00 + 0x2e8);
        }
        iVar6 = iVar6 + 1;
      } while (iVar6 < (int)local_30[3]);
    }
    local_30[3] = 0;
    CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_30);
    local_30[4] = local_30[0];
    CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_30);
  }
  if (bVar7) {
    CNavMesh::ClearSelectedSet(TheNavMesh);
  }
  *(undefined4 *)(pZVar5 + 0xc) = 0;
  TerrorNavArea::MakeNewTerrorMarker();
  this_01 = (CDirectorScriptedEventManager *)TheDirector;
  cVar2 = CDirector::IsFinale(TheDirector);
  if (cVar2 == '\0') {
    puVar4 = *(uint **)(TheDirector + 0x638);
  }
  else {
    puVar4 = *(uint **)(TheDirector + 0x638);
    if ((*puVar4 & 0xfffffffd) != 1) {
      if (param_2 == 9) {
        this_01 = (CDirectorScriptedEventManager *)this;
        AccumulateSpawnAreaCollection(this,this + 0x23c,9,param_3,local_60,pZVar5,bVar7,1);
        if (*(int *)(pZVar5 + 0xc) == 0) {
          TerrorNavArea::MakeNewTerrorMarker();
          AccumulateSpawnAreaCollection(this,this + 0x23c,0,param_3,local_60,pZVar5,bVar7,1);
          this_01 = (CDirectorScriptedEventManager *)this;
        }
      }
      else {
        cVar2 = CTerrorGameRules::IsVersusMode();
        if (cVar2 == '\0') {
          uVar10 = 0;
        }
        else {
          uVar10 = 8;
        }
        AccumulateSpawnAreaCollection(this,this + 0x23c,uVar10,param_3,local_60,pZVar5,bVar7,1);
        this_01 = (CDirectorScriptedEventManager *)this;
      }
      goto LAB_00a5db0a;
    }
  }
  if ((*(char *)((int)puVar4 + 0x111) != '\0') && (*puVar4 != 1)) {
LAB_00a5dfab:
                    /* try { // try from 00a5dfcc to 00a5e4bc has its CatchHandler @ 00a5e4f8 */
    AccumulateSpawnAreaCollection(this,this + 0x250,0,param_3,local_60,pZVar5,bVar7,1);
    this_01 = (CDirectorScriptedEventManager *)this;
    goto LAB_00a5db0a;
  }
  if (**(char **)(TheDirector + 0x640) == '\0') {
    if (*(char *)(*(int *)(TheDirector + 0x644) + 8) == '\0') {
      if (**(char **)(TheDirector + 0x648) == '\0') {
        AccumulateSurvivorActiveSet(this,param_2,param_3,local_60,pZVar5,bVar7);
        this_01 = (CDirectorScriptedEventManager *)this;
        goto LAB_00a5db0a;
      }
      iVar6 = *(int *)(*(char **)(TheDirector + 0x648) + 0x10c);
      if (iVar6 == 1) {
        AccumulateSurvivorActiveSet(this,param_2,param_3,local_60,pZVar5,bVar7);
        this_01 = (CDirectorScriptedEventManager *)this;
        goto LAB_00a5db0a;
      }
      if (iVar6 < 2) {
        if (iVar6 == 0) {
          this_01 = (CDirectorScriptedEventManager *)this;
          AccumulateSpawnAreaCollection(this,this + 0x23c,9,param_3,local_60,pZVar5,bVar7,1);
          if (*(int *)(pZVar5 + 0xc) == 0) {
            TerrorNavArea::MakeNewTerrorMarker();
            AccumulateSpawnAreaCollection(this,this + 0x23c,0,param_3,local_60,pZVar5,bVar7,1);
            this_01 = (CDirectorScriptedEventManager *)this;
          }
          goto LAB_00a5db0a;
        }
      }
      else {
        if (iVar6 == 2) goto LAB_00a5dfab;
        if (iVar6 == 3) {
          AccumulateSpawnAreaCollection(this,this + 0x264,0,param_3,local_60,pZVar5,bVar7,1);
          this_01 = (CDirectorScriptedEventManager *)this;
          goto LAB_00a5db0a;
        }
      }
      pcVar9 = "Unsupported ScriptedMode Spawn Rule\n";
      Warning("Unsupported ScriptedMode Spawn Rule\n");
      this_01 = (CDirectorScriptedEventManager *)pcVar9;
      goto LAB_00a5db0a;
    }
    cVar2 = CDirector::AreAllSurvivorsInFinaleArea();
    if (cVar2 != '\0') goto LAB_00a5e2ac;
    this_01 = *(CDirectorScriptedEventManager **)(TheDirector + 0x638);
    cVar2 = CDirectorScriptedEventManager::AreAllSurvivorsInBattlefield(this_01);
    if (cVar2 != '\0') goto LAB_00a5e439;
  }
  else {
    iVar6 = *(int *)(*(char **)(TheDirector + 0x640) + 4);
    if (iVar6 == 0) {
      param_2 = 0;
LAB_00a5e2ac:
      this_01 = (CDirectorScriptedEventManager *)this;
      AccumulateSpawnAreaCollection(this,this + 0x23c,param_2,param_3,local_60,pZVar5,bVar7,1);
    }
    else if (iVar6 == 1) {
      param_2 = 0;
LAB_00a5e439:
      this_01 = (CDirectorScriptedEventManager *)this;
      AccumulateSpawnAreaCollection(this,this + 0x250,param_2,param_3,local_60,pZVar5,bVar7,1);
    }
  }
  if (*(int *)(pZVar5 + 0xc) == 0) {
    TerrorNavArea::MakeNewTerrorMarker();
    AccumulateSurvivorActiveSet(this,0,param_3,local_60,pZVar5,bVar7);
    this_01 = (CDirectorScriptedEventManager *)this;
  }
LAB_00a5db0a:
  iVar6 = _DAT_0105db00;
  if (((DAT_0105d158 == '\0') || (_DAT_0105d154 != 0)) &&
     (iVar3 = ThreadGetCurrentId(this_01), iVar6 == iVar3)) {
    cVar2 = CVProfNode::ExitScope();
    if (cVar2 != '\0') {
      _DAT_0105d15c = (int *)_DAT_0105d15c[0x19];
    }
    DAT_0105d158 = _DAT_0105d15c == (int *)0x105d160;
  }
  if (local_44 != 0) {
    (**(code **)(local_44 + 0x54))(local_44,local_4c,local_48,0,0,0);
  }
  return pZVar5;
}

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)