L L4D2node

CDirector::TryToStartSurvivorRescue

0x00881ca0 · 1068 bytes · __thiscall

_ZN9CDirector24TryToStartSurvivorRescueEbP13CTerrorPlayer

Decompiled

undefined (3 params)

/* CDirector::TryToStartSurvivorRescue(bool, CTerrorPlayer*) */

void __thiscall
CDirector::TryToStartSurvivorRescue(CDirector *this,bool param_1,CTerrorPlayer *param_2)

{
  float fVar1;
  float fVar2;
  char cVar3;
  TerrorNavArea *pTVar4;
  undefined4 uVar5;
  undefined4 uVar6;
  undefined4 *puVar7;
  Vector *pVVar8;
  int iVar9;
  CSurvivorRescue *this_00;
  CSurvivorRescue *this_01;
  longdouble lVar10;
  undefined4 uVar11;
  undefined4 uVar12;
  float local_3c;
  undefined4 local_20 [4];
  
  if (param_1) {
    fVar1 = *(float *)(RescueFinaleSpawnRange._28_4_ + 0x2c);
  }
  else {
    fVar1 = *(float *)(RescueSpawnRange._28_4_ + 0x2c);
  }
  this_01 = (CSurvivorRescue *)0x0;
  local_3c = 3.4028235e+38;
  this_00 = (CSurvivorRescue *)0x0;
LAB_00881cf0:
  do {
    do {
      this_01 = (CSurvivorRescue *)
                CGlobalEntityList::FindEntityByClassname
                          ((CGlobalEntityList *)gEntList,(CBaseEntity *)this_01,
                           "info_survivor_rescue");
      if (this_01 == (CSurvivorRescue *)0x0) {
        if (this_00 != (CSurvivorRescue *)0x0) {
          cVar3 = CSurvivorRescue::CloseDoors(this_00);
          uVar11 = SUB84((double)local_3c,0);
          uVar12 = (undefined4)((ulonglong)(double)local_3c >> 0x20);
          if (cVar3 != '\0') {
            uVar5 = CBaseEntity::GetDebugName((CBaseEntity *)this_00);
            if (*(int *)(this_00 + 0x30) == 0) {
              iVar9 = 0;
            }
            else {
              iVar9 = *(int *)(this_00 + 0x30) - *(int *)(gpGlobals + 0x58) >> 4;
            }
            DevMsg("rescue spot %d(%s) closes door to start calling for help with nearest survivor %.1f path units away\n"
                   ,iVar9,uVar5,uVar11,uVar12);
            return;
          }
          uVar5 = (**(code **)(*(int *)param_2 + 0xb8))(param_2);
          uVar6 = CBaseEntity::GetDebugName((CBaseEntity *)this_00);
          if (*(int *)(this_00 + 0x30) == 0) {
            iVar9 = 0;
          }
          else {
            iVar9 = *(int *)(this_00 + 0x30) - *(int *)(gpGlobals + 0x58) >> 4;
          }
          DevMsg("rescue spot %d(%s) starts calling for help for %s with nearest survivor %.1f path units away\n"
                 ,iVar9,uVar6,uVar5,uVar11,uVar12);
          local_20[0] = 0xffffffff;
          puVar7 = (undefined4 *)(**(code **)(*(int *)this_00 + 0xc))(this_00);
          local_20[0] = *puVar7;
          CUtlVector<CHandle<CSurvivorRescue>,CUtlMemory<CHandle<CSurvivorRescue>,int>>::
          InsertBefore((CUtlVector<CHandle<CSurvivorRescue>,CUtlMemory<CHandle<CSurvivorRescue>,int>>
                        *)(this + 0x3e0),*(int *)(this + 0x3ec),(CHandle *)local_20);
          CSurvivorRescue::CallForHelp(this_00,param_2);
          lVar10 = (longdouble)CountdownTimer::Now();
          if ((float)lVar10 + 0.1 != *(float *)(this + 0x3dc)) {
            (**(code **)(*(int *)(this + 0x3d4) + 4))(this + 0x3d4,this + 0x3dc);
            *(float *)(this + 0x3dc) = (float)lVar10 + 0.1;
          }
          if (*(float *)(this + 0x3d8) != 0.1) {
            (**(code **)(*(int *)(this + 0x3d4) + 4))(this + 0x3d4,this + 0x3d8);
            *(undefined4 *)(this + 0x3d8) = 0x3dcccccd;
            return;
          }
        }
        return;
      }
      cVar3 = CSurvivorRescue::IsCallingForHelp(this_01);
    } while (cVar3 != '\0');
    if (param_1) goto LAB_00881e00;
  } while (*(int *)(this_01 + 0x1934) != 0);
  pTVar4 = (TerrorNavArea *)CSurvivorRescue::GetRescueNavArea(this_01);
  goto LAB_00881d3c;
LAB_00881e00:
  pTVar4 = (TerrorNavArea *)CSurvivorRescue::GetRescueNavArea(this_01);
  if ((pTVar4 != (TerrorNavArea *)0x0) && ((*(uint *)(pTVar4 + 300) & 0x140) != 0)) {
LAB_00881d3c:
    cVar3 = CSurvivorRescue::IsLiveSurvivorInside(this_01);
    if (cVar3 == '\0') {
      cVar3 = CSurvivorRescue::IsBehindClosedDoor(this_01);
      if (cVar3 == '\0') {
        pVVar8 = (Vector *)(**(code **)(*(int *)this_01 + 0x288))(this_01);
        cVar3 = CDirectorTacticalServices::IsVisibleToTeam
                          (*(CDirectorTacticalServices **)(this + 0x628),pVVar8,2,0,0.0,pTVar4,
                           (CBaseEntity *)this_01);
        if (cVar3 != '\0') goto LAB_00881cf0;
      }
      if (this_00 == (CSurvivorRescue *)0x0) {
        lVar10 = (longdouble)CSurvivorRescue::GetDistanceToNearestSurvivor(this_01,fVar1 + 500.0);
        fVar2 = (float)lVar10;
        if (0.0 <= fVar2) {
          if (fVar2 <= fVar1) {
            this_00 = this_01;
          }
          local_3c = (float)(~-(uint)(fVar1 < fVar2) & (uint)fVar2 |
                            (uint)local_3c & -(uint)(fVar1 < fVar2));
        }
      }
      else if ((*(int *)(this_01 + 0x1934) <= *(int *)(this_00 + 0x1934)) &&
              ((cVar3 = CSurvivorRescue::IsBehindClosedDoor(this_01), cVar3 != '\0' ||
               (cVar3 = CSurvivorRescue::IsBehindClosedDoor(this_00), cVar3 == '\0')))) {
        lVar10 = (longdouble)CSurvivorRescue::GetDistanceToNearestSurvivor(this_01,fVar1 + 500.0);
        fVar2 = (float)lVar10;
        if (((0.0 <= fVar2) && (fVar2 <= fVar1)) &&
           ((((cVar3 = CSurvivorRescue::IsBehindClosedDoor(this_00), cVar3 == '\0' &&
              (cVar3 = CSurvivorRescue::IsBehindClosedDoor(this_01), cVar3 != '\0')) ||
             (*(int *)(this_01 + 0x1934) < *(int *)(this_00 + 0x1934))) || (fVar2 < local_3c)))) {
          this_00 = this_01;
          local_3c = fVar2;
        }
      }
    }
  }
  goto LAB_00881cf0;
}

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)