L L4D2node

CTeamplayRoundBasedRules::BalanceTeams

0x004cd0b0 · 1183 bytes · __thiscall

_ZN24CTeamplayRoundBasedRules12BalanceTeamsEb

Decompiled

undefined (2 params)

/* CTeamplayRoundBasedRules::BalanceTeams(bool) */

void __thiscall CTeamplayRoundBasedRules::BalanceTeams(CTeamplayRoundBasedRules *this,bool param_1)

{
  char cVar1;
  ushort uVar2;
  int *piVar3;
  int *piVar4;
  int iVar5;
  int iVar6;
  CBasePlayer *pCVar7;
  CSameTeamGroup *this_00;
  char *pcVar8;
  int local_74;
  int local_64;
  int local_60;
  code *local_5c;
  int local_58;
  undefined4 local_54;
  undefined4 local_50;
  undefined2 local_4c;
  undefined2 local_4a;
  undefined2 local_48;
  undefined2 local_46;
  undefined4 local_44;
  undefined **local_40;
  undefined4 local_3c [3];
  undefined4 local_30;
  undefined4 local_2c;
  int local_24;
  int local_20;
  
  if (((*(int *)(mp_autoteambalance._28_4_ + 0x30) != 0) &&
      (cVar1 = (**(code **)(*(int *)this + 0x29c))(this), cVar1 == '\0')) &&
     (*(float *)(this + 0x458) < *(float *)(gpGlobals + 0xc) ||
      *(float *)(this + 0x458) == *(float *)(gpGlobals + 0xc))) {
    local_64 = 0;
    local_60 = 0;
    cVar1 = AreTeamsUnbalanced(this,&local_64,&local_60);
    if (cVar1 == '\0') {
      *(undefined4 *)(this + 0x464) = 0xbf800000;
      this[0x460] = (CTeamplayRoundBasedRules)0x0;
    }
    else {
      if (*(float *)(this + 0x464) <= 0.0 && *(float *)(this + 0x464) != 0.0) {
        *(undefined4 *)(this + 0x464) = *(undefined4 *)(gpGlobals + 0xc);
      }
      if ((this[0x460] == (CTeamplayRoundBasedRules)0x0) &&
         (1.0 < *(float *)(gpGlobals + 0xc) - *(float *)(this + 0x464))) {
        UTIL_ClientPrintAll(3,"#game_auto_team_balance_in","5",(char *)0x0,(char *)0x0,(char *)0x0);
        this[0x460] = (CTeamplayRoundBasedRules)0x1;
      }
      piVar3 = (int *)GetGlobalTeam(local_64);
      piVar4 = (int *)GetGlobalTeam(local_60);
      iVar5 = (**(code **)(*piVar3 + 0x354))(piVar3);
      iVar6 = (**(code **)(*piVar4 + 0x354))(piVar4);
      local_5c = CBalanceTeamGroup::Less;
      local_58 = 0;
      local_54 = 0;
      local_50 = 0;
      local_46 = 0xffff;
      local_74 = (iVar5 - iVar6) / 2;
      local_44 = 0;
      local_4c = 0xffff;
      local_4a = 0;
      local_48 = 0xffff;
                    /* try { // try from 004cd232 to 004cd25f has its CatchHandler @ 004cd5c5 */
      for (iVar5 = 0; iVar6 = (**(code **)(*piVar3 + 0x354))(piVar3), iVar5 < iVar6;
          iVar5 = iVar5 + 1) {
        pCVar7 = (CBasePlayer *)(**(code **)(*piVar3 + 0x358))(piVar3,iVar5);
        if (pCVar7 != (CBasePlayer *)0x0) {
          CSameTeamGroup::CSameTeamGroup((CSameTeamGroup *)&local_40);
          local_40 = &PTR_Build_00c21278;
          local_24 = 0;
          local_20 = 0;
                    /* try { // try from 004cd286 to 004cd2df has its CatchHandler @ 004cd564 */
          CBalanceTeamGroup::Build((CBalanceTeamGroup *)&local_40,(CGameRules *)this,pCVar7);
          iVar6 = CSameTeamGroup::Count((CSameTeamGroup *)&local_40);
          if ((0 < iVar6) &&
             (((!param_1 || ((0 < local_20 && (local_24 == 0)))) &&
              (iVar6 = CSameTeamGroup::Count((CSameTeamGroup *)&local_40), iVar6 <= local_74)))) {
            CUtlRBTree<CBalanceTeamGroup,unsigned_short,bool(*)(CBalanceTeamGroup_const&,CBalanceTeamGroup_const&),CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short>>
            ::Insert((CUtlRBTree<CBalanceTeamGroup,unsigned_short,bool(*)(CBalanceTeamGroup_const&,CBalanceTeamGroup_const&),CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short>>
                      *)&local_5c,(CBalanceTeamGroup *)&local_40);
          }
          local_40 = &PTR___cxa_pure_virtual_00c17010;
          local_30 = 0;
          CUtlMemory<CBasePlayer*,int>::Purge((CUtlMemory<CBasePlayer*,int> *)local_3c);
          local_2c = local_3c[0];
          CUtlMemory<CBasePlayer*,int>::Purge((CUtlMemory<CBasePlayer*,int> *)local_3c);
        }
      }
      uVar2 = CUtlRBTree<CBalanceTeamGroup,unsigned_short,bool(*)(CBalanceTeamGroup_const&,CBalanceTeamGroup_const&),CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short>>
              ::FirstInorder((CUtlRBTree<CBalanceTeamGroup,unsigned_short,bool(*)(CBalanceTeamGroup_const&,CBalanceTeamGroup_const&),CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short>>
                              *)&local_5c);
      while ((uVar2 != 0xffff && (0 < local_74))) {
        this_00 = (CSameTeamGroup *)((uint)uVar2 * 0x2c + local_58 + 8);
                    /* try { // try from 004cd355 to 004cd48e has its CatchHandler @ 004cd5c5 */
        iVar5 = CSameTeamGroup::Count(this_00);
        if (iVar5 != 0) {
          iVar5 = CSameTeamGroup::Count(this_00);
          iVar6 = 0;
          if (iVar5 <= local_74) {
            for (; iVar5 = CSameTeamGroup::Count(this_00), iVar6 < iVar5; iVar6 = iVar6 + 1) {
              piVar3 = (int *)CSameTeamGroup::GetPlayer(this_00,iVar6);
              if ((piVar3 != (int *)0x0) &&
                 (cVar1 = (**(code **)(*piVar3 + 0x16c))(piVar3), cVar1 != '\0')) {
                (**(code **)(*piVar3 + 0x194))(piVar3,local_60);
                piVar4 = gameeventmanager;
                piVar3[0x8e0] = *(int *)(gpGlobals + 0xc);
                piVar4 = (int *)(**(code **)(*piVar4 + 0x1c))
                                          (piVar4,"teamplay_teambalanced_player",0,0);
                if (piVar4 != (int *)0x0) {
                  if (piVar3[0xc] == 0) {
                    iVar5 = 0;
                  }
                  else {
                    iVar5 = piVar3[0xc] - *(int *)(gpGlobals + 0x58) >> 4;
                  }
                  (**(code **)(*piVar4 + 0x30))(piVar4,"player",iVar5);
                  (**(code **)(*piVar4 + 0x30))(piVar4,"team",local_60);
                  (**(code **)(*gameeventmanager + 0x20))(gameeventmanager,piVar4,0);
                }
                pcVar8 = (char *)(**(code **)(*piVar3 + 0xb8))(piVar3);
                UTIL_ClientPrintAll(3,"#game_player_was_team_balanced",pcVar8,(char *)0x0,
                                    (char *)0x0,(char *)0x0);
                local_74 = local_74 + -1;
              }
            }
          }
        }
        uVar2 = CUtlRBTree<CBalanceTeamGroup,unsigned_short,bool(*)(CBalanceTeamGroup_const&,CBalanceTeamGroup_const&),CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short>>
                ::NextInorder((CUtlRBTree<CBalanceTeamGroup,unsigned_short,bool(*)(CBalanceTeamGroup_const&,CBalanceTeamGroup_const&),CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short>>
                               *)&local_5c,uVar2);
      }
      CUtlRBTree<CBalanceTeamGroup,unsigned_short,bool(*)(CBalanceTeamGroup_const&,CBalanceTeamGroup_const&),CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short>>
      ::RemoveAll((CUtlRBTree<CBalanceTeamGroup,unsigned_short,bool(*)(CBalanceTeamGroup_const&,CBalanceTeamGroup_const&),CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short>>
                   *)&local_5c);
      local_48 = 0xffff;
      CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short>::Purge
                ((CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short> *)
                 &local_58);
      local_46 = 0xffff;
      CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short>::Purge
                ((CUtlMemory<UtlRBTreeNode_t<CBalanceTeamGroup,unsigned_short>,unsigned_short> *)
                 &local_58);
    }
  }
  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)