L L4D2node

CSoundEmitterSystem::EmitCloseCaption

0x004bca40 · 1858 bytes · __thiscall

_ZN19CSoundEmitterSystem16EmitCloseCaptionER16IRecipientFilteribPKcR10CUtlVectorI6Vector10CUtlMemoryIS5_iEEfbb

Decompiled

undefined (9 params)

/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
/* CSoundEmitterSystem::EmitCloseCaption(IRecipientFilter&, int, bool, char const*,
   CUtlVector<Vector, CUtlMemory<Vector, int> >&, float, bool, bool) */

void __thiscall
CSoundEmitterSystem::EmitCloseCaption
          (CSoundEmitterSystem *this,IRecipientFilter *param_1,int param_2,bool param_3,
          char *param_4,CUtlVector *param_5,float param_6,bool param_7,bool param_8)

{
  ushort uVar1;
  byte *pbVar2;
  bool bVar3;
  undefined1 *puVar4;
  char cVar5;
  int iVar6;
  CBaseEntity *this_00;
  int *piVar7;
  int iVar8;
  byte *pbVar9;
  int iVar10;
  uint *puVar11;
  undefined4 *puVar12;
  int iVar13;
  int in_GS_OFFSET;
  longdouble lVar14;
  uint *local_264;
  uint local_250;
  uint local_24c;
  undefined4 local_248;
  undefined4 local_244;
  CRecipientFilter local_240 [32];
  char local_220 [256];
  char local_120 [256];
  int local_20;
  
  puVar12 = (undefined4 *)&stack0xfffffd74;
  puVar11 = (uint *)&stack0xfffffd74;
  local_20 = *(int *)(in_GS_OFFSET + 0x14);
  if ((*(int *)(gpGlobals + 0x14) == 1) && (*(int *)(*(int *)(g_pClosecaption + 0x1c) + 0x30) == 0))
  goto LAB_004bce48;
  if (param_6 < 0.0) {
    iVar6 = (**(code **)(*soundemitterbase + 0x40))();
    param_6 = 2.0;
    if (iVar6 != 0) {
      lVar14 = (longdouble)(**(code **)(*enginesound + 0x10))();
      param_6 = (float)lVar14;
    }
  }
  V_strncpy(local_220,param_4,0x100);
  _V_strlower(local_220);
  iVar6 = _V_strstr(local_220,"\\");
  if (iVar6 != 0) {
    Hack_FixEscapeChars(local_220);
  }
  CRecipientFilter::CRecipientFilter(local_240);
                    /* try { // try from 004bcb02 to 004bceda has its CatchHandler @ 004bd1b0 */
  CRecipientFilter::CopyFrom(local_240,(CRecipientFilter *)param_1);
  CRecipientFilter::RemoveSplitScreenPlayers(local_240);
  if (!param_8) {
    CBaseEntity::RemoveRecipientsIfNotCloseCaptioning(local_240);
  }
  iVar6 = CRecipientFilter::GetRecipientCount(local_240);
  if (0 < iVar6) {
    iVar6 = CRecipientFilter::GetRecipientCount(local_240);
    iVar6 = iVar6 + -1;
    if (-1 < iVar6) {
      do {
        while( true ) {
          iVar10 = CRecipientFilter::GetRecipientIndex(local_240,iVar6);
          this_00 = (CBaseEntity *)UTIL_PlayerByIndex(iVar10);
          if (this_00 != (CBaseEntity *)0x0) break;
LAB_004bcb40:
          iVar6 = iVar6 + -1;
          if (iVar6 == -1) goto LAB_004bcbe0;
        }
        if (((byte)this_00[0x14d] & 8) != 0) {
          CBaseEntity::CalcAbsolutePosition(this_00);
        }
        local_24c = *(uint *)(this_00 + 0x2e0);
        local_248 = *(undefined4 *)(this_00 + 0x2e4);
        local_244 = *(undefined4 *)(this_00 + 0x2e8);
        cVar5 = AttenuateCaption(local_220,(Vector *)&local_24c,param_5);
        if (cVar5 == '\0') goto LAB_004bcb40;
        CRecipientFilter::RemoveRecipient(local_240,(CBasePlayer *)this_00);
        iVar6 = iVar6 + -1;
      } while (iVar6 != -1);
    }
  }
LAB_004bcbe0:
  iVar6 = CRecipientFilter::GetRecipientCount(local_240);
  if (0 < iVar6) {
    V_strncpy(local_120,local_220,0x100);
    pbVar2 = *(byte **)(gpGlobals + 0x58);
    if ((uint)param_2 < 0x800) {
      puVar4 = &stack0xfffffd74;
      if (pbVar2 == (byte *)0x0) goto LAB_004bccf0;
      pbVar9 = pbVar2 + param_2 * 0x10;
      if ((pbVar2[param_2 * 0x10] & 2) != 0) goto LAB_004bcce2;
LAB_004bcc3e:
      puVar4 = &stack0xfffffd74;
      if ((*(int **)(pbVar9 + 0xc) == (int *)0x0) ||
         (piVar7 = (int *)(**(code **)(**(int **)(pbVar9 + 0xc) + 0x18))(),
         puVar4 = &stack0xfffffd74, piVar7 == (int *)0x0)) goto LAB_004bccf0;
      (**(code **)(*piVar7 + 0x20))();
      puVar11 = (uint *)&stack0xfffffd70;
      iVar6 = (**(code **)(*soundemitterbase + 0x88))();
      if ((iVar6 == 0x15) || (iVar6 == 1)) {
        V_strncat(local_220,"_male",0x100,-1);
      }
      else {
        if ((iVar6 != 0x16) && (puVar4 = &stack0xfffffd70, iVar6 != 2)) goto LAB_004bccf0;
        V_strncat(local_220,"_female",0x100,-1);
      }
      bVar3 = true;
    }
    else {
      puVar4 = &stack0xfffffd74;
      if (pbVar2 != (byte *)0x0) {
LAB_004bcce2:
        pbVar9 = pbVar2;
        puVar4 = &stack0xfffffd74;
        if ((*pbVar2 & 2) == 0) goto LAB_004bcc3e;
      }
LAB_004bccf0:
      puVar11 = (uint *)puVar4;
      bVar3 = false;
    }
    local_250 = 0;
    puVar11[1] = (uint)local_220;
    *puVar11 = (uint)&local_24c;
    puVar11[-1] = 0x4bcd19;
    CaptionLookup_t::SetHash((CaptionLookup_t *)*puVar11,(char *)puVar11[1]);
    local_250 = local_24c;
    iVar6 = *(int *)(this + 0x50);
    if (0 < iVar6) {
      iVar10 = 0;
      iVar13 = 0;
      do {
        puVar11[1] = (uint)&local_24c;
        *puVar11 = *(int *)(this + 0x44) + iVar10 + 0x1c;
        puVar11[-1] = 0x4bcd7a;
        iVar8 = CUtlSortVector<CaptionLookup_t,CCaptionLookupLess>::Find
                          ((CUtlSortVector<CaptionLookup_t,CCaptionLookupLess> *)*puVar11,
                           (CaptionLookup_t *)puVar11[1]);
        if (iVar8 != -1) {
          if (iVar13 < iVar6) {
            if (*(ushort *)(*(int *)(*(int *)(this + 0x44) + 0x1c + iVar10) + iVar8 * 0xc + 10) < 5)
            goto LAB_004bcea8;
            goto LAB_004bcda9;
          }
          break;
        }
        iVar13 = iVar13 + 1;
        iVar10 = iVar10 + 0x54;
      } while (iVar13 != iVar6);
    }
    if (*(int *)(cc_showmissing._28_4_ + 0x30) != 0) {
      uVar1 = DAT_00f9cfc8;
      if (GetCaptionHash(char_const*,bool,unsigned_int&)::s_MissingHashes == '\0') {
        *puVar11 = (uint)&GetCaptionHash(char_const*,bool,unsigned_int&)::s_MissingHashes;
        puVar11[-1] = 0x4bd118;
        iVar6 = __cxa_guard_acquire();
        uVar1 = DAT_00f9cfc8;
        if (iVar6 != 0) {
          *puVar11 = (uint)&GetCaptionHash(char_const*,bool,unsigned_int&)::s_MissingHashes;
          _DAT_00f9cfca = 0;
          _DAT_00f9cfcc = 0xffff;
          _DAT_00f9cfce = 0xffff;
          GetCaptionHash(char_const*,bool,unsigned_int&)::s_MissingHashes =
               CDefOps<unsigned_int>::LessFunc;
          DAT_00f9cfbc = 0;
          _DAT_00f9cfc0 = 0;
          _DAT_00f9cfc4 = 0;
          DAT_00f9cfc8 = 0xffff;
          _DAT_00f9cfd0 = 0;
          puVar11[-1] = 0x4bd18a;
          __cxa_guard_release();
          puVar11[2] = (uint)&__dso_handle;
          puVar11[1] = (uint)&GetCaptionHash(char_const*,bool,unsigned_int&)::s_MissingHashes;
          *puVar11 = (uint)CUtlRBTree<unsigned_int,unsigned_short,bool(*)(unsigned_int_const&,unsigned_int_const&),CUtlMemory<UtlRBTreeNode_t<unsigned_int,unsigned_short>,unsigned_short>>
                           ::~CUtlRBTree;
          puVar11[-1] = 0x4bd1a6;
          __cxa_atexit();
          uVar1 = DAT_00f9cfc8;
        }
      }
      while (uVar1 != 0xffff) {
        local_264 = &local_250;
        iVar6 = (uint)uVar1 * 0xc;
        puVar11[1] = DAT_00f9cfbc + 8 + iVar6;
        *puVar11 = (uint)local_264;
                    /* try { // try from 004bcfe4 to 004bd106 has its CatchHandler @ 004bd1b0 */
        puVar11[-1] = 0x4bcfea;
        cVar5 = (*GetCaptionHash(char_const*,bool,unsigned_int&)::s_MissingHashes)();
        if (cVar5 == '\0') {
          puVar11[1] = (uint)local_264;
          *puVar11 = DAT_00f9cfbc + iVar6 + 8;
          puVar11[-1] = 0x4bd00b;
          cVar5 = (*GetCaptionHash(char_const*,bool,unsigned_int&)::s_MissingHashes)();
          if (cVar5 == '\0') goto LAB_004bcea8;
          if (CUtlRBTree<unsigned_int,unsigned_short,bool(*)(unsigned_int_const&,unsigned_int_const&),CUtlMemory<UtlRBTreeNode_t<unsigned_int,unsigned_short>,unsigned_short>>
              ::Links(unsigned_short)::s_Sentinel == '\0') {
            *puVar11 = (uint)&CUtlRBTree<unsigned_int,unsigned_short,bool(*)(unsigned_int_const&,unsigned_int_const&),CUtlMemory<UtlRBTreeNode_t<unsigned_int,unsigned_short>,unsigned_short>>
                              ::Links(unsigned_short)::s_Sentinel;
            puVar11[-1] = 0x4bd0bc;
            iVar10 = __cxa_guard_acquire();
            if (iVar10 != 0) {
              *puVar11 = (uint)&CUtlRBTree<unsigned_int,unsigned_short,bool(*)(unsigned_int_const&,unsigned_int_const&),CUtlMemory<UtlRBTreeNode_t<unsigned_int,unsigned_short>,unsigned_short>>
                                ::Links(unsigned_short)::s_Sentinel;
              DAT_00f19312 = 0xffff;
              CUtlRBTree<unsigned_int,unsigned_short,bool(*)(unsigned_int_const&,unsigned_int_const&),CUtlMemory<UtlRBTreeNode_t<unsigned_int,unsigned_short>,unsigned_short>>
              ::Links(unsigned_short)::s_Sentinel = 0xffff;
              DAT_00f19314 = 0xffff;
              puVar11[-1] = 0x4bd0f2;
              __cxa_guard_release();
            }
          }
          uVar1 = *(ushort *)(DAT_00f9cfbc + 2 + iVar6);
        }
        else {
          if (CUtlRBTree<unsigned_int,unsigned_short,bool(*)(unsigned_int_const&,unsigned_int_const&),CUtlMemory<UtlRBTreeNode_t<unsigned_int,unsigned_short>,unsigned_short>>
              ::Links(unsigned_short)::s_Sentinel == '\0') {
            *puVar11 = (uint)&CUtlRBTree<unsigned_int,unsigned_short,bool(*)(unsigned_int_const&,unsigned_int_const&),CUtlMemory<UtlRBTreeNode_t<unsigned_int,unsigned_short>,unsigned_short>>
                              ::Links(unsigned_short)::s_Sentinel;
            puVar11[-1] = 0x4bd06c;
            iVar6 = __cxa_guard_acquire();
            if (iVar6 != 0) {
              *puVar11 = (uint)&CUtlRBTree<unsigned_int,unsigned_short,bool(*)(unsigned_int_const&,unsigned_int_const&),CUtlMemory<UtlRBTreeNode_t<unsigned_int,unsigned_short>,unsigned_short>>
                                ::Links(unsigned_short)::s_Sentinel;
              CUtlRBTree<unsigned_int,unsigned_short,bool(*)(unsigned_int_const&,unsigned_int_const&),CUtlMemory<UtlRBTreeNode_t<unsigned_int,unsigned_short>,unsigned_short>>
              ::Links(unsigned_short)::s_Sentinel = 0xffff;
              DAT_00f19312 = 0xffff;
              DAT_00f19314 = 0xffff;
              puVar11[-1] = 0x4bd0a1;
              __cxa_guard_release();
            }
          }
          uVar1 = *(ushort *)(DAT_00f9cfbc + (uint)uVar1 * 0xc);
        }
      }
      local_264 = &local_250;
      *puVar11 = (uint)&GetCaptionHash(char_const*,bool,unsigned_int&)::s_MissingHashes;
      puVar11[1] = (uint)local_264;
      puVar11[-1] = 0x4bce8f;
      CUtlRBTree<unsigned_int,unsigned_short,bool(*)(unsigned_int_const&,unsigned_int_const&),CUtlMemory<UtlRBTreeNode_t<unsigned_int,unsigned_short>,unsigned_short>>
      ::Insert((CUtlRBTree<unsigned_int,unsigned_short,bool(*)(unsigned_int_const&,unsigned_int_const&),CUtlMemory<UtlRBTreeNode_t<unsigned_int,unsigned_short>,unsigned_short>>
                *)*puVar11,(uint *)puVar11[1]);
      *puVar11 = (uint)"Missing caption for %s\n";
      puVar11[1] = (uint)local_220;
      puVar11[-1] = 0x4bcea5;
      Msg();
    }
LAB_004bcea8:
    if (bVar3) {
      puVar11[2] = 1;
      puVar11[3] = (uint)&local_250;
      puVar11[1] = (uint)local_120;
      *puVar11 = (uint)this;
      puVar11[-1] = 0x4bcedb;
      cVar5 = GetCaptionHash((CSoundEmitterSystem *)*puVar11,(char *)puVar11[1],SUB41(puVar11[2],0),
                             (uint *)puVar11[3]);
      if (cVar5 != '\0') {
LAB_004bcda9:
        *puVar11 = (uint)g_CaptionRepeats;
        puVar11[1] = local_250;
        puVar11[-1] = 0x4bcdbf;
        cVar5 = CCaptionRepeatMgr::CanEmitCaption((CCaptionRepeatMgr *)*puVar11,puVar11[1]);
        if (cVar5 != '\0') {
          if (param_8) {
            puVar11[1] = (uint)"CloseCaptionDirect";
            *puVar11 = (uint)local_240;
            puVar11[-1] = 0x4bd107;
            UserMessageBegin((IRecipientFilter *)*puVar11,(char *)puVar11[1]);
          }
          else {
            puVar11[1] = (uint)"CloseCaption";
            *puVar11 = (uint)local_240;
            puVar11[-1] = 0x4bcde0;
            UserMessageBegin((IRecipientFilter *)*puVar11,(char *)puVar11[1]);
          }
          *puVar11 = local_250;
          puVar11[-1] = 0x4bcdee;
          MessageWriteLong(*puVar11);
          iVar10 = (int)(param_6 * 10.0);
          iVar6 = 0xffff;
          if ((iVar10 < 0x10000) && (iVar6 = 0, -1 < iVar10)) {
            iVar6 = iVar10;
          }
          puVar11[1] = 0xf;
          *puVar11 = iVar6;
          puVar11[-1] = 0x4bce24;
          MessageWriteUBitLong(*puVar11,puVar11[1]);
          puVar11[1] = 1;
          *puVar11 = (uint)param_3;
          puVar11[-1] = 0x4bce3b;
          MessageWriteUBitLong(*puVar11,puVar11[1]);
          puVar11[-1] = 0x4bce40;
          MessageEnd();
        }
      }
    }
  }
  *puVar11 = (uint)local_240;
  puVar11[-1] = 0x4bce48;
  CRecipientFilter::~CRecipientFilter((CRecipientFilter *)*puVar11);
  puVar12 = puVar11;
LAB_004bce48:
  if (local_20 != *(int *)(in_GS_OFFSET + 0x14)) {
                    /* WARNING: Subroutine does not return */
    *(undefined1 **)((int)puVar12 + -4) = &LAB_004bd1b0;
    __stack_chk_fail();
  }
  return;
}

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)