/* * Pull in the structures from disk, but don't recalculate the object * pointers. */ void restore_light_sources(struct memfile *mf, struct level *lev) { int count; intptr_t id; /* we need to restore and preserve order *but* we don't need * to preserve the absolute order, only the relative orders of all * global lights and all local lights---this is because global * lights are for stored on the level and moved around as you do. * As a result, they are saved in different places, and consequently * it will *not* cause a desync as long as relative order is preserved. * So it doesn't actually matter that we retain relative order to other * light sources on the level, only that we restore the light sources here * in reverse order. Inserting immediately after the first light leads to * the simplest code. */ light_source *ls, *prev = lev->lev_lights, *rest = prev ? prev->next : NULL; /* restore elements */ count = mread32(mf); while (count-- > 0) { ls = malloc(sizeof (light_source)); ls->type = mread32(mf); ls->range = mread16(mf); ls->flags = mread16(mf); id = mread32(mf); ls->id = (void *)id; ls->x = mread8(mf); ls->y = mread8(mf); ls->next = rest; if (prev) prev->next = ls; else lev->lev_lights = ls; prev = ls; } }
/* * Pull in the structures from disk, but don't recalculate the object * pointers. */ void restore_light_sources(struct memfile *mf, struct level *lev) { int count; long id; light_source *ls; /* restore elements */ count = mread32(mf); while (count-- > 0) { ls = malloc(sizeof(light_source)); ls->type = mread32(mf); ls->range = mread16(mf); ls->flags = mread16(mf); id = mread32(mf); /* prevent: "cast to pointer from integer of different size" */ ls->id = (void*)id; ls->x = mread8(mf); ls->y = mread8(mf); ls->next = lev->lev_lights; lev->lev_lights = ls; } }
struct obj *restore_obj(struct memfile *mf) { unsigned int oflags; char namelen; struct obj *otmp; mfmagic_check(mf, OBJ_MAGIC); namelen = mread32(mf); otmp = newobj(namelen); memset(otmp, 0, namelen + sizeof(struct obj)); otmp->o_id = mread32(mf); otmp->owt = mread32(mf); otmp->quan = mread32(mf); otmp->corpsenm = mread32(mf); otmp->oeaten = mread32(mf); otmp->age = mread32(mf); otmp->owornmask = mread32(mf); oflags = mread32(mf); otmp->otyp = mread16(mf); otmp->ox = mread8(mf); otmp->oy = mread8(mf); otmp->spe = mread8(mf); otmp->oclass = mread8(mf); otmp->invlet = mread8(mf); otmp->oartifact = mread8(mf); otmp->where = mread8(mf); otmp->timed = mread8(mf); otmp->cobj = mread8(mf) ? (void*)1 : NULL; /* set the pointer to 1 if there will be contents */ otmp->onamelth = namelen; otmp->cursed = (oflags >> 31) & 1; otmp->blessed = (oflags >> 30) & 1; otmp->unpaid = (oflags >> 29) & 1; otmp->no_charge = (oflags >> 28) & 1; otmp->known = (oflags >> 27) & 1; otmp->dknown = (oflags >> 26) & 1; otmp->bknown = (oflags >> 25) & 1; otmp->rknown = (oflags >> 24) & 1; otmp->oeroded = (oflags >> 22) & 3; otmp->oeroded2 = (oflags >> 20) & 3; otmp->oerodeproof = (oflags >> 19) & 1; otmp->olocked = (oflags >> 18) & 1; otmp->obroken = (oflags >> 17) & 1; otmp->otrapped = (oflags >> 16) & 1; otmp->recharged = (oflags >> 13) & 7; otmp->lamplit = (oflags >> 12) & 1; otmp->greased = (oflags >> 11) & 1; otmp->oattached = (oflags >> 9) & 3; otmp->in_use = (oflags >> 8) & 1; otmp->was_thrown = (oflags >> 7) & 1; otmp->bypass = (oflags >> 6) & 1; if (otmp->onamelth) mread(mf, ONAME(otmp), otmp->onamelth); if (otmp->oattached == OATTACHED_MONST) { struct monst *mtmp = restore_mon(mf); int monlen = sizeof(struct monst) + mtmp->mnamelth + mtmp->mxlth; otmp = realloc_obj(otmp, monlen, mtmp, otmp->onamelth, ONAME(otmp)); dealloc_monst(mtmp); } else if (otmp->oattached == OATTACHED_M_ID) { unsigned int mid = mread32(mf); otmp = obj_attach_mid(otmp, mid); } return otmp; }
void rest_regions(struct memfile *mf, struct level *lev, boolean ghostly) { /* If a bones file restore */ int i, j; unsigned len1, len2; long tmstamp; char *msg_buf; struct region *r; free_regions(lev); /* Just for security */ mfmagic_check(mf, REGION_MAGIC); tmstamp = save_decode_32(mread32(mf), moves, moves); if (ghostly) tmstamp = 0; else tmstamp = (moves - tmstamp); lev->n_regions = mread32(mf); lev->max_regions = lev->n_regions; if (lev->n_regions > 0) lev->regions = malloc(sizeof (struct region *) * lev->n_regions); for (i = 0; i < lev->n_regions; i++) { lev->regions[i] = malloc(sizeof (struct region)); r = lev->regions[i]; memset(r, 0, sizeof (struct region)); r->lev = lev; restore_rect(mf, &r->bounding_box); r->attach_2_m = mread32(mf); r->effect_id = mread32(mf); r->arg = mread32(mf); r->nrects = mread16(mf); if (r->nrects > 0) r->rects = malloc(sizeof (struct nhrect) * r->nrects); for (j = 0; j < r->nrects; j++) restore_rect(mf, &r->rects[j]); r->ttl = mread16(mf); r->expire_f = mread16(mf); r->can_enter_f = mread16(mf); r->enter_f = mread16(mf); r->can_leave_f = mread16(mf); r->leave_f = mread16(mf); r->inside_f = mread16(mf); r->n_monst = mread16(mf); r->max_monst = r->n_monst; r->player_flags = mread8(mf); r->attach_2_u = mread8(mf); r->visible = mread8(mf); if (r->n_monst > 0) r->monsters = malloc(sizeof (unsigned) * r->n_monst); for (j = 0; j < r->n_monst; j++) r->monsters[j] = mread32(mf); len1 = mread16(mf); len2 = mread16(mf); if (len1 > 0) { msg_buf = malloc(len1); mread(mf, msg_buf, len1); msg_buf[len1 - 1] = '\0'; r->enter_msg = msg_buf; } if (len2 > 0) { msg_buf = malloc(len2); mread(mf, msg_buf, len2); msg_buf[len2 - 1] = '\0'; r->leave_msg = msg_buf; } /* check for expired region */ if (r->ttl >= 0) r->ttl = (r->ttl > tmstamp) ? r->ttl - tmstamp : 0; if (ghostly) { /* settings pertained to old player */ clear_hero_inside(r); clear_heros_fault(r); } } for (i = lev->n_regions - 1; i >= 0; i--) if (ghostly && lev->regions[i]->n_monst > 0) reset_region_mids(lev->regions[i]); }