CResponseSystem::FindBestMatchingRule
0x005b8b20 · 924 bytes · __thiscall
_ZN15CResponseSystem20FindBestMatchingRuleERK14AI_CriteriaSetbRf
Decompiled
undefined (4 params)
/* CResponseSystem::FindBestMatchingRule(AI_CriteriaSet const&, bool, float&) */
undefined4 __thiscall
CResponseSystem::FindBestMatchingRule
(CResponseSystem *this,AI_CriteriaSet *param_1,bool param_2,float *param_3)
{
int iVar1;
float fVar2;
CResponseDict *pCVar3;
size_t __size;
uint *puVar4;
int iVar5;
int iVar6;
int iVar7;
undefined4 uVar8;
int iVar9;
int in_GS_OFFSET;
longdouble lVar10;
int local_74;
float local_50;
undefined4 *local_44;
int local_40;
int local_3c;
int local_38;
undefined4 *local_34;
CUtlVectorFixed local_30 [8];
int local_28;
CUtlVectorFixed *local_24;
int local_20;
local_40 = 4;
local_3c = 0x10;
local_20 = *(int *)(in_GS_OFFSET + 0x14);
local_44 = malloc(0x10);
local_38 = 0;
local_24 = local_30;
*param_3 = 0.0;
local_28 = 0;
local_34 = local_44;
/* try { // try from 005b8baa to 005b8e8c has its CatchHandler @ 005b8ebd */
ResponseRulePartition::GetDictsForCriteria
((ResponseRulePartition *)(this + 0x7c),local_30,param_1);
if (local_28 < 1) {
local_50 = 0.001;
}
else {
local_74 = 0;
local_50 = 0.001;
do {
pCVar3 = *(CResponseDict **)(local_30 + local_74 * 4);
if (*(ushort *)(pCVar3 + 0x12) != 0) {
iVar7 = 1;
iVar1 = *(ushort *)(pCVar3 + 0x12) + 1;
do {
while( true ) {
lVar10 = (longdouble)ScoreCriteriaAgainstRule(this,param_1,pCVar3,iVar7 - 1U,param_2);
fVar2 = (float)lVar10;
if (local_50 <= fVar2) break;
LAB_005b8c5b:
iVar7 = iVar7 + 1;
if (iVar7 == iVar1) goto LAB_005b8d88;
}
if (local_50 == fVar2) {
local_50 = (float)(local_38 * 4);
iVar9 = local_38 + 1;
iVar6 = local_38;
if (local_40 < iVar9) goto LAB_005b8ccd;
LAB_005b8c33:
iVar6 = (iVar9 - iVar6) + -1;
local_38 = iVar9;
if (0 < iVar6) goto LAB_005b8d46;
LAB_005b8c46:
puVar4 = (uint *)((int)local_44 + (int)local_50);
local_34 = local_44;
}
else {
iVar9 = 1;
local_38 = 0;
local_50 = 0.0;
iVar6 = 0;
if (0 < local_40) goto LAB_005b8c33;
LAB_005b8ccd:
iVar6 = local_38;
if (local_3c < 0) goto LAB_005b8c33;
if (local_3c == 0) {
if (local_40 == 0) {
if (iVar9 < 9) {
local_40 = 8;
goto LAB_005b8d07;
}
local_40 = 8;
}
do {
iVar5 = local_40;
local_40 = iVar5 * 2;
} while (local_40 < iVar9);
__size = iVar5 << 3;
}
else {
for (local_40 = (local_38 / local_3c + 1) * local_3c; local_40 < iVar9;
local_40 = (local_40 + iVar9) / 2) {
}
LAB_005b8d07:
__size = local_40 << 2;
}
if (local_44 == (undefined4 *)0x0) {
local_44 = malloc(__size);
goto LAB_005b8c33;
}
local_44 = realloc(local_44,__size);
local_38 = local_38 + 1;
iVar6 = (local_38 - iVar6) + -1;
if (iVar6 < 1) goto LAB_005b8c46;
LAB_005b8d46:
local_34 = local_44;
_V_memmove(local_44 + iVar9,(void *)((int)local_44 + (int)local_50),iVar6 << 2);
puVar4 = (uint *)((int)local_44 + (int)local_50);
}
local_50 = fVar2;
if (puVar4 != (uint *)0x0) {
*puVar4 = iVar7 - 1U | ((int)pCVar3 - (int)(this + 0x7c) >> 3) * 0x6db70000;
goto LAB_005b8c5b;
}
iVar7 = iVar7 + 1;
} while (iVar7 != iVar1);
}
LAB_005b8d88:
local_74 = local_74 + 1;
} while (local_74 < local_28);
}
iVar1 = local_38;
if (local_38 < 1) {
uVar8 = 0xffffffff;
}
else {
*param_3 = local_50;
if (local_38 == 1) {
uVar8 = *local_44;
}
else {
iVar7 = (**(code **)(*random_valve + 8))(random_valve,0,local_38 + -1);
if (param_2) {
DevMsg("Found %i matching rules, selecting slot %i\n",iVar1,iVar7);
}
uVar8 = local_44[iVar7];
}
}
local_28 = 0;
local_24 = local_30;
local_38 = 0;
CUtlMemory<unsigned_int,int>::Purge((CUtlMemory<unsigned_int,int> *)&local_44);
local_34 = local_44;
CUtlMemory<unsigned_int,int>::Purge((CUtlMemory<unsigned_int,int> *)&local_44);
if (local_20 == *(int *)(in_GS_OFFSET + 0x14)) {
return uVar8;
}
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
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.