summaryrefslogtreecommitdiff
path: root/src/csgo/materialsystem.h
blob: 263f80869321027569fab3706bec39e8f714ae47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "csgo.h"

class MATERIAL {
private:
  static IFACE_ENTRY* get_matsystem( CSGO* csgo ) {
    static IFACE_ENTRY* ret = u_vector_search<IFACE_ENTRY>( csgo->interfaces,
    []( IFACE_ENTRY i ) {
      return fnv1a( "materialsystem.dll" ) == fnv1a( i.module_name )
          && !!strcmp( i.name, "VMaterialSystem" );
    } );

    return ret;
  }

  static IFACE_ENTRY* get_matsystem_cvar( CSGO* csgo ) {
    static IFACE_ENTRY* ret = u_vector_search<IFACE_ENTRY>( csgo->interfaces,
    []( IFACE_ENTRY i ) {
      return fnv1a( "materialsystem.dll" ) == fnv1a( i.module_name )
          && !!strcmp( i.name, "VEngineCvar" );
    } );

    return ret;
  }
  
public:
  static U32 first_material( CSGO* csgo ) {
    IFACE_ENTRY* mat_system = get_matsystem( csgo );

    U16 mat_handle = csgo->read<U16>( mat_system->ptr + 0x250 );

    while( mat_handle != 0xffff ) {
      U32 handle_entries = csgo->read<U32>( mat_system->ptr + 0x244 );
      U16 next_handle = csgo->read<U16>( handle_entries + 16 * mat_handle );

      if( next_handle == 0xffff )
        return mat_handle;

      mat_handle = next_handle;
    }

    return 0;
  }

  static U16 next_material( CSGO* csgo, U16 mat ) {
    IFACE_ENTRY* mat_system = get_matsystem( csgo );

    if( mat == 0xffff )
      return 0;

    U32 handle_array = csgo->read<U32>( mat_system->ptr + 0x244 );
    U16 next_handle = csgo->read<U16>( handle_array + 16 + mat + 2 );
    if( next_handle == 0xffff )
      return 0xffff;

    for( U16 i = next_handle; i != 0xffff; i = csgo->read<U16>( handle_array * 16 + i ) ) {
      next_handle = i;
    }

    return next_handle;
  }
};