#ifndef GAME_H #define GAME_H #include #include #include #include #include #define MAX(x,y) (x >= y ? x : y) #define MIN(x,y) (x <= y ? x : y) #define ORC (struct monster)\ {\ .symbol = 'O',\ .name = "Zog Zog", \ .id = m_id++, .current_hp = 10, .max_hp = 10, .dmg = 1,\ .level = 5 , .xp = 0, .items = darray_new(), .isplayer = false\ } #define EMPTYFIELD (struct object)\ {\ .type = NOOBJ,\ .symbol = ' ',\ } #define WALLFIELD (struct object)\ {\ .type = WALL,\ .symbol = '#',\ } extern unsigned m_id; enum objtype {NOOBJ = 0, MONSTER, ITEM, WALL, TARGET}; enum itemtype {NOITEM = 0, EQUIP, USE}; struct equip { unsigned hp; unsigned dmg; bool isequipped; }; struct use { unsigned restorehp; }; struct object { enum objtype type; char symbol; }; struct item { struct object o; const char *name; enum itemtype type; union { struct equip e; struct use u; }u; }; struct monster { char symbol; const char *name; unsigned id; unsigned current_hp; unsigned max_hp; unsigned dmg; unsigned level; unsigned xp; darray(struct item) items; bool isplayer; }; struct field { union { struct object ground; struct item it; } *u; struct monster m; bool has_monster; }; struct game { struct field *map; size_t xs, ys; }; static inline struct field *game_at(const struct game *g, struct point p) { return &g->map[p.y * g->xs + p.x]; } static inline struct game create_game(size_t y, size_t x) { struct game ret; ret.map = xmalloc(x * y * sizeof(*ret.map)); for(size_t i = 0; i < x*y; i++) { ret.map[i].u = xmalloc(sizeof(*ret.map[i].u)); ret.map[i].has_monster = false; } ret.xs = x; ret.ys = y; return ret; } static inline void delete_game(struct game *g) { for(size_t y = 0; y < g->ys; y++) { for(size_t x = 0; x < g->xs; x++) { if(game_at(g, (struct point){y,x})->has_monster) darray_free(game_at(g, (struct point){y,x})->m.items); free(game_at(g, (struct point){y,x})->u); } } free(g->map); } enum action {MOVE, SPAWN, QUIT, INVENTORY, REDRAW, INVALID}; enum direction {UP,DOWN,LEFT,RIGHT}; struct choice { enum action a; union { enum direction d; }u; }; //returns a point that is relative to p in the direction d static inline struct point relative(struct point p, enum direction d) { switch(d) { case UP: return (struct point){p.y - 1, p.x}; case DOWN: return (struct point){p.y + 1, p.x}; case LEFT: return (struct point){p.y, p.x - 1}; case RIGHT: return (struct point){p.y, p.x + 1}; default: assert(false); } } static inline bool in_bounds(struct game *g, struct point p) { if(p.y >= 0 && p.y < g->ys && p.x >= 0 && p.x < g->xs) return true; else return false; } //randomly puts an enemy in an empty spot on the map static inline void spawn_enemy(struct game *g) { while(true) { struct point p = {randrange(0, g->ys), randrange(0, g->xs)}; if(in_bounds(g, p) && game_at(g, p)->u->ground.type != WALL && !game_at(g, p)->has_monster) { game_at(g, p)->m = ORC; game_at(g, p)->has_monster = true; break; } } } void loop(); //main game loop #endif