L L4D2node

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 into addons/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.



        

        

          

Type inference is best-effort from the C signature - sanity-check the DHooks types before shipping.

Return-type handling cheatsheet (DHookReturn)