L L4D2node

CTerrorPlayer::OnEndChangeLevel

0x008f8510 · 1072 bytes · __thiscall

_ZN13CTerrorPlayer16OnEndChangeLevelEv

Decompiled

undefined (1 param)

/* CTerrorPlayer::OnEndChangeLevel() */

undefined4 __thiscall CTerrorPlayer::OnEndChangeLevel(CTerrorPlayer *this)

{
  CBaseEdict *this_00;
  char cVar1;
  undefined4 uVar2;
  undefined4 uVar3;
  undefined4 uVar4;
  int iVar5;
  int iVar6;
  char *pcVar7;
  char *pcVar8;
  int iVar9;
  Checkpoint *pCVar10;
  undefined4 *puVar11;
  int iVar12;
  undefined1 *puVar13;
  
  ResetCheckpointStats(this);
  iVar9 = DAT_0100e518;
  uVar2 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(this + 0x30));
  uVar3 = (**(code **)(*(int *)this + 0xb8))(this);
  iVar12 = 0;
  UTIL_LogPrintf("OnEndChangelevel %s(%d): %d saved players:\n",uVar3,uVar2,iVar9);
  if (0 < DAT_0100e518) {
    do {
      while( true ) {
        iVar9 = iVar12 * 4;
        puVar11 = (undefined4 *)(g_SavedPlayers + iVar9);
        uVar2 = KeyValues::GetInt((KeyValues *)*puVar11,"restoreState",0);
        uVar3 = KeyValues::GetInt((KeyValues *)*puVar11,"userID",0);
        uVar4 = KeyValues::GetString((KeyValues *)*puVar11,"idealName","");
        UTIL_LogPrintf("\t%s(%d), state %d\n",uVar4,uVar3,uVar2);
        iVar5 = KeyValues::GetInt((KeyValues *)*puVar11,"userID",0);
        iVar6 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(this + 0x30));
        if (iVar5 != iVar6) break;
        iVar5 = KeyValues::GetInt((KeyValues *)*puVar11,"restoreState",0);
        if (iVar5 == 0) {
          pcVar7 = (char *)KeyValues::GetString((KeyValues *)*puVar11,"targetMap","");
          pcVar8 = *(char **)(gpGlobals + 0x3c);
          if (pcVar8 == (char *)0x0) {
            pcVar8 = "";
          }
          if ((pcVar7 == pcVar8) || (iVar5 = _V_stricmp(pcVar7,pcVar8), iVar5 == 0)) {
            KeyValues::SetInt(*(KeyValues **)(g_SavedPlayers + iVar9),"restoreState",1);
            iVar12 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(this + 0x30));
            KeyValues::SetInt(*(KeyValues **)(g_SavedPlayers + iVar9),"userID",iVar12);
            this[0x3374] = (CTerrorPlayer)0x1;
            (**(code **)(*(int *)this + 0x578))(this);
            CDirector::OnPlayerTransitioned(TheDirector);
            puVar11 = (undefined4 *)TransitionRestore(this);
            iVar9 = CBaseEntity::GetTeamNumber((CBaseEntity *)this);
            if (iVar9 == 2) {
              cVar1 = CDirector::IsInTransition(TheDirector);
              if (cVar1 == '\0') {
                CDirector::IsInTransition(TheDirector);
              }
              else if ((puVar11 == (undefined4 *)0x0) ||
                      (iVar9 = KeyValues::GetInt((KeyValues *)*puVar11,"tookOverBot",0), iVar9 == 0)
                      ) {
                cVar1 = (**(code **)(*(int *)this + 300))(this);
                if (cVar1 == '\0') {
                  pCVar10 = (Checkpoint *)TerrorNavMesh::GetInitialCheckpoint(TheNavMesh);
                  CheckpointRespawn(this,pCVar10);
                  if ((puVar11 != (undefined4 *)0x0) &&
                     (iVar9 = KeyValues::GetInt((KeyValues *)*puVar11,"skin",0),
                     iVar9 != *(int *)(this + 0x458))) {
                    if (this[0x6c] == (CTerrorPlayer)0x0) {
                      this_00 = *(CBaseEdict **)(this + 0x30);
                      if (this_00 != (CBaseEdict *)0x0) {
                        *(uint *)this_00 = *(uint *)this_00 | 0x101;
                        iVar12 = CBaseEdict::GetChangeAccessor(this_00);
                        *(undefined2 *)(iVar12 + 2) = 0;
                      }
                    }
                    else {
                      this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
                    }
                    *(int *)(this + 0x458) = iVar9;
                  }
                }
              }
              else {
                (**(code **)(*(int *)this + 300))(this);
              }
              CDirector::OnSurvivorAdded((CTerrorPlayer *)TheDirector);
            }
            return 1;
          }
          puVar13 = &DAT_00d539c2;
          if (*(undefined1 **)(gpGlobals + 0x3c) != (undefined1 *)0x0) {
            puVar13 = *(undefined1 **)(gpGlobals + 0x3c);
          }
          uVar2 = KeyValues::GetInt((KeyValues *)*puVar11,"userID",0);
          uVar3 = KeyValues::GetString((KeyValues *)*puVar11,"idealName","");
          UTIL_LogPrintf("Skipping saved player %s(%d) - we\'re on %s and it\'s only valid for %s\n"
                         ,uVar3,uVar2,puVar13,pcVar7);
          break;
        }
        iVar12 = iVar12 + 1;
        uVar2 = KeyValues::GetInt((KeyValues *)*puVar11,"userID",0);
        uVar3 = KeyValues::GetString((KeyValues *)*puVar11,"idealName","");
        UTIL_LogPrintf("Skipping saved player %s(%d) - restore was already done\n",uVar3,uVar2);
        if (DAT_0100e518 <= iVar12) {
          return 0;
        }
      }
      iVar12 = iVar12 + 1;
    } while (iVar12 < DAT_0100e518);
  }
  return 0;
}

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)