/* Write a light source structure to disk. */ static void write_ls(struct memfile *mf, light_source * ls) { struct obj *otmp; struct monst *mtmp; long id; if ((ls->flags & LSF_NEEDS_FIXUP)) { id = *(int32_t *) ls->id; } else if (ls->type == LS_OBJECT) { otmp = (struct obj *)ls->id; id = otmp->o_id; } else if (ls->type == LS_MONSTER) { mtmp = (struct monst *)ls->id; id = mtmp->m_id; } else { impossible("write_ls: bad type (%d)", ls->type); id = 0; } mtag(mf, id * 2 + ls->type, MTAG_LIGHT); mwrite32(mf, ls->type); mwrite16(mf, ls->range); mwrite16(mf, ls->flags | LSF_NEEDS_FIXUP); mwrite32(mf, id); mwrite8(mf, ls->x); mwrite8(mf, ls->y); }
void savegame(struct memfile *mf) { int count = 0; xchar ltmp; store_version(mf); /* Place flags, player info & moves at the beginning of the save. * This makes it possible to read them in nh_get_savegame_status without * parsing all the dungeon and level data */ save_flags(mf); save_you(mf, &u); mwrite32(mf, moves); save_mon(mf, &youmonst); /* store dungeon layout */ save_dungeon(mf); savelevchn(mf); /* store levels */ for (ltmp = 1; ltmp <= maxledgerno(); ltmp++) if (levels[ltmp]) count++; mwrite32(mf, count); for (ltmp = 1; ltmp <= maxledgerno(); ltmp++) { if (!levels[ltmp]) continue; mwrite8(mf, ltmp); /* level number*/ savelev(mf, ltmp); /* actual level*/ } savegamestate(mf); }
void save_steal(struct memfile *mf) { mtag(mf, 0, MTAG_STEAL); mwrite32(mf, stealoid); mwrite32(mf, stealmid); }
/* Write a light source structure to disk. */ static void write_ls(struct memfile *mf, light_source *ls) { struct obj *otmp; struct monst *mtmp; mwrite32(mf, ls->type); mwrite16(mf, ls->range); if ((ls->flags & LSF_NEEDS_FIXUP)) { mwrite16(mf, ls->flags); mwrite32(mf, (*(int32_t*)ls->id)); } else if (ls->type == LS_OBJECT) { mwrite16(mf, ls->flags | LSF_NEEDS_FIXUP); otmp = (struct obj *)ls->id; mwrite32(mf, otmp->o_id); } else if (ls->type == LS_MONSTER) { mwrite16(mf, ls->flags | LSF_NEEDS_FIXUP); mtmp = (struct monst *)ls->id; mwrite32(mf, mtmp->m_id); } else impossible("write_ls: bad type (%d)", ls->type); mwrite8(mf, ls->x); mwrite8(mf, ls->y); }
void store_version(struct memfile *mf) { mtag(mf, 0, MTAG_VERSION); mwrite32(mf, VERSION_NUMBER); mwrite32(mf, VERSION_FEATURES); mwrite32(mf, VERSION_SANITY1); }
void save_oracles(struct memfile *mf) { int i; mtag(mf, 0, MTAG_ORACLES); mwrite32(mf, oracle_cnt); if (oracle_cnt) for (i = 0; i < oracle_cnt; i++) mwrite32(mf, oracle_loc[i]); }
static void savetrapchn(struct memfile *mf, struct trap *trap, struct level *lev) { struct trap *trap2; unsigned short tflags; int count = 0; mfmagic_set(mf, TRAPCHAIN_MAGIC); for (trap2 = trap; trap2; trap2 = trap2->ntrap) count++; mwrite32(mf, count); for (; trap; trap = trap->ntrap) { /* To distinguish traps from each other in tags, we use x/y/z coords */ mtag(mf, ledger_no(&lev->z) + ((int)trap->tx << 8) + ((int)trap->ty << 16), MTAG_TRAP); mwrite8(mf, trap->tx); mwrite8(mf, trap->ty); mwrite8(mf, trap->dst.dnum); mwrite8(mf, trap->dst.dlevel); mwrite8(mf, trap->launch.x); mwrite8(mf, trap->launch.y); tflags = (trap->ttyp << 11) | (trap->tseen << 10) | (trap->once << 9) | (trap->madeby_u << 8); mwrite16(mf, tflags); mwrite16(mf, trap->vl.v_launch_otyp); } }
static void savedamage(struct memfile *mf, struct level *lev) { struct damage *damageptr; unsigned int xl = 0; for (damageptr = lev->damagelist; damageptr; damageptr = damageptr->next) xl++; mwrite32(mf, xl); for (damageptr = lev->damagelist; damageptr; damageptr = damageptr->next) { mwrite32(mf, damageptr->when); mwrite32(mf, damageptr->cost); mwrite8(mf, damageptr->place.x); mwrite8(mf, damageptr->place.y); mwrite8(mf, damageptr->typ); } }
void save_obj(struct memfile *mf, struct obj *obj) { unsigned int oflags; oflags = (obj->cursed << 31) | (obj->blessed << 30) | (obj->unpaid << 29) | (obj->no_charge << 28) | (obj->known << 27) | (obj->dknown << 26) | (obj->bknown << 25) | (obj->rknown << 24) | (obj->oeroded << 22) | (obj->oeroded2 << 20) | (obj->oerodeproof << 19) | (obj->olocked << 18) | (obj->obroken << 17) | (obj->otrapped << 16) | (obj->recharged << 13) | (obj->lamplit << 12) | (obj->greased << 11) | (obj->oattached << 9) | (obj->in_use << 8) | (obj->was_thrown << 7) | (obj->bypass << 6); mfmagic_set(mf, OBJ_MAGIC); mwrite32(mf, obj->onamelth); mwrite32(mf, obj->o_id); mwrite32(mf, obj->owt); mwrite32(mf, obj->quan); mwrite32(mf, obj->corpsenm); mwrite32(mf, obj->oeaten); mwrite32(mf, obj->age); mwrite32(mf, obj->owornmask); mwrite32(mf, oflags); mwrite16(mf, obj->otyp); mwrite8(mf, obj->ox); mwrite8(mf, obj->oy); mwrite8(mf, obj->spe); mwrite8(mf, obj->oclass); mwrite8(mf, obj->invlet); mwrite8(mf, obj->oartifact); mwrite8(mf, obj->where); mwrite8(mf, obj->timed); /* no need to save the value of the cobj pointer, but we will need to know * if there is something in here that needs to be restored */ mwrite8(mf, obj->cobj ? 1 : 0); if (obj->onamelth) mwrite(mf, ONAME(obj), obj->onamelth); if (obj->oattached == OATTACHED_MONST) save_mon(mf, (struct monst*)obj->oextra); else if (obj->oattached == OATTACHED_M_ID) mwrite32(mf, *(unsigned int*)obj->oextra); }
void save_history(struct memfile *mf) { int i, len; mfmagic_set(mf, HISTORY_MAGIC); mtag(mf, 0, MTAG_HISTORY); mwrite32(mf, histcount); /* don't need tags for individual history events, because they're always added at the end of the list */ for (i = 0; i < histcount; i++) { mwrite32(mf, histevents[i].when); mwrite32(mf, histevents[i].hidden); len = strlen(histevents[i].what) + 1; mwrite32(mf, len); mwrite(mf, histevents[i].what, len); } }
static void save_quest_status(struct memfile *mf) { unsigned int qflags; qflags = (quest_status.first_start << 31) | (quest_status.met_leader << 30) | (quest_status.not_ready << 27) | (quest_status.pissed_off << 26) | (quest_status.got_quest << 25) | (quest_status.first_locate << 24) | (quest_status.met_intermed << 23) | (quest_status.got_final << 22) | (quest_status.made_goal << 19) | (quest_status.met_nemesis << 18) | (quest_status.killed_nemesis << 17) | (quest_status.in_battle << 16) | (quest_status.cheater << 15) | (quest_status.touched_artifact << 14) | (quest_status.offered_artifact << 13) | (quest_status.got_thanks << 12) | (quest_status.leader_is_dead << 11); mwrite32(mf, qflags); mwrite32(mf, quest_status.leader_m_id); }
static void save_spellbook(struct memfile *mf) { int i; for (i = 0; i < MAXSPELL + 1; i++) { mwrite32(mf, spl_book[i].sp_know); mwrite16(mf, spl_book[i].sp_id); mwrite8(mf, spl_book[i].sp_lev); } }
/* save all the fruit names and ID's; this is used only in saving whole games * (not levels) and in saving bones levels. When saving a bones level, * we only want to save the fruits which exist on the bones level; the bones * level routine marks nonexistent fruits by making the fid negative. */ void savefruitchn(struct memfile *mf) { struct fruit *f1; unsigned int count = 0; mfmagic_set(mf, FRUITCHAIN_MAGIC); for (f1 = ffruit; f1; f1 = f1->nextf) if (f1->fid >= 0) count++; mwrite32(mf, count); for (f1 = ffruit; f1; f1 = f1->nextf) { if (f1->fid >= 0) { mwrite(mf, f1->fname, sizeof(f1->fname)); mwrite32(mf, f1->fid); } } }
static void save_location(struct memfile *mf, struct rm *loc) { unsigned int memflags; unsigned short rflags; unsigned char bg = loc->mem_bg; /* pack mem_door_l, mem_door_t into mem_bg */ switch (bg) { case S_vodoor: if (loc->mem_door_l && loc->mem_door_t) bg = S_vodoor_memlt; else if (loc->mem_door_l) bg = S_vodoor_meml; else if (loc->mem_door_t) bg = S_vodoor_memt; break; case S_hodoor: if (loc->mem_door_l && loc->mem_door_t) bg = S_hodoor_memlt; else if (loc->mem_door_l) bg = S_hodoor_meml; else if (loc->mem_door_t) bg = S_hodoor_memt; break; case S_vcdoor: if (loc->mem_door_l && loc->mem_door_t) bg = S_vcdoor_memlt; else if (loc->mem_door_l) bg = S_vcdoor_meml; else if (loc->mem_door_t) bg = S_vcdoor_memt; break; case S_hcdoor: if (loc->mem_door_l && loc->mem_door_t) bg = S_hcdoor_memlt; else if (loc->mem_door_l) bg = S_hcdoor_meml; else if (loc->mem_door_t) bg = S_hcdoor_memt; break; } memflags = (bg << 26) | (loc->mem_trap << 21) | (loc->mem_obj << 11) | (loc->mem_obj_mn << 2) | (loc->mem_invis << 1) | (loc->mem_stepped << 0); rflags = (loc->flags << 11) | (loc->horizontal << 10) | (loc->lit << 9) | (loc->waslit << 8) | (loc->roomno << 2) | (loc->edge << 1); mwrite32(mf, memflags); mwrite8(mf, loc->typ); mwrite8(mf, loc->seenv); mwrite16(mf, rflags); }
/* Save all light sources of the given range. */ void save_light_sources(struct memfile *mf, struct level *lev, int range) { int count, actual; count = maybe_write_ls(mf, lev, range, FALSE); mwrite32(mf, count); actual = maybe_write_ls(mf, lev, range, TRUE); if (actual != count) panic("counted %d light sources, wrote %d! [range=%d]", count, actual, range); }
/* * save_rooms : Save all the rooms on disk! */ void save_rooms(struct memfile *mf, struct level *lev) { short i; mfmagic_set(mf, ROOMS_MAGIC); /* "RDAT" */ mtag(mf, ledger_no(&lev->z), MTAG_ROOMS); /* First, write the number of rooms */ mwrite32(mf, lev->nroom); for (i = 0; i < lev->nroom; i++) save_room(mf, &lev->rooms[i]); }
static void savedamage(struct memfile *mf, struct level *lev) { struct damage *damageptr; unsigned int xl = 0; mtag(mf, ledger_no(&lev->z), MTAG_DAMAGE); for (damageptr = lev->damagelist; damageptr; damageptr = damageptr->next) xl++; mwrite32(mf, xl); for (damageptr = lev->damagelist; damageptr; damageptr = damageptr->next) { mtag(mf, damageptr->when, MTAG_DAMAGEVALUE); mwrite32(mf, damageptr->when); mwrite32(mf, damageptr->cost); mwrite8(mf, damageptr->place.x); mwrite8(mf, damageptr->place.y); mwrite8(mf, damageptr->typ); } }
/* * save_worm() * * Save the worm information for later use. The count is the number * of segments, including the dummy. Called from save.c. */ void save_worm(struct memfile *mf, struct level *lev) { int i, count; struct wseg *curr; for (i = 1; i < MAX_NUM_WORMS; i++) { for (count = 0, curr = lev->wtails[i]; curr; curr = curr->nseg) count++; mtag(mf, (int)ledger_no(&lev->z) * MAX_NUM_WORMS + i, MTAG_WORMS); /* Save number of segments */ mwrite32(mf, count); /* Save segment locations of the monster. */ if (count) { for (curr = lev->wtails[i]; curr; curr = curr->nseg) { mwrite8(mf, curr->wx); mwrite8(mf, curr->wy); } mwrite32(mf, lev->wgrowtime[i]); } } }
/* Save all light sources of the given range. */ void save_light_sources(struct memfile *mf, struct level *lev, int range) { int count, actual; mtag(mf, 2 * (int)ledger_no(&lev->z) + range, MTAG_LIGHTS); count = maybe_write_ls(mf, lev, range, FALSE); mwrite32(mf, count); actual = maybe_write_ls(mf, lev, range, TRUE); if (actual != count) panic("counted %d light sources, wrote %d! [range=%d]", count, actual, range); }
static void savelevchn(struct memfile *mf) { s_level *tmplev; int cnt = 0; for (tmplev = sp_levchn; tmplev; tmplev = tmplev->next) cnt++; mwrite32(mf, cnt); for (tmplev = sp_levchn; tmplev; tmplev = tmplev->next) { save_d_flags(mf, tmplev->flags); mwrite(mf, &tmplev->dlevel, sizeof(tmplev->dlevel)); mwrite(mf, tmplev->proto, sizeof(tmplev->proto)); mwrite8(mf, tmplev->boneid); mwrite8(mf, tmplev->rndlevs); } }
/** * save_regions : */ void save_regions(struct memfile *mf, struct level *lev) { int i, j; unsigned len1, len2; struct region *r; mfmagic_set(mf, REGION_MAGIC); mtag(mf, ledger_no(&lev->z), MTAG_REGION); mwrite32(mf, save_encode_32(moves, moves, moves)); /* timestamp */ mwrite32(mf, lev->n_regions); /* Note: level regions don't have ID numbers, so we can't tag individual regions; instead, diff efficiency depends on the fact that regions tend to stay in the order and are typically inserted or deleted near the end of the list */ for (i = 0; i < lev->n_regions; i++) { r = lev->regions[i]; save_rect(mf, r->bounding_box); mwrite32(mf, r->attach_2_m); mwrite32(mf, r->effect_id); mwrite32(mf, r->arg); mwrite16(mf, r->nrects); for (j = 0; j < r->nrects; j++) save_rect(mf, r->rects[j]); mwrite16(mf, r->ttl); mwrite16(mf, r->expire_f); mwrite16(mf, r->can_enter_f); mwrite16(mf, r->enter_f); mwrite16(mf, r->can_leave_f); mwrite16(mf, r->leave_f); mwrite16(mf, r->inside_f); mwrite16(mf, r->n_monst); mwrite8(mf, r->player_flags); mwrite8(mf, r->attach_2_u); mwrite8(mf, r->visible); for (j = 0; j < r->n_monst; j++) mwrite32(mf, r->monsters[j]); len1 = r->enter_msg ? strlen(r->enter_msg) + 1 : 0; mwrite16(mf, len1); len2 = r->leave_msg ? strlen(r->leave_msg) + 1 : 0; mwrite16(mf, len2); if (len1 > 0) mwrite(mf, r->enter_msg, len1); if (len2 > 0) mwrite(mf, r->leave_msg, len2); } }
static void saveobjchn(struct memfile *mf, struct obj *otmp) { int count = 0; struct obj *otmp2; mfmagic_set(mf, OBJCHAIN_MAGIC); for (otmp2 = otmp; otmp2; otmp2 = otmp2->nobj) count++; mwrite32(mf, count); while (otmp) { save_obj(mf, otmp); if (Has_contents(otmp)) saveobjchn(mf, otmp->cobj); otmp = otmp->nobj; } }
static void savemonchn(struct memfile *mf, struct monst *mtmp) { struct monst *mtmp2; unsigned int count = 0; mfmagic_set(mf, MONCHAIN_MAGIC); for (mtmp2 = mtmp; mtmp2; mtmp2 = mtmp2->nmon) count++; mwrite32(mf, count); while (mtmp) { mtmp2 = mtmp->nmon; save_mon(mf, mtmp); if (mtmp->minvent) saveobjchn(mf, mtmp->minvent); mtmp = mtmp2; } }
static void save_location(struct memfile *mf, struct rm *loc) { unsigned int lflags1; unsigned short lflags2; lflags1 = (loc->mem_bg << 26) | (loc->mem_trap << 21) | (loc->mem_obj << 11) | (loc->mem_obj_mn << 2) | (loc->mem_invis << 1); lflags2 = (loc->flags << 11) | (loc->horizontal << 10) | (loc->lit << 9) | (loc->waslit << 8) | (loc->roomno << 2) | (loc->edge << 1); mwrite32(mf, lflags1); mwrite8(mf, loc->typ); mwrite8(mf, loc->seenv); mwrite16(mf, lflags2); }
static void savetrapchn(struct memfile *mf, struct trap *trap) { struct trap *trap2; unsigned short tflags; int count = 0; mfmagic_set(mf, TRAPCHAIN_MAGIC); for (trap2 = trap; trap2; trap2 = trap2->ntrap) count++; mwrite32(mf, count); for (; trap; trap = trap->ntrap) { mwrite8(mf, trap->tx); mwrite8(mf, trap->ty); mwrite8(mf, trap->dst.dnum); mwrite8(mf, trap->dst.dlevel); mwrite8(mf, trap->launch.x); mwrite8(mf, trap->launch.y); tflags = (trap->ttyp << 11) | (trap->tseen << 10) | (trap->once << 9) | (trap->madeby_u << 8); mwrite16(mf, tflags); mwrite16(mf, trap->vl.v_launch_otyp); } }
static void savegamestate(struct memfile *mf) { unsigned book_id; mtag(mf, 0, MTAG_GAMESTATE); mfmagic_set(mf, STATE_MAGIC); /* must come before migrating_objs and migrating_mons are freed */ save_timers(mf, level, RANGE_GLOBAL); save_light_sources(mf, level, RANGE_GLOBAL); saveobjchn(mf, invent); savemonchn(mf, migrating_mons); save_mvitals(mf); save_quest_status(mf); save_spellbook(mf); save_artifacts(mf); save_oracles(mf); mwrite(mf, pl_character, sizeof pl_character); mwrite(mf, pl_fruit, sizeof pl_fruit); mwrite32(mf, current_fruit); savefruitchn(mf); savenames(mf); save_waterlevel(mf); mwrite32(mf, lastinvnr); save_mt_state(mf); save_track(mf); save_food(mf); save_steal(mf); save_dig_status(mf); book_id = book ? book->o_id : 0; mwrite32(mf, book_id); mwrite32(mf, stetho_last_used_move); mwrite32(mf, stetho_last_used_movement); mwrite32(mf, multi); save_rndmonst_state(mf); save_history(mf); }
void savelev(struct memfile *mf, xchar levnum) { int x, y; unsigned int lflags; struct level *lev = levels[levnum]; if (iflags.purge_monsters) { /* purge any dead monsters (necessary if we're starting * a panic save rather than a normal one, or sometimes * when changing levels without taking time -- e.g. * create statue trap then immediately level teleport) */ dmonsfree(lev); } mfmagic_set(mf, LEVEL_MAGIC); mwrite8(mf, lev->z.dnum); mwrite8(mf, lev->z.dlevel); mwrite(mf, lev->levname, sizeof(lev->levname)); for (x = 0; x < COLNO; x++) for (y = 0; y < ROWNO; y++) save_location(mf, &lev->locations[x][y]); mwrite32(mf, lev->lastmoves); mwrite(mf, &lev->upstair, sizeof(stairway)); mwrite(mf, &lev->dnstair, sizeof(stairway)); mwrite(mf, &lev->upladder, sizeof(stairway)); mwrite(mf, &lev->dnladder, sizeof(stairway)); mwrite(mf, &lev->sstairs, sizeof(stairway)); mwrite(mf, &lev->updest, sizeof(dest_area)); mwrite(mf, &lev->dndest, sizeof(dest_area)); mwrite8(mf, lev->flags.nfountains); mwrite8(mf, lev->flags.nsinks); lflags = (lev->flags.has_shop << 31) | (lev->flags.has_vault << 30) | (lev->flags.has_zoo << 29) | (lev->flags.has_court << 28) | (lev->flags.has_morgue << 27) | (lev->flags.has_beehive << 26) | (lev->flags.has_barracks << 25) | (lev->flags.has_temple << 24) | (lev->flags.has_swamp << 23) | (lev->flags.noteleport << 22) | (lev->flags.hardfloor << 21) | (lev->flags.nommap << 20) | (lev->flags.hero_memory << 19) | (lev->flags.shortsighted << 18) | (lev->flags.graveyard << 17) | (lev->flags.is_maze_lev << 16) | (lev->flags.is_cavernous_lev << 15) | (lev->flags.arboreal << 14) | (lev->flags.forgotten << 13); mwrite32(mf, lflags); mwrite(mf, lev->doors, sizeof(lev->doors)); save_rooms(mf, lev); /* no dynamic memory to reclaim */ /* must be saved before mons, objs, and buried objs */ save_timers(mf, lev, RANGE_LEVEL); save_light_sources(mf, lev, RANGE_LEVEL); savemonchn(mf, lev->monlist); save_worm(mf, lev); /* save worm information */ savetrapchn(mf, lev->lev_traps); saveobjchn(mf, lev->objlist); saveobjchn(mf, lev->buriedobjlist); saveobjchn(mf, lev->billobjs); save_engravings(mf, lev); savedamage(mf, lev); save_regions(mf, lev); }
static void save_flags(struct memfile *mf) { mwrite32(mf, flags.ident); mwrite32(mf, flags.moonphase); mwrite32(mf, flags.no_of_wizards); mwrite32(mf, flags.init_role); mwrite32(mf, flags.init_race); mwrite32(mf, flags.init_gend); mwrite32(mf, flags.init_align); mwrite32(mf, flags.randomall); mwrite32(mf, flags.pantheon); mwrite32(mf, flags.run); mwrite32(mf, flags.warntype); mwrite32(mf, flags.warnlevel); mwrite32(mf, flags.djinni_count); mwrite32(mf, flags.ghost_count); mwrite32(mf, flags.pickup_burden); mwrite8(mf, flags.autodig); mwrite8(mf, flags.autoquiver); mwrite8(mf, flags.beginner); mwrite8(mf, flags.confirm); mwrite8(mf, flags.debug); mwrite8(mf, flags.explore); mwrite8(mf, flags.female); mwrite8(mf, flags.forcefight); mwrite8(mf, flags.friday13); mwrite8(mf, flags.legacy); mwrite8(mf, flags.lit_corridor); mwrite8(mf, flags.made_amulet); mwrite8(mf, flags.mon_moving); mwrite8(mf, flags.move); mwrite8(mf, flags.mv); mwrite8(mf, flags.nopick); mwrite8(mf, flags.null); mwrite8(mf, flags.pickup); mwrite8(mf, flags.pushweapon); mwrite8(mf, flags.rest_on_space); mwrite8(mf, flags.safe_dog); mwrite8(mf, flags.silent); mwrite8(mf, flags.sortpack); mwrite8(mf, flags.soundok); mwrite8(mf, flags.sparkle); mwrite8(mf, flags.tombstone); mwrite8(mf, flags.verbose); mwrite8(mf, flags.prayconfirm); mwrite8(mf, flags.travel); mwrite8(mf, flags.end_disclose); mwrite8(mf, flags.menu_style); mwrite8(mf, flags.elbereth_enabled); mwrite8(mf, flags.rogue_enabled); mwrite8(mf, flags.seduce_enabled); mwrite8(mf, flags.bones_enabled); mwrite(mf, flags.inv_order, sizeof(flags.inv_order)); }