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 intoaddons/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.
Signatures + Functions block. The plugin uses
DHookCreateFromConf - DHooks reads return type, this-type,
calling convention, and argument types straight from the gamedata. Less
boilerplate in the plugin, types travel with the gamedata.
Gamedata KeyValues
DHooks plugin example
Type inference is best-effort from the C signature - sanity-check the DHooks types before shipping.