L L4D2node

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