SmokerAssault::Update
0x00ab9200 · 3766 bytes · __thiscall
_ZN13SmokerAssault6UpdateEP6Smokerf
Decompiled
undefined (3 params)
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
/* SmokerAssault::Update(Smoker*, float) */
SmokerAssault * __thiscall SmokerAssault::Update(SmokerAssault *this,Smoker *param_1,float param_2)
{
float fVar1;
uint uVar2;
code *pcVar3;
char cVar4;
Smoker SVar5;
int *piVar6;
int *piVar7;
uint *puVar8;
int *piVar9;
CBaseEntity *this_00;
int iVar10;
int iVar11;
Smoker *pSVar12;
int iVar13;
SmokerTongueVictim *this_01;
Vector *pVVar14;
CTerrorPlayer *pCVar15;
float fVar16;
undefined *puVar17;
undefined4 uVar18;
float *pfVar19;
int *local_64;
float local_60;
int local_54;
int local_50;
int local_4c;
int local_48;
int local_44;
int local_40;
int local_3c;
int local_38;
undefined **local_34;
float local_30;
CBaseEntity *local_2c;
undefined4 local_28;
undefined4 local_24;
undefined4 local_20;
pfVar19 = (float *)&stack0xffffff64;
piVar6 = (int *)(**(code **)(*(int *)param_2 + 0x9b4))();
pCVar15 = (CTerrorPlayer *)0x0;
uVar2 = *(uint *)(param_1 + 0x34);
if (((uVar2 != 0xffffffff) &&
(puVar17 = g_pEntityList + (uVar2 & 0xfff) * 0x10, puVar17 != (undefined *)0xfffffffc)) &&
(*(uint *)(puVar17 + 8) == uVar2 >> 0xc)) {
pCVar15 = *(CTerrorPlayer **)(puVar17 + 4);
}
piVar7 = (int *)BossZombiePlayerBot::ChooseVictim
((BossZombiePlayerBot *)param_2,pCVar15,4,(CBaseCombatCharacter *)0x0);
if (piVar7 == (int *)0x0) {
*(undefined4 *)(param_1 + 0x34) = 0xffffffff;
goto LAB_00ab92a6;
}
puVar8 = (uint *)(**(code **)(*piVar7 + 0xc))();
puVar17 = g_pEntityList;
uVar2 = *puVar8;
*(uint *)(param_1 + 0x34) = uVar2;
if (((uVar2 == 0xffffffff) ||
(puVar17 = puVar17 + (uVar2 & 0xfff) * 0x10, puVar17 == (undefined *)0xfffffffc)) ||
((*(uint *)(puVar17 + 8) != uVar2 >> 0xc ||
((*(int **)(puVar17 + 4) == (int *)0x0 ||
(cVar4 = (**(code **)(**(int **)(puVar17 + 4) + 300))(), cVar4 == '\0'))))))
goto LAB_00ab92a6;
uVar2 = *(uint *)((int)param_2 + 0x30bc);
if ((uVar2 == 0xffffffff) ||
(((puVar17 = g_pEntityList + (uVar2 & 0xfff) * 0x10, puVar17 == (undefined *)0xfffffffc ||
(*(uint *)(puVar17 + 8) != uVar2 >> 0xc)) ||
(piVar7 = *(int **)(puVar17 + 4), piVar7 == (int *)0x0)))) {
*(undefined4 *)this = 3;
*(undefined4 *)(this + 4) = 0;
*(char **)(this + 8) = "No ability!";
return this;
}
if (0 < *(int *)(param_1 + 0x443c)) {
piVar9 = (int *)(**(code **)(*(int *)param_2 + 0x9b0))();
cVar4 = (**(code **)(*piVar9 + 0x114))();
if (cVar4 != '\0') {
uVar18 = 0;
uVar2 = *(uint *)(param_1 + 0x34);
if (((uVar2 != 0xffffffff) &&
(puVar17 = g_pEntityList + (uVar2 & 0xfff) * 0x10, puVar17 != (undefined *)0xfffffffc)) &&
(*(uint *)(puVar17 + 8) == uVar2 >> 0xc)) {
uVar18 = *(undefined4 *)(puVar17 + 4);
}
local_34 = &PTR_operator___00d34e38;
local_30 = param_2;
local_2c = (CBaseEntity *)(**(code **)(*(int *)param_2 + 0x9b0))();
local_64 = (int *)0x0;
uVar2 = *(uint *)(param_1 + 0x34);
if (((uVar2 != 0xffffffff) &&
(puVar17 = g_pEntityList + (uVar2 & 0xfff) * 0x10, puVar17 != (undefined *)0xfffffffc)) &&
(*(uint *)(puVar17 + 8) == uVar2 >> 0xc)) {
local_64 = *(int **)(puVar17 + 4);
}
iVar10 = (int)param_2 + 0x4028;
pSVar12 = param_1 + 0x38;
local_28 = uVar18;
piVar6 = (int *)(**(code **)(*(int *)((int)param_2 + 0x4028) + 0xc0))();
cVar4 = (**(code **)(*(int *)((int)param_2 + 0x4028) + 0x104))();
if ((((cVar4 == '\0') && (cVar4 = (**(code **)(*piVar6 + 0xd4))(), cVar4 == '\0')) &&
(cVar4 = (**(code **)(*(int *)(param_1 + 0x38) + 0x80))(), cVar4 == '\0')) &&
(cVar4 = (**(code **)(*(int *)(param_1 + 0x38) + 0x80))(), cVar4 == '\0')) {
(**(code **)(*(int *)(param_1 + 0x38) + 0x90))();
piVar7 = (int *)&stack0xffffff60;
local_4c = local_40;
local_48 = local_3c;
local_44 = local_38;
pcVar3 = *(code **)(*piVar6 + 0x158);
(**(code **)(*piVar6 + 300))();
cVar4 = (*pcVar3)();
if (cVar4 != '\0') {
if (*(int *)(DirectChaseNavCheck._28_4_ + 0x30) != 0) {
pVVar14 = (Vector *)(**(code **)(*piVar6 + 300))();
cVar4 = CNavMesh::DoesRayStayWithinMesh(TheNavMesh,pVVar14,(Vector *)&local_40);
if (cVar4 == '\0') goto LAB_00aba027;
}
(**(code **)(*piVar6 + 0x120))();
(**(code **)(*piVar6 + 0xb4))();
piVar6 = (int *)(**(code **)(*(int *)((int)param_2 + 0x4028) + 0xc4))();
(**(code **)(*piVar6 + 0xc4))();
(**(code **)(*(int *)(param_1 + 0x38) + 0x48))();
param_1[0x4844] = (Smoker)0x1;
goto LAB_00ab99ad;
}
LAB_00aba027:
piVar6 = &local_4c;
piVar7 = (int *)&stack0xffffff60;
}
else {
piVar6 = (int *)0x0;
piVar7 = (int *)&stack0xffffff64;
}
local_54 = 0;
local_50 = 0;
if (_towlower == 0) {
local_38 = 0;
}
else {
*piVar7 = _towlower;
piVar7[1] = (int)&local_54;
piVar7[0xb] = (int)"ChasePath::Update";
piVar7[10] = (int)"NextBot";
piVar7[9] = (int)"(%s)%s";
piVar7[8] = (int)&ChasePath::Update(INextBot*,CBaseEntity*,IPathCost_const&,Vector*)::tm_fmt
;
piVar7[7] = 0x68;
piVar7[6] = (int)"/data/src/game/server/nextbot/path/nextbotchasepath.h";
piVar7[5] = 0;
piVar7[3] = 0;
piVar7[4] = 0;
piVar7[2] = 0;
pcVar3 = *(code **)(_towlower + 0x50);
piVar7[-1] = 0xab98d6;
(*pcVar3)();
local_38 = _towlower;
}
iVar11 = _DAT_0105db00;
local_40 = local_54;
local_3c = local_50;
if ((_DAT_0105d154 != 0) || (DAT_0105d158 == '\0')) {
/* try { // try from 00ab9903 to 00ab9907 has its CatchHandler @ 00aba13e */
piVar7[-1] = 0xab9908;
iVar13 = ThreadGetCurrentId();
if (iVar11 == iVar13) {
if ((char *)*_DAT_0105d15c != "ChasePath::Update") {
piVar7[4] = 4;
piVar7[3] = (int)"NextBot";
piVar7[2] = 0;
piVar7[1] = (int)"ChasePath::Update";
*piVar7 = (int)_DAT_0105d15c;
/* try { // try from 00ab9ef0 to 00ab9f13 has its CatchHandler @ 00aba13e */
piVar7[-1] = 0xab9ef5;
_DAT_0105d15c =
(int *)CVProfNode::GetSubNode
((char *)*piVar7,piVar7[1],(char *)piVar7[2],piVar7[3]);
}
puVar8 = (uint *)(_DAT_0105d1e8 + 4 + _DAT_0105d15c[0x1c] * 8);
*puVar8 = *puVar8 | 4;
*piVar7 = (int)_DAT_0105d15c;
piVar7[-1] = 0xab9f14;
CVProfNode::EnterScope();
DAT_0105d158 = '\0';
}
}
piVar7[4] = (int)piVar6;
piVar7[3] = (int)&local_34;
piVar7[1] = iVar10;
*piVar7 = (int)pSVar12;
piVar7[2] = (int)local_64;
/* try { // try from 00ab992c to 00ab993c has its CatchHandler @ 00aba150 */
piVar7[-1] = 0xab9931;
ChasePath::RefreshPath
((ChasePath *)*piVar7,(INextBot *)piVar7[1],(CBaseEntity *)piVar7[2],
(IPathCost *)piVar7[3],(Vector *)piVar7[4]);
piVar7[1] = iVar10;
*piVar7 = (int)pSVar12;
piVar7[-1] = 0xab993d;
PathFollower::Update((PathFollower *)*piVar7,(INextBot *)piVar7[1]);
iVar11 = _DAT_0105db00;
if ((DAT_0105d158 == '\0') || (_DAT_0105d154 != 0)) {
piVar7[-1] = 0xab995a;
iVar13 = ThreadGetCurrentId();
if (iVar11 == iVar13) {
*piVar7 = (int)_DAT_0105d15c;
piVar7[-1] = 0xab9f2d;
cVar4 = CVProfNode::ExitScope();
if (cVar4 != '\0') {
_DAT_0105d15c = (int *)_DAT_0105d15c[0x19];
}
DAT_0105d158 = _DAT_0105d15c == (int *)0x105d160;
}
}
if (local_38 != 0) {
piVar7[5] = 0;
piVar7[4] = 0;
piVar7[3] = 0;
*piVar7 = local_38;
piVar7[1] = local_40;
piVar7[2] = local_3c;
pcVar3 = *(code **)(local_38 + 0x54);
piVar7[-1] = 0xab9995;
(*pcVar3)();
}
iVar11 = *(int *)(param_1 + 0x38);
*piVar7 = (int)pSVar12;
pcVar3 = *(code **)(iVar11 + 0x44);
piVar7[-1] = 0xab99a4;
SVar5 = (Smoker)(*pcVar3)();
param_1[0x4844] = SVar5;
LAB_00ab99ad:
piVar7[1] = iVar10;
piVar7[2] = (int)local_64;
*piVar7 = (int)pSVar12;
piVar7[-1] = 0xab99c3;
DirectChasePath::NotifyVictim
((DirectChasePath *)*piVar7,(INextBot *)piVar7[1],(CBaseEntity *)piVar7[2]);
*(undefined4 *)this = 0;
*(undefined4 *)(this + 4) = 0;
*(undefined4 *)(this + 8) = 0;
return this;
}
}
(**(code **)(*piVar6 + 0xc4))();
cVar4 = (**(code **)(*piVar7 + 0x33c))();
if (((cVar4 != '\0') && (cVar4 = (**(code **)(*piVar7 + 0x32c))(), cVar4 != '\0')) &&
(*(int *)(ZombieAllowAIToUseAbilities._28_4_ + 0x30) != 0)) {
pCVar15 = (CTerrorPlayer *)0x0;
uVar2 = *(uint *)(param_1 + 0x34);
if (((uVar2 != 0xffffffff) &&
(puVar17 = g_pEntityList + (uVar2 & 0xfff) * 0x10, puVar17 != (undefined *)0xfffffffc)) &&
(*(uint *)(puVar17 + 8) == uVar2 >> 0xc)) {
pCVar15 = *(CTerrorPlayer **)(puVar17 + 4);
}
this_01 = ::operator_new(0x48);
/* try { // try from 00ab9c02 to 00ab9c06 has its CatchHandler @ 00aba12c */
SmokerTongueVictim::SmokerTongueVictim(this_01,pCVar15);
*(undefined4 *)(param_1 + 0x20) = 0;
*(undefined4 *)(param_1 + 0x24) = 0;
*(undefined4 *)(param_1 + 0x28) = 0;
*(undefined4 *)(param_1 + 0x2c) = 0;
*(undefined4 *)this = 2;
*(SmokerTongueVictim **)(this + 4) = this_01;
*(char **)(this + 8) = "Victim is close, attack!";
return this;
}
fVar1 = (float)((int)param_2 + 0x4028);
cVar4 = (**(code **)(*(int *)((int)param_2 + 0x4028) + 0x11c))();
if (cVar4 == '\0') {
piVar6 = (int *)(**(code **)(*(int *)param_2 + 0x9bc))();
cVar4 = (**(code **)(*piVar6 + 0xd0))();
if (cVar4 == '\0') goto LAB_00ab948a;
}
else {
LAB_00ab948a:
local_34 = &PTR_operator___00d20e60;
local_30 = fVar1;
local_28 = (**(code **)(*(int *)((int)param_2 + 0x4028) + 0xc0))();
this_00 = (CBaseEntity *)(**(code **)(*(int *)((int)param_2 + 0x4028) + 0xb4))();
iVar10 = (**(code **)(*(int *)this_00 + 0x14c))();
local_24 = 0x3f800000;
if (iVar10 != 0) {
local_24 = *(undefined4 *)(iVar10 + 0x1cec);
}
cVar4 = (**(code **)(*(int *)this_00 + 0x16c))();
local_2c = (CBaseEntity *)0x0;
if (cVar4 != '\0') {
local_2c = this_00;
}
iVar10 = CBaseEntity::GetTeamNumber(this_00);
local_20 = 9;
if (iVar10 == 3) {
local_20 = (**(code **)(*(int *)this_00 + 0x544))();
}
local_60 = 0.0;
uVar2 = *(uint *)(param_1 + 0x34);
if (((uVar2 != 0xffffffff) &&
(puVar17 = g_pEntityList + (uVar2 & 0xfff) * 0x10, puVar17 != (undefined *)0xfffffffc)) &&
(*(uint *)(puVar17 + 8) == uVar2 >> 0xc)) {
local_60 = *(float *)(puVar17 + 4);
}
pSVar12 = param_1 + 0x38;
piVar6 = (int *)(**(code **)(*(int *)((int)param_2 + 0x4028) + 0xc0))();
cVar4 = (**(code **)(*(int *)((int)param_2 + 0x4028) + 0x104))();
if ((((cVar4 == '\0') && (cVar4 = (**(code **)(*piVar6 + 0xd4))(), cVar4 == '\0')) &&
(cVar4 = (**(code **)(*(int *)(param_1 + 0x38) + 0x80))(), cVar4 == '\0')) &&
(cVar4 = (**(code **)(*(int *)(param_1 + 0x38) + 0x80))(), cVar4 == '\0')) {
(**(code **)(*(int *)(param_1 + 0x38) + 0x90))();
pfVar19 = (float *)&stack0xffffff60;
local_4c = local_40;
local_48 = local_3c;
local_44 = local_38;
pcVar3 = *(code **)(*piVar6 + 0x158);
(**(code **)(*piVar6 + 300))();
cVar4 = (*pcVar3)();
if (cVar4 == '\0') {
LAB_00aba104:
local_64 = &local_4c;
pfVar19 = (float *)&stack0xffffff60;
goto LAB_00ab957e;
}
if (*(int *)(DirectChaseNavCheck._28_4_ + 0x30) != 0) {
pVVar14 = (Vector *)(**(code **)(*piVar6 + 300))();
cVar4 = CNavMesh::DoesRayStayWithinMesh(TheNavMesh,pVVar14,(Vector *)&local_40);
if (cVar4 == '\0') goto LAB_00aba104;
}
(**(code **)(*piVar6 + 0x120))();
(**(code **)(*piVar6 + 0xb4))();
piVar6 = (int *)(**(code **)(*(int *)((int)param_2 + 0x4028) + 0xc4))();
(**(code **)(*piVar6 + 0xc4))();
(**(code **)(*(int *)(param_1 + 0x38) + 0x48))();
param_1[0x4844] = (Smoker)0x1;
}
else {
local_64 = (int *)0x0;
pfVar19 = (float *)&stack0xffffff64;
LAB_00ab957e:
local_54 = 0;
local_50 = 0;
if (_towlower == 0) {
local_38 = 0;
}
else {
*pfVar19 = (float)_towlower;
pfVar19[1] = (float)&local_54;
pfVar19[0xb] = (float)"ChasePath::Update";
pfVar19[10] = (float)"NextBot";
pfVar19[9] = (float)"(%s)%s";
pfVar19[8] = (float)&ChasePath::Update(INextBot*,CBaseEntity*,IPathCost_const&,Vector*)::
tm_fmt;
pfVar19[7] = 1.45735e-43;
pfVar19[6] = (float)"/data/src/game/server/nextbot/path/nextbotchasepath.h";
pfVar19[5] = 0.0;
pfVar19[3] = 0.0;
pfVar19[4] = 0.0;
pfVar19[2] = 0.0;
pcVar3 = *(code **)(_towlower + 0x50);
pfVar19[-1] = 1.5757666e-38;
(*pcVar3)();
local_38 = _towlower;
}
iVar10 = _DAT_0105db00;
local_40 = local_54;
local_3c = local_50;
if ((_DAT_0105d154 != 0) || (DAT_0105d158 == '\0')) {
/* try { // try from 00ab9626 to 00ab962a has its CatchHandler @ 00aba117 */
pfVar19[-1] = 1.575774e-38;
iVar11 = ThreadGetCurrentId();
if (iVar10 == iVar11) {
if ((char *)*_DAT_0105d15c != "ChasePath::Update") {
pfVar19[4] = 5.60519e-45;
pfVar19[3] = (float)"NextBot";
pfVar19[2] = 0.0;
pfVar19[1] = (float)"ChasePath::Update";
*pfVar19 = (float)_DAT_0105d15c;
/* try { // try from 00aba05f to 00aba082 has its CatchHandler @ 00aba117 */
pfVar19[-1] = 1.5761407e-38;
_DAT_0105d15c =
(int *)CVProfNode::GetSubNode
((char *)*pfVar19,(int)pfVar19[1],(char *)pfVar19[2],
(int)pfVar19[3]);
}
puVar8 = (uint *)(_DAT_0105d1e8 + 4 + _DAT_0105d15c[0x1c] * 8);
*puVar8 = *puVar8 | 4;
*pfVar19 = (float)_DAT_0105d15c;
pfVar19[-1] = 1.576145e-38;
CVProfNode::EnterScope();
DAT_0105d158 = '\0';
}
}
pfVar19[1] = fVar1;
*pfVar19 = (float)pSVar12;
pfVar19[4] = (float)local_64;
pfVar19[3] = (float)&local_34;
pfVar19[2] = local_60;
/* try { // try from 00ab9650 to 00ab9660 has its CatchHandler @ 00aba140 */
pfVar19[-1] = 1.5757799e-38;
ChasePath::RefreshPath
((ChasePath *)*pfVar19,(INextBot *)pfVar19[1],(CBaseEntity *)pfVar19[2],
(IPathCost *)pfVar19[3],(Vector *)pfVar19[4]);
pfVar19[1] = fVar1;
*pfVar19 = (float)pSVar12;
pfVar19[-1] = 1.5757816e-38;
PathFollower::Update((PathFollower *)*pfVar19,(INextBot *)pfVar19[1]);
iVar10 = _DAT_0105db00;
if ((DAT_0105d158 == '\0') || (_DAT_0105d154 != 0)) {
pfVar19[-1] = 1.575786e-38;
iVar11 = ThreadGetCurrentId();
if (iVar10 == iVar11) {
*pfVar19 = (float)_DAT_0105d15c;
pfVar19[-1] = 1.5761486e-38;
cVar4 = CVProfNode::ExitScope();
if (cVar4 != '\0') {
_DAT_0105d15c = (int *)_DAT_0105d15c[0x19];
}
DAT_0105d158 = _DAT_0105d15c == (int *)0x105d160;
}
}
if (local_38 != 0) {
pfVar19[5] = 0.0;
pfVar19[4] = 0.0;
pfVar19[3] = 0.0;
*pfVar19 = (float)local_38;
pfVar19[1] = (float)local_40;
pfVar19[2] = (float)local_3c;
pcVar3 = *(code **)(local_38 + 0x54);
pfVar19[-1] = 1.5757945e-38;
(*pcVar3)();
}
iVar10 = *(int *)(param_1 + 0x38);
*pfVar19 = (float)pSVar12;
pcVar3 = *(code **)(iVar10 + 0x44);
pfVar19[-1] = 1.5757961e-38;
SVar5 = (Smoker)(*pcVar3)();
param_1[0x4844] = SVar5;
}
pfVar19[1] = fVar1;
*pfVar19 = (float)pSVar12;
pfVar19[2] = local_60;
pfVar19[-1] = 1.5758e-38;
DirectChasePath::NotifyVictim
((DirectChasePath *)*pfVar19,(INextBot *)pfVar19[1],(CBaseEntity *)pfVar19[2]);
if (*(int *)(param_1 + 0x443c) < 1) {
iVar10 = *(int *)param_2;
*pfVar19 = param_2;
pcVar3 = *(code **)(iVar10 + 0x9b0);
pfVar19[-1] = 1.5761106e-38;
piVar6 = (int *)(*pcVar3)();
pcVar3 = *(code **)(*piVar6 + 0xb4);
uVar2 = *(uint *)(param_1 + 0x34);
iVar10 = 0;
if (((uVar2 != 0xffffffff) &&
(puVar17 = g_pEntityList + (uVar2 & 0xfff) * 0x10, puVar17 != (undefined *)0xfffffffc)) &&
(*(uint *)(puVar17 + 8) == uVar2 >> 0xc)) {
iVar10 = *(int *)(puVar17 + 4);
}
if ((*(byte *)(iVar10 + 0x14d) & 8) != 0) {
*pfVar19 = (float)iVar10;
pfVar19[-1] = 1.576156e-38;
CBaseEntity::CalcAbsolutePosition((CBaseEntity *)*pfVar19);
}
pfVar19[2] = 1.0;
pfVar19[1] = (float)(iVar10 + 0x2e0);
*pfVar19 = (float)piVar6;
pfVar19[-1] = 1.5761254e-38;
(*pcVar3)();
}
}
iVar10 = *(int *)param_2;
*pfVar19 = param_2;
pcVar3 = *(code **)(iVar10 + 0x9b0);
pfVar19[-1] = 1.575804e-38;
piVar6 = (int *)(*pcVar3)();
iVar10 = *piVar6;
*pfVar19 = (float)piVar6;
pcVar3 = *(code **)(iVar10 + 0x114);
pfVar19[-1] = 1.5758055e-38;
cVar4 = (*pcVar3)();
if (cVar4 == '\0') {
fVar16 = 0.0;
pcVar3 = *(code **)(*(int *)((int)param_2 + 0x4028) + 0x114);
uVar2 = *(uint *)(param_1 + 0x34);
if (((uVar2 != 0xffffffff) &&
(puVar17 = g_pEntityList + (uVar2 & 0xfff) * 0x10, puVar17 != (undefined *)0xfffffffc)) &&
(*(uint *)(puVar17 + 8) == uVar2 >> 0xc)) {
fVar16 = *(float *)(puVar17 + 4);
}
pfVar19[2] = 50.0;
pfVar19[1] = fVar16;
*pfVar19 = fVar1;
pfVar19[-1] = 1.5758188e-38;
cVar4 = (*pcVar3)();
if (cVar4 != '\0') {
iVar10 = *(int *)param_2;
pfVar19[1] = -1.0;
*pfVar19 = param_2;
pcVar3 = *(code **)(iVar10 + 0x940);
pfVar19[-1] = 1.5758226e-38;
(*pcVar3)();
}
}
LAB_00ab92a6:
*(undefined4 *)this = 0;
*(undefined4 *)(this + 4) = 0;
*(undefined4 *)(this + 8) = 0;
return this;
}
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.