CTerrorPlayer::ReplaceWithBot
0x009cb040 · 1375 bytes · __thiscall
_ZN13CTerrorPlayer14ReplaceWithBotEb
Decompiled
undefined (2 params)
/* WARNING: Type propagation algorithm not settling */
/* CTerrorPlayer::ReplaceWithBot(bool) */
SurvivorBot * __thiscall CTerrorPlayer::ReplaceWithBot(CTerrorPlayer *this,bool param_1)
{
CBaseEdict *pCVar1;
code *pcVar2;
char cVar3;
int iVar4;
undefined4 uVar5;
int iVar6;
char *pcVar7;
int *piVar8;
CTerrorPlayer *pCVar9;
ZombieReplacement local_248 [60];
undefined4 local_20c;
undefined4 local_208;
undefined4 local_204;
undefined4 local_200;
undefined4 local_1fc;
undefined4 local_1e8;
undefined4 local_1e4;
undefined4 local_1e0;
undefined4 local_1dc;
undefined4 local_1d8;
undefined4 local_150;
undefined4 local_14c;
undefined4 local_148;
undefined4 local_144;
undefined4 local_140;
undefined **local_10c;
undefined4 local_108;
undefined4 local_b8;
undefined **local_9c;
undefined4 local_98;
undefined4 local_94;
undefined **local_84;
undefined4 local_80;
undefined **local_6c;
undefined4 local_68;
undefined **local_5c;
undefined4 local_58;
undefined4 local_54;
undefined **local_50;
undefined4 local_4c;
undefined4 local_3c;
undefined4 local_38;
undefined4 local_34;
undefined4 local_30;
undefined4 local_2c;
undefined4 local_28;
undefined4 local_24;
undefined4 local_20;
cVar3 = (**(code **)(*(int *)this + 0x778))(this);
if ((cVar3 != '\0') && (!param_1)) {
return (SurvivorBot *)0x0;
}
cVar3 = (**(code **)(*(int *)this + 300))(this);
if (cVar3 == '\0') {
iVar4 = CBaseEntity::GetTeamNumber((CBaseEntity *)this);
joined_r0x009cb18e:
if (iVar4 == 3) {
return (SurvivorBot *)0x0;
}
}
else {
cVar3 = (**(code **)(*(int *)this + 0x558))(this);
if (cVar3 != '\0') {
iVar4 = CBaseEntity::GetTeamNumber((CBaseEntity *)this);
goto joined_r0x009cb18e;
}
}
if (*(int *)(nav_edit._28_4_ + 0x30) != 0) {
return (SurvivorBot *)0x0;
}
if (TheDirector[0x114] != (CDirector)0x0) {
return (SurvivorBot *)0x0;
}
iVar4 = CBaseEntity::GetTeamNumber((CBaseEntity *)this);
if (iVar4 == 2) {
cVar3 = CDirector::NoSurvivorBots(TheDirector);
if (cVar3 != '\0') {
return (SurvivorBot *)0x0;
}
local_1e8 = 0;
local_1e4 = 0;
local_1e0 = 0;
local_1dc = 0;
local_1d8 = 0;
local_144 = 0xffffffff;
local_10c = &PTR_NetworkStateChanged_00c23e10;
local_108 = 0xbf800000;
local_b8 = 0xffffffff;
local_9c = &PTR_NetworkStateChanged_00c0b6e0;
local_98 = 0;
local_94 = 0xbf800000;
local_84 = &PTR_NetworkStateChanged_00c23e10;
local_80 = 0xbf800000;
local_6c = &PTR_NetworkStateChanged_00c23e10;
local_68 = 0xbf800000;
local_5c = &PTR_NetworkStateChanged_00c0b6e0;
local_58 = 0;
local_54 = 0xbf800000;
local_50 = &PTR_NetworkStateChanged_00c23e10;
local_4c = 0xbf800000;
local_3c = 0xffffffff;
local_38 = 0xffffffff;
local_34 = 0;
local_30 = 0;
local_2c = 0;
local_28 = 0;
local_24 = 0;
local_20 = 0xffffffff;
/* try { // try from 009cb2b7 to 009cb387 has its CatchHandler @ 009cb5b9 */
SurvivorReplacement::Save((SurvivorReplacement *)local_248,this);
iVar4 = *(int *)(this + 0x2ba0);
if (iVar4 != 8) {
if (this[0x6c] == (CTerrorPlayer)0x0) {
pCVar1 = *(CBaseEdict **)(this + 0x30);
if (pCVar1 != (CBaseEdict *)0x0) {
*(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
iVar6 = CBaseEdict::GetChangeAccessor(pCVar1);
*(undefined2 *)(iVar6 + 2) = 0;
}
}
else {
this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
}
*(undefined4 *)(this + 0x2ba0) = 8;
}
(**(code **)(*(int *)this + 0x70))(this,*DAT_0101739c);
pcVar7 = (char *)SurvivorCharacterDisplayName(iVar4);
pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<SurvivorBot>(pcVar7);
if (pCVar9 != (CTerrorPlayer *)0x0) {
if (param_1) {
(**(code **)(*(int *)this + 0x194))(this,1);
}
SurvivorReplacement::Restore((SurvivorReplacement *)local_248,this,pCVar9);
}
if (iVar4 != *(int *)(this + 0x2ba0)) {
if (this[0x6c] == (CTerrorPlayer)0x0) {
pCVar1 = *(CBaseEdict **)(this + 0x30);
if (pCVar1 != (CBaseEdict *)0x0) {
*(uint *)pCVar1 = *(uint *)pCVar1 | 0x101;
iVar6 = CBaseEdict::GetChangeAccessor(pCVar1);
*(undefined2 *)(iVar6 + 2) = 0;
}
}
else {
this[0x70] = (CTerrorPlayer)((byte)this[0x70] | 1);
}
*(int *)(this + 0x2ba0) = iVar4;
}
local_28 = 0;
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_34);
local_24 = local_34;
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_34);
local_1dc = 0;
CUtlMemory<CTerrorWeapon*,int>::Purge((CUtlMemory<CTerrorWeapon*,int> *)&local_1e8);
local_1d8 = local_1e8;
CUtlMemory<CTerrorWeapon*,int>::Purge((CUtlMemory<CTerrorWeapon*,int> *)&local_1e8);
goto LAB_009cb3e6;
}
iVar4 = CBaseEntity::GetTeamNumber((CBaseEntity *)this);
if (iVar4 != 3) {
return (SurvivorBot *)0x0;
}
local_20c = 0;
local_208 = 0;
local_204 = 0;
local_200 = 0;
local_1fc = 0;
local_150 = 0;
local_14c = 0;
local_148 = 0;
local_144 = 0;
local_140 = 0;
/* try { // try from 009cb14f to 009cb15e has its CatchHandler @ 009cb5dc */
ZombieReplacement::Save(local_248,this);
uVar5 = (**(code **)(*(int *)this + 0x544))(this);
switch(uVar5) {
default:
pCVar9 = (CTerrorPlayer *)0x0;
goto LAB_009cb4cc;
case 1:
pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Smoker>("Smoker");
break;
case 2:
pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Boomer>("Boomer");
break;
case 3:
pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Hunter>("Hunter");
break;
case 4:
pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Spitter>("Spitter");
break;
case 5:
pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Jockey>("Jockey");
break;
case 6:
pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Charger>("Charger");
break;
case 8:
/* try { // try from 009cb4aa to 009cb589 has its CatchHandler @ 009cb5dc */
pCVar9 = (CTerrorPlayer *)NextBotCreatePlayerBot<Tank>("Tank");
}
if (pCVar9 != (CTerrorPlayer *)0x0) {
ZombieReplacement::Restore(local_248,this,pCVar9);
}
LAB_009cb4cc:
local_144 = 0;
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_150);
local_140 = local_150;
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_150);
local_200 = 0;
CUtlMemory<CTerrorWeapon*,int>::Purge((CUtlMemory<CTerrorWeapon*,int> *)&local_20c);
local_1fc = local_20c;
CUtlMemory<CTerrorWeapon*,int>::Purge((CUtlMemory<CTerrorWeapon*,int> *)&local_20c);
LAB_009cb3e6:
if (pCVar9 == (CTerrorPlayer *)0x0) {
return (SurvivorBot *)0x0;
}
piVar8 = (int *)(**(code **)(*gameeventmanager + 0x1c))(gameeventmanager,"player_bot_replace",0,0)
;
if (piVar8 == (int *)0x0) {
return (SurvivorBot *)pCVar9;
}
pcVar2 = *(code **)(*piVar8 + 0x30);
uVar5 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(this + 0x30));
(*pcVar2)(piVar8,"player",uVar5);
pcVar2 = *(code **)(*piVar8 + 0x30);
uVar5 = (**(code **)(*engine + 0x40))(engine,*(undefined4 *)(pCVar9 + 0x30));
(*pcVar2)(piVar8,"bot",uVar5);
(**(code **)(*gameeventmanager + 0x20))(gameeventmanager,piVar8,0);
return (SurvivorBot *)pCVar9;
}
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.