L L4D2node

CBaseCombatCharacter::FVisible

0x005f7940 · 1293 bytes · __thiscall

_ZN20CBaseCombatCharacter8FVisibleEP11CBaseEntityiPS1_

Decompiled

undefined (4 params)

/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
/* CBaseCombatCharacter::FVisible(CBaseEntity*, int, CBaseEntity**) */

uint __thiscall
CBaseCombatCharacter::FVisible
          (CBaseCombatCharacter *this,CBaseEntity *param_1,int param_2,CBaseEntity **param_3)

{
  ushort uVar1;
  char cVar2;
  uint uVar3;
  int iVar4;
  CBaseEntity **ppCVar5;
  undefined4 *puVar6;
  CBaseEntity *pCVar7;
  undefined *puVar8;
  ushort *puVar9;
  uint uVar10;
  int iVar11;
  int local_50;
  CBaseEntity *local_48;
  undefined4 local_44;
  undefined4 local_40;
  undefined4 local_38;
  undefined4 local_34;
  int local_30;
  CBaseCombatCharacter *local_2c;
  CBaseCombatCharacter *local_28;
  undefined4 local_24;
  
  local_44 = 0;
  local_40 = 0;
  if (___atan2f_finite == 0) {
    local_30 = 0;
  }
  else {
    (**(code **)(___atan2f_finite + 0x50))
              (___atan2f_finite,&local_44,0,0,0,0,"/data/src/game/server/basecombatcharacter.cpp",
               0x139,&FVisible(CBaseEntity*,int,CBaseEntity**)::tm_fmt,"(%s)%s","Unaccounted",
               "CBaseCombatCharacter::FVisible");
    local_30 = ___atan2f_finite;
  }
  iVar11 = _DAT_0105db00;
  local_38 = local_44;
  local_34 = local_40;
                    /* try { // try from 005f7ab6 to 005f7b04 has its CatchHandler @ 005f7e89 */
  if (((_DAT_0105d154 != 0) || (DAT_0105d158 == '\0')) &&
     (iVar4 = ThreadGetCurrentId(), iVar11 == iVar4)) {
    if ((char *)*_DAT_0105d15c != "CBaseCombatCharacter::FVisible") {
      _DAT_0105d15c =
           (int *)CVProfNode::GetSubNode((char *)_DAT_0105d15c,0xc5b45c,(char *)0x1,0xbfafa1);
    }
    CVProfNode::EnterScope();
    DAT_0105d158 = '\0';
  }
  if (((param_2 == 0x4041) && (*(int *)(ai_use_visibility_cache._28_4_ + 0x30) != 0)) &&
     (this != (CBaseCombatCharacter *)param_1)) {
    local_24 = 0xffffffff;
    local_2c = (CBaseCombatCharacter *)param_1;
    local_28 = this;
    local_50 = g_VisibilityCache._4_4_;
    uVar1 = g_VisibilityCache._16_2_;
    if (this < param_1) {
      local_2c = this;
      local_28 = (CBaseCombatCharacter *)param_1;
    }
    while (uVar1 != 0xffff) {
      while( true ) {
        uVar10 = (uint)uVar1;
        iVar11 = uVar10 * 0x18;
        puVar9 = (ushort *)(local_50 + iVar11);
        iVar4 = memcmp(&local_2c,puVar9 + 4,8);
        if (iVar4 < 0) break;
        iVar4 = memcmp(puVar9 + 4,&local_2c,8);
        if (-1 < iVar4) {
          if (uVar10 == 0xffff) goto LAB_005f7c30;
          if (0.09 <= *(float *)(gpGlobals + 0xc) - *(float *)(puVar9 + 10)) goto LAB_005f7c54;
          uVar10 = *(uint *)(puVar9 + 8);
          uVar3 = CONCAT31((int3)((uint)puVar9 >> 8),uVar10 != 0xffffffff);
          if (uVar10 == 0xffffffff) {
            if (param_3 != (CBaseEntity **)0x0) {
              uVar3 = uVar3 ^ 1;
              *param_3 = (CBaseEntity *)0x0;
              goto LAB_005f7a1f;
            }
          }
          else if (param_3 != (CBaseEntity **)0x0) {
            if (((uVar10 == 0xffffffff) ||
                (puVar8 = g_pEntityList + (uVar10 & 0xfff) * 0x10, puVar8 == (undefined *)0xfffffffc
                )) || (*(uint *)(puVar8 + 8) != uVar10 >> 0xc)) {
              *param_3 = (CBaseEntity *)0x0;
            }
            else {
              pCVar7 = *(CBaseEntity **)(puVar8 + 4);
              *param_3 = pCVar7;
              if (pCVar7 != (CBaseEntity *)0x0) goto LAB_005f7da8;
            }
            pCVar7 = (CBaseEntity *)GetWorldEntity();
            *param_3 = pCVar7;
          }
LAB_005f7da8:
          uVar3 = uVar3 ^ 1;
          goto LAB_005f7a1f;
        }
        if (CUtlRBTree<VisibilityCacheEntry_t,unsigned_short,CVisibilityCacheEntryLess,CUtlMemory<UtlRBTreeNode_t<VisibilityCacheEntry_t,unsigned_short>,unsigned_short>>
            ::Links(unsigned_short)::s_Sentinel == '\0') {
          iVar4 = __cxa_guard_acquire(&CUtlRBTree<VisibilityCacheEntry_t,unsigned_short,CVisibilityCacheEntryLess,CUtlMemory<UtlRBTreeNode_t<VisibilityCacheEntry_t,unsigned_short>,unsigned_short>>
                                       ::Links(unsigned_short)::s_Sentinel);
          if (iVar4 != 0) {
            DAT_00f244ba = 0xffff;
            CUtlRBTree<VisibilityCacheEntry_t,unsigned_short,CVisibilityCacheEntryLess,CUtlMemory<UtlRBTreeNode_t<VisibilityCacheEntry_t,unsigned_short>,unsigned_short>>
            ::Links(unsigned_short)::s_Sentinel = 0xffff;
            DAT_00f244bc = 0xffff;
            __cxa_guard_release(&CUtlRBTree<VisibilityCacheEntry_t,unsigned_short,CVisibilityCacheEntryLess,CUtlMemory<UtlRBTreeNode_t<VisibilityCacheEntry_t,unsigned_short>,unsigned_short>>
                                 ::Links(unsigned_short)::s_Sentinel);
          }
          local_50 = g_VisibilityCache._4_4_;
          puVar9 = (ushort *)(iVar11 + g_VisibilityCache._4_4_);
        }
        uVar1 = puVar9[1];
        if (uVar1 == 0xffff) goto LAB_005f7c30;
      }
      if (CUtlRBTree<VisibilityCacheEntry_t,unsigned_short,CVisibilityCacheEntryLess,CUtlMemory<UtlRBTreeNode_t<VisibilityCacheEntry_t,unsigned_short>,unsigned_short>>
          ::Links(unsigned_short)::s_Sentinel == '\0') {
        iVar4 = __cxa_guard_acquire(&CUtlRBTree<VisibilityCacheEntry_t,unsigned_short,CVisibilityCacheEntryLess,CUtlMemory<UtlRBTreeNode_t<VisibilityCacheEntry_t,unsigned_short>,unsigned_short>>
                                     ::Links(unsigned_short)::s_Sentinel);
        if (iVar4 != 0) {
          CUtlRBTree<VisibilityCacheEntry_t,unsigned_short,CVisibilityCacheEntryLess,CUtlMemory<UtlRBTreeNode_t<VisibilityCacheEntry_t,unsigned_short>,unsigned_short>>
          ::Links(unsigned_short)::s_Sentinel = 0xffff;
          DAT_00f244ba = 0xffff;
          DAT_00f244bc = 0xffff;
          __cxa_guard_release(&CUtlRBTree<VisibilityCacheEntry_t,unsigned_short,CVisibilityCacheEntryLess,CUtlMemory<UtlRBTreeNode_t<VisibilityCacheEntry_t,unsigned_short>,unsigned_short>>
                               ::Links(unsigned_short)::s_Sentinel);
        }
        local_50 = g_VisibilityCache._4_4_;
        puVar9 = (ushort *)(iVar11 + g_VisibilityCache._4_4_);
      }
      uVar1 = *puVar9;
    }
LAB_005f7c30:
    if (g_VisibilityCache._18_2_ != -1) {
                    /* try { // try from 005f7c4c to 005f7da2 has its CatchHandler @ 005f7e9e */
      uVar10 = CUtlRBTree<VisibilityCacheEntry_t,unsigned_short,CVisibilityCacheEntryLess,CUtlMemory<UtlRBTreeNode_t<VisibilityCacheEntry_t,unsigned_short>,unsigned_short>>
               ::Insert((CUtlRBTree<VisibilityCacheEntry_t,unsigned_short,CVisibilityCacheEntryLess,CUtlMemory<UtlRBTreeNode_t<VisibilityCacheEntry_t,unsigned_short>,unsigned_short>>
                         *)g_VisibilityCache,(VisibilityCacheEntry_t *)&local_2c);
      uVar10 = uVar10 & 0xffff;
LAB_005f7c54:
      local_48 = (CBaseEntity *)0x0;
      ppCVar5 = &local_48;
      if (param_3 != (CBaseEntity **)0x0) {
        ppCVar5 = param_3;
      }
      uVar3 = CBaseEntity::FVisible((CBaseEntity *)this,param_1,0x4041,ppCVar5);
      if ((char)uVar3 == '\0') {
        pCVar7 = *ppCVar5;
        iVar11 = g_VisibilityCache._4_4_ + uVar10 * 0x18;
        if (pCVar7 == (CBaseEntity *)0x0) {
          *(undefined4 *)(iVar11 + 0x10) = 0xffffffff;
        }
        else {
          puVar6 = (undefined4 *)(**(code **)(*(int *)pCVar7 + 0xc))(pCVar7);
          *(undefined4 *)(iVar11 + 0x10) = *puVar6;
          iVar11 = g_VisibilityCache._4_4_ + uVar10 * 0x18;
        }
      }
      else {
        iVar11 = g_VisibilityCache._4_4_ + uVar10 * 0x18;
        *(undefined4 *)(iVar11 + 0x10) = 0xffffffff;
      }
      *(undefined4 *)(iVar11 + 0x14) = *(undefined4 *)(gpGlobals + 0xc);
      goto LAB_005f7a1f;
    }
    param_2 = 0x4041;
  }
                    /* try { // try from 005f7a18 to 005f7a1c has its CatchHandler @ 005f7e9e */
  uVar3 = CBaseEntity::FVisible((CBaseEntity *)this,param_1,param_2,param_3);
LAB_005f7a1f:
  iVar11 = _DAT_0105db00;
  if (((DAT_0105d158 == '\0') || (_DAT_0105d154 != 0)) &&
     (iVar4 = ThreadGetCurrentId(), iVar11 == iVar4)) {
    cVar2 = CVProfNode::ExitScope();
    if (cVar2 != '\0') {
      _DAT_0105d15c = (int *)_DAT_0105d15c[0x19];
    }
    DAT_0105d158 = _DAT_0105d15c == (int *)0x105d160;
  }
  if (local_30 != 0) {
    (**(code **)(local_30 + 0x54))(local_30,local_38,local_34,0,0,0);
  }
  return uVar3;
}

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)