/* * 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); }
void rehumanize(void) { /* You can't revert back while unchanging */ if (Unchanging && (u.mh < 1)) { killer_format = NO_KILLER_PREFIX; killer = "killed while stuck in creature form"; done(DIED); } if (emits_light(youmonst.data)) del_light_source(level, LS_MONSTER, &youmonst); polyman("You return to %s form!", urace.adj); if (u.uhp < 1) { char kbuf[256]; sprintf(kbuf, "reverting to unhealthy %s form", urace.adj); killer_format = KILLED_BY; killer = kbuf; done(DIED); } if (!uarmg) selftouch("No longer petrify-resistant, you"); nomul(0, NULL); iflags.botl = 1; vision_full_recalc = 1; encumber_msg(); }
void rehumanize (void) { /* You can't revert back while unchanging */ if (Unchanging && (u.mh < 1)) { killer = killed_by_const(KM_WHILE_STUCK_IN_CREATURE_FORM); done(DIED); } if (emits_light(youmonst.data)) del_light_source(LS_MONSTER, (void *)&youmonst); polyman("return to %s form!", urace.adj); if (u.uhp < 1) { char kbuf[256]; sprintf(kbuf, "reverting to unhealthy %s form", urace.adj); fprintf(stderr, "TODO killer = %s\n", kbuf); done(DIED); } if (!uarmg) selftouch("No longer petrify-resistant, you"); nomul(0); vision_full_recalc = 1; (void) encumber_msg(); }
void polyself(boolean forcecontrol) { char buf[BUFSZ]; int old_light, new_light; int mntmp = NON_PM; int tries=0; boolean draconian = (uarm && uarm->otyp >= GRAY_DRAGON_SCALE_MAIL && uarm->otyp <= YELLOW_DRAGON_SCALES); boolean iswere = (u.ulycn >= LOW_PM || is_were(youmonst.data)); boolean isvamp = (youmonst.data->mlet == S_VAMPIRE || u.umonnum == PM_VAMPIRE_BAT); boolean was_floating = (Levitation || Flying); if (!Polymorph_control && !forcecontrol && !draconian && !iswere && !isvamp) { if (rn2(20) > ACURR(A_CON)) { pline("You shudder for a moment."); losehp(rnd(30), "system shock", KILLED_BY_AN); exercise(A_CON, FALSE); return; } } old_light = Upolyd ? emits_light(youmonst.data) : 0; if (Polymorph_control || forcecontrol) { do { getlin("Become what kind of monster? [type the name]", buf); mntmp = name_to_mon(buf); if (mntmp < LOW_PM) pline("I've never heard of such monsters."); /* Note: humans are illegal as monsters, but an * illegal monster forces newman(), which is what we * want if they specified a human.... */ else if (!polyok(&mons[mntmp]) && !your_race(&mons[mntmp])) pline("You cannot polymorph into that."); else break; } while (++tries < 5); if (tries==5) pline("That's enough tries!"); /* allow skin merging, even when polymorph is controlled */ if (draconian && (mntmp == armor_to_dragon(uarm->otyp) || tries == 5)) goto do_merge; } else if (draconian || iswere || isvamp) { /* special changes that don't require polyok() */ if (draconian) { do_merge: mntmp = armor_to_dragon(uarm->otyp); if (!(mvitals[mntmp].mvflags & G_GENOD)) { /* allow G_EXTINCT */ pline("You merge with your scaly armor."); uskin = uarm; uarm = NULL; /* save/restore hack */ uskin->owornmask |= I_SPECIAL; } } else if (iswere) { if (is_were(youmonst.data)) mntmp = PM_HUMAN; /* Illegal; force newman() */ else mntmp = u.ulycn; } else { if (youmonst.data->mlet == S_VAMPIRE) mntmp = PM_VAMPIRE_BAT; else mntmp = PM_VAMPIRE; } /* if polymon fails, "you feel" message has been given so don't follow up with another polymon or newman */ if (mntmp == PM_HUMAN) newman(); /* werecritter */ else polymon(mntmp); goto made_change; /* maybe not, but this is right anyway */ } if (mntmp < LOW_PM) { tries = 0; do { /* randomly pick an "ordinary" monster */ mntmp = rn1(SPECIAL_PM - LOW_PM, LOW_PM); } while ((!polyok(&mons[mntmp]) || is_placeholder(&mons[mntmp])) && tries++ < 200); } /* The below polyok() fails either if everything is genocided, or if * we deliberately chose something illegal to force newman(). */ if (!polyok(&mons[mntmp]) || !rn2(5) || your_race(&mons[mntmp])) newman(); else if (!polymon(mntmp)) return; if (!uarmg) selftouch("No longer petrify-resistant, you"); made_change: new_light = Upolyd ? emits_light(youmonst.data) : 0; if (old_light != new_light) { if (old_light) del_light_source(level, LS_MONSTER, &youmonst); if (new_light == 1) ++new_light; /* otherwise it's undetectable */ if (new_light) new_light_source(level, u.ux, u.uy, new_light, LS_MONSTER, &youmonst); } if (is_pool(level, u.ux,u.uy) && was_floating && !(Levitation || Flying) && !breathless(youmonst.data) && !amphibious(youmonst.data) && !Swimming) drown(); }