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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
#include "utils.h"
#include "assets.h"
// Pretty much any object in the game.
#ifndef ENTITY_H
#define ENTITY_H
#define ENTITY_COUNT 15
#define ENTITY_NAME_MAX 16
#define INTERACTION_MENU_MAX 9
#define INTERACTION_LABEL_MAX 32
#define INTERACTION_CHAT_MAX 256
#define ENTITY_BUILDING_CUBE_SIZE (Vector3){4.0, 4.0, 4.0}
#define BUILDING_DEFAULT_ROOF_HEIGHT 10.0
#define BUILDING_ROOF_SLICES 9 // Yes 9 (:
typedef int8_t EntityId;
typedef enum InteractionCommand InteractionCommand;
typedef enum Selection Selection;
typedef struct Entity Entity;
typedef InteractionCommand (*InteractionCallback)(Entity* entity, Game* game,
Selection selection);
typedef void (*InitEntityCallback)(Entity* entity);
typedef void (*UpdateEntityCallback)(Entity* entity, Game* game);
typedef void (*CloseEntityCallback)(Entity* entity);
enum {
ENTITY_NONE = -1,
OLD_MINT,
STICKY_NICKEL,
TREE,
BUSH,
FLOWER,
POND,
UTILITY_POLE,
SAMANTHA,
SAMANTHAS_SPOT,
TRASHCAN,
TRASH,
MEDICAL_TRASH,
JOHN,
JOHNS_STORE,
RON
};
enum InteractionCommand {
INTERACTION_END,
INTERACTION_TALK,
INTERACTION_SHOW_MENU,
INTERACTION_TALK_AND_SHOW_MENU,
INTERACTION_DO_NOTHING
};
enum Selection {
SELECTION_NONE = -1,
SELECTION_INTERACT,
SELECTION_NEXT_MESSAGE,
SELECTION_MENU_ITEM, // +x to select any given menu entry
SELECTION_LEAVE = SELECTION_MENU_ITEM + INTERACTION_MENU_MAX
};
struct Entity {
EntityId id;
Vector3 position; // Shouldnt be changed directly.
BoundingBox box;
void* data;
};
typedef struct {
EntityId id;
AssetId texture;
int count;
} EntityItem;
// Cubemap based building.
typedef struct {
Model model;
Color* pixelMap;
int width;
int height;
float roofSize;
float roofHeight;
Vector3 roofOffset;
} EntityBuilding;
typedef struct {
char name[ENTITY_NAME_MAX];
InitEntityCallback initCallback;
UpdateEntityCallback updateCallback;
CloseEntityCallback closeCallback;
InteractionCallback interactionCallback;
bool isPlace;
bool isBuilding;
bool canBeSelected;
float placeAreaSize; // If <= 0.0 use collision instead.
} EntityEntry;
// Am I still insane if I am aware of my insanity?
extern const EntityEntry entityEntries[ENTITY_COUNT];
Entity createEntity(EntityId id, Vector3 position);
void updateEntity(Entity* entity, Game* game);
void closeEntity(Entity* entity);
const char* getEntityName(EntityId id);
void setEntityPosition(Entity* entity, Vector3 position);
void placeEntityOnGround(Entity* entity, const World* world);
bool entityIsPlace(EntityId id);
bool entityIsBuilding(EntityId id);
bool entityCanBeSelected(EntityId id);
float getEntityPlaceAreaSize(EntityId id);
float getEntityDistance(Entity entity, Vector3 position);
InteractionCommand interactWithEntity(Entity* entity, Game* game,
Selection selection);
int getInteractionMenuIndex(Selection selection);
BoundingBox entityBoxFromScale(float scale, float width, float height);
EntityBuilding* createEntityBuilding(Image heightmap);
void freeEntityBuilding(EntityBuilding* building);
bool isBuildingBlockWall(const EntityBuilding* building, int x, int y);
void drawBuildingRoof(const EntityBuilding* building, Vector3 position,
Color color);
#endif
|