146 lines
3.6 KiB
C
146 lines
3.6 KiB
C
#include <curses.h>
|
|
#include <locale.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
#include "cavegen.h"
|
|
#include "common.h"
|
|
#include "display.h"
|
|
#include "entity.h"
|
|
#include "ht.h"
|
|
|
|
bool entity_set_pos(struct entity *e, struct point p, struct map *map)
|
|
{
|
|
if (e->solid) {
|
|
if (p.y < 0 || p.x < 0 || p.y >= map->height || p.x >= map->width) {
|
|
return false;
|
|
}
|
|
if (map->map[p.y * map->width + p.x] == WALL) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
e->p = p;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool game_update(
|
|
display_t *disp, enum action action, ht_t *entities, struct map *map
|
|
)
|
|
{
|
|
struct entity *player = ht_find(entities, "player");
|
|
struct entity *camera = ht_find(entities, "camera");
|
|
|
|
struct point newp = player->p;
|
|
struct point newp_cam = camera->p;
|
|
switch (action) {
|
|
case ACTION_EXIT : return true;
|
|
case ACTION_UP :
|
|
--newp.y;
|
|
--newp_cam.y;
|
|
display_message(disp, "moving up");
|
|
break;
|
|
case ACTION_DOWN :
|
|
++newp.y;
|
|
++newp_cam.y;
|
|
display_message(disp, "moving down");
|
|
break;
|
|
case ACTION_LEFT :
|
|
--newp.x;
|
|
--newp_cam.x;
|
|
display_message(disp, "moving left");
|
|
break;
|
|
case ACTION_RIGHT :
|
|
++newp.x;
|
|
++newp_cam.x;
|
|
display_message(disp, "moving right");
|
|
break;
|
|
case ACTION_STAIR_DOWN :
|
|
if (map->map[player->p.y * map->width + player->p.x] == DOWN_STAIR) {
|
|
free(map->map);
|
|
create_cave(map);
|
|
|
|
newp = map->entry_point;
|
|
newp_cam.x = map->entry_point.x - MAIN_PANEL_WIDTH / 2 + 1;
|
|
newp_cam.y = map->entry_point.y - MAIN_PANEL_HEIGHT / 2 + 1;
|
|
display_message(disp, "moving down stairs");
|
|
} else {
|
|
display_message(disp, "no stairs to go down");
|
|
}
|
|
break;
|
|
case ACTION_STAIR_UP :
|
|
if (map->map[player->p.y * WIDTH + player->p.x] == UP_STAIR) {
|
|
display_message(disp, "moving up stairs");
|
|
return true;
|
|
} else {
|
|
display_message(disp, "no stairs to go up");
|
|
}
|
|
break;
|
|
default : display_message(disp, "unrecognized command"); break;
|
|
}
|
|
|
|
if (entity_set_pos(player, newp, map))
|
|
entity_set_pos(camera, newp_cam, map);
|
|
|
|
return false;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
unsigned int seed = time(NULL);
|
|
srand(seed);
|
|
|
|
display_t *disp = display_init();
|
|
|
|
// create the map
|
|
struct map map;
|
|
create_cave(&map);
|
|
|
|
// create the entity map
|
|
ht_t *entities = ht_create(1);
|
|
|
|
// create the camera
|
|
struct entity camera;
|
|
camera.disp_ch = "";
|
|
camera.solid = false;
|
|
camera.visible = false;
|
|
ht_insert(entities, "camera", &camera);
|
|
|
|
// create the player
|
|
struct entity player;
|
|
player.disp_ch = "@";
|
|
player.solid = true;
|
|
player.visible = true;
|
|
ht_insert(entities, "player", &player);
|
|
|
|
// set starting point
|
|
struct point cam_p = {
|
|
.x = map.entry_point.x - MAIN_PANEL_WIDTH / 2 + 1,
|
|
.y = map.entry_point.y - MAIN_PANEL_HEIGHT / 2 + 1,
|
|
};
|
|
entity_set_pos(&player, map.entry_point, &map);
|
|
entity_set_pos(&camera, cam_p, &map);
|
|
|
|
// start displaying things
|
|
display_map(disp, &map, entities);
|
|
display_instructions(disp);
|
|
display_status(disp, &player);
|
|
display_message(disp, "");
|
|
|
|
int ch;
|
|
bool done = false;
|
|
while (!done) {
|
|
enum action action = display_process_input();
|
|
done = game_update(disp, action, entities, &map);
|
|
display_map(disp, &map, entities);
|
|
}
|
|
|
|
free(map.map);
|
|
ht_destroy(entities);
|
|
display_destroy(disp);
|
|
|
|
endwin();
|
|
|
|
return 0;
|
|
}
|