L L4D2node

CDirector::CreateRescuableSurvivors

0x00884d70 · 1463 bytes · __thiscall

_ZN9CDirector24CreateRescuableSurvivorsEv

Decompiled

undefined (1 param)

/* CDirector::CreateRescuableSurvivors() */

void __thiscall CDirector::CreateRescuableSurvivors(CDirector *this)

{
  uint uVar1;
  char cVar2;
  bool bVar3;
  char cVar4;
  int iVar5;
  undefined4 uVar6;
  int iVar7;
  CSurvivorRescue *pCVar8;
  undefined *puVar9;
  int iVar10;
  longdouble lVar11;
  float fVar12;
  int local_68 [5];
  undefined4 local_54;
  undefined4 local_50;
  undefined4 local_4c;
  int local_48;
  undefined4 local_44;
  undefined4 local_40;
  CTerrorPlayer *local_3c;
  int local_38 [3];
  CTerrorPlayer *local_2c;
  int local_28;
  undefined4 local_24;
  
  if (*(int *)(RescueDisabled._28_4_ + 0x30) == 0) {
    lVar11 = (longdouble)CountdownTimer::Now();
    if (((*(float *)(this + 0x3dc) <= (float)lVar11) && (this[0x160] != (CDirector)0x0)) &&
       (cVar2 = AllowSurvivorRescue(this), cVar2 != '\0')) {
      fVar12 = *(float *)(RescueInterval._28_4_ + 0x2c);
      lVar11 = (longdouble)CountdownTimer::Now();
      if ((float)lVar11 + fVar12 != *(float *)(this + 0x3dc)) {
        (**(code **)(*(int *)(this + 0x3d4) + 4))(this + 0x3d4,this + 0x3dc);
        *(float *)(this + 0x3dc) = (float)lVar11 + fVar12;
      }
      if (fVar12 != *(float *)(this + 0x3d8)) {
        (**(code **)(*(int *)(this + 0x3d4) + 4))(this + 0x3d4,this + 0x3d8);
        *(float *)(this + 0x3d8) = fVar12;
      }
      local_3c = (CTerrorPlayer *)CONCAT22(local_3c._2_2_,0x101);
      bVar3 = ForEachTerrorPlayer<SurvivorsInFinaleScan>((SurvivorsInFinaleScan *)&local_3c);
      cVar2 = CDirectorScriptedEventManager::AreAllSurvivorsInBattlefield
                        (*(CDirectorScriptedEventManager **)(this + 0x638));
      iVar10 = *(int *)(this + 0x3ec) + -1;
      iVar7 = iVar10 * 4;
      if (-1 < iVar10) {
        do {
          uVar1 = *(uint *)(*(int *)(this + 0x3e0) + iVar7);
          if (((uVar1 == 0xffffffff) ||
              (puVar9 = g_pEntityList + (uVar1 & 0xfff) * 0x10, puVar9 == (undefined *)0xfffffffc))
             || ((*(uint *)(puVar9 + 8) != uVar1 >> 0xc ||
                 (pCVar8 = *(CSurvivorRescue **)(puVar9 + 4), pCVar8 == (CSurvivorRescue *)0x0)))) {
LAB_00884e88:
            CUtlVector<CHandle<CSurvivorRescue>,CUtlMemory<CHandle<CSurvivorRescue>,int>>::
            FastRemove((CUtlVector<CHandle<CSurvivorRescue>,CUtlMemory<CHandle<CSurvivorRescue>,int>>
                        *)(this + 0x3e0),iVar10);
          }
          else {
            if (**(int **)(this + 0x638) != 5) {
LAB_00884ee8:
              local_38[1] = 0;
              local_28 = 0xffffffff;
              local_24 = 0;
              local_3c = (CTerrorPlayer *)0x0;
              CSurvivorRescue::InputRescue(pCVar8,(inputdata_t *)&local_3c);
              goto LAB_00884e88;
            }
            cVar4 = CSurvivorRescue::IsCallingForHelp(pCVar8);
            if ((cVar4 == '\0') || (iVar5 = CSurvivorRescue::GetSurvivor(pCVar8), iVar5 == 0)) {
              if (**(int **)(this + 0x638) != 5) goto LAB_00884ee8;
LAB_00884f43:
              CSurvivorRescue::CallForHelp(pCVar8,(CTerrorPlayer *)0x0);
              goto LAB_00884e88;
            }
            iVar5 = CSurvivorRescue::GetRescueNavArea(pCVar8);
            fVar12 = 0.0;
            if (iVar5 == 0) {
LAB_0088508b:
              uVar6 = CBaseEntity::GetDebugName((CBaseEntity *)pCVar8);
              if (*(int *)(pCVar8 + 0x30) == 0) {
                iVar5 = 0;
              }
              else {
                iVar5 = *(int *)(pCVar8 + 0x30) - *(int *)(gpGlobals + 0x58) >> 4;
              }
              DevMsg("rescue spot %d(%s) stops calling for help with nearest survivor at least %.1f path units away\n"
                     ,iVar5,uVar6,(double)fVar12);
              iVar5 = (**(code **)(*gameeventmanager + 0x1c))
                                (gameeventmanager,"survivor_rescue_abandoned",0,0);
              if (iVar5 != 0) {
                (**(code **)(*gameeventmanager + 0x20))(gameeventmanager,iVar5,0);
              }
              goto LAB_00884f43;
            }
            if ((*(uint *)(iVar5 + 300) & 0x140) == 0) {
              fVar12 = *(float *)(RescueIgnoreDistance._28_4_ + 0x2c);
            }
            else {
              fVar12 = *(float *)(RescueFinaleIgnoreDistance._28_4_ + 0x2c);
            }
            lVar11 = (longdouble)
                     CSurvivorRescue::GetDistanceToNearestSurvivor(pCVar8,fVar12 + 500.0);
            if ((float)lVar11 < 0.0) goto LAB_0088508b;
          }
          iVar10 = iVar10 + -1;
          iVar7 = iVar7 + -4;
        } while (iVar10 != -1);
      }
      if ((**(int **)(this + 0x638) == 5) &&
         (*(char *)((int)*(int **)(this + 0x638) + 0x111) == '\0')) {
        if ((bVar3) || (cVar2 != '\0')) {
          local_3c = (CTerrorPlayer *)0x0;
          local_38[0] = 0;
          local_38[1] = 0;
          local_38[2] = 0;
          local_28 = CONCAT31(local_28._1_3_,bVar3);
          local_2c = (CTerrorPlayer *)0x0;
                    /* try { // try from 00884fbc to 00884fe0 has its CatchHandler @ 0088537b */
          ForEachTerrorPlayer<FinaleRescuableSurvivor>((FinaleRescuableSurvivor *)&local_3c);
          if (0 < local_38[2]) {
            TryToStartSurvivorRescue(this,true,*(CTerrorPlayer **)local_3c);
          }
          local_38[2] = 0;
          CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_3c);
          local_2c = local_3c;
          CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_3c);
        }
        else {
          local_54 = 0xc61c3c00;
          local_50 = 2;
          local_4c = 0;
          local_48 = 0;
          local_44 = 0;
          local_40 = 1;
          ForEachTerrorPlayer<HighestFlowDistance>((HighestFlowDistance *)&local_54);
          if (local_48 != 0) {
            iVar10 = 0;
            local_68[0] = 0;
            local_68[1] = 0;
            local_68[2] = 0;
            local_68[3] = 0;
            local_68[4] = 0;
            if (0 < *(int *)(this + 0x3ec)) {
              do {
                pCVar8 = (CSurvivorRescue *)0x0;
                uVar1 = *(uint *)(*(int *)(this + 0x3e0) + iVar10 * 4);
                if (((uVar1 != 0xffffffff) &&
                    (puVar9 = g_pEntityList + (uVar1 & 0xfff) * 0x10,
                    puVar9 != (undefined *)0xfffffffc)) && (*(uint *)(puVar9 + 8) == uVar1 >> 0xc))
                {
                  pCVar8 = *(CSurvivorRescue **)(puVar9 + 4);
                }
                    /* try { // try from 00885203 to 00885227 has its CatchHandler @ 00885358 */
                local_3c = (CTerrorPlayer *)CSurvivorRescue::GetSurvivor(pCVar8);
                if (local_3c != (CTerrorPlayer *)0x0) {
                  CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>>::InsertBefore
                            ((CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>> *)local_68,
                             local_68[3],&local_3c);
                }
                iVar10 = iVar10 + 1;
              } while (iVar10 < *(int *)(this + 0x3ec));
            }
            iVar10 = local_68[3];
            local_38[0] = 0;
            local_38[1] = 0;
            local_38[2] = 0;
            local_2c = (CTerrorPlayer *)0x0;
            local_28 = 0;
            local_3c = (CTerrorPlayer *)0x0;
            if (local_68[3] != 0) {
              CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>>::GrowVector
                        ((CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>> *)local_38,
                         local_68[3]);
                    /* try { // try from 0088532b to 0088532f has its CatchHandler @ 0088536d */
              CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>>::ShiftElementsRight
                        ((CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>> *)local_38,0,
                         iVar10);
              if (0 < iVar10) {
                iVar7 = 0;
                do {
                  *(undefined4 *)(local_38[0] + iVar7 * 4) =
                       *(undefined4 *)(local_68[0] + iVar7 * 4);
                  iVar7 = iVar7 + 1;
                } while (iVar7 != iVar10);
              }
            }
                    /* try { // try from 008852a4 to 008852c3 has its CatchHandler @ 00885379 */
            ForEachTerrorPlayer<BestRescuableSurvivor>((BestRescuableSurvivor *)&local_3c);
            if (local_3c != (CTerrorPlayer *)0x0) {
              TryToStartSurvivorRescue(this,false,local_3c);
            }
            local_2c = (CTerrorPlayer *)0x0;
            CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_38);
            local_28 = local_38[0];
            CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_38);
            local_68[3] = 0;
            CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_68);
            local_68[4] = local_68[0];
            CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_68);
          }
        }
      }
    }
  }
  return;
}

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)