L L4D2node

ZombieManager::GetRandomPZSpawnPosition

0x00a5e910 · 930 bytes · __thiscall

_ZNK13ZombieManager24GetRandomPZSpawnPositionE15ZombieClassTypeiP13CTerrorPlayerP6Vector

Decompiled

undefined (5 params)

/* ZombieManager::GetRandomPZSpawnPosition(ZombieClassType, int, CTerrorPlayer*, Vector*) const */

undefined4 __thiscall
ZombieManager::GetRandomPZSpawnPosition
          (ZombieManager *this,int param_2,int param_3,undefined4 param_4,undefined4 *param_5)

{
  bool bVar1;
  char cVar2;
  int iVar3;
  int *piVar4;
  int iVar5;
  undefined4 uVar6;
  int iVar7;
  int local_3c;
  undefined4 local_28;
  undefined4 local_24;
  undefined4 local_20;
  
  if (param_5 == (undefined4 *)0x0) {
    return 0;
  }
  cVar2 = CDirector::IsFinale(TheDirector);
  if (cVar2 == '\0') {
    piVar4 = *(int **)(TheDirector + 0x638);
    if ((**(char **)(TheDirector + 0x640) != '\0') || (*(char *)((int)piVar4 + 0x111) != '\0'))
    goto LAB_00a5e944;
    iVar3 = *piVar4;
    local_3c = 3;
LAB_00a5e957:
    iVar7 = local_3c;
    if (iVar3 != 1) goto LAB_00a5e960;
  }
  else {
    piVar4 = *(int **)(TheDirector + 0x638);
LAB_00a5e944:
    if (param_2 != 8) {
      iVar3 = *piVar4;
      local_3c = 4;
      goto LAB_00a5e957;
    }
    local_3c = 4;
    iVar7 = local_3c;
    if (*piVar4 != 1) goto LAB_00a5e960;
    local_3c = 3;
  }
  iVar7 = 4;
  if (piVar4[1] != 0x11) {
    iVar7 = local_3c;
  }
LAB_00a5e960:
  local_3c = iVar7;
  cVar2 = CTerrorGameRules::IsVersusMode();
  iVar3 = local_3c;
  if ((cVar2 != '\0') && (cVar2 = CDirector::IsFinale(TheDirector), cVar2 != '\0')) {
    iVar3 = (uint)(**(int **)(TheDirector + 0x638) != 1) * 5 + 3;
  }
  if (param_2 == 1) {
    local_3c = 6;
  }
  else {
    local_3c = iVar3;
    if (param_2 == 6) {
      iVar7 = RandomInt(1,100);
      local_3c = 1;
      if (10 < iVar7) {
        local_3c = iVar3;
      }
    }
  }
  iVar3 = CDirector::GetScriptValue(TheDirector,"PreferredSpecialDirection",-1);
  if (iVar3 == -1) {
    iVar3 = local_3c;
  }
  piVar4 = (int *)CollectSpawnAreas(this,iVar3,param_2);
  if (piVar4[3] == 0) {
    piVar4 = (int *)CollectSpawnAreas(this,4,param_2);
    iVar7 = **(int **)(TheDirector + 0x638);
  }
  else {
    iVar7 = **(int **)(TheDirector + 0x638);
  }
  if (((iVar7 == 1) && (param_2 == 8)) &&
     (cVar2 = CDirectorChallengeMode::TankRun(*(CDirectorChallengeMode **)(TheDirector + 0x648)),
     cVar2 == '\0')) {
    param_3 = param_3 + 5;
    bVar1 = true;
  }
  else {
    bVar1 = false;
  }
  if ((piVar4[3] != 0) && (0 < param_3)) {
    iVar7 = 0;
    do {
      if ((iVar7 <= (param_3 * 2) / 3) || (bVar1)) {
        iVar5 = piVar4[3];
      }
      else {
        piVar4 = (int *)CollectSpawnAreas(this,4,param_2);
        iVar5 = piVar4[3];
        if (iVar5 == 0) break;
      }
      iVar5 = RandomInt(0,iVar5 + -1);
      iVar5 = *(int *)(*piVar4 + iVar5 * 4);
      TerrorNavArea::FindRandomSpot();
      *param_5 = local_28;
      param_5[1] = local_24;
      param_5[2] = local_20;
      cVar2 = CanZombieSpawnHere(this,param_5,iVar5,param_2,1,param_4);
      if (cVar2 != '\0') {
        return 1;
      }
      if ((*(byte *)(iVar5 + 0x57) & 0x20) == 0) {
        param_5[2] = (float)param_5[2] + 18.0;
        cVar2 = CanZombieSpawnHere(this,param_5,iVar5,param_2,1,param_4);
        if (cVar2 != '\0') {
          return 1;
        }
      }
      iVar7 = iVar7 + 1;
    } while (iVar7 != param_3);
  }
  if (*(int *)(ZombieDebug._28_4_ + 0x30) != 0) {
    iVar7 = piVar4[3];
    uVar6 = ZombieClassName(param_2);
    Msg("ZombieManager::GetRandomPZSpawnPosition failed! type: %s spawn set count: %d tries: %d location requirement: %d\n"
        ,uVar6,iVar7,param_3,iVar3);
  }
  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)