Map objects rendered and correctly used.

This commit is contained in:
2014-03-08 18:09:39 -04:30
parent 2aacbd98b9
commit 4f04317f00
5 changed files with 737 additions and 569 deletions

View File

@@ -6,13 +6,7 @@
#ifndef STATE_CONSTS_H
#define STATE_CONSTS_H
#if defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__)
#define F_SEP "\\"
#elif defined(__linux__) || defined(__GNUC__)
#define F_SEP "/"
#else
#error "Unrecognized system."
#endif
enum COLORS {
BAR_COLOR = 1,

View File

@@ -12,6 +12,13 @@
#include "in_game.h"
#include "map.h"
#define MAX_KEYS 15
static const char *keyMsg = "You picked up a key.";
static const char *saysMsg = " says: ";
static const char *openDoor = "The door opens.";
static const char *doorLock = "This door is locked.";
typedef struct PLAYER {
unsigned short x;
unsigned short y;
@@ -22,12 +29,16 @@ static bool **seen;
static bool ** wmap;
static bool w_mov = FALSE;
static bool uK, dK, lK, rK;
static clock_t then;
static clock_t then, msgThen;
static player_t player;
static map_cell_t ** map;
game_obj_t objs[MAX_OBJECTS];
static game_obj_t objs[MAX_OBJECTS];
static int mW, mH, nO;
fov_settings_type fov_settings;
static fov_settings_type fov_settings;
static int keys[MAX_KEYS];
static int freeKey;
static char msg[128];
static bool newMsg = FALSE;
void input();
gsname_t update();
@@ -35,9 +46,12 @@ void render(int, int);
void drawGui(int, int);
void setPlayerStart();
void initObjects();
void initKeys();
void drawNeon(int, int, floor_t);
void apply(void *, int, int, int, int, void *);
bool opaque(void *, int, int);
void loadMap(const char *);
bool canMoveTo(int, int);
void initInGameState( gs_t * gs) {
int i, j;
@@ -72,21 +86,7 @@ void initInGameState( gs_t * gs) {
}
initObjects();
errcode_t rc = readMapData("map_file.map", &map, &mW, &mH);
if(rc != NO_ERROR){
fprintf(stderr, "\t%s: readMapData() returned %d\n", __FILE__, rc);
exit(rc);
}
game_obj_t * objsP = objs;
rc = readMapObjects("map_file.map", &objsP, &nO);
if(rc != NO_ERROR){
fprintf(stderr, "\t%s: readMapObjects() returned %d\n", __FILE__, rc);
exit(rc);
}
setPlayerStart();
loadMap("map_file.map");
fov_settings_init(&fov_settings);
fov_settings_set_opacity_test_function(&fov_settings, opaque);
@@ -99,7 +99,6 @@ void input(){
key = getch();
if(key != ERR){
fprintf(stderr, "\t%s: Caught keycode %d\n", __FILE__, key);
if(key == KEY_UP) uK = TRUE;
if(key == KEY_DOWN) dK = TRUE;
if(key == KEY_LEFT) lK = TRUE;
@@ -108,32 +107,133 @@ void input(){
}
gsname_t update(){
int iX, iY;
clock_t msgNow, delta;
int i, j, k, d, iX, iY, nX, nY;
iX = player.x;
iY = player.y;
nX = iX;
nY = iY;
if(uK) nY = iY - 1 < 0 ? mH - 1 : iY - 1;
if(dK) nY = (iY + 1) % mH;
if(lK) nX = iX - 1 < 0 ? mW - 1 : iX - 1;
if(rK) nX = (iX + 1) % mW;
/* Find if the player is standing on an exit, then load the next map. */
for(i = 0; i < nO; i++){
if(objs[i].type == EXIT){
if(objs[i].x == iY && objs[i].y == iX){
player.x = objs[i].eX;
player.y = objs[i].eY;
loadMap(objs[i].target);
return IN_GAME;
}
}
}
/* TODO: use keys.*/
for(i = 0; i < nO; i++){
if(objs[i].type == KEY){
if(objs[i].x == iY && objs[i].y == iX){
keys[freeKey] = objs[i].id;
objs[i].type = NONE;
for(j = 0; keyMsg[j] && j < 128; j++){
msg[j] = keyMsg[j];
}
newMsg = TRUE;
msgThen = clock();
}
}
}
/* Listen to a person. */
for(i = 0; i < nO; i++){
if(objs[i].type == PERSON){
if(objs[i].x == nY && objs[i].y == nX){
for(k = 0; k < nO; k++)
if(objs[k].type == DIALOG && objs[k].id == objs[i].dId) break;
for(j = 0; objs[i].name[j] && j < 128; j++)
msg[j] = objs[i].name[j];
for(d = 0; saysMsg[d] && j < 128; j++, d++)
msg[j] = saysMsg[d];
for(d = 0; objs[k].dialog[d] && j < 128; j++, d++)
msg[j] = objs[k].dialog[d];
newMsg = TRUE;
msgThen = clock();
}
}
}
for(i = 0; i < nO; i++){
if(objs[i].type == DOOR){
if(objs[i].x == nY && objs[i].y == nX){
if(!objs[i].unlocked){
for(j = 0; j < MAX_KEYS; j++){
if(keys[j] == objs[i].id){
objs[i].unlocked = 1;
break;
}
}
if(objs[i].unlocked){
for(j = 0; openDoor[j] && j < 128; j++){
msg[j] = openDoor[j];
}
}else{
for(j = 0; doorLock[j] && j < 128; j++){
msg[j] = doorLock[j];
}
}
newMsg = TRUE;
msgThen = clock();
}
}
}
}
if(newMsg){
msgNow = clock();
delta = msgNow - msgThen;
if((int)delta / (int)CLOCKS_PER_SEC >= 4){
msgThen = msgNow;
for(j = 0; j < 128; j++){
msg[j] = '\0';
}
newMsg = FALSE;
}
}
/* Move the player. */
if(uK){
iY = iY - 1 < 0 ? mH - 1 : iY - 1;
if((map[iY][iX].f > WINDOW_WALL && map[iY][iX].f <= WATER) || map[iY][iX].f == SECRET_WALL) player.y = iY;
if(canMoveTo(iY, iX)) player.y = iY;
uK = FALSE;
}
if(dK){
iY = (iY + 1) % mH;
if((map[iY][iX].f > WINDOW_WALL && map[iY][iX].f <= WATER) || map[iY][iX].f == SECRET_WALL) player.y = iY;
if(canMoveTo(iY, iX)) player.y = iY;
dK = FALSE;
}
if(lK){
iX = iX - 1 < 0 ? mW - 1 : iX - 1;
if((map[iY][iX].f > WINDOW_WALL && map[iY][iX].f <= WATER) || map[iY][iX].f == SECRET_WALL) player.x = iX;
if(canMoveTo(iY, iX)) player.x = iX;
lK = FALSE;
}
if(rK){
iX = (iX + 1) % mW;
if((map[iY][iX].f > WINDOW_WALL && map[iY][iX].f <= WATER) || map[iY][iX].f == SECRET_WALL) player.x = iX;
if(canMoveTo(iY, iX)) player.x = iX;
rK = FALSE;
}
@@ -142,7 +242,7 @@ gsname_t update(){
void render(int w, int h){
clock_t now, delta;
int i, j, pi, pj, ioff, joff, di, dj;
int i, j, k, pi, pj, ioff, joff, di, dj;
now = clock();
delta = now - then;
@@ -151,16 +251,16 @@ void render(int w, int h){
w_mov = TRUE;
}
pi = (((w - 1) - 27) / 2) + 27;
pj = (h - 2) / 2 + 1;
pi = (((w - 1) - 1) / 2) + 1;
pj = (h - 3) / 2 + 1;
ioff = (w - 28) / 2;
joff = (h - 2) / 2;
ioff = (w - 28 - 27) / 2;
joff = (h - 3) / 2;
fov_circle(&fov_settings, &map, NULL, player.x, player.y, (MAX_MAP_SIZE / 2) - 1);
for(i = 27; i < w - 1; i++){
for(j = 1; j < h - 1; j++){
for(i = 1; i < w - 1; i++){
for(j = 1; j < h - 3; j++){
move(j, i);
di = i - 27 + player.x - ioff;
@@ -226,6 +326,23 @@ void render(int w, int h){
drawNeon(dj, di, BAR);
break;
}
move(j, i);
for(k = 0; k < nO; k++){
if(objs[k].x == dj && objs[k].y == di){
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
else attron(COLOR_PAIR(MN_COLOR));
if(objs[k].type == DOOR){
printw("\u25D9");
}else if(objs[k].type == KEY){
printw("k");
}else if(objs[k].type == PERSON){
printw("\u263A");
}
}
}
}else{
attron(COLOR_PAIR(MN_COLOR));
printw(" ");
@@ -323,50 +440,52 @@ void drawNeon(int i, int j, floor_t floor){
}
void drawGui(int w, int h){
int i, j;
int i;
attron(COLOR_PAIR(BSC_COLOR));
/* Clear the gui space. */
for(i = 1; i < 26; i++){
for(j = 1; j < h - 1; j++){
move(j, i);
for(i = 1; i < w - 1; i++){
move(h - 2, i);
printw(" ");
}
}
/* Upper horizontal bar. */
move(0, 0);
printw("\u2554");
for(i = 0; i < w - 2; i++){
if(i != 25){
printw("\u2550");
}else{
printw("\u2566");
}
}
printw("\u2557");
/* Lower horizontal bar. */
/* Lower horizontal bars. */
move(h - 3, 0);
printw("\u255A");
for(i = 0; i < w - 2; i++){
printw("\u2550");
}
printw("\u255D");
move(h - 1, 0);
printw("\u255A");
for(i = 0; i < w - 2; i++){
if(i != 25){
printw("\u2550");
}else{
printw("\u2569");
}
}
printw("\u255D");
/* Vertical bars. */
for(i = 1; i < h - 1; i++){
move(i, 0);
printw("\u2551");
move(i, 26);
printw("\u2551");
if(i != h - 3) printw("\u2551");
else printw("\u2560");
move(i, w-1);
printw("\u2551");
if(i != h - 3) printw("\u2551");
else printw("\u2563");
}
move(h - 2, 1);
for(i = 0; msg[i] && i < w - 2; i++){
printw("%c", msg[i]);
}
}
@@ -402,6 +521,15 @@ void initObjects(){
}
}
void initKeys(){
int i;
freeKey = 0;
for(i = 0; i < MAX_KEYS; ++i){
keys[i] = -1;
}
}
void apply(void *map, int x, int y, int dx, int dy, void *src){
if(x < 0 || x >= MAX_MAP_SIZE) return;
if(y < 0 || y >= MAX_MAP_SIZE) return;
@@ -411,12 +539,68 @@ void apply(void *map, int x, int y, int dx, int dy, void *src){
}
bool opaque(void *m, int x, int y){
int k;
if(x < 0 || x >= MAX_MAP_SIZE) return FALSE;
if(y < 0 || y >= MAX_MAP_SIZE) return FALSE;
if(map[y][x].f == SOLID_WALL || map[y][x].f == SECRET_WALL){
return TRUE;
}else{
for(k = 0; k < nO; k++){
if(objs[k].type == DOOR){
if(objs[k].x == y && objs[k].y == x){
return TRUE;
}
}
}
return FALSE;
}
}
void loadMap(const char * file){
int i, j;
errcode_t rc = readMapData(file, &map, &mW, &mH);
if(rc != NO_ERROR){
fprintf(stderr, "\t%s.loadMap(): readMapData() returned %d\n", __FILE__, rc);
exit(rc);
}
game_obj_t * objsP = objs;
rc = readMapObjects(file, &objsP, &nO);
if(rc != NO_ERROR){
fprintf(stderr, "\t%s.loadMap(): readMapObjects() returned %d\n", __FILE__, rc);
exit(rc);
}
setPlayerStart();
initKeys();
for ( i = 0; i < MAX_MAP_SIZE; ++i ) {
for(j = 0; j < MAX_MAP_SIZE; ++j){
vis[i][j] = FALSE;
seen[i][j] = FALSE;
}
}
}
bool canMoveTo(int iY, int iX){
int k;
for(k = 0; k < nO; k++){
if(objs[k].x == iY && objs[k].y == iX){
if(objs[k].type == DOOR){
if(objs[k].unlocked) return TRUE;
else return FALSE;
}else if(objs[k].type == PERSON){
return FALSE;
}
}
}
if((map[iY][iX].f > WINDOW_WALL && map[iY][iX].f <= WATER) || map[iY][iX].f == SECRET_WALL)
return TRUE;
else
return FALSE;
}

View File

@@ -28,13 +28,7 @@ static bool resize = FALSE;
int main() {
bool finished = FALSE;
#if defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__)
char * home_dir = getenv("APPDATA");
#elif defined(__linux__) || defined(__GNUC__)
char * home_dir = getenv("HOME");
#else
#error "Unrecognized system."
#endif
FILE * f; /* To avoid a warning. */
clock_t then, now, delta;
unsigned int fps = 0, pfps = 0;
@@ -70,15 +64,11 @@ int main() {
fprintf(stderr, "%s", asctime(current_date));
/* Try to create the data directory with permissions 775. */
if(mkdir(data_dir, S_IRWXU | S_IWGRP | S_IRGRP| S_IROTH | S_IXOTH) == 0){
/* The data directory was sucessfully created. */
}else{
if(mkdir(data_dir, S_IRWXU | S_IWGRP | S_IRGRP| S_IROTH | S_IXOTH) != 0){
if(errno != EEXIST){
/* The directory does not exists and could not be created. */
perror("\t" __FILE__);
fprintf(stderr, "\tdata_dir is: %s\n", data_dir);
}else{
/* The directory already exits. */
}
}
}else{