WitchWander::Update
0x00a450f0 · 4178 bytes · __thiscall
_ZN11WitchWander6UpdateEP8Infectedf
Decompiled
undefined (3 params)
/* WitchWander::Update(Infected*, float) */
WitchWander * __thiscall WitchWander::Update(WitchWander *this,Infected *param_1,float param_2)
{
uint uVar1;
int iVar2;
CBaseEdict *pCVar3;
char cVar4;
int iVar5;
int *piVar6;
int *piVar7;
undefined *puVar8;
CBaseEntity *pCVar9;
WitchAttack *this_00;
undefined4 *puVar10;
int *piVar11;
int iVar12;
int iVar13;
int iVar14;
longdouble lVar15;
float fVar16;
float fVar17;
float local_7c;
float local_70;
int local_6c;
float local_68;
undefined4 local_64;
undefined4 local_60;
undefined4 local_5c;
int *local_58;
undefined4 local_54;
float local_50;
undefined4 local_4c;
undefined1 local_48;
undefined1 local_47;
int local_44 [5];
int local_30 [8];
if ((Update(Infected*,float)::m_masterMusicTimer == '\0') &&
(iVar5 = __cxa_guard_acquire(&Update(Infected*,float)::m_masterMusicTimer), iVar5 != 0)) {
Update(Infected*,float)::m_masterMusicTimer._0_4_ = &PTR_NetworkStateChanged_00c0b6e0;
Update(Infected*,float)::m_masterMusicTimer._4_4_ = 0;
Update(Infected*,float)::m_masterMusicTimer._8_4_ = 0xbf800000;
__cxa_guard_release(&Update(Infected*,float)::m_masterMusicTimer);
}
piVar6 = (int *)(**(code **)(*(int *)param_2 + 0x590))(param_2);
piVar7 = (int *)(**(code **)(*(int *)param_2 + 0x594))(param_2);
if (*(int *)(param_1 + 0x4850) != -1) {
cVar4 = (**(code **)(*piVar7 + 0xe4))(piVar7,0x2b3);
if (cVar4 != '\0') {
if ((*(char *)((int)param_2 + 0x488) != '\0') &&
(uVar1 = *(uint *)(param_1 + 0x4850), uVar1 != 0xffffffff)) {
puVar8 = g_pEntityList + (uVar1 & 0xfff) * 0x10;
if ((puVar8 == (undefined *)0xfffffffc) || (*(uint *)(puVar8 + 8) != uVar1 >> 0xc)) {
pCVar9 = (CBaseEntity *)0x0;
}
else {
pCVar9 = *(CBaseEntity **)(puVar8 + 4);
}
cVar4 = WitchAttack::IsValidEnemy(pCVar9);
if (cVar4 != '\0') {
*(uint *)((int)param_2 + 0x1c74) = *(uint *)((int)param_2 + 0x1c74) & 0xfffffdff;
pCVar9 = (CBaseEntity *)0x0;
uVar1 = *(uint *)(param_1 + 0x4850);
if (((uVar1 != 0xffffffff) &&
(puVar8 = g_pEntityList + (uVar1 & 0xfff) * 0x10, puVar8 != (undefined *)0xfffffffc))
&& (*(uint *)(puVar8 + 8) == uVar1 >> 0xc)) {
pCVar9 = *(CBaseEntity **)(puVar8 + 4);
}
this_00 = ::operator_new(0x487c);
/* try { // try from 00a4520e to 00a45212 has its CatchHandler @ 00a46163 */
WitchAttack::WitchAttack(this_00,pCVar9);
*(undefined4 *)(param_1 + 0x20) = 0;
*(undefined4 *)(param_1 + 0x24) = 0;
*(undefined4 *)(param_1 + 0x28) = 0;
*(undefined4 *)(param_1 + 0x2c) = 0;
*(undefined4 *)this = 2;
*(WitchAttack **)(this + 4) = this_00;
*(char **)(this + 8) = "Attacking Survivor that stayed close for too long";
return this;
}
}
*(undefined4 *)this = 0;
*(undefined4 *)(this + 4) = 0;
*(undefined4 *)(this + 8) = 0;
return this;
}
cVar4 = (**(code **)(*piVar7 + 0xd8))(piVar7,0x2b3,0);
if (cVar4 != '\0') {
PathFollower::Invalidate((PathFollower *)(param_1 + 0x40));
(**(code **)(*piVar6 + 0xe0))(piVar6);
(**(code **)(*piVar6 + 0xa4))(piVar6);
CBaseEntity::SetAbsVelocity((CBaseEntity *)param_2,(Vector *)&vec3_origin);
CBaseEntity::EmitSound((CBaseEntity *)param_2,"WitchZombie.Scream",0.0,(float *)0x0);
*(undefined4 *)this = 0;
*(undefined4 *)(this + 4) = 0;
*(undefined4 *)(this + 8) = 0;
return this;
}
}
fVar16 = *(float *)(z_witch_wander_personal_space._28_4_ + 0x2c);
if ((*(byte *)((int)param_2 + 0x14d) & 8) != 0) {
CBaseEntity::CalcAbsolutePosition((CBaseEntity *)param_2);
}
local_68 = fVar16 * fVar16;
local_44[0] = 0;
local_44[1] = 0;
local_44[2] = 0;
local_44[3] = 0;
local_64 = *(undefined4 *)((int)param_2 + 0x2e0);
local_44[4] = 0;
local_60 = *(undefined4 *)((int)param_2 + 0x2e4);
local_30[0] = 0;
local_5c = *(undefined4 *)((int)param_2 + 0x2e8);
local_30[1] = 0;
local_30[2] = 0;
local_30[3] = 0;
local_30[4] = 0;
local_58 = (int *)0x0;
local_54 = 0x4cbebc20;
local_4c = 0;
local_48 = 1;
local_47 = 0;
local_50 = 1e+08;
/* try { // try from 00a45337 to 00a45700 has its CatchHandler @ 00a46175 */
ForEachSurvivor<VisibleSurvivorsInRangeScan>((VisibleSurvivorsInRangeScan *)&local_68);
piVar11 = local_58;
if ((local_58 == (int *)0x0) ||
(lVar15 = (longdouble)
(**(code **)(*(int *)((int)param_2 + 0x1a3c) + 0x124))
((int)param_2 + 0x1a3c,local_58),
*(float *)(z_witch_wander_personal_space._28_4_ + 0x2c) <= (float)lVar15 &&
(float)lVar15 != *(float *)(z_witch_wander_personal_space._28_4_ + 0x2c))) {
if (*(float *)(param_1 + 0x484c) != -1.0) {
(**(code **)(*(int *)(param_1 + 0x4844) + 4))(param_1 + 0x4844,param_1 + 0x484c);
*(undefined4 *)(param_1 + 0x484c) = 0xbf800000;
}
fVar16 = *(float *)((int)param_2 + 0x1d98);
fVar17 = fVar16;
if (0.0 < fVar16) {
fVar17 = fVar16 - 0.1;
}
if (fVar17 <= 0.0) {
fVar17 = 0.0;
}
if (fVar16 != fVar17) {
if (*(char *)((int)param_2 + 0x6c) == '\0') {
pCVar3 = *(CBaseEdict **)((int)param_2 + 0x30);
if (pCVar3 != (CBaseEdict *)0x0) {
*(uint *)pCVar3 = *(uint *)pCVar3 | 0x101;
iVar5 = CBaseEdict::GetChangeAccessor(pCVar3);
*(undefined2 *)(iVar5 + 2) = 0;
}
}
else {
*(byte *)((int)param_2 + 0x70) = *(byte *)((int)param_2 + 0x70) | 1;
}
*(float *)((int)param_2 + 0x1d98) = fVar17;
}
*(undefined4 *)((int)param_2 + 0x1d8c) = 0x3f800000;
lVar15 = (longdouble)CountdownTimer::Now();
if (*(float *)(param_1 + 0x3c) <= (float)lVar15) {
CBaseEntity::EmitSound((CBaseEntity *)param_2,"WanderWitchZombie.Despair",0.0,(float *)0x0);
lVar15 = (longdouble)RandomFloat(0x40800000,0x40c00000);
fVar16 = (float)lVar15;
lVar15 = (longdouble)CountdownTimer::Now();
if ((float)lVar15 + fVar16 != *(float *)(param_1 + 0x3c)) {
(**(code **)(*(int *)(param_1 + 0x34) + 4))(param_1 + 0x34,param_1 + 0x3c);
*(float *)(param_1 + 0x3c) = (float)lVar15 + fVar16;
}
if (fVar16 != *(float *)(param_1 + 0x38)) {
(**(code **)(*(int *)(param_1 + 0x34) + 4))(param_1 + 0x34,param_1 + 0x38);
*(float *)(param_1 + 0x38) = fVar16;
}
if ((*(byte *)((int)param_2 + 0x14d) & 8) != 0) {
CBaseEntity::CalcAbsolutePosition((CBaseEntity *)param_2);
}
CSoundEnt::InsertSound
(8,(Vector *)((int)param_2 + 0x2e0),0x800,fVar16,(CBaseEntity *)param_2,10,
(CBaseEntity *)0x0);
}
local_7c = *(float *)(z_witch_wander_music_min_interval._28_4_ + 0x2c);
fVar16 = *(float *)(z_witch_wander_music_max_dist._28_4_ + 0x2c);
fVar17 = *(float *)(z_witch_wander_music_min_dist._28_4_ + 0x2c);
if (fVar16 == fVar17) {
local_7c = (float)(~-(uint)(local_50 < fVar16) &
(uint)*(float *)(z_witch_wander_music_max_interval._28_4_ + 0x2c) |
(uint)local_7c & -(uint)(local_50 < fVar16));
}
else {
local_7c = ((local_50 - fVar17) *
(*(float *)(z_witch_wander_music_max_interval._28_4_ + 0x2c) - local_7c)) /
(fVar16 - fVar17) + local_7c;
}
lVar15 = (longdouble)IntervalTimer::Now();
if (((local_7c < (float)lVar15 - *(float *)(param_1 + 0x4830)) &&
(lVar15 = (longdouble)CountdownTimer::Now(),
(float)Update(Infected*,float)::m_masterMusicTimer._8_4_ <= (float)lVar15)) &&
(*(float *)(param_1 + 0x484c) <= 0.0)) {
if (*(int *)((int)param_2 + 0x30) == 0) {
local_6c = 0;
}
else {
local_6c = *(int *)((int)param_2 + 0x30) - *(int *)(gpGlobals + 0x58) >> 4;
}
ForEachTerrorPlayer<WitchWanderMusic>((WitchWanderMusic *)&local_6c);
lVar15 = (longdouble)IntervalTimer::Now();
if ((float)lVar15 != *(float *)(param_1 + 0x4830)) {
(**(code **)(*(int *)(param_1 + 0x482c) + 4))(param_1 + 0x482c,param_1 + 0x4830);
*(float *)(param_1 + 0x4830) = (float)lVar15;
}
lVar15 = (longdouble)RandomFloat(0x3e800000,0x3f800000);
fVar16 = (float)lVar15;
lVar15 = (longdouble)CountdownTimer::Now();
if ((float)lVar15 + fVar16 != (float)Update(Infected*,float)::m_masterMusicTimer._8_4_) {
Update(Infected*,float)::m_masterMusicTimer._8_4_ = (float)lVar15 + fVar16;
}
if (fVar16 != (float)Update(Infected*,float)::m_masterMusicTimer._4_4_) {
Update(Infected*,float)::m_masterMusicTimer._4_4_ = fVar16;
}
}
}
else {
local_70 = 0.0;
if (*(float *)(param_1 + 0x484c) <= 0.0) {
fVar16 = *(float *)(z_witch_wander_personal_time._28_4_ + 0x2c);
lVar15 = (longdouble)CountdownTimer::Now();
if ((float)lVar15 + fVar16 != *(float *)(param_1 + 0x484c)) {
(**(code **)(*(int *)(param_1 + 0x4844) + 4))(param_1 + 0x4844,param_1 + 0x484c);
*(float *)(param_1 + 0x484c) = (float)lVar15 + fVar16;
}
if (fVar16 != *(float *)(param_1 + 0x4848)) {
(**(code **)(*(int *)(param_1 + 0x4844) + 4))(param_1 + 0x4844,param_1 + 0x4848);
*(float *)(param_1 + 0x4848) = fVar16;
}
}
else {
lVar15 = (longdouble)CountdownTimer::Now();
if ((float)lVar15 < *(float *)(param_1 + 0x484c)) {
/* try { // try from 00a45806 to 00a45eb2 has its CatchHandler @ 00a46175 */
(**(code **)(*piVar7 + 0xc4))(piVar7,piVar11,3,0x3dcccccd,0,0,1,0x3e800000);
fVar16 = *(float *)(param_1 + 0x484c);
if (fVar16 <= 0.0) {
fVar16 = 1.0;
}
else {
lVar15 = (longdouble)CountdownTimer::Now();
fVar16 = (fVar16 - (float)lVar15) / *(float *)(param_1 + 0x4848);
if (1.0 <= fVar16) {
fVar16 = 1.0;
}
if (fVar16 <= 0.0) {
fVar16 = 0.0;
}
fVar16 = 1.0 - fVar16;
}
if (fVar16 != *(float *)((int)param_2 + 0x1d98)) {
if (*(char *)((int)param_2 + 0x6c) == '\0') {
pCVar3 = *(CBaseEdict **)((int)param_2 + 0x30);
if (pCVar3 != (CBaseEdict *)0x0) {
*(uint *)pCVar3 = *(uint *)pCVar3 | 0x101;
iVar5 = CBaseEdict::GetChangeAccessor(pCVar3);
*(undefined2 *)(iVar5 + 2) = 0;
}
}
else {
*(byte *)((int)param_2 + 0x70) = *(byte *)((int)param_2 + 0x70) | 1;
}
*(float *)((int)param_2 + 0x1d98) = fVar16;
}
lVar15 = (longdouble)CountdownTimer::Now();
if (*(float *)(param_1 + 0x3c) <= (float)lVar15) {
fVar16 = *(float *)(param_1 + 0x484c);
if (fVar16 <= 0.0) {
LAB_00a460c6:
CBaseEntity::EmitSound((CBaseEntity *)param_2,"WitchZombie.GrowlHigh",0.0,(float *)0x0);
}
else {
lVar15 = (longdouble)CountdownTimer::Now();
fVar16 = (fVar16 - (float)lVar15) / *(float *)(param_1 + 0x4848);
if (1.0 <= fVar16) {
fVar16 = 1.0;
}
if (fVar16 <= 0.0) {
fVar16 = 0.0;
}
if (fVar16 < 0.25) goto LAB_00a460c6;
fVar16 = *(float *)(param_1 + 0x484c);
if (fVar16 <= 0.0) {
LAB_00a460eb:
CBaseEntity::EmitSound
((CBaseEntity *)param_2,"WitchZombie.GrowlMedium",0.0,(float *)0x0);
}
else {
lVar15 = (longdouble)CountdownTimer::Now();
fVar16 = (fVar16 - (float)lVar15) / *(float *)(param_1 + 0x4848);
if (1.0 <= fVar16) {
fVar16 = 1.0;
}
if (fVar16 <= 0.0) {
fVar16 = 0.0;
}
if (fVar16 < 0.5) goto LAB_00a460eb;
CBaseEntity::EmitSound((CBaseEntity *)param_2,"WitchZombie.GrowlLow",0.0,(float *)0x0)
;
}
}
lVar15 = (longdouble)RandomFloat(0x3f800000,0x40000000);
fVar16 = (float)lVar15;
lVar15 = (longdouble)CountdownTimer::Now();
if ((float)lVar15 + fVar16 != *(float *)(param_1 + 0x3c)) {
(**(code **)(*(int *)(param_1 + 0x34) + 4))(param_1 + 0x34,param_1 + 0x3c);
*(float *)(param_1 + 0x3c) = (float)lVar15 + fVar16;
}
if (fVar16 != *(float *)(param_1 + 0x38)) {
(**(code **)(*(int *)(param_1 + 0x34) + 4))(param_1 + 0x34,param_1 + 0x38);
*(float *)(param_1 + 0x38) = fVar16;
}
}
}
else {
puVar10 = (undefined4 *)(**(code **)(*piVar11 + 0xc))(piVar11);
*(undefined4 *)(param_1 + 0x4850) = *puVar10;
}
}
fVar16 = *(float *)(param_1 + 0x484c);
if (fVar16 <= 0.0) {
fVar16 = 0.0;
}
else {
lVar15 = (longdouble)CountdownTimer::Now();
fVar16 = (fVar16 - (float)lVar15) / *(float *)(param_1 + 0x4848);
if (1.0 <= fVar16) {
fVar16 = 1.0;
}
if (fVar16 <= 0.0) {
fVar16 = local_70;
}
}
*(float *)((int)param_2 + 0x1d8c) = fVar16;
}
iVar5 = 0;
if (0 < local_44[3]) {
LAB_00a45430:
do {
iVar2 = *(int *)(local_44[0] + iVar5 * 4);
if (iVar2 != 0) {
piVar11 = (int *)(**(code **)(*(int *)param_2 + 0xc))(param_2);
local_6c = *piVar11;
iVar12 = CUtlVector<CHandle<CBaseEntity>,CUtlMemory<CHandle<CBaseEntity>,int>>::Find
((CUtlVector<CHandle<CBaseEntity>,CUtlMemory<CHandle<CBaseEntity>,int>> *
)(iVar2 + 0x3c50),(CHandle *)&local_6c);
if (iVar12 < 0) {
CUtlVector<CHandle<CBaseEntity>,CUtlMemory<CHandle<CBaseEntity>,int>>::InsertBefore
((CUtlVector<CHandle<CBaseEntity>,CUtlMemory<CHandle<CBaseEntity>,int>> *)
(iVar2 + 0x3c50),*(int *)(iVar2 + 0x3c5c),(CHandle *)&local_6c);
iVar5 = iVar5 + 1;
if (local_44[3] <= iVar5) break;
goto LAB_00a45430;
}
}
iVar5 = iVar5 + 1;
} while (iVar5 < local_44[3]);
}
iVar5 = 0;
if (0 < local_30[3]) {
do {
iVar2 = *(int *)(local_30[0] + iVar5 * 4);
if (iVar2 != 0) {
piVar11 = (int *)(**(code **)(*(int *)param_2 + 0xc))(param_2);
local_6c = *piVar11;
iVar12 = CUtlVector<CHandle<CBaseEntity>,CUtlMemory<CHandle<CBaseEntity>,int>>::Find
((CUtlVector<CHandle<CBaseEntity>,CUtlMemory<CHandle<CBaseEntity>,int>> *
)(iVar2 + 0x3c50),(CHandle *)&local_6c);
if (iVar12 != -1) {
iVar14 = *(int *)(iVar2 + 0x3c5c);
iVar13 = (iVar14 - iVar12) + -1;
if (0 < iVar13) {
iVar12 = iVar12 * 4 + 4;
_V_memmove((void *)(*(int *)(iVar2 + 0x3c50) + -4 + iVar12),
(void *)(*(int *)(iVar2 + 0x3c50) + iVar12),iVar13 * 4);
iVar14 = *(int *)(iVar2 + 0x3c5c);
}
*(int *)(iVar2 + 0x3c5c) = iVar14 + -1;
}
}
iVar5 = iVar5 + 1;
} while (iVar5 < local_30[3]);
}
if (*(int *)(param_1 + 0x4444) < 1) {
cVar4 = (**(code **)(*piVar7 + 0xe4))(piVar7,0x2b2);
if (cVar4 == '\0') {
(**(code **)(*piVar7 + 0xd8))(piVar7,0x2b2,0);
(**(code **)(*piVar6 + 0xe0))(piVar6);
CBaseEntity::SetAbsVelocity((CBaseEntity *)param_2,(Vector *)&vec3_origin);
}
lVar15 = (longdouble)CountdownTimer::Now();
if ((float)lVar15 < *(float *)(param_1 + 0x483c)) goto LAB_00a45b02;
cVar4 = BuildWanderPath((WitchWander *)param_1,(Infected *)param_2);
if (cVar4 == '\0') {
iVar5 = RandomInt(3,6);
fVar16 = (float)iVar5;
lVar15 = (longdouble)CountdownTimer::Now();
if ((float)lVar15 + fVar16 != *(float *)(param_1 + 0x483c)) {
(**(code **)(*(int *)(param_1 + 0x4834) + 4))(param_1 + 0x4834,param_1 + 0x483c);
*(float *)(param_1 + 0x483c) = (float)lVar15 + fVar16;
}
if (fVar16 != *(float *)(param_1 + 0x4838)) {
(**(code **)(*(int *)(param_1 + 0x4834) + 4))(param_1 + 0x4834,param_1 + 0x4838);
*(float *)(param_1 + 0x4838) = fVar16;
}
goto LAB_00a45b02;
}
}
else {
PathFollower::Update((PathFollower *)(param_1 + 0x40),(INextBot *)((int)param_2 + 0x1a3c));
cVar4 = (**(code **)(*piVar6 + 200))(piVar6);
if (((cVar4 == '\0') && (cVar4 = (**(code **)(*piVar6 + 0x114))(piVar6), cVar4 == '\0')) &&
(cVar4 = (**(code **)(*piVar6 + 0xf8))(piVar6), cVar4 != '\0')) {
if ((*(byte *)((int)param_2 + 0x14d) & 8) != 0) {
/* try { // try from 00a45fa6 to 00a46154 has its CatchHandler @ 00a46175 */
CBaseEntity::CalcAbsolutePosition((CBaseEntity *)param_2);
}
fVar16 = *(float *)((int)param_2 + 0x2e0);
if (((fVar16 == *(float *)(param_1 + 0x4820)) &&
(*(float *)(param_1 + 0x4824) == *(float *)((int)param_2 + 0x2e4))) &&
(*(float *)(param_1 + 0x4828) == *(float *)((int)param_2 + 0x2e8))) {
PathFollower::Invalidate((PathFollower *)(param_1 + 0x40));
lVar15 = (longdouble)RandomFloat(0x3f800000,0x40000000);
fVar16 = (float)lVar15;
lVar15 = (longdouble)CountdownTimer::Now();
if ((float)lVar15 + fVar16 != *(float *)(param_1 + 0x483c)) {
(**(code **)(*(int *)(param_1 + 0x4834) + 4))(param_1 + 0x4834,param_1 + 0x483c);
*(float *)(param_1 + 0x483c) = (float)lVar15 + fVar16;
}
if (fVar16 != *(float *)(param_1 + 0x4838)) {
(**(code **)(*(int *)(param_1 + 0x4834) + 4))(param_1 + 0x4834,param_1 + 0x4838);
*(float *)(param_1 + 0x4838) = fVar16;
}
}
else {
if ((*(byte *)((int)param_2 + 0x14d) & 8) != 0) {
CBaseEntity::CalcAbsolutePosition((CBaseEntity *)param_2);
fVar16 = *(float *)((int)param_2 + 0x2e0);
}
*(float *)(param_1 + 0x4820) = fVar16;
*(undefined4 *)(param_1 + 0x4824) = *(undefined4 *)((int)param_2 + 0x2e4);
*(undefined4 *)(param_1 + 0x4828) = *(undefined4 *)((int)param_2 + 0x2e8);
}
cVar4 = (**(code **)(*piVar7 + 0xe4))(piVar7,0x2b1);
if (cVar4 != '\0') goto LAB_00a45b02;
(**(code **)(*piVar7 + 0xd8))(piVar7,0x2b1,0);
(**(code **)(*piVar6 + 0xf0))(piVar6,0x420c0000);
}
}
*(undefined4 *)(param_1 + 0x4820) = vec3_origin;
*(undefined4 *)(param_1 + 0x4824) = DAT_01053d4c;
*(undefined4 *)(param_1 + 0x4828) = DAT_01053d50;
LAB_00a45b02:
local_30[3] = 0;
*(undefined4 *)this = 0;
*(undefined4 *)(this + 4) = 0;
*(undefined4 *)(this + 8) = 0;
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_30);
local_30[4] = local_30[0];
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_30);
local_44[3] = 0;
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_44);
local_44[4] = local_44[0];
CUtlMemory<CTerrorPlayer*,int>::Purge((CUtlMemory<CTerrorPlayer*,int> *)local_44);
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.