CDirectorSurvivalMode::UpdateSurvival
0x008c0310 · 2190 bytes · __thiscall
_ZN21CDirectorSurvivalMode14UpdateSurvivalEv
Decompiled
undefined (1 param)
/* CDirectorSurvivalMode::UpdateSurvival() */
uint __thiscall CDirectorSurvivalMode::UpdateSurvival(CDirectorSurvivalMode *this)
{
undefined *puVar1;
undefined4 uVar2;
undefined4 uVar3;
byte bVar4;
char cVar5;
uint uVar6;
int iVar7;
CBaseEntity *pCVar8;
int iVar9;
int in_GS_OFFSET;
longdouble lVar10;
float fVar11;
CDirectorSurvivalMode *local_50;
Vector local_40 [12];
undefined4 local_34;
float local_30;
undefined4 local_2c;
char local_28 [8];
int local_20;
local_20 = *(int *)(in_GS_OFFSET + 0x14);
uVar6 = CTerrorGameRules::IsSurvivalMode();
if ((char)uVar6 == '\0') goto LAB_008c0428;
if (*this == (CDirectorSurvivalMode)0x0) {
if (*(float *)(this + 0x4c) <= 0.0) goto LAB_008c0428;
lVar10 = (longdouble)CountdownTimer::Now();
fVar11 = *(float *)(this + 0x4c);
if (fVar11 <= (float)lVar10) {
OnSurvivalRoundStarted(this,1,0);
goto LAB_008c0428;
}
if ((0 < *(int *)(this + 0x9c)) &&
(lVar10 = (longdouble)CountdownTimer::Now(),
fVar11 - (float)lVar10 <= (float)*(int *)(this + 0x9c))) {
V_snprintf(local_28,8,"%d");
UTIL_ClientPrintAll(5,"#Survival_Spawn_Start_Warning",local_28,(char *)0x0,(char *)0x0,
(char *)0x0);
*(int *)(this + 0x9c) = *(int *)(this + 0x9c) + -10;
}
if (*this == (CDirectorSurvivalMode)0x0) goto LAB_008c0428;
}
if (*(float *)(this + 0x40) <= 0.0) {
lVar10 = (longdouble)CountdownTimer::Now();
if (*(float *)(this + 0x10) <= (float)lVar10) goto LAB_008c04f5;
}
else {
lVar10 = (longdouble)CountdownTimer::Now();
if ((float)lVar10 < *(float *)(this + 0x40)) goto LAB_008c0428;
DevMsg(2,"[SURVIVAL]: Lull ended.");
if (*(float *)(this + 0x40) != -1.0) {
(**(code **)(*(int *)(this + 0x38) + 4))(this + 0x38,this + 0x40);
*(undefined4 *)(this + 0x40) = 0xbf800000;
}
fVar11 = *(float *)(this + 0x78);
lVar10 = (longdouble)CountdownTimer::Now();
if ((float)lVar10 + fVar11 != *(float *)(this + 0x1c)) {
(**(code **)(*(int *)(this + 0x14) + 4))(this + 0x14,this + 0x1c);
*(float *)(this + 0x1c) = (float)lVar10 + fVar11;
}
local_50 = this + 0x14;
if (fVar11 != *(float *)(this + 0x18)) {
(**(code **)(*(int *)(this + 0x14) + 4))(local_50,this + 0x18);
*(float *)(this + 0x18) = fVar11;
}
CountdownTimer::Now();
LAB_008c04f5:
StartSurvivalPanicEvent();
DevMsg(2,"[SURVIVAL]: HORDE ATTACK!\n");
fVar11 = *(float *)(this + 0x74);
lVar10 = (longdouble)CountdownTimer::Now();
if ((float)lVar10 + fVar11 != *(float *)(this + 0x10)) {
(**(code **)(*(int *)(this + 8) + 4))(this + 8,this + 0x10);
*(float *)(this + 0x10) = (float)lVar10 + fVar11;
}
if (fVar11 != *(float *)(this + 0xc)) {
(**(code **)(*(int *)(this + 8) + 4))(this + 8,this + 0xc);
*(float *)(this + 0xc) = fVar11;
}
fVar11 = *(float *)(this + 0x74) - *(float *)(SurvivalHordeStageIntervalDecay._28_4_ + 0x2c);
if (fVar11 <= 10.0) {
fVar11 = 10.0;
}
*(float *)(this + 0x74) = fVar11;
DevMsg(2,"[SURVIVAL]: Horde Stage interval: %f\n",(double)fVar11);
}
local_50 = this + 0x14;
lVar10 = (longdouble)CountdownTimer::Now();
if (*(float *)(this + 0x28) <= (float)lVar10) {
iVar7 = 0;
do {
if ((&UpdateSurvival()::limitIncreaseConvars)[iVar7] != (undefined *)0x0) {
iVar9 = *(int *)(this + iVar7 * 4 + 0x50) +
*(int *)(*(int *)((&UpdateSurvival()::limitIncreaseConvars)[iVar7] + 0x1c) + 0x30);
puVar1 = (&UpdateSurvival()::limitMaxConvars)[iVar7];
*(int *)(this + iVar7 * 4 + 0x50) = iVar9;
if (*(int *)(*(int *)(puVar1 + 0x1c) + 0x30) < iVar9) {
*(int *)(this + iVar7 * 4 + 0x50) = *(int *)(*(int *)(puVar1 + 0x1c) + 0x30);
}
}
iVar7 = iVar7 + 1;
} while (iVar7 != 7);
lVar10 = (longdouble)CountdownTimer::Now();
fVar11 = *(float *)(this + 0x24);
if ((float)lVar10 + fVar11 != *(float *)(this + 0x28)) {
(**(code **)(*(int *)(this + 0x20) + 4))(this + 0x20,this + 0x28);
*(float *)(this + 0x28) = (float)lVar10 + fVar11;
}
fVar11 = *(float *)(this + 0x7c) - *(float *)(SurvivalSpecialSpawnIntervalDecay._28_4_ + 0x2c);
if (fVar11 <= 1.0) {
fVar11 = 1.0;
}
*(float *)(this + 0x7c) = fVar11;
DevMsg(2,"[SURVIVAL]: Special Spawn Interval: %f\n",(double)fVar11);
}
lVar10 = (longdouble)CountdownTimer::Now();
if (*(float *)(this + 0x1c) <= (float)lVar10) {
bVar4 = ZombieManager::GetRandomPZSpawnPosition(TheZombieManager,8,10,0,local_40);
if (bVar4 != 0) {
lVar10 = (longdouble)RandomFloat(0,0x43b40000);
local_30 = (float)lVar10;
local_34 = 0;
local_2c = 0;
pCVar8 = (CBaseEntity *)
ZombieManager::SpawnTank(TheZombieManager,local_40,(QAngle *)&local_34);
if (pCVar8 != (CBaseEntity *)0x0) {
cVar5 = CTerrorGameRules::HasPlayerControlledZombies();
if (cVar5 != '\0') {
CDirector::TryOfferingTankBot(TheDirector,pCVar8,true);
}
if (*(uint *)(this + 0x98) < 0xb) {
*(undefined4 *)(this + 0x88) =
*(undefined4 *)(g_nTanksPerStage + *(uint *)(this + 0x98) * 4);
}
else {
*(undefined4 *)(this + 0x88) = 2;
}
cVar5 = CTerrorGameRules::HasPlayerControlledZombies();
if (cVar5 == '\0') {
iVar7 = *(int *)(this + 0x88);
}
else {
iVar9 = CDirector::GetTankLimit(TheDirector);
iVar7 = *(int *)(this + 0x88);
if (iVar9 < iVar7) {
iVar7 = CDirector::GetTankLimit(TheDirector);
}
*(int *)(this + 0x88) = iVar7;
}
DevMsg(2,"[SURVIVAL]: TANK ATTACK! Tanks this stage: %d (Stage %d)\n",iVar7,
*(undefined4 *)(this + 0x98));
iVar7 = *(int *)(this + 0x8c);
*(int *)(this + 0x8c) = iVar7 + 1;
if (iVar7 + 1 < *(int *)(this + 0x88)) {
fVar11 = *(float *)(survival_tank_multiple_spawn_delay._28_4_ + 0x2c);
lVar10 = (longdouble)CountdownTimer::Now();
if ((float)lVar10 + fVar11 != *(float *)(this + 0x1c)) {
(**(code **)(*(int *)(this + 0x14) + 4))(local_50,this + 0x1c);
*(float *)(this + 0x1c) = (float)lVar10 + fVar11;
}
if (fVar11 != *(float *)(this + 0x18)) {
(**(code **)(*(int *)(this + 0x14) + 4))(local_50,this + 0x18);
uVar6 = (uint)bVar4;
*(float *)(this + 0x18) = fVar11;
}
}
else {
iVar7 = *(int *)(this + 0x94);
*(int *)(this + 0x94) = iVar7 + 1;
if (*(int *)(this + 0x90) <= iVar7 + 1) {
*(int *)(this + 0x84) = *(int *)(this + 0x84) + 1;
*(undefined4 *)(this + 0x94) = 0;
fVar11 = *(float *)(this + 0x80);
lVar10 = (longdouble)CountdownTimer::Now();
if ((float)lVar10 + fVar11 != *(float *)(this + 0x40)) {
(**(code **)(*(int *)(this + 0x38) + 4))(this + 0x38,this + 0x40);
*(float *)(this + 0x40) = (float)lVar10 + fVar11;
}
if (fVar11 != *(float *)(this + 0x3c)) {
(**(code **)(*(int *)(this + 0x38) + 4))(this + 0x38,this + 0x3c);
*(float *)(this + 0x3c) = fVar11;
}
DevMsg(2,"[SURVIVAL]: Starting a lull. Next wave: %d\n",*(undefined4 *)(this + 0x84));
lVar10 = (longdouble)CountdownTimer::Now();
uVar3 = survival_lull_time._28_4_;
uVar2 = survival_lull_time_max._28_4_;
if (600.0 <= (*(float *)(this + 0x30) - *(float *)(this + 0x34)) + (float)lVar10) {
fVar11 = *(float *)(this + 0x80) -
*(float *)(survival_lull_time_increment._28_4_ + 0x2c);
*(float *)(this + 0x80) = fVar11;
if (fVar11 <= *(float *)(uVar3 + 0x2c)) {
fVar11 = *(float *)(uVar3 + 0x2c);
}
*(float *)(this + 0x80) = fVar11;
}
else {
fVar11 = *(float *)(survival_lull_time_increment._28_4_ + 0x2c) +
*(float *)(this + 0x80);
*(float *)(this + 0x80) = fVar11;
if (*(float *)(uVar2 + 0x2c) <= fVar11) {
fVar11 = *(float *)(uVar2 + 0x2c);
}
*(float *)(this + 0x80) = fVar11;
}
if (((byte)this[0x84] & 1) == 0) {
iVar7 = *(int *)(this + 0x70);
if (*(int *)(this + 0x90) + 1 <= *(int *)(this + 0x70)) {
iVar7 = *(int *)(this + 0x90) + 1;
}
*(int *)(this + 0x90) = iVar7;
fVar11 = *(float *)(this + 0x78) -
*(float *)(SurvivalTankStageIntervalDecay._28_4_ + 0x2c);
if (fVar11 <= 20.0) {
fVar11 = 20.0;
}
*(float *)(this + 0x78) = fVar11;
DevMsg(2,"[SURVIVAL]: Tank Stage interval: %f\n",(double)fVar11);
}
}
*(undefined4 *)(this + 0x8c) = 0;
*(int *)(this + 0x98) = *(int *)(this + 0x98) + 1;
fVar11 = *(float *)(this + 0x78);
lVar10 = (longdouble)CountdownTimer::Now();
if ((float)lVar10 + fVar11 != *(float *)(this + 0x1c)) {
(**(code **)(*(int *)(this + 0x14) + 4))(local_50,this + 0x1c);
*(float *)(this + 0x1c) = (float)lVar10 + fVar11;
}
if (fVar11 != *(float *)(this + 0x18)) {
(**(code **)(*(int *)(this + 0x14) + 4))(local_50,this + 0x18);
uVar6 = (uint)bVar4;
*(float *)(this + 0x18) = fVar11;
}
}
}
}
}
LAB_008c0428:
if (local_20 != *(int *)(in_GS_OFFSET + 0x14)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return uVar6;
}
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.