ZombieManager::CanZombieSpawnHere
0x00a5a120 · 2114 bytes · __thiscall
_ZNK13ZombieManager18CanZombieSpawnHereERK6VectorP13TerrorNavArea15ZombieClassTypebP20CBaseCombatCharacter
Decompiled
undefined (6 params)
/* ZombieManager::CanZombieSpawnHere(Vector const&, TerrorNavArea*, ZombieClassType, bool,
CBaseCombatCharacter*) const */
undefined4 __thiscall
ZombieManager::CanZombieSpawnHere
(undefined4 this,Vector *param_1,CNavArea *param_2,int param_4,char param_5,
IHandleEntity *param_6)
{
CDirectorTacticalServices *this_00;
CBaseEntity *this_01;
char cVar1;
char cVar2;
undefined4 uVar3;
int iVar4;
int iVar5;
uint uVar6;
char *pcVar7;
undefined4 uVar8;
float fVar9;
float fVar10;
undefined4 local_e8;
undefined4 local_e4;
float local_e0;
undefined4 local_dc;
undefined4 local_d8;
float local_d4;
float local_cc;
float local_c8;
float local_c4;
undefined4 local_c0;
undefined4 local_bc;
CBaseEntity *local_b8;
undefined4 local_b4;
undefined4 local_b0;
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;
Vector local_70 [12];
Vector local_64 [32];
float local_44;
char local_39;
uVar3 = CDirector::IsInTransition(TheDirector);
if ((char)uVar3 != '\0') {
return 0;
}
if ((param_4 != 0) && (((byte)param_2[0x54] & 1) != 0)) {
return 0;
}
if ((param_6 == (IHandleEntity *)0x0) ||
(cVar1 = (**(code **)(*(int *)param_6 + 0x16c))(param_6), cVar1 == '\0')) {
uVar8 = 0x202420b;
}
else {
cVar1 = (**(code **)(*(int *)param_6 + 0x16c))(param_6);
uVar8 = 0x202420b;
if (cVar1 != '\0') {
uVar8 = (**(code **)(*(int *)param_6 + 0x7a0))(param_6,0);
}
}
iVar4 = (**(code **)(*g_pGameRules + 0x7c))(g_pGameRules);
iVar5 = (**(code **)(*g_pGameRules + 0x7c))(g_pGameRules);
local_87 = 0;
local_bc = 0;
local_b8 = (CBaseEntity *)0x0;
local_b4 = 0;
local_8c = 0;
local_9c = (*(float *)(iVar4 + 0x18) - *(float *)(iVar5 + 0xc)) * 0.5;
local_98 = (*(float *)(iVar4 + 0x1c) - *(float *)(iVar5 + 0x10)) * 0.5;
local_94 = (*(float *)(iVar4 + 0x20) - *(float *)(iVar5 + 0x14)) * 0.5;
local_88 = local_98 * local_98 + local_9c * local_9c + local_94 * local_94 < 1e-06;
local_ac = (*(float *)(iVar4 + 0x18) + *(float *)(iVar5 + 0xc)) * 0.5;
local_cc = *(float *)param_1 + local_ac;
local_a8 = (*(float *)(iVar4 + 0x1c) + *(float *)(iVar5 + 0x10)) * 0.5;
local_c8 = *(float *)(param_1 + 4) + local_a8;
local_a4 = (*(float *)(iVar4 + 0x20) + *(float *)(iVar5 + 0x14)) * 0.5;
local_c4 = *(float *)(param_1 + 8) + local_a4;
local_ac = -local_ac;
local_a8 = -local_a8;
local_a4 = -local_a4;
CTraceFilterSimple::CTraceFilterSimple
((CTraceFilterSimple *)&local_dc,param_6,8,(_func_bool_IHandleEntity_ptr_int *)0x0);
(**(code **)(*enginetrace + 0x14))(enginetrace,&local_cc,uVar8,(CTraceFilterSimple *)&local_dc);
if (*(int *)(r_visualizetraces._28_4_ + 0x30) != 0) {
DebugDrawLine(local_70,local_64,0xff,0xff,0,true,-1.0);
}
if ((local_39 != '\0') || (local_44 < 1.0)) {
if (*(int *)(ZombieDebug._28_4_ + 0x30) == 0) {
return uVar3;
}
iVar4 = CDirector::GetCommonInfectedLimit(TheDirector);
if (0 < iVar4) {
uVar8 = ZombieClassName(param_4);
pcVar7 = "(mob) ";
if (param_5 == '\0') {
pcVar7 = "";
}
Msg("CanZombieSpawnHere: Spot blocked (%.0f, %.0f, %.0f) for a %s%s\n",
(double)*(float *)param_1,(double)*(float *)(param_1 + 4),(double)*(float *)(param_1 + 8),
pcVar7,uVar8);
return uVar3;
}
return uVar3;
}
if (param_2 == (CNavArea *)0x0) {
param_2 = (CNavArea *)CNavMesh::GetNavArea(TheNavMesh,param_1,120.0);
cVar1 = CDirectorChallengeMode::TankRun(*(CDirectorChallengeMode **)(TheDirector + 0x648));
if (s_ManualSpawn != '\0') goto LAB_00a5a3bf;
if (param_2 != (CNavArea *)0x0) goto LAB_00a5a440;
}
else {
cVar1 = CDirectorChallengeMode::TankRun(*(CDirectorChallengeMode **)(TheDirector + 0x648));
if (s_ManualSpawn != '\0') goto LAB_00a5a3bf;
LAB_00a5a440:
uVar6 = *(uint *)(param_2 + 300);
if ((uVar6 & 0x800) != 0) {
cVar2 = CDirector::HasAnySurvivorLeftSafeArea(TheDirector);
if (cVar2 == '\0') {
return 0;
}
uVar6 = *(uint *)(param_2 + 300);
}
if (((uVar6 & 0x80) != 0) && (cVar1 == '\0')) {
return 0;
}
cVar2 = CNavArea::IsBlocked(param_2,3,false);
if (cVar2 != '\0') {
return 0;
}
uVar3 = CZombieBorder::IsBehindZombieBorder((Vector *)(param_2 + 0x2c));
if ((char)uVar3 != '\0') {
return 0;
}
if (((byte)param_2[0x12d] & 0x10) != 0) {
iVar4 = UTIL_GetClosestPlayer(param_1,2,&local_cc);
if ((iVar4 != 0) && (local_cc < *(float *)(NavObscureRange._28_4_ + 0x2c))) {
return uVar3;
}
goto LAB_00a5a3bf;
}
}
if (cVar1 == '\0') {
this_00 = *(CDirectorTacticalServices **)(TheDirector + 0x628);
local_e8 = *(undefined4 *)param_1;
local_e4 = *(undefined4 *)(param_1 + 4);
local_e0 = *(float *)(param_1 + 8) + 56.8;
/* try { // try from 00a5a6c2 to 00a5a6c6 has its CatchHandler @ 00a5a97b */
cVar1 = CDirectorTacticalServices::IsVisibleToTeam
(this_00,(Vector *)&local_e8,2,3,0.0,(TerrorNavArea *)param_2,
(CBaseEntity *)0x0);
if (cVar1 == '\0') {
local_dc = *(undefined4 *)param_1;
local_d8 = *(undefined4 *)(param_1 + 4);
local_d4 = *(float *)(param_1 + 8) + 35.5;
/* try { // try from 00a5a8f7 to 00a5a8fb has its CatchHandler @ 00a5a987 */
cVar1 = CDirectorTacticalServices::IsVisibleToTeam
(this_00,(Vector *)&local_dc,2,3,0.0,(TerrorNavArea *)param_2,
(CBaseEntity *)0x0);
if (cVar1 == '\0') {
local_cc = *(float *)param_1;
local_c8 = *(float *)(param_1 + 4);
local_c4 = *(float *)(param_1 + 8) + 1.0;
/* try { // try from 00a5a969 to 00a5a96d has its CatchHandler @ 00a5a985 */
cVar1 = CDirectorTacticalServices::IsVisibleToTeam
(this_00,(Vector *)&local_cc,2,3,0.0,(TerrorNavArea *)param_2,
(CBaseEntity *)0x0);
if (cVar1 == '\0') goto LAB_00a5a3bf;
}
}
uVar3 = CDirector::IsLocationFoggedToSurvivors(TheDirector,param_1);
if ((char)uVar3 == '\0') {
if (param_2 == (CNavArea *)0x0) {
return 0;
}
TerrorNavArea::MarkAreaCleared((TerrorNavArea *)param_2,(CTerrorPlayer *)0x0);
return uVar3;
}
}
LAB_00a5a3bf:
g_IsZombieSpawnMobRush = param_5;
if (param_4 == 9) {
return 0;
}
g_ZombieClass = param_4;
if (param_4 != 0) {
if (s_ManualSpawn == '\0') {
fVar10 = *(float *)(ZombieSpawnSafetyRange._28_4_ + 0x2c);
local_bc = CONCAT31(local_bc._1_3_,1);
local_c0 = 2;
local_b8 = (CBaseEntity *)0x0;
local_b4 = 0x4e6e6b28;
local_b0 = 0;
local_cc = *(float *)param_1;
local_c8 = *(float *)(param_1 + 4);
local_c4 = *(float *)(param_1 + 8);
ForEachPlayer<ClosestPlayerScan>((ClosestPlayerScan *)&local_cc);
this_01 = local_b8;
if (local_b8 == (CBaseEntity *)0x0) {
return 0;
}
if (((byte)local_b8[0x14d] & 8) == 0) {
fVar9 = *(float *)(local_b8 + 0x2e8) - *(float *)(param_1 + 8);
fVar10 = fVar10 - ABS(fVar9);
}
else {
CBaseEntity::CalcAbsolutePosition(local_b8);
fVar9 = *(float *)(this_01 + 0x2e8) - *(float *)(param_1 + 8);
fVar10 = fVar10 - ABS(fVar9);
if (((byte)this_01[0x14d] & 8) != 0) {
CBaseEntity::CalcAbsolutePosition(this_01);
fVar9 = *(float *)(this_01 + 0x2e8) - *(float *)(param_1 + 8);
}
}
if ((*(float *)(this_01 + 0x2e4) - *(float *)(param_1 + 4)) *
(*(float *)(this_01 + 0x2e4) - *(float *)(param_1 + 4)) +
(*(float *)(this_01 + 0x2e0) - *(float *)param_1) *
(*(float *)(this_01 + 0x2e0) - *(float *)param_1) + fVar9 * fVar9 < fVar10 * fVar10) {
return 0;
}
}
if ((((g_ZombieClass == 7) && (s_ManualSpawn == '\0')) &&
(*(float *)(param_2 + 0x154) <= 0.0 && *(float *)(param_2 + 0x154) != 0.0)) &&
(cVar1 = CDirector::IsFinale(TheDirector), cVar1 == '\0')) {
g_ZombieClass = 0;
Warning("Witch converted to a normal Infected!\n");
}
}
return 1;
}
SourceMod gamedata
paste intoaddons/sourcemod/gamedata/<your_plugin>.txt
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.
Type inference is best-effort from the C signature - sanity-check the DHooks types before shipping.