L L4D2node

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 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)