#include #include #include #include #include "defs.h" #include "lf.h" #include "map.h" #include "move.h" #include "nexus.h" #include "objects.h" #include "save.h" extern lifeform_t *player; extern map_t *firstmap; int loadall(void) { DIR *dir; struct dirent *ent; char *filename; FILE *f; dir = opendir(MAPDIR); if (!dir) { dblog("Could not open map directory '%s'",MAPDIR); return B_TRUE; } // for each map file in directory while ((ent = readdir(dir)) != NULL) { char *p; // ie. start of 4 char prefix p = ent->d_name + strlen(ent->d_name) - 4; // load this map if (!strcmp(p, ".map") ) { if (!loadmap(ent->d_name)) { printf("Error loading map from file '%s'",ent->d_name); exit(1); } } } closedir(dir); loadsavegame(); return B_FALSE; } // load and allocate one lifeform from given file lifeform_t *loadlf(FILE *f, cell_t *where) { lifeform_t *l; int lfid, lfraceid; long obid; int rv; int i; char buf[BUFLEN]; int obcount; int mapid; map_t *m; int x,y; int db = B_TRUE; if (db) dblog("--> Loading lifeform...\n"); fscanf(f, "startlf\n"); fscanf(f, "lfid: %d\n",&lfid); fscanf(f, "race: %d\n",&lfraceid); fscanf(f, "map: %d\n",&mapid); fscanf(f, "pos: %d,%d\n",&x, &y); // find the map m = findmap(mapid); if (!m) { dblog("ERROR loading lf id %d: can't find map id %d\n",lfid,mapid); exit(1); } if (where == NULL) { where = getcellat(m, x, y); } if (!m) { dblog("ERROR loading lf id %d: can't find cell at %d,%d on map id %d\n",lfid,x,y,mapid); exit(1); } l = addlf(where, lfraceid); l->id = lfid; l->x = x; l->y = y; // load rest of this lf fscanf(f, "contr: %d\n",&l->controller); fscanf(f, "hp: %d/%d\n",&l->hp, &l->maxhp); fscanf(f, "alive: %d\n",&l->alive); fgets(buf, BUFLEN, f); // lastdam buf[strlen(buf)-1] = '\0'; // strip newline l->lastdam = strdup(buf + 9); // after 'lastdam: ' fscanf(f, "timespent: %d\n",&l->timespent); fscanf(f, "sorted: %d\n",&l->sorted); if (db) dblog("--> Got hp=%d/%d. timespend=%d. sorted=%d. Now loading ob list.",l->hp,l->maxhp,l->timespent,l->sorted); // load object list obcount = 0; obid = 9999; // for testing rv = fscanf(f, "ob:%ld\n",&obid); while (obid != -1) { if (db) dblog("--> Load ob id %d into list...",obid); l->pack->oblist[obcount] = obid; obcount++; fscanf(f, "ob:%ld\n",&obid); } // terminate with -1s! for (i = obcount ; i < MAXPILEOBS; i++) { l->pack->oblist[i] = -1; } if (db) dblog("--> Finished oblist. Found %d objects.",obcount); // now load load object defs! fscanf(f, "obdefs\n"); for (i = 0; i < obcount; i++) { //if (db) dblog("-----> ob %d/%d...\n",i+1,obcount); if (loadob(f, l->pack)) { dblog("Error - can't create object %d/%d!\n",i+1,obcount); exit(1); } } // is this the player? if (l->controller == C_PLAYER) { player = l; } } map_t *loadmap(char *basefile) { FILE *f; char filename[BUFLEN]; char buf[BUFLEN]; char buf2[BUFLEN]; int obcount; int i; int x,y; int db = B_TRUE; lifeform_t *l; object_t *o,*nexto; map_t *m; cell_t *dummycell; if (db) dblog("Loading map from %s...",basefile); sprintf(filename, "%s/%s",MAPDIR,basefile); f = fopen(filename, "rt"); // create map m = addmap(); dummycell = malloc(sizeof(cell_t)); dummycell->obpile = addobpile(NULL, dummycell); dummycell->map = m; dummycell->type = (celltype_t *)0xabcde; // for debugging if (!m) { dblog("Error creating map while loading file '%s'",filename); return NULL; } // load map info if (db) dblog("--> Loading map info...\n"); fscanf(f, "id:%d\n",&m->id); // map id fgets(buf, BUFLEN, f); // map name buf[strlen(buf)-1] = '\0'; // strip newline m->name = strdup(buf + 5); // after 'name:' fscanf(f, "habitat:%d\n",(int *)&m->habitat); // habitat fscanf(f, "seed:%d\n",&m->seed); // seed fscanf(f, "dims:%d,%d\n",&m->w, &m->h); // map dimensons fscanf(f, "nextlfid:%ld\n",&m->nextlfid); fscanf(f, "nextmaps:\n"); for (i = 0; i < MAXDIR_ORTH; i++) { fscanf(f, "%d\n",&m->nextmap[i]); // map dimensons } if (db) dblog("--> Finished map info. name='%s', dims=%d x %d\n",m->name, m->w, m->h); fscanf(f, "id:%d\n",&m->id); // map id // load lifeforms if (db) dblog("--> Loading lifeforms...\n"); fscanf(f, "lifeforms:\n"); fscanf(f, "%s\n",buf); while (!strcmp(buf ,"startlf")) { loadlf(f, dummycell); // check for more lifeforms... fscanf(f, "%s\n",buf); } // load cells if (db) dblog("--> Loading map cells...\n"); fscanf(f, "cells:\n"); for (y = 0; y < m->h; y++) { for (x = 0; x < m->w; x++) { cell_t *c; celltype_t *ct; int celltypeid; long obid; //if (db) dblog("cell %d,%d...",x,y); // allocate this cell c = addcell(m, x, y); /* c = m->cell[y * m->w + x]; c->map = m; c->obpile = addobpile(NULL, c); c->lf = NULL; c->x = x; c->y = y; c->roomid = -1; */ // cell info fscanf(f, "%d,%d,%d,%d\n", &c->roomid, &celltypeid, &c->known, &c->visited); ct = findcelltype(celltypeid); if (ct) { c->type = ct; } else { dblog("ERROR loading map cells - can't find celltype id %ld\n",celltypeid); exit(1); } // cell objects obcount = 0; fscanf(f, "ob:%ld\n",&obid); while (obid != -1) { c->obpile->oblist[obcount] = obid; obcount++; fscanf(f, "ob:%ld\n",&obid); } // terminate with -1s! for (i = obcount ; i < MAXPILEOBS; i++) { c->obpile->oblist[i] = -1; } } } // load object definitions if (db) dblog("--> Loading object definitions for map obs...\n"); fscanf(f, "MAPOBS:%d\n",&obcount); // how many obs? // create all objects in a dummy cell for (i = 0; i < obcount; i++) { if (db) dblog("-----> ob %d/%d...\n",i+1,obcount); if (loadob(f, dummycell->obpile)) { dblog("Error - can't create object %d/%d!\n",i+1,obcount); exit(1); } } // hand out the objects to lifeforms... for (l = m->lf ; l ; l = l->next) { int curob = 0; long obid; obid = l->pack->oblist[curob]; while (obid != -1) { int found = B_FALSE; // find this ob id in the dummycell for (o = dummycell->obpile->first ; o ; o = nexto) { nexto = o->next; if (o->id == obid) { relinkob(o, l->pack); found = B_TRUE; break; } } if (!found) { dblog("Error loading obs - lf %d should have obid %ld but can't find it.\n",l->id, obid); exit(1); } // next one curob++; obid = l->pack->oblist[curob]; } // clear the oblist for (i = 0; i < MAXPILEOBS; i++) { l->pack->oblist[i] = -1; } } // hand out objects to cells for (y = 0; y < m->h; y++) { for (x = 0; x < m->w; x++) { cell_t *c; long obid; int curob = 0; c = m->cell[y * m->w + x]; obid = c->obpile->oblist[curob]; while (obid != -1) { int found = B_FALSE; // find this ob id in the dummycell for (o = dummycell->obpile->first ; o ; o = nexto) { nexto = o->next; if (o->id == obid) { relinkob(o, c->obpile); found = B_TRUE; break; } } if (!found) { dblog("Error loading obs - cell %d,%d should have obid %ld but can't find it.\n",x,y, obid); exit(1); } // next one curob++; } // clear the oblist for (i = 0; i < MAXPILEOBS; i++) { c->obpile->oblist[i] = -1; } } } fclose(f); // move lifeforms to their proper locations for (l = m->lf ; l ; l = l->next) { cell_t *c; c = getcellat(m, l->x, l->y); if (!c) { dblog("Error loading map - Can't find cell at %d,%d to place lifeform id %d.\n", l->x, l->y, l->id); exit(1); } movelf(l, c); //dblog("Moving lf %d to %d,%d\n",l->id, l->x, l->y); } free(dummycell); return m; } int loadob(FILE *f, obpile_t *op) { objecttype_t *ot; object_t *o; material_t *mat; long obid; int otid,matid; char buf[BUFLEN]; int flagid; flag_t tempflag; int rv; fscanf(f, "id:%ld\n",&obid); fscanf(f, "type:%d\n",&otid); ot = findot(otid); if (!ot) { dblog("ERROR loading objects - can't find obtype id %ld\n",obid); return B_TRUE; } // create the object o = addob(op, ot->name); // overwrite ob parameters o->id = obid; fscanf(f, "material:%d\n",&matid); mat = findmaterial(matid); if (!mat) { dblog("ERROR loading objects - can't find material %d\n",matid); return B_TRUE; } o->material = mat; fscanf(f, "weight:%f\n",&o->weight); fgets(buf, BUFLEN, f); // inscription buf[strlen(buf)-1] = '\0'; // strip newline o->inscription = strdup(buf + 6); // after 'inscr:' if (!strcmp(o->inscription, "^^^")) { // ie. if equal to ^^^... free(o->inscription); o->inscription = NULL; } fscanf(f, "letter:%c\n",&o->letter); fscanf(f, "bless:%d\n",&o->blessed); fscanf(f, "blessknown:%d\n",&o->blessknown); fscanf(f, "amt:%d\n",&o->amt); fscanf(f, "flags:\n"); rv = fscanf(f, "%d,%d,%d,%d,%d\n", &tempflag.id, &tempflag.nvals, &tempflag.val[0], &tempflag.val[1], &tempflag.val[2]); // get flag text fgets(buf, BUFLEN, f); buf[strlen(buf)-1] = '\0'; // strip newline while (tempflag.id != -1) { dblog("got flag id=%d\n",tempflag.id); addflag(o->flags, tempflag.id, tempflag.val[0], tempflag.val[1], tempflag.val[2], strcmp(buf, "^^^") ? buf : NULL); // load next one rv = fscanf(f, "%d,%d,%d,%d,%d\n", &tempflag.id, &tempflag.nvals, &tempflag.val[0], &tempflag.val[1], &tempflag.val[2]); //dblog("fscanf returned %d\n",rv); } fscanf(f, "endob\n"); return B_FALSE; } int loadsavegame(void) { DIR *dir; struct dirent *ent; char filename[BUFLEN]; FILE *f; // now see if there is a savegame... dir = opendir(SAVEDIR); if (!dir) { dblog("Could not open savegame directory '%s'",SAVEDIR); return B_TRUE; } ent = readdir(dir); while ((ent = readdir(dir)) != NULL) { char *p; // ie. start of 4 char prefix p = ent->d_name + strlen(ent->d_name) - 4; // load this savegame if (!strcmp(p, ".sav") ) { sprintf(filename, "%s/%s",SAVEDIR,ent->d_name); dblog("Trying to load from %s\n",filename); f = fopen(filename, "rt"); if (!f) { printf("Error opening savegame file '%s'",ent->d_name); exit(1); } if (!loadlf(f, NULL)) { printf("Error loading savegame from file '%s'",ent->d_name); exit(1); } fclose(f); // successful load - kill the savegame now unlink(filename); break; } } closedir(dir); return B_FALSE; } int savelf(FILE *f, lifeform_t *l) { object_t *o; int obcount = 0; // save this lf fprintf(f, "startlf\n"); fprintf(f, "lfid: %d\n",l->id); fprintf(f, "race: %d\n",l->race->id); fprintf(f, "map: %d\n",l->cell->map->id); fprintf(f, "pos: %d,%d\n",l->cell->x, l->cell->y); fprintf(f, "contr: %d\n",l->controller); fprintf(f, "hp: %d/%d\n",l->hp, l->maxhp); fprintf(f, "alive: %d\n",l->alive); fprintf(f, "lastdam: %s\n",l->lastdam); fprintf(f, "timespent: %d\n",l->timespent); fprintf(f, "sorted: %d\n",l->sorted); // lifeform objects obcount = 0; for (o = l->pack->first ; o ; o = o->next) { fprintf(f, "ob:%ld\n",o->id); obcount++; } fprintf(f, "ob:-1\n"); fprintf(f, "obdefs\n"); // now save our object definitions for (o = l->pack->first ; o ; o = o->next) { saveob(f, o); } return B_FALSE; } int savemap(map_t *m) { FILE *f; char filename[BUFLEN]; int i; object_t *o; lifeform_t *l; int x,y; int obcount = 0; // TODO: check that map dir exists sprintf(filename, "%s/map%d.map",MAPDIR, m->id); f = fopen(filename, "wt"); // save map info fprintf(f, "id:%d\n",m->id); // map id fprintf(f, "name:%s\n",m->name); // map name fprintf(f, "habitat:%d\n",m->habitat); // habitat fprintf(f, "seed:%d\n",m->seed); // seed fprintf(f, "dims:%d,%d\n",m->w, m->h); // map dimensons fprintf(f, "nextlfid:%ld\n",m->nextlfid); fprintf(f, "nextmaps:\n"); for (i = 0; i < MAXDIR_ORTH; i++) { fprintf(f, "%d\n",m->nextmap[i] ); // map dimensons } // save all non-player lifeforms (includes their objects) fprintf(f, "lifeforms:\n"); for (l = m->lf ; l ; l = l->next) { if (l->controller != C_PLAYER) { // don't save the player! savelf(f, l); } } fprintf(f, "endlifeforms\n"); // cells fprintf(f, "cells:\n"); for (y = 0; y < m->h; y++) { for (x = 0; x < m->w; x++) { cell_t *c; c = getcellat(m, x, y); // cell info fprintf(f, "%d,%d,%d,%d\n", c->roomid, c->type->id, c->known, c->visited); // cell objects for (o = c->obpile->first ; o ; o = o->next) { fprintf(f, "ob:%ld\n",o->id); obcount++; } fprintf(f, "ob:-1\n"); } } // save object definitions from map cells fprintf(f, "MAPOBS:%d\n",obcount); for (y = 0; y < m->h; y++) { for (x = 0; x < m->w; x++) { cell_t *c; c = getcellat(m, x, y); // cell objects for (o = c->obpile->first ; o ; o = o->next) { saveob(f, o); } } } fclose(f); return B_FALSE; } int saveob(FILE *f, object_t *o) { flag_t *fl; fprintf(f, "id:%ld\n",o->id); fprintf(f, "type:%d\n",o->type->id); fprintf(f, "material:%d\n",o->material->id); fprintf(f, "weight:%f\n",o->weight); fprintf(f, "inscr:%s\n",o->inscription ? o->inscription : "^^^"); fprintf(f, "letter:%c\n",o->letter); fprintf(f, "bless:%d\n",o->blessed); fprintf(f, "blessknown:%d\n",o->blessknown); fprintf(f, "amt:%d\n",o->amt); fprintf(f, "flags:\n"); for (fl = o->flags->first ; fl ; fl = fl->next) { fprintf(f, "%d,%d,%d,%d,%d\n", fl->id, fl->nvals, fl->val[0], fl->val[1], fl->val[2]); if (!fl->text || !strcmp(fl->text, "")) { fprintf(f, "%s\n","^^^"); } else { fprintf(f, "%s\n",fl->text); } } fprintf(f, "-1,-1,-1,-1,-1\n"); fprintf(f, "endob\n"); return B_FALSE; }