/* Copyright 2008 Ido Yehieli This file is part of CryptRover. CryptRover is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CryptRover is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CryptRover. If not, see . */ #include #include #include #include "map.h" #include "utils.h" #include "entities.h" #include "items.h" #include "io.h" tile_t tile_m[Y_][X_]; int tile_color_m[Y_][X_]; view_t view_m[Y_][X_]; ent_t ent_l[ENTS_]; ent_t *ent_m[Y_][X_]; item_t item_l[ITEMS_]; item_t *item_m[Y_][X_]; void save_score(int level) { FILE *score_f = fopen("scores.dat", "a+"); fprintf(score_f, "Gold: %-4d Level: %-2d HP:%3d%% Air:%3d%% Battery:%3d%%\n", ent_l[0].coins,level,100*ent_l[0].hp/PLAYER_HP, 100*ent_l[0].air/PLAYER_AIR,100*ent_l[0].battery/PLAYER_BATTERY); fclose(score_f); } void end_game(int level){ save_score(level); show_highscore(); #ifdef __SDL__ Mix_CloseAudio(); SDL_Quit(); #endif exit(end_curses()); } void you_won(int level) { mvaddstr(LINES/2-1,COLS/2-9," YOU HAVE WON! :) "); readchar(); end_game(level); } void you_lost(int level) { #ifdef __SDL__ Mix_PlayChannel(-1, Mix_LoadWAV("media/grunt.wav"), 0); #endif mvaddstr(LINES/2-1,COLS/2-9," YOU HAVE LOST! :( "); readchar(); end_game(level); } bool player_action(int key,int *y,int *x, int *level) { switch (key) { case 'k'://up case 'w': case '8': return move_to(y,x,-1,0); case 'j'://down case 'x': case '2': return move_to(y,x,1,0); case 'h'://left case 'a': case '4': return move_to(y,x,0,-1); case 'l'://right case 'd': case '6': return move_to(y,x,0,1); case 'y'://upper left case 'q': case '7': return move_to(y,x,-1,-1); case 'u'://upper right case 'e': case '9': return move_to(y,x,-1,1); case 'b'://lower left case 'z': case '1': return move_to(y,x,1,-1); case 'n'://lower right case 'c': case '3': return move_to(y,x,1,1); case '.'://wait case 's': case '5': return true; case 'f'://flip flashlight on and off ent_l[0].light_on=ent_l[0].light_on?0:1; return true; case '<'://next level case ',': if (NEXT_LEVEL==tile_m[*y][*x].type) { if (++(*level)>LAST_LEVEL) you_won(*level); init_map(); init_ents(*level); init_items(); return true; } else return false; case ESC: case CTRL_C: you_lost(*level); case '?': refresh(); show_help(); return false; default: return false; } } int main(int argc, char *argv[]) { //initialization srand((unsigned)time(NULL)); int error_lines=init_curses(); #ifdef __SDL__ SDL_Init(SDL_INIT_AUDIO); int audio_rate = 22050; Uint16 audio_format = AUDIO_S16; int audio_channels = 2; int audio_buffers = 4096; if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)) { mvaddstr(error_lines++,X_+1,"Unable to open audio"); } Mix_Music *music = Mix_LoadMUS("media/A_Nightmare_On_Elm_Street.ogg"); Mix_PlayMusic(music, -1); Mix_Chunk *alert = Mix_LoadWAV("media/alert.wav"); #endif //current dungeon level int level=1; init_map(); init_ents(level); init_items(); //the player and their coordinates ent_t *pl=&ent_l[0]; int *y=&(pl->y); int *x=&(pl->x); //draw start conditions fov(*y,*x, FOV_RADIUS); draw_screen(); //message window int info_lines=print_info(error_lines,level); refresh(); init_message_win(info_lines); //help window show_help(); unsigned int turn=0; bool lost=false; while (!lost) { turn++; //acting on player's input while (!player_action(readchar(),y,x,&level)); //use unused item if the player is standing on one use_item(pl); //move living enemies in the player's direction for (int e=1;e0 && ent_l[e].speed && turn%ent_l[e].speed) move_enemy(&ent_l[e],pl); if (pl->hp<1) { lost=true; break; } } //mark last turn's field of view as SEEN for (int yy=0;yybattery>0 && pl->light_on) pl->battery--; //decrease air if (--pl->air<1) { add_message("You suffocate!",C_AIR|A_STANDOUT); lost=true; } else if (pl->air<=AIR_CHARGE && (100*pl->air/PLAYER_AIR)%5==0) { #ifdef __SDL__ Mix_PlayChannel(-1, alert, 0); #endif add_message("DANGER - LOW AIR SUPPLY.",C_AIR|A_BOLD); } //mark current field of view as IN_SIGHT fov(*y,*x, FOV_RADIUS); //draw screen draw_screen(); print_info(error_lines,level); } you_lost(level); }