/* * Deallocate the object. _All_ objects should be run through here for * them to be deallocated. */ void dealloc_obj(struct obj *obj) { if (obj->where != OBJ_FREE) panic("dealloc_obj: obj not free (%d,%d,%d)", obj->where, obj->otyp, obj->invlet); /* free up any timers attached to the object */ if (obj->timed) obj_stop_timers(obj); /* * Free up any light sources attached to the object. * * We may want to just call del_light_source() without any * checks (requires a code change there). Otherwise this * list must track all objects that can have a light source * attached to it (and also requires lamplit to be set). */ if (obj_sheds_light(obj)) del_light_source(LS_OBJECT, (genericptr_t) obj); if (obj == thrownobj) thrownobj = (struct obj*)0; free((genericptr_t) obj); }
/* * OEXTRA note: Passing mtmp causes mtraits to be saved * even if ptr passed as well, but ptr is always used for * the corpse type (corpsenm). That allows the corpse type * to be different from the original monster, * i.e. vampire -> human corpse * yet still allow restoration of the original monster upon * resurrection. */ struct obj * mkcorpstat(int objtype, struct monst *mtmp, struct permonst *ptr, int x, int y, boolean init) /* CORPSE or STATUE */ { register struct obj *otmp; if (objtype != CORPSE && objtype != STATUE) warning("making corpstat type %d", objtype); if (x == 0 && y == 0) { /* special case - random placement */ otmp = mksobj(objtype, init, FALSE); if (otmp) rloco(otmp); } else otmp = mksobj_at(objtype, x, y, init, FALSE); if (otmp) { if (mtmp) { struct obj *otmp2; if (!ptr) ptr = mtmp->data; /* save_mtraits frees original data pointed to by otmp */ otmp2 = save_mtraits(otmp, mtmp); if (otmp2) otmp = otmp2; } /* use the corpse or statue produced by mksobj() as-is unless `ptr' is non-null */ if (ptr) { int old_corpsenm = otmp->corpsenm; otmp->corpsenm = monsndx(ptr); otmp->owt = weight(otmp); if (otmp->otyp == CORPSE && (special_corpse(old_corpsenm) || special_corpse(otmp->corpsenm))) { obj_stop_timers(otmp); start_corpse_timeout(otmp); } } } return(otmp); }
/* * Get a random player name and class from the high score list, * and attach them to an object (for statues or morgue corpses). */ struct obj * tt_oname(struct obj *otmp) { int rank, fd; struct toptenentry *toptenlist, *tt; if (!otmp) return NULL; fd = open_datafile(RECORD, O_RDONLY, SCOREPREFIX); toptenlist = read_topten(fd, 100); /* load the top 100 scores */ close(fd); /* try to find a valid entry, reducing the value range for rank each time */ rank = rn2(100); while (!validentry(toptenlist[rank]) && rank) rank = rn2(rank); tt = &toptenlist[rank]; if (!validentry(toptenlist[rank])) otmp = NULL; /* the topten list is empty */ else { /* reset timer in case corpse started out as lizard or troll */ if (otmp->otyp == CORPSE) obj_stop_timers(otmp); otmp->corpsenm = classmon(tt->plrole, (tt->plgend[0] == 'F')); otmp->owt = weight(otmp); otmp = oname(otmp, tt->name); if (otmp->otyp == CORPSE) start_corpse_timeout(otmp); } free(toptenlist); return otmp; }