CDirector::CreateRescuableSurvivors
0x00884d70 · 1463 bytes · __thiscall
_ZN9CDirector24CreateRescuableSurvivorsEv
Decompiled
undefined (1 param)
/* CDirector::CreateRescuableSurvivors() */
void __thiscall CDirector::CreateRescuableSurvivors(CDirector *this)
{
uint uVar1;
char cVar2;
bool bVar3;
char cVar4;
int iVar5;
undefined4 uVar6;
int iVar7;
CSurvivorRescue *pCVar8;
undefined *puVar9;
int iVar10;
longdouble lVar11;
float fVar12;
int local_68 [5];
undefined4 local_54;
undefined4 local_50;
undefined4 local_4c;
int local_48;
undefined4 local_44;
undefined4 local_40;
CTerrorPlayer *local_3c;
int local_38 [3];
CTerrorPlayer *local_2c;
int local_28;
undefined4 local_24;
if (*(int *)(RescueDisabled._28_4_ + 0x30) == 0) {
lVar11 = (longdouble)CountdownTimer::Now();
if (((*(float *)(this + 0x3dc) <= (float)lVar11) && (this[0x160] != (CDirector)0x0)) &&
(cVar2 = AllowSurvivorRescue(this), cVar2 != '\0')) {
fVar12 = *(float *)(RescueInterval._28_4_ + 0x2c);
lVar11 = (longdouble)CountdownTimer::Now();
if ((float)lVar11 + fVar12 != *(float *)(this + 0x3dc)) {
(**(code **)(*(int *)(this + 0x3d4) + 4))(this + 0x3d4,this + 0x3dc);
*(float *)(this + 0x3dc) = (float)lVar11 + fVar12;
}
if (fVar12 != *(float *)(this + 0x3d8)) {
(**(code **)(*(int *)(this + 0x3d4) + 4))(this + 0x3d4,this + 0x3d8);
*(float *)(this + 0x3d8) = fVar12;
}
local_3c = (CTerrorPlayer *)CONCAT22(local_3c._2_2_,0x101);
bVar3 = ForEachTerrorPlayer<SurvivorsInFinaleScan>((SurvivorsInFinaleScan *)&local_3c);
cVar2 = CDirectorScriptedEventManager::AreAllSurvivorsInBattlefield
(*(CDirectorScriptedEventManager **)(this + 0x638));
iVar10 = *(int *)(this + 0x3ec) + -1;
iVar7 = iVar10 * 4;
if (-1 < iVar10) {
do {
uVar1 = *(uint *)(*(int *)(this + 0x3e0) + iVar7);
if (((uVar1 == 0xffffffff) ||
(puVar9 = g_pEntityList + (uVar1 & 0xfff) * 0x10, puVar9 == (undefined *)0xfffffffc))
|| ((*(uint *)(puVar9 + 8) != uVar1 >> 0xc ||
(pCVar8 = *(CSurvivorRescue **)(puVar9 + 4), pCVar8 == (CSurvivorRescue *)0x0)))) {
LAB_00884e88:
CUtlVector<CHandle<CSurvivorRescue>,CUtlMemory<CHandle<CSurvivorRescue>,int>>::
FastRemove((CUtlVector<CHandle<CSurvivorRescue>,CUtlMemory<CHandle<CSurvivorRescue>,int>>
*)(this + 0x3e0),iVar10);
}
else {
if (**(int **)(this + 0x638) != 5) {
LAB_00884ee8:
local_38[1] = 0;
local_28 = 0xffffffff;
local_24 = 0;
local_3c = (CTerrorPlayer *)0x0;
CSurvivorRescue::InputRescue(pCVar8,(inputdata_t *)&local_3c);
goto LAB_00884e88;
}
cVar4 = CSurvivorRescue::IsCallingForHelp(pCVar8);
if ((cVar4 == '\0') || (iVar5 = CSurvivorRescue::GetSurvivor(pCVar8), iVar5 == 0)) {
if (**(int **)(this + 0x638) != 5) goto LAB_00884ee8;
LAB_00884f43:
CSurvivorRescue::CallForHelp(pCVar8,(CTerrorPlayer *)0x0);
goto LAB_00884e88;
}
iVar5 = CSurvivorRescue::GetRescueNavArea(pCVar8);
fVar12 = 0.0;
if (iVar5 == 0) {
LAB_0088508b:
uVar6 = CBaseEntity::GetDebugName((CBaseEntity *)pCVar8);
if (*(int *)(pCVar8 + 0x30) == 0) {
iVar5 = 0;
}
else {
iVar5 = *(int *)(pCVar8 + 0x30) - *(int *)(gpGlobals + 0x58) >> 4;
}
DevMsg("rescue spot %d(%s) stops calling for help with nearest survivor at least %.1f path units away\n"
,iVar5,uVar6,(double)fVar12);
iVar5 = (**(code **)(*gameeventmanager + 0x1c))
(gameeventmanager,"survivor_rescue_abandoned",0,0);
if (iVar5 != 0) {
(**(code **)(*gameeventmanager + 0x20))(gameeventmanager,iVar5,0);
}
goto LAB_00884f43;
}
if ((*(uint *)(iVar5 + 300) & 0x140) == 0) {
fVar12 = *(float *)(RescueIgnoreDistance._28_4_ + 0x2c);
}
else {
fVar12 = *(float *)(RescueFinaleIgnoreDistance._28_4_ + 0x2c);
}
lVar11 = (longdouble)
CSurvivorRescue::GetDistanceToNearestSurvivor(pCVar8,fVar12 + 500.0);
if ((float)lVar11 < 0.0) goto LAB_0088508b;
}
iVar10 = iVar10 + -1;
iVar7 = iVar7 + -4;
} while (iVar10 != -1);
}
if ((**(int **)(this + 0x638) == 5) &&
(*(char *)((int)*(int **)(this + 0x638) + 0x111) == '\0')) {
if ((bVar3) || (cVar2 != '\0')) {
local_3c = (CTerrorPlayer *)0x0;
local_38[0] = 0;
local_38[1] = 0;
local_38[2] = 0;
local_28 = CONCAT31(local_28._1_3_,bVar3);
local_2c = (CTerrorPlayer *)0x0;
/* try { // try from 00884fbc to 00884fe0 has its CatchHandler @ 0088537b */
ForEachTerrorPlayer<FinaleRescuableSurvivor>((FinaleRescuableSurvivor *)&local_3c);
if (0 < local_38[2]) {
TryToStartSurvivorRescue(this,true,*(CTerrorPlayer **)local_3c);
}
local_38[2] = 0;
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_3c);
local_2c = local_3c;
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)&local_3c);
}
else {
local_54 = 0xc61c3c00;
local_50 = 2;
local_4c = 0;
local_48 = 0;
local_44 = 0;
local_40 = 1;
ForEachTerrorPlayer<HighestFlowDistance>((HighestFlowDistance *)&local_54);
if (local_48 != 0) {
iVar10 = 0;
local_68[0] = 0;
local_68[1] = 0;
local_68[2] = 0;
local_68[3] = 0;
local_68[4] = 0;
if (0 < *(int *)(this + 0x3ec)) {
do {
pCVar8 = (CSurvivorRescue *)0x0;
uVar1 = *(uint *)(*(int *)(this + 0x3e0) + iVar10 * 4);
if (((uVar1 != 0xffffffff) &&
(puVar9 = g_pEntityList + (uVar1 & 0xfff) * 0x10,
puVar9 != (undefined *)0xfffffffc)) && (*(uint *)(puVar9 + 8) == uVar1 >> 0xc))
{
pCVar8 = *(CSurvivorRescue **)(puVar9 + 4);
}
/* try { // try from 00885203 to 00885227 has its CatchHandler @ 00885358 */
local_3c = (CTerrorPlayer *)CSurvivorRescue::GetSurvivor(pCVar8);
if (local_3c != (CTerrorPlayer *)0x0) {
CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>>::InsertBefore
((CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>> *)local_68,
local_68[3],&local_3c);
}
iVar10 = iVar10 + 1;
} while (iVar10 < *(int *)(this + 0x3ec));
}
iVar10 = local_68[3];
local_38[0] = 0;
local_38[1] = 0;
local_38[2] = 0;
local_2c = (CTerrorPlayer *)0x0;
local_28 = 0;
local_3c = (CTerrorPlayer *)0x0;
if (local_68[3] != 0) {
CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>>::GrowVector
((CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>> *)local_38,
local_68[3]);
/* try { // try from 0088532b to 0088532f has its CatchHandler @ 0088536d */
CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>>::ShiftElementsRight
((CUtlVector<CTerrorPlayer*,CUtlMemory<CTerrorPlayer*,int>> *)local_38,0,
iVar10);
if (0 < iVar10) {
iVar7 = 0;
do {
*(undefined4 *)(local_38[0] + iVar7 * 4) =
*(undefined4 *)(local_68[0] + iVar7 * 4);
iVar7 = iVar7 + 1;
} while (iVar7 != iVar10);
}
}
/* try { // try from 008852a4 to 008852c3 has its CatchHandler @ 00885379 */
ForEachTerrorPlayer<BestRescuableSurvivor>((BestRescuableSurvivor *)&local_3c);
if (local_3c != (CTerrorPlayer *)0x0) {
TryToStartSurvivorRescue(this,false,local_3c);
}
local_2c = (CTerrorPlayer *)0x0;
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_38);
local_28 = local_38[0];
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_38);
local_68[3] = 0;
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_68);
local_68[4] = local_68[0];
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_68);
}
}
}
}
}
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.