TerrorNavMesh::FindGoalArea
0x00977ac0 · 1321 bytes · __thiscall
_ZNK13TerrorNavMesh12FindGoalAreaEv
Decompiled
undefined (1 param)
/* TerrorNavMesh::FindGoalArea() const */
int * __thiscall TerrorNavMesh::FindGoalArea(TerrorNavMesh *this)
{
int *piVar1;
CBaseEntity *pCVar2;
int *piVar3;
Checkpoint *this_00;
int iVar4;
int iVar5;
int *piVar6;
int iVar7;
float fVar8;
float fVar9;
float fVar10;
float fVar11;
float local_4c [3];
float local_40 [3];
Extent local_34 [12];
float afStack_28 [6];
pCVar2 = (CBaseEntity *)
CGlobalEntityList::FindEntityByName
((CGlobalEntityList *)gEntList,(CBaseEntity *)0x0,"nav_flow_target",
(CBaseEntity *)0x0,(CBaseEntity *)0x0,(CBaseEntity *)0x0,
(IEntityFindFilter *)0x0);
if ((pCVar2 != (CBaseEntity *)0x0) &&
(piVar3 = (int *)CNavMesh::GetNearestNavArea((CNavMesh *)this,pCVar2,0,200.0),
piVar3 != (int *)0x0)) {
ZombieDebugPrint(1,"Goal area set by a nav_flow_target!\n");
return piVar3;
}
this_00 = (Checkpoint *)GetLastCheckpoint(this);
if ((this_00 != (Checkpoint *)0x0) &&
(piVar3 = (int *)Checkpoint::GetLargestArea(this_00), piVar3 != (int *)0x0)) {
ZombieDebugPrint(1,"Goal area set by checkpoint!\n");
return piVar3;
}
pCVar2 = (CBaseEntity *)
CGlobalEntityList::FindEntityByClassname
((CGlobalEntityList *)gEntList,(CBaseEntity *)0x0,"trigger_finale");
if (((pCVar2 != (CBaseEntity *)0x0) &&
(piVar3 = (int *)CNavMesh::GetNearestNavArea((CNavMesh *)this,pCVar2,0,200.0),
piVar3 != (int *)0x0)) && ((*(byte *)(piVar3 + 0x4b) & 0x40) != 0)) {
ZombieDebugPrint(1,"Goal area set by finale attribute and radio!\n");
return piVar3;
}
pCVar2 = (CBaseEntity *)0x0;
while (pCVar2 = (CBaseEntity *)
CGlobalEntityList::FindEntityByClassname
((CGlobalEntityList *)gEntList,pCVar2,"prop_health_cabinet"),
pCVar2 != (CBaseEntity *)0x0) {
piVar3 = (int *)CNavMesh::GetNearestNavArea((CNavMesh *)this,pCVar2,0,200.0);
if ((piVar3 != (int *)0x0) && ((*(byte *)(piVar3 + 0x4b) & 0x40) != 0)) {
ZombieDebugPrint(1,"Goal area set by finale attribute and health cabinet!\n");
return piVar3;
}
}
if (0 < DAT_00fe6000) {
piVar3 = (int *)*TheNavAreas;
if ((piVar3[0x4b] & 0x10040U) != 0x10040) {
iVar5 = 0;
do {
iVar5 = iVar5 + 1;
if (iVar5 == DAT_00fe6000) {
local_4c[0] = 1e+09;
iVar7 = 0;
local_4c[1] = 1e+09;
local_4c[2] = 1e+09;
local_40[0] = -1e+09;
local_40[1] = -1e+09;
local_40[2] = -1e+09;
iVar5 = DAT_00fe6000;
do {
if (((byte)((CNavArea *)TheNavAreas[iVar7])[300] & 0x40) != 0) {
CNavArea::GetExtent((CNavArea *)TheNavAreas[iVar7],local_34);
iVar5 = 0;
do {
fVar11 = *(float *)(local_34 + iVar5 * 4);
if (local_4c[iVar5] <= fVar11) {
if (local_40[iVar5] <= fVar11 && fVar11 != local_40[iVar5]) {
local_40[iVar5] = fVar11;
}
}
else {
local_4c[iVar5] = fVar11;
}
iVar5 = iVar5 + 1;
} while (iVar5 != 3);
iVar4 = 0;
do {
fVar11 = afStack_28[iVar4];
if (local_4c[iVar4] <= fVar11) {
if (local_40[iVar4] <= fVar11 && fVar11 != local_40[iVar4]) {
local_40[iVar4] = fVar11;
}
}
else {
local_4c[iVar4] = fVar11;
}
iVar4 = iVar4 + 1;
iVar5 = DAT_00fe6000;
} while (iVar4 != 3);
}
iVar7 = iVar7 + 1;
} while (iVar7 < iVar5);
if (iVar5 < 1) goto LAB_00977ff1;
fVar11 = (float)0x4e6e6b28;
piVar6 = (int *)0x0;
piVar3 = TheNavAreas;
do {
piVar1 = (int *)*piVar3;
if (((*(byte *)(piVar1 + 0x4b) & 0x40) != 0) &&
(fVar10 = (float)piVar1[0xb] - (local_40[0] + local_4c[0]) * 0.5,
fVar8 = (float)piVar1[0xc] - (local_40[1] + local_4c[1]) * 0.5,
fVar9 = (float)piVar1[0xd] - (local_40[2] + local_4c[2]) * 0.5,
fVar8 = fVar8 * fVar8 + fVar10 * fVar10 + fVar9 * fVar9, fVar8 < fVar11)) {
piVar6 = piVar1;
fVar11 = fVar8;
}
piVar3 = piVar3 + 1;
} while (piVar3 != TheNavAreas + iVar5);
if (piVar6 == (int *)0x0) goto LAB_00977ff1;
ZombieDebugPrint(1,
"Goal area set by finale attribute at center of area, note the quality is questionable - ie. may not be reachable.\n"
);
if (*(int *)(NavDebugFinaleArea._28_4_ + 0x30) == 0) {
return piVar6;
}
(**(code **)(*piVar6 + 0x54))(piVar6,0xff,0xff,0,0xff,0x47c34ff3,1);
goto LAB_00977ea2;
}
piVar3 = (int *)TheNavAreas[iVar5];
} while ((piVar3[0x4b] & 0x10040U) != 0x10040);
}
ZombieDebugPrint(1,
"Goal area set by finale and rescue closet attributes, ie. the finale is reachable.\n"
);
return piVar3;
}
local_4c[0] = 1e+09;
local_4c[1] = 1e+09;
local_4c[2] = 1e+09;
local_40[0] = -1e+09;
local_40[1] = -1e+09;
local_40[2] = -1e+09;
LAB_00977ff1:
if (*(int *)(NavDebugFinaleArea._28_4_ + 0x30) != 0) {
piVar6 = (int *)0x0;
LAB_00977ea2:
NDebugOverlay::Box((Vector *)&vec3_origin,(Vector *)local_4c,(Vector *)local_40,0xff,0xff,0,0xff
,1e+07);
if (piVar6 != (int *)0x0) {
return piVar6;
}
}
pCVar2 = (CBaseEntity *)
CGlobalEntityList::FindEntityByName
((CGlobalEntityList *)gEntList,(CBaseEntity *)0x0,"nav_cordon_flow_target",
(CBaseEntity *)0x0,(CBaseEntity *)0x0,(CBaseEntity *)0x0,
(IEntityFindFilter *)0x0);
if (pCVar2 == (CBaseEntity *)0x0) {
return (int *)0x0;
}
piVar3 = (int *)CNavMesh::GetNearestNavArea((CNavMesh *)this,pCVar2,0,200.0);
iVar5 = CGlobalEntityList::FindEntityByName
((CGlobalEntityList *)gEntList,pCVar2,"nav_cordon_flow_target",
(CBaseEntity *)0x0,(CBaseEntity *)0x0,(CBaseEntity *)0x0,
(IEntityFindFilter *)0x0);
if (iVar5 != 0) {
ZombieDebugPrint(1,"Flow Warning: Found multiple nav_cordon_flow_target(s).\n");
}
if (piVar3 == (int *)0x0) {
return (int *)0x0;
}
ZombieDebugPrint(1,"Goal area set by nav_cordon_flow_target.\n");
return piVar3;
}
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.