summaryrefslogtreecommitdiff
path: root/src/game/object.h
blob: 3f0592c2dc21d894ad5f83f0cc458b9d269cbf24 (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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#pragma once
#include "../util/allocator.h"
#include "../util/vector.h"
#include "../util/fnv.h"

typedef void ( *OBJECT_DEINIT_FN )( struct OBJECT* obj );
inline const char* obj_classid_to_name( U32 classid );
inline LIST<struct OBJECT_PROP*>* obj_proplist( U32 classid );

enum ObjectClass_t {
  OBJCLASS_NONE = 0,
  OBJCLASS_WORLD,
  OBJCLASS_TRIGGER,
  OBJCLASS_PLAYER,
  OBJCLASS_BASENPC,
  OBJCLASS_LAST
};

static const char* OBJCLASS_NAMES[] = {
  "none (invalid - FIXME)",
  "world",
  "trigger",
  "player",
  "base_npc",
};


// todo: come up with a good way to make these static
struct OBJECT_PROP {
  OBJECT_PROP( const char* name, U32 size, U32 classid, U32 offset ) {
    this->name = name;
    this->size = size;
    this->hash = fnv1a( name );
    this->offset = offset;
    LIST<OBJECT_PROP*>* l = obj_proplist( classid );
    l->push( this );
  }

  const char* name;
  FNV1A hash;
  U32 offset;
  U32 size;
};


inline LIST<OBJECT_PROP*>* obj_proplist( U32 classid ) {
  static struct LIST<OBJECT_PROP*> prop_lists[OBJCLASS_LAST];

  if( classid >= OBJCLASS_LAST ) {
    dlog( "obj_classid_to_name() : invalid classid passed (%d)", classid );
    return 0;
  }

  return &prop_lists[classid];
}

#define OBJVAR( type, name ) \
  type name; \
  constexpr static U32 __##name##_offset() { OBJ_SELF_TYPE t; return (U32)( (U64)&t.name - (U64)&t ); } \
  static inline OBJECT_PROP __##name##_props{ #name, sizeof(type), OBJ_SELF_TYPE::CLASSID, (U32)( __##name##_offset() )  }

#define OBJVARV( type, name, val ) \
  type name{ type( val ) }; \
  constexpr static U32 __##name##_offset() { OBJ_SELF_TYPE t; return (U32)( (U64)&t.name - (U64)&t ); } \
  static inline OBJECT_PROP __##name##_props{ #name, sizeof(type), OBJ_SELF_TYPE::CLASSID, (U32)( __##name##_offset() )  }

#define OBJVAR_STR( name, len ) \
  char name##[len]; \
  constexpr static U32 __##name##_offset() { OBJ_SELF_TYPE t; return (U32)( (U64)&t.name - (U64)&t ); } \
  static inline OBJECT_PROP __##name##_props{ #name, sizeof(type), OBJ_SELF_TYPE::CLASSID, (U32)( __##name##_offset() )  }

struct OBJECT {
  static const U32 CLASSID = OBJCLASS_NONE;
  using OBJ_SELF_TYPE = OBJECT;

  U32 classid;
  U8  keeponlevel{};
  char name[64];

  OBJECT* parent;
  LIST<OBJECT*> children{};
  OBJECT_DEINIT_FN deinit_fn{};

  OBJVAR( VEC3, pos );
  OBJVAR( VEC3, rot );
  OBJVAR( I32, idx );
  OBJVAR( VEC3, velocity );
  OBJVAR( VEC3, mins );
  OBJVAR( VEC3, maxs );
};

inline const char* obj_classid_to_name( U32 classid ) {
  if( classid > (sizeof(OBJCLASS_NAMES) / sizeof(OBJCLASS_NAMES[0])) ) {
    dlog( "obj_classid_to_name() : invalid classid passed (%d)", classid );
    return "INVALIDCLASSID";
  }

  return OBJCLASS_NAMES[classid];
}