L L4D2node

CDirector::SwapTeams

0x00887140 · 1167 bytes · __thiscall

_ZN9CDirector9SwapTeamsEv

Decompiled

undefined (1 param)

/* CDirector::SwapTeams() */

void __thiscall CDirector::SwapTeams(CDirector *this)

{
  CTerrorPlayer *pCVar1;
  CBaseEntity *this_00;
  char cVar2;
  int *piVar3;
  KeyValues *pKVar4;
  int iVar5;
  undefined4 uVar6;
  undefined4 uVar7;
  undefined4 uVar8;
  int iVar9;
  int local_1bc;
  int local_1b8;
  CollectPlayersOnTeam local_1b4 [128];
  int local_134;
  undefined4 local_130;
  CollectPlayersOnTeam local_12c [128];
  int local_ac;
  undefined4 local_a8;
  CollectPlayersOnTeam local_a4 [128];
  int local_24;
  undefined4 local_20;
  
  this[0x114] = (CDirector)0x1;
  CDirectorVersusMode::SwapTeams(*(CDirectorVersusMode **)(this + 0x63c));
  CDirectorScavengeMode::SwapTeams(*(CDirectorScavengeMode **)(this + 0x644));
  local_130 = 1;
  local_134 = 0;
  ForEachPlayer<CollectPlayersOnTeam>(local_1b4);
  if (0 < local_134) {
    iVar9 = 0;
    do {
      pCVar1 = *(CTerrorPlayer **)(local_1b4 + iVar9 * 4);
      if (((((pCVar1 != (CTerrorPlayer *)0x0) &&
            (cVar2 = (**(code **)(*(int *)pCVar1 + 0x16c))(pCVar1), cVar2 != '\0')) &&
           (*(int *)(pCVar1 + 0x30) != 0)) &&
          ((*(int *)(pCVar1 + 0x30) - *(int *)(gpGlobals + 0x58) >> 4 != 0 &&
           (piVar3 = (int *)(**(code **)(*(int *)pCVar1 + 0x654))(pCVar1), piVar3 != (int *)0x0))))
         && ((cVar2 = (**(code **)(*piVar3 + 0x16c))(piVar3), cVar2 != '\0' &&
             (cVar2 = (**(code **)(*piVar3 + 0x778))(piVar3), cVar2 != '\0')))) {
        CTerrorPlayer::TakeOverBot(pCVar1,false);
      }
      iVar9 = iVar9 + 1;
    } while (iVar9 < local_134);
  }
  iVar9 = 0;
  local_a8 = 2;
  local_ac = 0;
  ForEachPlayer<CollectPlayersOnTeam>(local_12c);
  local_20 = 3;
  local_24 = 0;
  ForEachPlayer<CollectPlayersOnTeam>(local_a4);
  if (0 < local_ac) {
    do {
      this_00 = *(CBaseEntity **)(local_12c + iVar9 * 4);
      if (((this_00 != (CBaseEntity *)0x0) &&
          (cVar2 = (**(code **)(*(int *)this_00 + 0x16c))(this_00), cVar2 != '\0')) &&
         ((*(int *)(this_00 + 0x30) != 0 &&
          (*(int *)(this_00 + 0x30) - *(int *)(gpGlobals + 0x58) >> 4 != 0)))) {
        (**(code **)(*(int *)this_00 + 0x8e0))(this_00,0);
        cVar2 = (**(code **)(*(int *)this_00 + 0x778))(this_00);
        if (cVar2 == '\0') {
          uVar7 = CBaseEntity::GetTeamNumber(this_00);
          uVar6 = (**(code **)(*(int *)this_00 + 0xb8))(this_00);
          Msg("Switching Survivor \'%s\' from team %d to ZOMBIE\n",uVar6,uVar7);
          (**(code **)(*(int *)this_00 + 0x194))(this_00,3);
        }
        else {
          uVar7 = CBaseEntity::GetTeamNumber(this_00);
          uVar6 = (**(code **)(*(int *)this_00 + 0xb8))(this_00);
          Msg("Switching Survivor Bot \'%s\' from team %d to SPECTATOR\n",uVar6,uVar7);
          (**(code **)(*(int *)this_00 + 0x194))(this_00,1);
        }
        uVar6 = CBaseEntity::GetTeamNumber(this_00);
        Msg("   -> Player is now on team %d\n",uVar6,uVar7);
      }
      iVar9 = iVar9 + 1;
    } while (iVar9 < local_ac);
  }
  iVar9 = 0;
  if (0 < local_24) {
    do {
      pCVar1 = *(CTerrorPlayer **)(local_a4 + iVar9 * 4);
      if ((((pCVar1 != (CTerrorPlayer *)0x0) &&
           (cVar2 = (**(code **)(*(int *)pCVar1 + 0x16c))(pCVar1), cVar2 != '\0')) &&
          (*(int *)(pCVar1 + 0x30) != 0)) &&
         ((*(int *)(pCVar1 + 0x30) - *(int *)(gpGlobals + 0x58) >> 4 != 0 &&
          (cVar2 = (**(code **)(*(int *)pCVar1 + 0x778))(pCVar1), cVar2 == '\0')))) {
        local_1bc = 0;
        local_1b8 = 8;
        pKVar4 = (KeyValues *)PlayerAvatarGet(this,*(edict_t **)(pCVar1 + 0x30));
        PlayerAvatarUnpack(this,pKVar4,&local_1bc,(SurvivorCharacterType *)&local_1b8);
        if ((local_1b8 == 8) || (iVar5 = CTerrorPlayer::GetPlayerByCharacter(local_1b8), iVar5 != 0)
           ) {
          uVar6 = CBaseEntity::GetTeamNumber((CBaseEntity *)pCVar1);
          uVar7 = (**(code **)(*(int *)pCVar1 + 0xb8))(pCVar1);
          Msg("Switching Zombie \'%s\' from team %d to SURVIVOR\n",uVar7,uVar6);
          CTerrorPlayer::SetDesiredCharacter(pCVar1,8);
        }
        else {
          uVar6 = SurvivorCharacterName(local_1b8);
          uVar7 = CBaseEntity::GetTeamNumber((CBaseEntity *)pCVar1);
          uVar8 = (**(code **)(*(int *)pCVar1 + 0xb8))(pCVar1);
          Msg("Switching Zombie \'%s\' from team %d to SURVIVOR %s\n",uVar8,uVar7,uVar6);
          CTerrorPlayer::SetDesiredCharacter(pCVar1,local_1b8);
        }
        (**(code **)(*(int *)pCVar1 + 0x194))(pCVar1,2);
        uVar6 = CBaseEntity::GetTeamNumber((CBaseEntity *)pCVar1);
        Msg("   -> Player is now on team %d\n",uVar6);
      }
      iVar9 = iVar9 + 1;
    } while (iVar9 < local_24);
  }
  cVar2 = NoSurvivorBots(this);
  if (((cVar2 == '\0') && (piVar3 = (int *)GetGlobalTeam(2), piVar3 != (int *)0x0)) &&
     (iVar9 = (**(code **)(*piVar3 + 0x354))(piVar3), iVar9 < 4)) {
    iVar9 = (**(code **)(*piVar3 + 0x354))(piVar3);
    if (0 < 4 - iVar9) {
      iVar5 = 0;
      do {
        iVar5 = iVar5 + 1;
        AddSurvivorBot(this,8);
        Msg("Adding a survivor bot to fill out Survivor team\n");
      } while (iVar5 != 4 - iVar9);
    }
  }
  this[0x114] = (CDirector)0x0;
  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)