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 intoaddons/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.
Signatures + Functions block. The plugin uses
DHookCreateFromConf - DHooks reads return type, this-type,
calling convention, and argument types straight from the gamedata. Less
boilerplate in the plugin, types travel with the gamedata.
Gamedata KeyValues
DHooks plugin example
Type inference is best-effort from the C signature - sanity-check the DHooks types before shipping.