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); } }
/* 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 save_steal(struct memfile *mf) { mtag(mf, 0, MTAG_STEAL); mwrite32(mf, stealoid); mwrite32(mf, stealmid); }
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 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_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); } }
/* * 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 save_mvitals(struct memfile *mf) { /* mtag useful here because migration is variable-length */ mtag(mf, 0, MTAG_MVITALS); int i; for (i = 0; i < NUMMONS; i++) { mwrite8(mf, mvitals[i].born); mwrite8(mf, mvitals[i].died); mwrite8(mf, mvitals[i].mvflags); } }
/* 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); }
void savegame(struct memfile *mf) { int count = 0; xchar ltmp; /* no tag useful here as store_version adds one */ 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); /* no tag useful here; you is fixed-length */ save_mon(mf, &youmonst); /* store dungeon layout */ save_dungeon(mf); savelevchn(mf); /* store levels */ mtag(mf, 0, MTAG_LEVELS); for (ltmp = 1; ltmp <= maxledgerno(); ltmp++) if (levels[ltmp]) count++; mwrite32(mf, count); for (ltmp = 1; ltmp <= maxledgerno(); ltmp++) { if (!levels[ltmp]) continue; mtag(mf, ltmp, MTAG_LEVELS); mwrite8(mf, ltmp); /* level number */ savelev(mf, ltmp); /* actual level */ } savegamestate(mf); }
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); } }
/* 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) { mtag(mf, f1->fid, MTAG_FRUIT); mwrite(mf, f1->fname, sizeof (f1->fname)); mwrite32(mf, f1->fid); } } }
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); }
/* * 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]); } } }