L L4D2node

CTerrorPlayer::UpdateZombieFrustration

0x00a03410 · 1292 bytes · __thiscall

_ZN13CTerrorPlayer23UpdateZombieFrustrationEv

Decompiled

undefined (1 param)

/* CTerrorPlayer::UpdateZombieFrustration() */

void __thiscall CTerrorPlayer::UpdateZombieFrustration(CTerrorPlayer *this)

{
  code *pcVar1;
  CBaseEdict *pCVar2;
  CDirector *pCVar3;
  char cVar4;
  int iVar5;
  CBaseEntity *this_00;
  int *piVar6;
  undefined4 uVar7;
  int iVar8;
  longdouble lVar9;
  float fVar10;
  int local_30;
  undefined4 local_24;
  int local_20;
  
  if (((((*(int *)(ZombieFrustration._28_4_ + 0x30) != 0) &&
        (iVar8 = CBaseEntity::GetTeamNumber((CBaseEntity *)this), iVar8 == 3)) &&
       (iVar8 = (**(code **)(*(int *)this + 0x544))(this), iVar8 == 8)) &&
      ((cVar4 = (**(code **)(*(int *)this + 0x778))(this), cVar4 == '\0' &&
       (cVar4 = (**(code **)(*(int *)this + 0x558))(this), cVar4 == '\0')))) &&
     (TheDirector[0x1dc] != (CDirector)0x0)) {
    if (*(float *)(this + 0x3a84) <= 0.0) {
      return;
    }
    lVar9 = (longdouble)CountdownTimer::Now();
    if ((float)lVar9 < *(float *)(this + 0x3a84)) {
      return;
    }
    fVar10 = 99999.9;
    if (0.0 < *(float *)(this + 0x3128)) {
      lVar9 = (longdouble)IntervalTimer::Now();
      fVar10 = (float)lVar9 - *(float *)(this + 0x3128);
    }
    if (fVar10 < *(float *)(ZombieFrustrationLOSDelay._28_4_ + 0x2c) ||
        fVar10 == *(float *)(ZombieFrustrationLOSDelay._28_4_ + 0x2c)) {
      return;
    }
    lVar9 = (longdouble)CountdownTimer::Now();
    if ((float)lVar9 + 1.0 != *(float *)(this + 0x3a84)) {
      (**(code **)(*(int *)(this + 0x3a7c) + 4))(this + 0x3a7c,this + 0x3a84);
      *(float *)(this + 0x3a84) = (float)lVar9 + 1.0;
    }
    if (*(float *)(this + 0x3a80) != 1.0) {
      (**(code **)(*(int *)(this + 0x3a7c) + 4))(this + 0x3a7c,this + 0x3a80);
      *(undefined4 *)(this + 0x3a80) = 0x3f800000;
    }
    local_24 = 1;
    local_20 = 0;
    ForEachTerrorPlayer<LiveSurvivorCounter>((LiveSurvivorCounter *)&local_24);
    if (local_20 != 0) {
      cVar4 = CDirector::HasAnySurvivorLeftSafeArea(TheDirector);
      if (cVar4 == '\0') {
        return;
      }
      cVar4 = CDirector::IsAnySurvivorInExitCheckpoint();
      if (cVar4 != '\0') {
        return;
      }
      cVar4 = CDirector::IsFinaleWon(TheDirector);
      if (cVar4 != '\0') {
        return;
      }
      iVar5 = *(int *)(this + 0x3a78);
      iVar8 = iVar5 + (int)(100 / (longlong)*(int *)(ZombieFrustrationLifetime._28_4_ + 0x30));
      if (100 < iVar8) {
        iVar8 = 100;
      }
      if (iVar5 != iVar8) {
        if (this[0x6c] == (CTerrorPlayer)0x0) {
          pCVar2 = *(CBaseEdict **)(this + 0x30);
          if (pCVar2 != (CBaseEdict *)0x0) {
            *(uint *)pCVar2 = *(uint *)pCVar2 | 0x101;
            iVar5 = CBaseEdict::GetChangeAccessor(pCVar2);
            *(undefined2 *)(iVar5 + 2) = 0;
          }
        }
        else {
          this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
        }
        *(int *)(this + 0x3a78) = iVar8;
        iVar5 = iVar8;
      }
      if (iVar5 < 100) {
        return;
      }
      if (((byte)this[0x153] & 8) != 0) {
        return;
      }
      cVar4 = CDirectorChallengeMode::TankRun(*(CDirectorChallengeMode **)(TheDirector + 0x648));
      if (cVar4 == '\0') {
        if (*(int *)(gpGlobals + 0x14) < 1) {
          local_30 = 0;
        }
        else {
          local_30 = 0;
          iVar8 = 1;
          do {
            this_00 = (CBaseEntity *)UTIL_PlayerByIndex(iVar8);
            if ((((this_00 != (CBaseEntity *)0x0) &&
                 (cVar4 = (**(code **)(*(int *)this_00 + 0x16c))(this_00), cVar4 != '\0')) &&
                ((*(int *)(this_00 + 0x30) != 0 &&
                 (((*(int *)(this_00 + 0x30) - *(int *)(gpGlobals + 0x58) >> 4 != 0 &&
                   (iVar5 = CBaseEntity::GetTeamNumber(this_00), iVar5 == 3)) &&
                  (cVar4 = (**(code **)(*(int *)this_00 + 0x778))(this_00), cVar4 == '\0')))))) &&
               (((cVar4 = (**(code **)(*(int *)this_00 + 300))(this_00), cVar4 == '\0' ||
                 (iVar5 = CBaseEntity::GetTeamNumber(this_00), iVar5 != 3)) ||
                (iVar5 = (**(code **)(*(int *)this_00 + 0x544))(this_00), iVar5 != 8)))) {
              local_30 = local_30 + 1;
            }
            iVar8 = iVar8 + 1;
          } while (iVar8 <= *(int *)(gpGlobals + 0x14));
        }
        pCVar3 = TheDirector;
        fVar10 = *(float *)(TheDirector + 0x180);
        if (0.0 < fVar10) {
          lVar9 = (longdouble)CountdownTimer::Now();
          fVar10 = (fVar10 - (float)lVar9) / *(float *)(pCVar3 + 0x17c);
          if (1.0 <= fVar10) {
            fVar10 = 1.0;
          }
          if (fVar10 <= 0.0) {
            fVar10 = 0.0;
          }
          if (0.0 < fVar10) {
            return;
          }
        }
        pCVar3 = TheDirector;
        fVar10 = *(float *)(TheDirector + 0x18c);
        if (0.0 < fVar10) {
          lVar9 = (longdouble)CountdownTimer::Now();
          fVar10 = (fVar10 - (float)lVar9) / *(float *)(pCVar3 + 0x188);
          if (1.0 <= fVar10) {
            fVar10 = 1.0;
          }
          if (fVar10 <= 0.0) {
            fVar10 = 0.0;
          }
          if (0.0 < fVar10) {
            return;
          }
        }
        piVar6 = (int *)(**(code **)(*gameeventmanager + 0x1c))
                                  (gameeventmanager,"tank_frustrated",0,0);
        if (piVar6 != (int *)0x0) {
          pcVar1 = *(code **)(*piVar6 + 0x30);
          uVar7 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(this + 0x30));
          (*pcVar1)(piVar6,"userid",uVar7);
          (**(code **)(*gameeventmanager + 0x20))(gameeventmanager,piVar6,0);
        }
        if ((local_30 != 0) && (*(int *)(TheDirector + 0x118) < 2)) {
          CDirector::TryOfferingTankBot(TheDirector,(CBaseEntity *)this,false);
          return;
        }
        ReplaceWithBot(this,false);
        SetPreSpawnClass(this,3);
        CCSPlayer::State_Transition((CCSPlayer *)this,8);
        return;
      }
      CBasePlayer::CommitSuicide((CBasePlayer *)this,false,false);
      return;
    }
  }
  if (*(int *)(this + 0x3a78) == 0) {
    return;
  }
  if (this[0x6c] == (CTerrorPlayer)0x0) {
    pCVar2 = *(CBaseEdict **)(this + 0x30);
    if (pCVar2 != (CBaseEdict *)0x0) {
      *(uint *)pCVar2 = *(uint *)pCVar2 | 0x101;
      iVar8 = CBaseEdict::GetChangeAccessor(pCVar2);
      *(undefined2 *)(iVar8 + 2) = 0;
    }
  }
  else {
    this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
  }
  *(undefined4 *)(this + 0x3a78) = 0;
  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)