L L4D2node

CDirector::OnFirstSurvivorLeftSafeArea

0x008816f0 · 1414 bytes · __thiscall

_ZN9CDirector27OnFirstSurvivorLeftSafeAreaEP13CTerrorPlayer

Decompiled

undefined (2 params)

/* CDirector::OnFirstSurvivorLeftSafeArea(CTerrorPlayer*) */

void __thiscall CDirector::OnFirstSurvivorLeftSafeArea(CDirector *this,CTerrorPlayer *param_1)

{
  code *pcVar1;
  char cVar2;
  int *piVar3;
  undefined4 uVar4;
  int iVar5;
  CEventLog *pCVar6;
  longdouble lVar7;
  longdouble lVar8;
  float fVar9;
  CDeactivateMovementConstraints local_3d;
  undefined4 local_3c;
  undefined4 local_38;
  undefined1 local_34;
  undefined4 local_30;
  undefined4 local_2c;
  char *local_28;
  undefined1 local_24;
  undefined4 local_20;
  
  cVar2 = CDirectorScavengeMode::OnFirstSurvivorLeftSafeAreaNonVirtual
                    (*(CTerrorPlayer **)(this + 0x644));
  if (cVar2 != '\0') {
    return;
  }
  (**(code **)(**(int **)(this + 0x634) + 0x18))(*(int **)(this + 0x634),param_1);
  this[0x160] = (CDirector)0x1;
  local_38 = 2;
  local_34 = 1;
  local_30 = 0;
  local_3c = 0xffffffff;
  ForEachSurvivor<PlayerCounter>((PlayerCounter *)&local_3c);
  if (((this[0x28e] == (CDirector)0x0) && (cVar2 = IsTransitioned(), cVar2 == '\0')) ||
     (m_isScenarioRestart != '\0')) {
    lVar7 = (longdouble)GetMobSpawnMaxInterval(this);
    lVar8 = (longdouble)GetMobSpawnMinInterval(this);
    lVar7 = (longdouble)RandomFloat((float)lVar8 * 0.25,(float)lVar7);
    fVar9 = (float)lVar7;
    lVar7 = (longdouble)CountdownTimer::Now();
    if ((float)lVar7 + fVar9 != *(float *)(this + 0x29c)) {
      (**(code **)(*(int *)(this + 0x294) + 4))(this + 0x294,this + 0x29c);
      *(float *)(this + 0x29c) = (float)lVar7 + fVar9;
    }
    if (fVar9 != *(float *)(this + 0x298)) {
      (**(code **)(*(int *)(this + 0x294) + 4))(this + 0x294,this + 0x298);
      *(float *)(this + 0x298) = fVar9;
    }
    piVar3 = (int *)(**(code **)(*gameeventmanager + 0x1c))
                              (gameeventmanager,"player_left_start_area",0,0);
    if (piVar3 != (int *)0x0) {
      pcVar1 = *(code **)(*piVar3 + 0x30);
      uVar4 = 0;
      if (param_1 != (CTerrorPlayer *)0x0) {
        uVar4 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(param_1 + 0x30));
      }
      (*pcVar1)(piVar3,"userid",uVar4);
      (**(code **)(*piVar3 + 0x30))(piVar3,"playercount",local_30);
      (**(code **)(*gameeventmanager + 0x20))(gameeventmanager,piVar3,0);
    }
    if (param_1 != (CTerrorPlayer *)0x0) {
      CTerrorPlayer::FireChallengeModeExplanationEvents(param_1);
    }
  }
  else {
    fVar9 = *(float *)(this + 0x38c);
    if (fVar9 < 30.0) {
      *(undefined4 *)(this + 0x38c) = 0x41f00000;
      fVar9 = 30.0;
    }
    lVar7 = (longdouble)CountdownTimer::Now();
    if ((float)lVar7 + fVar9 != *(float *)(this + 0x29c)) {
      (**(code **)(*(int *)(this + 0x294) + 4))(this + 0x294,this + 0x29c);
      *(float *)(this + 0x29c) = (float)lVar7 + fVar9;
    }
    if (fVar9 != *(float *)(this + 0x298)) {
      (**(code **)(*(int *)(this + 0x294) + 4))(this + 0x294,this + 0x298);
      *(float *)(this + 0x298) = fVar9;
    }
    iVar5 = CGlobalEntityList::FindEntityByClassname
                      ((CGlobalEntityList *)gEntList,(CBaseEntity *)0x0,"trigger_finale");
    if (iVar5 == 0) {
      fVar9 = *(float *)(DirectorTankCheckpointInterval._28_4_ + 0x2c);
      if (*(float *)(DirectorTankCheckpointInterval._28_4_ + 0x2c) <= *(float *)(this + 0x390)) {
        fVar9 = *(float *)(this + 0x390);
      }
      lVar7 = (longdouble)CountdownTimer::Now();
      if ((float)lVar7 + fVar9 != *(float *)(this + 0x174)) {
        (**(code **)(*(int *)(this + 0x16c) + 4))(this + 0x16c,this + 0x174);
        *(float *)(this + 0x174) = (float)lVar7 + fVar9;
      }
      if (fVar9 != *(float *)(this + 0x170)) {
        (**(code **)(*(int *)(this + 0x16c) + 4))(this + 0x16c,this + 0x170);
        *(float *)(this + 0x170) = fVar9;
      }
    }
    else if (*(float *)(this + 0x174) != -1.0) {
      (**(code **)(*(int *)(this + 0x16c) + 4))(this + 0x16c,this + 0x174);
      *(undefined4 *)(this + 0x174) = 0xbf800000;
    }
    TryOfferingTankFromLastMap(this);
  }
  piVar3 = (int *)(**(code **)(*gameeventmanager + 0x1c))
                            (gameeventmanager,"player_left_safe_area",0,0);
  if (piVar3 != (int *)0x0) {
    pcVar1 = *(code **)(*piVar3 + 0x30);
    uVar4 = 0;
    if (param_1 != (CTerrorPlayer *)0x0) {
      uVar4 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(param_1 + 0x30));
    }
    (*pcVar1)(piVar3,"userid",uVar4);
    (**(code **)(*piVar3 + 0x30))(piVar3,"playercount",local_30);
    (**(code **)(*gameeventmanager + 0x20))(gameeventmanager,piVar3,0);
  }
  fVar9 = *(float *)(DirectorSpecialSpawnDelay._28_4_ + 0x2c);
  lVar7 = (longdouble)CountdownTimer::Now();
  if ((float)lVar7 + fVar9 != *(float *)(this + 0x1d8)) {
    (**(code **)(*(int *)(this + 0x1d0) + 4))(this + 0x1d0,this + 0x1d8);
    *(float *)(this + 0x1d8) = (float)lVar7 + fVar9;
  }
  if (fVar9 != *(float *)(this + 0x1d4)) {
    (**(code **)(*(int *)(this + 0x1d0) + 4))(this + 0x1d0,this + 0x1d4);
    *(float *)(this + 0x1d4) = fVar9;
  }
  pCVar6 = (CEventLog *)TheLog();
  uVar4 = CEventLog::FormatPlayer(pCVar6,(CBaseEntity *)param_1);
  UTIL_LogPrintf("Allowing spawning - %s left safe area\n",uVar4);
  pCVar6 = (CEventLog *)TheLog();
  uVar4 = CEventLog::FormatPlayer(pCVar6,(CBaseEntity *)param_1);
  DevMsg("Allowing spawning - %s left safe area\n",uVar4);
  local_2c = 3;
  local_28 = "zombie_intro";
  local_24 = 0;
  local_20 = 0;
  ForEachPlayer<CShowViewportPanel>((CShowViewportPanel *)&local_2c);
  ForEachPlayer<CDeactivateMovementConstraints>(&local_3d);
  cVar2 = CTerrorGameRules::IsVersusMode();
  if (cVar2 == '\0') {
    return;
  }
  CDirectorVersusMode::OnVersusRoundStarted();
  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)