game.h
Raw
1#ifndef GAME_H
2#define GAME_H
3#include <stddef.h>
4#include <stdbool.h>
5#include <assert.h>
6#include <helper.h>
7#include <darray.h>
8#define MAXITEMS 10
9
10extern unsigned m_id;
11
12enum objtype {NOOBJ = 0, MONSTER, ITEM, WALL, TARGET};
13enum itemtype {NOITEM = 0, EQUIP, USE};
14
15struct equip
16{
17 unsigned hp;
18 unsigned dmg;
19 bool isequipped;
20};
21
22struct use
23{
24 unsigned restorehp;
25};
26
27struct item
28{
29 const char *name;
30 enum itemtype type;
31 union
32 {
33 struct equip e;
34 struct use u;
35 }u;
36};
37
38
39struct monster
40{
41 const char *name;
42 unsigned id;
43 unsigned current_hp;
44 unsigned max_hp;
45 unsigned dmg;
46 unsigned level;
47 unsigned xp;
48 darray(struct item) items;
49 bool isplayer;
50};
51
52static inline size_t item_len(const struct monster *m)
53{
54 for(size_t i = 0; i < MAXITEMS; i++)
55 {
56 if(darray_item(m->items, i).type == NOITEM)
57 return i;
58 }
59 return MAXITEMS;
60}
61
62
63struct object
64{
65 enum objtype type;
66 char symbol;
67 union
68 {
69 struct monster m;
70 struct item i;
71 } u;
72};
73
74struct game
75{
76 struct object *map;
77 size_t xs, ys;
78};
79
80static inline struct object *game_at(const struct game *g, struct point p)
81{
82 return &g->map[p.y * g->xs + p.x];
83}
84
85
86static inline struct game create_game(size_t y, size_t x)
87{
88 struct game ret;
89 ret.map = xmalloc(x * y * sizeof * ret.map);
90 ret.xs = x;
91 ret.ys = y;
92
93 return ret;
94}
95
96static inline void delete_game(struct game *g)
97{
98 for(size_t y = 0; y < g->ys; y++)
99 {
100 for(size_t x = 0; x < g->xs; x++)
101 {
102 if(game_at(g, (struct point){y,x})->type == MONSTER)
103 darray_free(game_at(g, (struct point){y,x})->u.m.items);
104 }
105 }
106 free(g->map);
107}
108
109enum action {MOVE, SPAWN, QUIT, INVENTORY, REDRAW, INVALID};
110enum direction {UP,DOWN,LEFT,RIGHT};
111
112struct choice
113{
114 enum action a;
115 union
116 {
117 enum direction d;
118 }u;
119};
120
121#define MAX(x,y) (x >= y ? x : y)
122#define MIN(x,y) (x <= y ? x : y)
123
124#define ORC (struct object)\
125 {\
126 .type = MONSTER,\
127 .symbol = 'O',\
128 .u.m = {"Zog Zog", m_id++, 10, 10, 1, 5 , 0, darray_new(), false}\
129 }
130
131#define EMPTYFIELD (struct object)\
132 {\
133 .type = NOOBJ,\
134 .symbol = ' ',\
135 }
136#define WALLFIELD (struct object)\
137 {\
138 .type = WALL,\
139 .symbol = '#',\
140 }
141
142static inline struct point relative(struct point p, enum direction d)
143{
144 switch(d)
145 {
146 case UP:
147 return (struct point){p.y - 1, p.x};
148 case DOWN:
149 return (struct point){p.y + 1, p.x};
150 case LEFT:
151 return (struct point){p.y, p.x - 1};
152 case RIGHT:
153 return (struct point){p.y, p.x + 1};
154 default:
155 assert(false);
156 }
157}
158
159static inline bool in_bounds(struct game *g, struct point p)
160{
161 if(p.y >= 0 && p.y < g->ys && p.x >= 0 && p.x < g->xs)
162 return true;
163 else
164 return false;
165}
166
167static inline void spawn_enemy(struct game *g)
168{
169 while(true)
170 {
171 struct point p = {randrange(0, g->ys), randrange(0, g->xs)};
172 if(in_bounds(g, p) && game_at(g, p)->type == NOOBJ) {
173 *game_at(g, p) = ORC;
174 break;
175 }
176 }
177}
178
179
180#endif
181