#include #include #include #include #include "io.h" #include "lf.h" #include "map.h" #include "nexus.h" #include "objects.h" #include "save.h" material_t *material = NULL,*lastmaterial = NULL; objectclass_t *objectclass = NULL,*lastobjectclass = NULL; objecttype_t *objecttype = NULL,*lastobjecttype = NULL; celltype_t *firstcelltype = NULL,*lastcelltype = NULL; race_t *firstrace = NULL,*lastrace = NULL; map_t *firstmap = NULL,*lastmap = NULL; FILE *logfile; enum ERROR reason; // global for returning errors lifeform_t *player = NULL; int gameover; int gamestarted = B_FALSE; int main(char **argv, int argc) { int newworld = B_FALSE; atexit(cleanup); // init params init(); // load whatever maps are available loadall(); // init graphics initgfx(); // if no maps, make the initial level if (!firstmap) { newworld = B_TRUE; addmap(); createmap(firstmap, H_DUNGEON); } // if no player, add them if (!player) { msg("Welcome to %snexus!", newworld ? "the new " : ""); more(); player = addlf(getrandomcelloftype(firstmap, CT_ROOM), R_HUMAN); player->controller = C_PLAYER; outfitlf(player); addlf(getcellindir(player->cell, D_N), R_BAT); } else { msg("Welcome back!"); more(); } // start game - this will cause debug messages to now // go to the log file instead of stdout. gamestarted = B_TRUE; // show level drawscreen(); // MAIN LOOP gameover = B_FALSE; while (!gameover) { // someone has a turn donextturn(player->cell->map); // update lifeform structue to figure out who goes next sortlf(player->cell->map); // TODO: monsters move etc // check for death etc doeffects(); // show level drawscreen(); // check end of game checkendgame(); } // print tombstone tombstone(player); } celltype_t *addcelltype(int id, char glyph, int solid, int transparent) { celltype_t *a; // add to the end of the list if (firstcelltype == NULL) { firstcelltype = malloc(sizeof(celltype_t)); a = firstcelltype; a->prev = NULL; } else { // go to end of list a = lastcelltype; a->next = malloc(sizeof(celltype_t)); a->next->prev = a; a = a->next; } lastcelltype = a; a->next = NULL; // set props a->id = id; a->glyph = glyph; a->solid = solid; a->transparent = transparent; } void checkendgame(void) { if (!player->alive) { gameover = B_TRUE; } } void cleanup(void) { fclose(logfile); cleanupgfx(); } void doeffects(void) { lifeform_t *lf; // check for death for (lf = player->cell->map->lf; lf ; lf = lf->next) { if (lf->hp <= 0) { // die! die(lf); } } } void donextturn(map_t *map) { lifeform_t *who; // show messages to plaeyr drawmsg(); who = map->lf; if (who->controller == C_PLAYER) { drawcursor(); // find out what player wants to do handleinput(); } else { // TODO: do ai move aimove(who); } // everyone else's time goes down by 1 for (who = map->lf->next ; who ; who = who->next ){ if (who->timespent > 0) who->timespent--; } } celltype_t *findcelltype(int id) { celltype_t *ct; for (ct = firstcelltype; ct ; ct = ct->next) { if (ct->id == id) { return ct; } } return NULL; } char *getdirname(int dir) { switch (dir) { case D_N: return "North"; case D_E: return "East"; case D_S: return "South"; case D_W: return "West"; case D_UNKNOWN: return "D_UNKNOWN"; case D_NONE: return "D_NONE"; } return "?errordir?"; } int init(void) { // random numbers srand(time(NULL)); // open log file logfile = fopen("log.txt","wt"); fprintf(logfile, "\n\n\n====== NEW LOGFILE ====\n"); // cell types addcelltype(CT_WALL, '#', B_SOLID, B_OPAQUE); addcelltype(CT_ROOMWALL, '#', B_SOLID, B_OPAQUE); addcelltype(CT_CORRIDOR, '.', B_EMPTY, B_TRANS); addcelltype(CT_LOOPCORRIDOR, 'L', B_EMPTY, B_TRANS); addcelltype(CT_ROOM, '.', B_EMPTY, B_TRANS); addcelltype(CT_DOOROPEN, '-', B_EMPTY, B_TRANS); addcelltype(CT_DOORCLOSED, '+', B_SOLID, B_OPAQUE); initobjects(); initrace(); return B_FALSE; } int isplayerturn(void) { if (player->cell->map->lf->controller == C_PLAYER) { return B_TRUE; } return B_FALSE; } // get a random number int rnd(int min, int max) { int res; res = (rand() % (max - min + 1)) + min; return res; } // sort map's lifeform list by time spent void sortlf(map_t *map) { int donesomething; lifeform_t *l; int adjustby; int db = B_FALSE; // bubblesort if (db) { dblog("BEFORE sortlf():"); for (l = map->lf ; l ; l = l->next) { dblog("- %s (timespent= %d) (sorted=%d)", (l == player) ? "player" : l->race->name, l->timespent,l->sorted); } } donesomething = B_TRUE; while (donesomething) { donesomething = B_FALSE; for (l = map->lf ; l ; l = l->next) { if (!l->sorted && l->next && (l->timespent > l->next->timespent) ) { lifeform_t *temp; // remember next element temp = l->next; // remove this element from list if (l->prev == NULL) { // first map->lf = l->next; } else { // not first l->prev->next = l->next; } // don't bother checking for next - we know ther eis one. l->next->prev = l->prev; // re-add element afterwards l->next = temp->next; l->prev = temp; temp->next = l; if (l->next == NULL) map->lastlf = l; donesomething = B_TRUE; } else { l->sorted = B_TRUE; } } } if (db) { dblog("AFTER SORT:"); for (l = map->lf ; l ; l = l->next) { dblog("- %s (timespent= %d) (sorted=%d)", (l == player) ? "player" : l->race->name, l->timespent,l->sorted); } } // now go through the list and make the first element be 0 adjustby = map->lf->timespent; for (l = map->lf ; l ; l = l->next) { l->timespent -= adjustby; l->sorted = B_FALSE; } }