CNavMesh::UpdateGeneration
0x0072dcd0 · 3130 bytes · __thiscall
_ZN8CNavMesh16UpdateGenerationEf
Decompiled
undefined (2 params)
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
/* CNavMesh::UpdateGeneration(float) */
undefined4 __thiscall CNavMesh::UpdateGeneration(CNavMesh *this,float param_1)
{
int iVar1;
double dVar2;
char cVar3;
int iVar4;
KeyValues *this_00;
CBaseEntity *this_01;
char *pcVar5;
undefined4 uVar6;
undefined1 *puVar7;
char *pcVar8;
longdouble lVar9;
uint uVar10;
undefined1 in_stack_ffffffa4;
undefined1 uVar11;
int *piVar12;
ulonglong uVar13;
float local_2c;
CNavArea *local_28;
undefined4 local_24;
float local_20;
lVar9 = (longdouble)Plat_FloatTime();
dVar2 = (double)lVar9;
if (UpdateGeneration(float)::s_playerSettleTimer == '\0') {
in_stack_ffffffa4 = 0x80;
iVar4 = __cxa_guard_acquire();
if (iVar4 != 0) {
in_stack_ffffffa4 = 0x80;
UpdateGeneration(float)::s_playerSettleTimer._0_4_ = &PTR_NetworkStateChanged_00c0b6e0;
UpdateGeneration(float)::s_playerSettleTimer._4_4_ = 0;
UpdateGeneration(float)::s_playerSettleTimer._8_4_ = 0xbf800000;
__cxa_guard_release();
}
}
if (UpdateGeneration(float)::s_unlitAreas == '\0') {
in_stack_ffffffa4 = 0x78;
iVar4 = __cxa_guard_acquire();
if (iVar4 != 0) {
UpdateGeneration(float)::s_unlitAreas = 0;
_DAT_00fe6ecc = 0;
_DAT_00fe6ed0 = 0;
DAT_00fe6ed4 = 0;
_DAT_00fe6ed8 = 0;
__cxa_guard_release(&UpdateGeneration(float)::s_unlitAreas);
in_stack_ffffffa4 = 0x10;
__cxa_atexit(CUtlVector<CNavArea*,CUtlMemory<CNavArea*,int>>::~CUtlVector,
&UpdateGeneration(float)::s_unlitAreas);
}
}
if (UpdateGeneration(float)::s_unlitSeedAreas == '\0') {
in_stack_ffffffa4 = 0x70;
iVar4 = __cxa_guard_acquire();
if (iVar4 != 0) {
UpdateGeneration(float)::s_unlitSeedAreas = (int *)0x0;
_DAT_00fe6eb8 = 0;
_DAT_00fe6ebc = 0;
DAT_00fe6ec0 = 0;
_DAT_00fe6ec4 = 0;
__cxa_guard_release(&UpdateGeneration(float)::s_unlitSeedAreas);
in_stack_ffffffa4 = 0x10;
__cxa_atexit(CUtlVector<CNavArea*,CUtlMemory<CNavArea*,int>>::~CUtlVector,
&UpdateGeneration(float)::s_unlitSeedAreas);
}
}
if (UpdateGeneration(float)::host_thread_mode == '\0') {
in_stack_ffffffa4 = 0x68;
iVar4 = __cxa_guard_acquire();
if (iVar4 != 0) {
/* try { // try from 0072dd4f to 0072dd53 has its CatchHandler @ 0072e9a8 */
ConVarRef::ConVarRef
((ConVarRef *)&UpdateGeneration(float)::host_thread_mode,"host_thread_mode");
in_stack_ffffffa4 = 0x68;
__cxa_guard_release();
}
}
switch(*(undefined4 *)(this + 0x524)) {
case 0:
AnalysisProgress("Sampling walkable space...",*(int *)(this + 0x530) / 10,0,
(bool)in_stack_ffffffa4);
*(int *)(this + 0x530) = (*(int *)(this + 0x530) + 1) % 1000;
do {
cVar3 = SampleStep(this);
if (cVar3 == '\0') {
*(undefined4 *)(this + 0x524) = 1;
return 1;
}
lVar9 = (longdouble)Plat_FloatTime();
} while ((double)lVar9 - dVar2 <= (double)param_1);
return 1;
case 1:
Msg("Creating navigation areas from sampled data...\n");
if ((*(int *)(this + 0x528) == 2) && (ClearSelectedSet(this), 0 < DAT_00fe6000)) {
iVar4 = 0;
do {
iVar1 = iVar4 * 4;
iVar4 = iVar4 + 1;
AddToSelectedSet(this,*(CNavArea **)(TheNavAreas + iVar1));
} while (iVar4 < DAT_00fe6000);
}
CreateNavAreasFromNodes(this);
if (*(int *)(this + 0x528) == 2) {
CommandNavToggleSelectedSet(this);
}
DestroyHidingSpots();
uVar6 = 1;
*(undefined4 *)(this + 0x524) = 2;
*(undefined4 *)(this + 0x52c) = 0;
break;
case 2:
do {
iVar4 = *(int *)(this + 0x52c);
if (DAT_00fe6000 <= iVar4) {
Msg("Finding hiding spots...DONE\n");
*(undefined4 *)(this + 0x524) = 3;
*(undefined4 *)(this + 0x52c) = 0;
return 1;
}
piVar12 = *(int **)(TheNavAreas + iVar4 * 4);
*(int *)(this + 0x52c) = iVar4 + 1;
(**(code **)(*piVar12 + 0x5c))();
uVar11 = SUB41(piVar12,0);
lVar9 = (longdouble)Plat_FloatTime();
} while ((double)lVar9 - dVar2 <= (double)param_1);
AnalysisProgress("Finding hiding spots...",(*(int *)(this + 0x52c) * 100) / DAT_00fe6000,1,
(bool)uVar11);
uVar6 = 1;
break;
case 3:
do {
iVar4 = *(int *)(this + 0x52c);
if (DAT_00fe6000 <= iVar4) {
Msg("Finding encounter spots...DONE\n");
*(undefined4 *)(this + 0x524) = 4;
*(undefined4 *)(this + 0x52c) = 0;
return 1;
}
piVar12 = *(int **)(TheNavAreas + iVar4 * 4);
*(int *)(this + 0x52c) = iVar4 + 1;
(**(code **)(*piVar12 + 100))();
uVar11 = SUB41(piVar12,0);
lVar9 = (longdouble)Plat_FloatTime();
} while ((double)lVar9 - dVar2 <= (double)param_1);
AnalysisProgress("Finding encounter spots...",(*(int *)(this + 0x52c) * 100) / DAT_00fe6000,1,
(bool)uVar11);
uVar6 = 1;
break;
case 4:
do {
iVar4 = *(int *)(this + 0x52c);
if (DAT_00fe6000 <= iVar4) {
Msg("Finding sniper spots...DONE\n");
*(undefined4 *)(this + 0x524) = 5;
*(undefined4 *)(this + 0x52c) = 0;
return 1;
}
piVar12 = *(int **)(TheNavAreas + iVar4 * 4);
*(int *)(this + 0x52c) = iVar4 + 1;
(**(code **)(*piVar12 + 0x60))();
uVar11 = SUB41(piVar12,0);
lVar9 = (longdouble)Plat_FloatTime();
} while ((double)lVar9 - dVar2 <= (double)param_1);
AnalysisProgress("Finding sniper spots...",(*(int *)(this + 0x52c) * 100) / DAT_00fe6000,1,
(bool)uVar11);
uVar6 = 1;
break;
case 5:
do {
iVar4 = *(int *)(this + 0x52c);
if (DAT_00fe6000 <= iVar4) {
Msg("Finding earliest occupy times...DONE\n");
if ((*(int *)(this + 0x528) == 2) ||
(cVar3 = (**(code **)(*engine + 8))(engine), cVar3 != '\0')) goto LAB_0072e6bc;
*(undefined4 *)(this + 0x524) = 6;
if ((float)UpdateGeneration(float)::s_playerSettleTimer._8_4_ != -1.0) {
UpdateGeneration(float)::s_playerSettleTimer._8_4_ = 0xbf800000;
}
DAT_00fe6ed4 = 0;
iVar4 = CNavArea::m_masterMarker + 1;
CNavArea::m_masterMarker = 1;
if (iVar4 != 0) {
CNavArea::m_masterMarker = iVar4;
}
iVar4 = 0;
if (0 < DAT_00fe6000) {
do {
iVar1 = iVar4 * 4;
iVar4 = iVar4 + 1;
CUtlVector<CNavArea*,CUtlMemory<CNavArea*,int>>::InsertBefore
((CUtlVector<CNavArea*,CUtlMemory<CNavArea*,int>> *)
&UpdateGeneration(float)::s_unlitAreas,DAT_00fe6ed4,
(CNavArea **)(TheNavAreas + iVar1));
CUtlVector<CNavArea*,CUtlMemory<CNavArea*,int>>::InsertBefore
((CUtlVector<CNavArea*,CUtlMemory<CNavArea*,int>> *)
&UpdateGeneration(float)::s_unlitSeedAreas,DAT_00fe6ec0,
(CNavArea **)(iVar1 + TheNavAreas));
} while (iVar4 < DAT_00fe6000);
}
goto LAB_0072e6c6;
}
piVar12 = *(int **)(TheNavAreas + iVar4 * 4);
*(int *)(this + 0x52c) = iVar4 + 1;
(**(code **)(*piVar12 + 0x68))();
uVar11 = SUB41(piVar12,0);
lVar9 = (longdouble)Plat_FloatTime();
} while ((double)lVar9 - dVar2 <= (double)param_1);
AnalysisProgress("Finding earliest occupy times...",
(*(int *)(this + 0x52c) * 100) / DAT_00fe6000,1,(bool)uVar11);
uVar6 = 1;
break;
case 6:
uVar13 = 0;
(**(code **)(*UpdateGeneration(float)::host_thread_mode + 8))
(UpdateGeneration(float)::host_thread_mode,0);
this_01 = (CBaseEntity *)UTIL_GetListenServerHost();
if ((DAT_00fe6ed4 != 0) && (this_01 != (CBaseEntity *)0x0)) {
lVar9 = (longdouble)CountdownTimer::Now();
if ((float)lVar9 < (float)UpdateGeneration(float)::s_playerSettleTimer._8_4_) {
return 1;
}
iVar4 = 0;
for (; iVar4 < (int)DAT_00fe6ed4; DAT_00fe6ed4 = DAT_00fe6ed4 - 1) {
while( true ) {
local_28 = *(CNavArea **)(UpdateGeneration(float)::s_unlitAreas + iVar4 * 4);
cVar3 = (**(code **)(*(int *)local_28 + 0x70))(local_28);
if (cVar3 != '\0') break;
iVar4 = iVar4 + 1;
if ((int)DAT_00fe6ed4 <= iVar4) goto LAB_0072e43b;
}
CUtlVector<CNavArea*,CUtlMemory<CNavArea*,int>>::FindAndRemove
((CUtlVector<CNavArea*,CUtlMemory<CNavArea*,int>> *)
&UpdateGeneration(float)::s_unlitSeedAreas,&local_28);
uVar13 = CONCAT44(1,iVar4);
CUtlVector<CNavArea*,CUtlMemory<CNavArea*,int>>::ShiftElementsLeft
((CUtlVector<CNavArea*,CUtlMemory<CNavArea*,int>> *)
&UpdateGeneration(float)::s_unlitAreas,iVar4,1);
}
LAB_0072e43b:
if (DAT_00fe6ed4 != 0) {
if (DAT_00fe6ec0 != 0) {
iVar4 = *UpdateGeneration(float)::s_unlitSeedAreas;
iVar1 = DAT_00fe6ec0;
if (0 < DAT_00fe6ec0) {
iVar1 = 0;
if (DAT_00fe6ec0 + -1 != 0) {
*UpdateGeneration(float)::s_unlitSeedAreas =
UpdateGeneration(float)::s_unlitSeedAreas[DAT_00fe6ec0 + -1];
iVar1 = DAT_00fe6ec0 + -1;
}
}
DAT_00fe6ec0 = iVar1;
local_28 = *(CNavArea **)(iVar4 + 0x2c);
local_24 = *(undefined4 *)(iVar4 + 0x30);
local_20 = *(float *)(iVar4 + 0x34);
cVar3 = GetGroundHeight(this,(Vector *)&local_28,&local_2c,(Vector *)0x0);
if (cVar3 != '\0') {
local_20 = local_2c;
}
local_20 = local_20 + 17.5;
CBaseEntity::SetAbsOrigin(this_01,(Vector *)&local_28);
AnalysisProgress("Finding light intensity...",
(int)((DAT_00fe6000 - DAT_00fe6ed4) * 100) / DAT_00fe6000,1,
SUB41(this_01,0));
UpdateGeneration(float)::s_movedPlayerToArea = *(undefined4 *)(iVar4 + 0x8c);
lVar9 = (longdouble)CountdownTimer::Now();
if ((float)lVar9 + 0.1 != (float)UpdateGeneration(float)::s_playerSettleTimer._8_4_) {
UpdateGeneration(float)::s_playerSettleTimer._8_4_ = (float)lVar9 + 0.1;
}
if ((float)UpdateGeneration(float)::s_playerSettleTimer._4_4_ == 0.1) {
return 1;
}
UpdateGeneration(float)::s_playerSettleTimer._4_4_ = 0x3dcccccd;
return 1;
}
uVar13 = (ulonglong)DAT_00fe6ed4;
Msg("Finding light intensity...DONE (%d unlit areas)\n",DAT_00fe6ed4);
if ((DAT_00fe6ed4 != 0) && (Warning("To see unlit areas:\n"), 0 < (int)DAT_00fe6ed4)) {
iVar4 = 0;
do {
iVar1 = iVar4 * 4;
iVar4 = iVar4 + 1;
uVar10 = *(uint *)(*(int *)(UpdateGeneration(float)::s_unlitAreas + iVar1) + 0x8c);
uVar13 = (ulonglong)uVar10;
Warning("nav_unmark; nav_mark %d; nav_warp_to_mark;\n",uVar10);
} while (iVar4 < (int)DAT_00fe6ed4);
}
*(undefined4 *)(this + 0x524) = 7;
*(undefined4 *)(this + 0x52c) = 0;
}
}
Msg("Finding light intensity...DONE\n",uVar13);
LAB_0072e6bc:
*(undefined4 *)(this + 0x524) = 7;
LAB_0072e6c6:
*(undefined4 *)(this + 0x52c) = 0;
return 1;
case 7:
iVar4 = *(int *)(this + 0x52c);
if (iVar4 == 0) {
(**(code **)(*(int *)this + 0x90))(this,*(int *)(this + 0x528) == 2);
Msg("Start custom...\n ");
iVar4 = *(int *)(this + 0x52c);
}
while( true ) {
if (DAT_00fe6000 <= iVar4) {
Msg("Post custom...\n ");
(**(code **)(*(int *)this + 0x88))(this);
(**(code **)(*(int *)this + 0x94))(this);
Msg("Custom game-specific analysis...DONE\n");
*(undefined4 *)(this + 0x524) = 8;
*(undefined4 *)(this + 0x52c) = 0;
ConVarRef::ConVarRef((ConVarRef *)&local_28,"mat_queue_mode");
(**(code **)(*(int *)local_28 + 8))(local_28,0xffffffff);
(**(code **)(*UpdateGeneration(float)::host_thread_mode + 8))
(UpdateGeneration(float)::host_thread_mode,*(undefined4 *)(this + 0x570));
return 1;
}
piVar12 = *(int **)(TheNavAreas + iVar4 * 4);
*(int *)(this + 0x52c) = iVar4 + 1;
(**(code **)(*piVar12 + 0x6c))(piVar12,*(int *)(this + 0x528) == 2);
uVar11 = SUB41(piVar12,0);
lVar9 = (longdouble)Plat_FloatTime();
if ((double)param_1 < (double)lVar9 - dVar2) break;
iVar4 = *(int *)(this + 0x52c);
}
AnalysisProgress("Custom game-specific analysis...",
(*(int *)(this + 0x52c) * 100) / DAT_00fe6000,1,(bool)uVar11);
return 1;
case 8:
if ((*(int *)(this + 0x528) == 1) || (*(int *)(this + 0x528) == 4)) {
this[0x4e] = (CNavMesh)0x1;
}
lVar9 = (longdouble)Plat_FloatTime();
uVar10 = SUB84((double)((float)lVar9 - *(float *)(this + 0x538)),0);
Msg("Generation complete! %0.1f seconds elapsed.\n");
iVar4 = *(int *)(this + 0x528);
this[0x4c] = (CNavMesh)0x1;
*(undefined4 *)(this + 0x528) = 0;
*(undefined4 *)(this + 0x564) = 0;
this_00 = KeyValues::operator_new((KeyValues *)0x2c,uVar10);
/* try { // try from 0072e04b to 0072e04f has its CatchHandler @ 0072e996 */
KeyValues::KeyValues(this_00,"data",(IKeyValuesSystem *)0x0,false);
ShowViewPortPanelToAll("nav_progress",false,this_00);
KeyValues::deleteThis();
cVar3 = (**(code **)(*(int *)this + 0x30))(this);
if (cVar3 == '\0') {
pcVar5 = (char *)GetFilename();
pcVar8 = "(null)";
if (pcVar5 != (char *)0x0) {
pcVar8 = pcVar5;
}
Msg("ERROR: Cannot save navigation map \'%s\'.\n",pcVar8);
}
else {
uVar6 = GetFilename();
Msg("Navigation map \'%s\' saved.\n",uVar6);
}
if (this[0x534] == (CNavMesh)0x0) {
uVar6 = 0;
if (iVar4 == 2) {
iVar4 = 0;
if (0 < DAT_00fe6000) {
do {
iVar1 = iVar4 * 4;
iVar4 = iVar4 + 1;
CNavArea::ResetNodes(*(CNavArea **)(TheNavAreas + iVar1));
} while (iVar4 < DAT_00fe6000);
}
}
else {
puVar7 = &DAT_00d539c2;
if (*(undefined1 **)(gpGlobals + 0x3c) != (undefined1 *)0x0) {
puVar7 = *(undefined1 **)(gpGlobals + 0x3c);
}
(**(code **)*engine)(engine,puVar7,0);
}
}
else {
(**(code **)(*engine + 0x94))(engine,"quit\n");
uVar6 = 0;
}
break;
default:
uVar6 = 0;
}
return uVar6;
}
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.