1 /* NetHack 3.6 mkobj.c $NHDT-Date: 1447475943 2015/11/14 04:39:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.113 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
7 STATIC_DCL void FDECL(mkbox_cnts, (struct obj *));
8 STATIC_DCL void FDECL(maybe_adjust_light, (struct obj *, int));
9 STATIC_DCL void FDECL(obj_timer_checks, (struct obj *,
10 XCHAR_P, XCHAR_P, int));
11 STATIC_DCL void FDECL(container_weight, (struct obj *));
12 STATIC_DCL struct obj *FDECL(save_mtraits, (struct obj *, struct monst *));
13 STATIC_DCL void FDECL(objlist_sanity, (struct obj *, int, const char *));
14 STATIC_DCL void FDECL(mon_obj_sanity, (struct monst *, const char *));
15 STATIC_DCL const char *FDECL(where_name, (struct obj *));
16 STATIC_DCL void FDECL(insane_object, (struct obj *, const char *,
17 const char *, struct monst *));
18 STATIC_DCL void FDECL(check_contained, (struct obj *, const char *));
19 STATIC_DCL void FDECL(sanity_check_worn, (struct obj *));
22 int iprob; /* probability of an item type */
23 char iclass; /* item class */
26 static const struct icp mkobjprobs[] = { { 10, WEAPON_CLASS },
36 { 1, AMULET_CLASS } };
38 static const struct icp boxiprobs[] = { { 18, GEM_CLASS },
46 { 1, AMULET_CLASS } };
48 static const struct icp rogueprobs[] = { { 12, WEAPON_CLASS },
56 static const struct icp hellprobs[] = { { 20, WEAPON_CLASS },
65 { 4, AMULET_CLASS } };
70 struct oextra *oextra;
72 oextra = (struct oextra *) alloc(sizeof(struct oextra));
85 struct oextra *x = o->oextra;
89 free((genericptr_t) x->oname);
91 free_omonst(o); /* 'o' rather than 'x' */
93 free((genericptr_t) x->omid);
95 free((genericptr_t) x->olong);
97 free((genericptr_t) x->omailcmd);
99 free((genericptr_t) x);
100 o->oextra = (struct oextra *) 0;
109 otmp->oextra = newoextra();
111 struct monst *m = newmonst();
113 /* newmonst() allocates memory but doesn't initialize anything */
114 (void) memset((genericptr_t) m, 0, sizeof (struct monst));
115 m->mextra = (struct mextra *) 0;
116 m->nmon = (struct monst *) 0;
126 struct monst *m = OMONST(otmp);
131 free((genericptr_t) m);
132 OMONST(otmp) = (struct monst *) 0;
142 otmp->oextra = newoextra();
144 OMID(otmp) = (unsigned *) alloc(sizeof (unsigned));
145 (void) memset((genericptr_t) OMID(otmp), 0, sizeof (unsigned));
153 if (otmp->oextra && OMID(otmp)) {
154 free((genericptr_t) OMID(otmp));
155 OMID(otmp) = (unsigned *) 0;
164 otmp->oextra = newoextra();
166 OLONG(otmp) = (long *) alloc(sizeof (long));
167 (void) memset((genericptr_t) OLONG(otmp), 0, sizeof (long));
175 if (otmp->oextra && OLONG(otmp)) {
176 free((genericptr_t) OLONG(otmp));
177 OLONG(otmp) = (long *) 0;
182 new_omailcmd(otmp, response_cmd)
184 const char *response_cmd;
187 otmp->oextra = newoextra();
190 OMAILCMD(otmp) = dupstr(response_cmd);
197 if (otmp->oextra && OMAILCMD(otmp)) {
198 free((genericptr_t) OMAILCMD(otmp));
199 OMAILCMD(otmp) = (char *) 0;
204 mkobj_at(let, x, y, artif)
211 otmp = mkobj(let, artif);
212 place_object(otmp, x, y);
217 mksobj_at(otyp, x, y, init, artif)
223 otmp = mksobj(otyp, init, artif);
224 place_object(otmp, x, y);
233 int tprob, i, prob = rnd(1000);
235 if (oclass == RANDOM_CLASS) {
236 const struct icp *iprobs = Is_rogue_level(&u.uz)
237 ? (const struct icp *) rogueprobs
238 : Inhell ? (const struct icp *) hellprobs
239 : (const struct icp *) mkobjprobs;
241 for (tprob = rnd(100); (tprob -= iprobs->iprob) > 0; iprobs++)
243 oclass = iprobs->iclass;
246 i = bases[(int) oclass];
247 while ((prob -= objects[i].oc_prob) > 0)
250 if (objects[i].oc_class != oclass || !OBJ_NAME(objects[i]))
251 panic("probtype error, oclass=%d i=%d", (int) oclass, i);
253 return mksobj(i, TRUE, artif);
261 register struct obj *otmp;
263 box->cobj = (struct obj *) 0;
277 /* initial inventory: sack starts out empty */
278 if (moves <= 1 && !in_mklev) {
291 for (n = rn2(n + 1); n > 0; n--) {
292 if (box->otyp == ICE_BOX) {
293 if (!(otmp = mksobj(CORPSE, TRUE, TRUE)))
295 /* Note: setting age to 0 is correct. Age has a different
296 * from usual meaning for objects stored in ice boxes. -KAA
300 (void) stop_timer(ROT_CORPSE, obj_to_any(otmp));
301 (void) stop_timer(REVIVE_MON, obj_to_any(otmp));
305 const struct icp *iprobs = boxiprobs;
307 for (tprob = rnd(100); (tprob -= iprobs->iprob) > 0; iprobs++)
309 if (!(otmp = mkobj(iprobs->iclass, TRUE)))
312 /* handle a couple of special cases */
313 if (otmp->oclass == COIN_CLASS) {
314 /* 2.5 x level's usual amount; weight adjusted below */
315 otmp->quan = (long) (rnd(level_difficulty() + 2) * rnd(75));
316 otmp->owt = weight(otmp);
318 while (otmp->otyp == ROCK) {
319 otmp->otyp = rnd_class(DILITHIUM_CRYSTAL, LOADSTONE);
322 otmp->owt = weight(otmp);
324 if (box->otyp == BAG_OF_HOLDING) {
328 otmp->owt = weight(otmp);
330 while (otmp->otyp == WAN_CANCELLATION)
331 otmp->otyp = rnd_class(WAN_LIGHT, WAN_LIGHTNING);
334 (void) add_to_container(box, otmp);
338 /* select a random, common monster type */
342 register struct permonst *ptr;
344 unsigned short excludeflags;
346 /* Plan A: get a level-appropriate common monster */
351 /* Plan B: get any common monster */
352 excludeflags = G_UNIQ | G_NOGEN | (Inhell ? G_NOHELL : G_HELL);
354 i = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
356 } while ((ptr->geno & excludeflags) != 0);
362 copy_oextra(obj2, obj1)
363 struct obj *obj2, *obj1;
365 if (!obj2 || !obj1 || !obj1->oextra)
369 obj2->oextra = newoextra();
371 oname(obj2, ONAME(obj1));
372 if (has_omonst(obj1)) {
375 (void) memcpy((genericptr_t) OMONST(obj2),
376 (genericptr_t) OMONST(obj1), sizeof(struct monst));
377 OMONST(obj2)->mextra = (struct mextra *) 0;
378 OMONST(obj2)->nmon = (struct monst *) 0;
380 OMONST(obj2)->m_id = context.ident++;
381 if (OMONST(obj2)->m_id) /* ident overflowed */
382 OMONST(obj2)->m_id = context.ident++;
384 if (OMONST(obj1)->mextra)
385 copy_mextra(OMONST(obj2), OMONST(obj1));
387 if (has_omid(obj1)) {
390 (void) memcpy((genericptr_t) OMID(obj2), (genericptr_t) OMID(obj1),
393 if (has_olong(obj1)) {
396 (void) memcpy((genericptr_t) OLONG(obj2), (genericptr_t) OLONG(obj1),
399 if (has_omailcmd(obj1)) {
400 new_omailcmd(obj2, OMAILCMD(obj1));
405 * Split obj so that it gets size gets reduced by num. The quantity num is
406 * put in the object structure delivered by this call. The returned object
407 * has its wornmask cleared and is positioned just following the original
408 * in the nobj chain (and nexthere chain when on the floor).
417 if (obj->cobj || num <= 0L || obj->quan <= num)
418 panic("splitobj"); /* can't split containers */
420 *otmp = *obj; /* copies whole structure */
421 otmp->oextra = (struct oextra *) 0;
422 otmp->o_id = context.ident++;
424 otmp->o_id = context.ident++; /* ident overflowed */
425 otmp->timed = 0; /* not timed, yet */
426 otmp->lamplit = 0; /* ditto */
427 otmp->owornmask = 0L; /* new object isn't worn */
429 obj->owt = weight(obj);
431 otmp->owt = weight(otmp); /* -= obj->owt ? */
433 context.objsplit.parent_oid = obj->o_id;
434 context.objsplit.child_oid = otmp->o_id;
436 /* Only set nexthere when on the floor, nexthere is also used */
437 /* as a back pointer to the container object when contained. */
438 if (obj->where == OBJ_FLOOR)
439 obj->nexthere = otmp;
440 copy_oextra(otmp, obj);
442 free_omid(otmp); /* only one association with m_id*/
444 splitbill(obj, otmp);
446 obj_split_timers(obj, otmp);
447 if (obj_sheds_light(obj))
448 obj_split_light_source(obj, otmp);
452 /* try to find the stack obj was split from, then merge them back together;
453 returns the combined object if unsplit is successful, null otherwise */
458 unsigned target_oid = 0;
459 struct obj *oparent = 0, *ochild = 0, *list = 0;
462 * We don't operate on floor objects (we're following o->nobj rather
463 * than o->nexthere), on free objects (don't know which list to use when
464 * looking for obj's parent or child), on bill objects (too complicated,
465 * not needed), or on buried or migrating objects (not needed).
466 * [This could be improved, but at present additional generality isn't
469 switch (obj->where) {
476 return (struct obj *) 0;
481 list = obj->ocarry->minvent;
484 list = obj->ocontainer->cobj;
488 /* first try the expected case; obj is split from another stack */
489 if (obj->o_id == context.objsplit.child_oid) {
490 /* parent probably precedes child and will require list traversal */
492 target_oid = context.objsplit.parent_oid;
493 if (obj->nobj && obj->nobj->o_id == target_oid)
495 } else if (obj->o_id == context.objsplit.parent_oid) {
496 /* alternate scenario: another stack was split from obj;
497 child probably follows parent and will be found here */
499 target_oid = context.objsplit.child_oid;
500 if (obj->nobj && obj->nobj->o_id == target_oid)
503 /* if we have only half the split, scan obj's list to find other half */
504 if (ochild && !oparent) {
506 for (obj = list; obj; obj = obj->nobj)
507 if (obj->o_id == target_oid) {
511 } else if (oparent && !ochild) {
512 /* alternate scenario */
513 for (obj = list; obj; obj = obj->nobj)
514 if (obj->o_id == target_oid) {
519 /* if we have both parent and child, try to merge them;
520 if successful, return the combined stack, otherwise return null */
521 return (oparent && ochild && merged(&oparent, &ochild)) ? oparent : 0;
524 /* reset splitobj()/unsplitobj() context */
528 context.objsplit.parent_oid = context.objsplit.child_oid = 0;
532 * Insert otmp right after obj in whatever chain(s) it is on. Then extract
533 * obj from the chain(s). This function does a literal swap. It is up to
534 * the caller to provide a valid context for the swap. When done, obj will
535 * still exist, but not on any chain.
537 * Note: Don't use use obj_extract_self() -- we are doing an in-place swap,
538 * not actually moving something.
541 replace_object(obj, otmp)
545 otmp->where = obj->where;
546 switch (obj->where) {
551 otmp->nobj = obj->nobj;
553 extract_nobj(obj, &invent);
556 otmp->nobj = obj->nobj;
557 otmp->ocontainer = obj->ocontainer;
559 extract_nobj(obj, &obj->ocontainer->cobj);
562 otmp->nobj = obj->nobj;
563 otmp->ocarry = obj->ocarry;
565 extract_nobj(obj, &obj->ocarry->minvent);
568 otmp->nobj = obj->nobj;
569 otmp->nexthere = obj->nexthere;
573 obj->nexthere = otmp;
574 extract_nobj(obj, &fobj);
575 extract_nexthere(obj, &level.objects[obj->ox][obj->oy]);
578 panic("replace_object: obj position");
584 * Create a dummy duplicate to put on shop bill. The duplicate exists
585 * only in the billobjs chain. This function is used when a shop object
586 * is being altered, and a copy of the original is needed for billing
587 * purposes. For example, when eating, where an interruption will yield
588 * an object which is different from what it started out as; the "I x"
589 * command needs to display the original object.
591 * The caller is responsible for checking otmp->unpaid and
592 * costly_spot(u.ux, u.uy). This function will make otmp no charge.
594 * Note that check_unpaid_usage() should be used instead for partial
595 * usage of an object.
598 bill_dummy_object(otmp)
599 register struct obj *otmp;
601 register struct obj *dummy;
605 cost = unpaid_cost(otmp, FALSE);
606 subfrombill(otmp, shop_keeper(*u.ushops));
610 dummy->oextra = (struct oextra *) 0;
611 dummy->where = OBJ_FREE;
612 dummy->o_id = context.ident++;
614 dummy->o_id = context.ident++; /* ident overflowed */
616 copy_oextra(dummy, otmp);
618 free_omid(dummy); /* only one association with m_id*/
619 if (Is_candle(dummy))
621 dummy->owornmask = 0L; /* dummy object is not worn */
622 addtobill(dummy, FALSE, TRUE, TRUE);
624 alter_cost(dummy, -cost);
625 /* no_charge is only valid for some locations */
627 (otmp->where == OBJ_FLOOR || otmp->where == OBJ_CONTAINED) ? 1 : 0;
632 /* alteration types; must match COST_xxx macros in hack.h */
633 static const char *const alteration_verbs[] = {
635 "cancel", "drain", "uncharge", "unbless", "uncurse", "disenchant",
636 "degrade", "dilute", "erase", "burn", "neutralize", "destroy", "splatter",
637 "bite", "open", "break the lock on", "rust", "rot", "tarnish"
639 "
\96³
\8cø
\89»
\82µ
\82½", "
\97ò
\89»
\82³
\82¹
\82½", "
\95ú
\8fo
\82³
\82¹
\82½", "
\8fj
\95\9f\82ð
\89ð
\82¢
\82½", "
\8eô
\82¢
\82ð
\89ð
\82¢
\82½", "
\96\82\97Í
\82ð
\8c¸
\82ç
\82µ
\82½",
640 "
\97ò
\89»
\82³
\82¹
\82½", "
\94\96\82ß
\82½", "
\8fÁ
\82µ
\82½", "
\94R
\82â
\82µ
\82½", "
\96³
\93Å
\89»
\82µ
\82½", "
\89ó
\82µ
\82½", "
\8eg
\82Á
\82½",
641 "
\90H
\82×
\82½", "
\8aJ
\82¯
\82½", "
\8c®
\82ð
\89ó
\82µ
\82½", "
\8eK
\82Ñ
\82³
\82¹
\82½", "
\95\85\82ç
\82¹
\82½", "
\8f\9d\82Â
\82¯
\82½"
645 /* possibly bill for an object which the player has just modified */
647 costly_alteration(obj, alter_type)
654 #if 0 /*JP*//*
\8eg
\82í
\82È
\82¢*/
655 const char *those, *them;
657 struct monst *shkp = 0;
659 if (alter_type < 0 || alter_type >= SIZE(alteration_verbs)) {
660 impossible("invalid alteration type (%d)", alter_type);
664 ox = oy = 0; /* lint suppression */
665 objroom = '\0'; /* ditto */
666 if (carried(obj) || obj->where == OBJ_FREE) {
667 /* OBJ_FREE catches obj_no_longer_held()'s transformation
668 of crysknife back into worm tooth; the object has been
669 removed from inventory but not necessarily placed at
670 its new location yet--the unpaid flag will still be set
671 if this item is owned by a shop */
675 /* this get_obj_location shouldn't fail, but if it does,
676 use hero's location */
677 if (!get_obj_location(obj, &ox, &oy, CONTAINED_TOO))
678 ox = u.ux, oy = u.uy;
679 if (!costly_spot(ox, oy))
681 objroom = *in_rooms(ox, oy, SHOPBASE);
682 /* if no shop cares about it, we're done */
683 if (!billable(&shkp, obj, objroom, FALSE))
687 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
689 those = "that", them = "it";
691 those = "those", them = "them";
694 /* when shopkeeper describes the object as being uncursed or unblessed
695 hero will know that it is now uncursed; will also make the feedback
696 from `I x' after bill_dummy_object() be more specific for this item */
697 set_bknown = (alter_type == COST_UNCURS || alter_type == COST_UNBLSS);
699 switch (obj->where) {
700 case OBJ_FREE: /* obj_no_longer_held() */
705 verbalize("You %s %s %s, you pay for %s!",
706 alteration_verbs[alter_type], those, simpleonames(obj),
709 verbalize("%s
\82ð%s
\82Ì
\82È
\82ç
\81C
\94\83\82Á
\82Ä
\82à
\82ç
\82¤
\82æ
\81I",
710 simpleonames(obj), alteration_verbs[alter_type]);
712 bill_dummy_object(obj);
717 if (costly_spot(u.ux, u.uy) && objroom == *u.ushops) {
719 verbalize("You %s %s, you pay for %s!",
720 alteration_verbs[alter_type], those, them);
722 verbalize("%s
\82Ì
\82È
\82ç
\81C
\94\83\82Á
\82Ä
\82à
\82ç
\82¤
\82æ
\81I",
723 alteration_verbs[alter_type]);
725 bill_dummy_object(obj);
727 (void) stolen_value(obj, ox, oy, FALSE, FALSE);
733 static const char dknowns[] = { WAND_CLASS, RING_CLASS, POTION_CLASS,
734 SCROLL_CLASS, GEM_CLASS, SPBOOK_CLASS,
735 WEAPON_CLASS, TOOL_CLASS, 0 };
738 mksobj(otyp, init, artif)
745 char let = objects[otyp].oc_class;
749 otmp->age = monstermoves;
750 otmp->o_id = context.ident++;
752 otmp->o_id = context.ident++; /* ident overflowed */
756 otmp->where = OBJ_FREE;
757 otmp->dknown = index(dknowns, let) ? 0 : 1;
758 if ((otmp->otyp >= ELVEN_SHIELD && otmp->otyp <= ORCISH_SHIELD)
759 || otmp->otyp == SHIELD_OF_REFLECTION)
761 if (!objects[otmp->otyp].oc_uses_known)
765 otmp->corpsenm = NON_PM;
770 otmp->quan = is_multigen(otmp) ? (long) rn1(6, 6) : 1L;
773 otmp->blessed = rn2(2);
774 } else if (!rn2(10)) {
778 blessorcurse(otmp, 10);
779 if (is_poisonable(otmp) && !rn2(100))
782 if (artif && !rn2(20))
783 otmp = mk_artifact(otmp, (aligntyp) A_NONE);
787 switch (otmp->otyp) {
789 /* possibly overridden by mkcorpstat() */
792 otmp->corpsenm = undead_to_corpse(rndmonnum());
793 while ((mvitals[otmp->corpsenm].mvflags & G_NOCORPSE)
796 /* perhaps rndmonnum() only wants to make G_NOCORPSE
798 this level; let's create an adventurer's corpse
800 otmp->corpsenm = PM_HUMAN;
802 /* timer set below */
805 otmp->corpsenm = NON_PM; /* generic egg */
807 for (tryct = 200; tryct > 0; --tryct) {
808 mndx = can_be_hatched(rndmonnum());
809 if (mndx != NON_PM && !dead_species(mndx, TRUE)) {
810 otmp->corpsenm = mndx; /* typed egg */
814 /* timer set below */
817 otmp->corpsenm = NON_PM; /* empty (so far) */
819 set_tin_variety(otmp, SPINACH_TIN);
821 for (tryct = 200; tryct > 0; --tryct) {
822 mndx = undead_to_corpse(rndmonnum());
823 if (mons[mndx].cnutrit
824 && !(mvitals[mndx].mvflags & G_NOCORPSE)) {
825 otmp->corpsenm = mndx;
826 set_tin_variety(otmp, RANDOM_TIN);
830 blessorcurse(otmp, 10);
833 otmp->spe = context.current_fruit;
834 flags.made_fruit = TRUE;
837 otmp->quan = (long) rnd(2);
840 if (Is_pudding(otmp)) {
842 otmp->known = otmp->bknown = otmp->rknown = otmp->dknown = 1;
844 PM_GRAY_OOZE + (otmp->otyp - GLOB_OF_GRAY_OOZE);
845 /* this ensures that they don't fail merging because of
846 * BUC status or other irrelevancies */
848 if (otmp->otyp != CORPSE && otmp->otyp != MEAT_RING
849 && otmp->otyp != KELP_FROND && !rn2(6)) {
855 otmp->corpsenm = 0; /* LOADSTONE hack */
856 if (otmp->otyp == LOADSTONE)
858 else if (otmp->otyp == ROCK)
859 otmp->quan = (long) rn1(6, 6);
860 else if (otmp->otyp != LUCKSTONE && !rn2(6))
866 switch (otmp->otyp) {
870 otmp->age = 20L * /* 400 or 200 */
871 (long) objects[otmp->otyp].oc_cost;
873 otmp->quan = 1L + (long) (rn2(2) ? rn2(7) : 0);
874 blessorcurse(otmp, 5);
879 otmp->age = (long) rn1(500, 1000);
881 blessorcurse(otmp, 5);
886 blessorcurse(otmp, 2);
890 otmp->olocked = !!(rn2(5));
891 otmp->otrapped = !(rn2(10));
901 case EXPENSIVE_CAMERA:
904 otmp->spe = rn1(70, 30);
908 blessorcurse(otmp, 10);
912 blessorcurse(otmp, 2);
921 otmp->corpsenm = rndmonnum();
922 while (is_human(&mons[otmp->corpsenm]) && tryct2++ < 30);
923 blessorcurse(otmp, 4);
926 case BELL_OF_OPENING:
933 case DRUM_OF_EARTHQUAKE:
934 otmp->spe = rn1(5, 4);
939 if (otmp->otyp == AMULET_OF_YENDOR)
940 context.made_amulet = TRUE;
941 if (rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION
942 || otmp->otyp == AMULET_OF_CHANGE
943 || otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) {
946 blessorcurse(otmp, 10);
953 if (otmp->otyp == POT_OIL)
954 otmp->age = MAX_OIL_IN_FLASK; /* amount of oil */
958 if (otmp->otyp != SCR_MAIL)
960 blessorcurse(otmp, 4);
963 otmp->spestudied = 0;
964 blessorcurse(otmp, 17);
968 && (otmp->otyp == FUMBLE_BOOTS
969 || otmp->otyp == LEVITATION_BOOTS
970 || otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT
971 || otmp->otyp == GAUNTLETS_OF_FUMBLING || !rn2(11))) {
974 } else if (!rn2(10)) {
975 otmp->blessed = rn2(2);
978 blessorcurse(otmp, 10);
979 if (artif && !rn2(40))
980 otmp = mk_artifact(otmp, (aligntyp) A_NONE);
981 /* simulate lacquered armor for samurai */
982 if (Role_if(PM_SAMURAI) && otmp->otyp == SPLINT_MAIL
983 && (moves <= 1 || In_quest(&u.uz))) {
985 /* optimizer bitfield bug */
986 otmp->oerodeproof = 1;
989 otmp->oerodeproof = otmp->rknown = 1;
994 if (otmp->otyp == WAN_WISHING)
998 rn1(5, (objects[otmp->otyp].oc_dir == NODIR) ? 11 : 4);
999 blessorcurse(otmp, 17);
1000 otmp->recharged = 0; /* used to control recharging */
1003 if (objects[otmp->otyp].oc_charged) {
1004 blessorcurse(otmp, 3);
1006 if (rn2(10) && bcsign(otmp))
1007 otmp->spe = bcsign(otmp) * rne(3);
1009 otmp->spe = rn2(2) ? rne(3) : -rne(3);
1011 /* make useless +0 rings much less common */
1013 otmp->spe = rn2(4) - rn2(3);
1014 /* negative rings are usually cursed */
1015 if (otmp->spe < 0 && rn2(5))
1017 } else if (rn2(10) && (otmp->otyp == RIN_TELEPORTATION
1018 || otmp->otyp == RIN_POLYMORPH
1019 || otmp->otyp == RIN_AGGRAVATE_MONSTER
1020 || otmp->otyp == RIN_HUNGER || !rn2(9))) {
1025 switch (otmp->otyp) {
1027 /* possibly overridden by mkcorpstat() */
1028 otmp->corpsenm = rndmonnum();
1029 if (!verysmall(&mons[otmp->corpsenm])
1030 && rn2(level_difficulty() / 2 + 10) > 10)
1031 (void) add_to_container(otmp, mkobj(SPBOOK_CLASS, FALSE));
1035 break; /* do nothing */
1037 impossible("impossible mkobj %d, sym '%c'.", otmp->otyp,
1038 objects[otmp->otyp].oc_class);
1039 return (struct obj *) 0;
1042 /* some things must get done (corpsenm, timers) even if init = 0 */
1043 switch (otmp->otyp) {
1045 if (otmp->corpsenm == NON_PM) {
1046 otmp->corpsenm = undead_to_corpse(rndmonnum());
1047 if (mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE | G_GONE))
1048 otmp->corpsenm = urole.malenum;
1053 if (otmp->corpsenm == NON_PM)
1054 otmp->corpsenm = rndmonnum();
1058 set_corpsenm(otmp, otmp->corpsenm);
1061 otmp->novelidx = -1; /* "none of the above"; will be changed */
1062 otmp = oname(otmp, noveltitle(&otmp->novelidx));
1066 /* unique objects may have an associated artifact entry */
1067 if (objects[otyp].oc_unique && !otmp->oartifact)
1068 otmp = mk_artifact(otmp, (aligntyp) A_NONE);
1069 otmp->owt = weight(otmp);
1074 * Several areas of the code made direct reassignments
1075 * to obj->corpsenm. Because some special handling is
1076 * required in certain cases, place that handling here
1077 * and call this routine in place of the direct assignment.
1079 * If the object was a lizard or lichen corpse:
1080 * - ensure that you don't end up with some
1081 * other corpse type which has no rot-away timer.
1083 * If the object was a troll corpse:
1084 * - ensure that you don't end up with some other
1085 * corpse type which resurrects from the dead.
1087 * Re-calculates the weight of figurines and corpses to suit the
1090 * Existing timeout value for egg hatch is preserved.
1094 set_corpsenm(obj, id)
1101 if (obj->otyp == EGG)
1102 when = stop_timer(HATCH_EGG, obj_to_any(obj));
1105 obj_stop_timers(obj); /* corpse or figurine */
1109 switch (obj->otyp) {
1111 start_corpse_timeout(obj);
1112 obj->owt = weight(obj);
1115 if (obj->corpsenm != NON_PM && !dead_species(obj->corpsenm, TRUE)
1116 && (carried(obj) || mcarried(obj)))
1117 attach_fig_transform_timeout(obj);
1118 obj->owt = weight(obj);
1121 if (obj->corpsenm != NON_PM && !dead_species(obj->corpsenm, TRUE))
1122 attach_egg_hatch_timeout(obj, when);
1124 default: /* tin, etc. */
1125 obj->owt = weight(obj);
1131 * Start a corpse decay or revive timer.
1132 * This takes the age of the corpse into consideration as of 3.4.0.
1135 start_corpse_timeout(body)
1138 long when; /* rot away when this old */
1139 long corpse_age; /* age of corpse */
1143 #define TAINT_AGE (50L) /* age when corpses go bad */
1144 #define TROLL_REVIVE_CHANCE 37 /* 1/37 chance for 50 turns ~ 75% chance */
1145 #define ROT_AGE (250L) /* age when corpses rot away */
1147 /* lizards and lichen don't rot or revive */
1148 if (body->corpsenm == PM_LIZARD || body->corpsenm == PM_LICHEN)
1151 action = ROT_CORPSE; /* default action: rot away */
1152 rot_adjust = in_mklev ? 25 : 10; /* give some variation */
1153 corpse_age = monstermoves - body->age;
1154 if (corpse_age > ROT_AGE)
1157 when = ROT_AGE - corpse_age;
1158 when += (long) (rnz(rot_adjust) - rot_adjust);
1160 if (is_rider(&mons[body->corpsenm])) {
1162 * Riders always revive. They have a 1/3 chance per turn
1163 * of reviving after 12 turns. Always revive by 500.
1165 action = REVIVE_MON;
1166 for (when = 12L; when < 500L; when++)
1170 } else if (mons[body->corpsenm].mlet == S_TROLL && !body->norevive) {
1172 for (age = 2; age <= TAINT_AGE; age++)
1173 if (!rn2(TROLL_REVIVE_CHANCE)) { /* troll revives */
1174 action = REVIVE_MON;
1182 (void) start_timer(when, TIMER_OBJECT, action, obj_to_any(body));
1186 maybe_adjust_light(obj, old_range)
1192 int new_range = arti_light_radius(obj), delta = new_range - old_range;
1194 /* radius of light emitting artifact varies by curse/bless state
1195 so will change after blessing or cursing */
1197 obj_adjust_light_radius(obj, new_range);
1198 /* simplifying assumptions: hero is wielding this object;
1199 artifacts have to be in use to emit light and monsters'
1200 gear won't change bless or curse state */
1201 if (!Blind && get_obj_location(obj, &ox, &oy, 0)) {
1203 if (iflags.last_msg == PLNMSG_OBJ_GLOWS)
1204 /* we just saw "The <obj> glows <color>." from dipping */
1205 Strcpy(buf, (obj->quan == 1L) ? "It" : "They");
1206 else if (carried(obj) || cansee(ox, oy))
1207 Strcpy(buf, Yname2(obj));
1209 /* initial activation says "dimly" if cursed,
1210 "brightly" if uncursed, and "brilliantly" if blessed;
1211 when changing intensity, using "less brightly" is
1212 straightforward for dimming, but we need "brighter"
1213 rather than "more brightly" for brightening; ugh */
1214 pline("%s %s %s%s.", buf, otense(obj, "shine"),
1215 (abs(delta) > 1) ? "much " : "",
1216 (delta > 0) ? "brighter" : "less brightly");
1223 * bless(), curse(), unbless(), uncurse() -- any relevant message
1224 * about glowing amber/black/&c should be delivered prior to calling
1225 * these routines to make the actual curse/bless state change.
1230 register struct obj *otmp;
1234 if (otmp->oclass == COIN_CLASS)
1237 old_light = arti_light_radius(otmp);
1240 if (carried(otmp) && confers_luck(otmp))
1242 else if (otmp->otyp == BAG_OF_HOLDING)
1243 otmp->owt = weight(otmp);
1244 else if (otmp->otyp == FIGURINE && otmp->timed)
1245 (void) stop_timer(FIG_TRANSFORM, obj_to_any(otmp));
1247 maybe_adjust_light(otmp, old_light);
1253 register struct obj *otmp;
1258 old_light = arti_light_radius(otmp);
1260 if (carried(otmp) && confers_luck(otmp))
1262 else if (otmp->otyp == BAG_OF_HOLDING)
1263 otmp->owt = weight(otmp);
1265 maybe_adjust_light(otmp, old_light);
1270 register struct obj *otmp;
1274 if (otmp->oclass == COIN_CLASS)
1277 old_light = arti_light_radius(otmp);
1280 /* welded two-handed weapon interferes with some armor removal */
1281 if (otmp == uwep && bimanual(uwep))
1283 /* rules at top of wield.c state that twoweapon cannot be done
1284 with cursed alternate weapon */
1285 if (otmp == uswapwep && u.twoweap)
1287 /* some cursed items need immediate updating */
1288 if (carried(otmp) && confers_luck(otmp))
1290 else if (otmp->otyp == BAG_OF_HOLDING)
1291 otmp->owt = weight(otmp);
1292 else if (otmp->otyp == FIGURINE) {
1293 if (otmp->corpsenm != NON_PM && !dead_species(otmp->corpsenm, TRUE)
1294 && (carried(otmp) || mcarried(otmp)))
1295 attach_fig_transform_timeout(otmp);
1298 maybe_adjust_light(otmp, old_light);
1304 register struct obj *otmp;
1309 old_light = arti_light_radius(otmp);
1311 if (carried(otmp) && confers_luck(otmp))
1313 else if (otmp->otyp == BAG_OF_HOLDING)
1314 otmp->owt = weight(otmp);
1315 else if (otmp->otyp == FIGURINE && otmp->timed)
1316 (void) stop_timer(FIG_TRANSFORM, obj_to_any(otmp));
1318 maybe_adjust_light(otmp, old_light);
1323 blessorcurse(otmp, chance)
1324 register struct obj *otmp;
1325 register int chance;
1327 if (otmp->blessed || otmp->cursed)
1342 register struct obj *otmp;
1344 return (!!otmp->blessed - !!otmp->cursed);
1348 * Calculate the weight of the given object. This will recursively follow
1349 * and calculate the weight of any containers.
1351 * Note: It is possible to end up with an incorrect weight if some part
1352 * of the code messes with a contained object and doesn't update the
1353 * container's weight.
1357 register struct obj *obj;
1359 int wt = objects[obj->otyp].oc_weight;
1361 if (SchroedingersBox(obj))
1362 wt += mons[PM_HOUSECAT].cwt;
1363 if (Is_container(obj) || obj->otyp == STATUE) {
1364 struct obj *contents;
1365 register int cwt = 0;
1367 if (obj->otyp == STATUE && obj->corpsenm >= LOW_PM)
1368 wt = (int) obj->quan * ((int) mons[obj->corpsenm].cwt * 3 / 2);
1370 for (contents = obj->cobj; contents; contents = contents->nobj)
1371 cwt += weight(contents);
1373 * The weight of bags of holding is calculated as the weight
1374 * of the bag plus the weight of the bag's contents modified
1377 * Bag status Weight of contents
1378 * ---------- ------------------
1380 * blessed x/4 [rounded up: (x+3)/4]
1381 * otherwise x/2 [rounded up: (x+1)/2]
1383 * The macro DELTA_CWT in pickup.c also implements these
1386 if (obj->otyp == BAG_OF_HOLDING)
1387 cwt = obj->cursed ? (cwt * 2) : obj->blessed ? ((cwt + 3) / 4)
1392 if (obj->otyp == CORPSE && obj->corpsenm >= LOW_PM) {
1393 long long_wt = obj->quan * (long) mons[obj->corpsenm].cwt;
1395 wt = (long_wt > LARGEST_INT) ? LARGEST_INT : (int) long_wt;
1397 wt = eaten_stat(wt, obj);
1399 } else if (obj->oclass == FOOD_CLASS && obj->oeaten) {
1400 return eaten_stat((int) obj->quan * wt, obj);
1401 } else if (obj->oclass == COIN_CLASS) {
1402 return (int) ((obj->quan + 50L) / 100L);
1403 } else if (obj->otyp == HEAVY_IRON_BALL && obj->owt != 0) {
1404 return (int) obj->owt; /* kludge for "very" heavy iron ball */
1406 return (wt ? wt * (int) obj->quan : ((int) obj->quan + 1) >> 1);
1409 static int treefruits[] = { APPLE, ORANGE, PEAR, BANANA, EUCALYPTUS_LEAF };
1412 rnd_treefruit_at(x, y)
1415 return mksobj_at(treefruits[rn2(SIZE(treefruits))], x, y, TRUE, FALSE);
1419 mkgold(amount, x, y)
1423 register struct obj *gold = g_at(x, y);
1426 amount = (long) (1 + rnd(level_difficulty() + 2) * rnd(30));
1428 gold->quan += amount;
1430 gold = mksobj_at(GOLD_PIECE, x, y, TRUE, FALSE);
1431 gold->quan = amount;
1433 gold->owt = weight(gold);
1437 /* return TRUE if the corpse has special timing */
1438 #define special_corpse(num) \
1439 (((num) == PM_LIZARD) || ((num) == PM_LICHEN) || (is_rider(&mons[num])) \
1440 || (mons[num].mlet == S_TROLL))
1443 * OEXTRA note: Passing mtmp causes mtraits to be saved
1444 * even if ptr passed as well, but ptr is always used for
1445 * the corpse type (corpsenm). That allows the corpse type
1446 * to be different from the original monster,
1447 * i.e. vampire -> human corpse
1448 * yet still allow restoration of the original monster upon
1452 mkcorpstat(objtype, mtmp, ptr, x, y, corpstatflags)
1453 int objtype; /* CORPSE or STATUE */
1455 struct permonst *ptr;
1457 unsigned corpstatflags;
1459 register struct obj *otmp;
1460 boolean init = ((corpstatflags & CORPSTAT_INIT) != 0);
1462 if (objtype != CORPSE && objtype != STATUE)
1463 impossible("making corpstat type %d", objtype);
1464 if (x == 0 && y == 0) { /* special case - random placement */
1465 otmp = mksobj(objtype, init, FALSE);
1469 otmp = mksobj_at(objtype, x, y, init, FALSE);
1476 /* save_mtraits frees original data pointed to by otmp */
1477 otmp2 = save_mtraits(otmp, mtmp);
1481 /* use the corpse or statue produced by mksobj() as-is
1482 unless `ptr' is non-null */
1484 int old_corpsenm = otmp->corpsenm;
1486 otmp->corpsenm = monsndx(ptr);
1487 otmp->owt = weight(otmp);
1488 if (otmp->otyp == CORPSE && (special_corpse(old_corpsenm)
1489 || special_corpse(otmp->corpsenm))) {
1490 obj_stop_timers(otmp);
1491 start_corpse_timeout(otmp);
1499 * Return the type of monster that this corpse will
1500 * revive as, even if it has a monster structure
1501 * attached to it. In that case, you can't just
1502 * use obj->corpsenm, because the stored monster
1503 * type can, and often is, different.
1504 * The return value is an index into mons[].
1507 corpse_revive_type(obj)
1513 && ((mtmp = get_mtraits(obj, FALSE)) != (struct monst *) 0)) {
1514 /* mtmp is a temporary pointer to a monster's stored
1515 attributes, not a real monster */
1516 revivetype = mtmp->mnum;
1518 revivetype = obj->corpsenm;
1523 * Attach a monster id to an object, to provide
1524 * a lasting association between the two.
1527 obj_attach_mid(obj, mid)
1532 return (struct obj *) 0;
1539 save_mtraits(obj, mtmp)
1544 forget_temple_entry(mtmp); /* EPRI() */
1545 if (!has_omonst(obj))
1547 if (has_omonst(obj)) {
1548 struct monst *mtmp2 = OMONST(obj);
1551 mtmp2->mextra = (struct mextra *) 0;
1553 mtmp2->mnum = monsndx(mtmp->data);
1554 /* invalidate pointers */
1555 /* m_id is needed to know if this is a revived quest leader */
1556 /* but m_id must be cleared when loading bones */
1557 mtmp2->nmon = (struct monst *) 0;
1558 mtmp2->data = (struct permonst *) 0;
1559 mtmp2->minvent = (struct obj *) 0;
1561 copy_mextra(mtmp2, mtmp);
1566 /* returns a pointer to a new monst structure based on
1567 * the one contained within the obj.
1570 get_mtraits(obj, copyof)
1574 struct monst *mtmp = (struct monst *) 0;
1575 struct monst *mnew = (struct monst *) 0;
1577 if (has_omonst(obj))
1583 mnew->mextra = (struct mextra *) 0;
1585 copy_mextra(mnew, mtmp);
1587 /* Never insert this returned pointer into mon chains! */
1594 /* make an object named after someone listed in the scoreboard file */
1596 mk_tt_object(objtype, x, y)
1597 int objtype; /* CORPSE or STATUE */
1600 register struct obj *otmp, *otmp2;
1601 boolean initialize_it;
1603 /* player statues never contain books */
1604 initialize_it = (objtype != STATUE);
1605 if ((otmp = mksobj_at(objtype, x, y, initialize_it, FALSE)) != 0) {
1606 /* tt_oname will return null if the scoreboard is empty */
1607 if ((otmp2 = tt_oname(otmp)) != 0)
1613 /* make a new corpse or statue, uninitialized if a statue (i.e. no books) */
1615 mk_named_object(objtype, ptr, x, y, nm)
1616 int objtype; /* CORPSE or STATUE */
1617 struct permonst *ptr;
1622 unsigned corpstatflags =
1623 (objtype != STATUE) ? CORPSTAT_INIT : CORPSTAT_NONE;
1625 otmp = mkcorpstat(objtype, (struct monst *) 0, ptr, x, y, corpstatflags);
1627 otmp = oname(otmp, nm);
1633 register struct obj *otmp;
1635 int otyp = otmp->otyp;
1636 int omat = objects[otyp].oc_material;
1638 /* Candles can be burned, but they're not flammable in the sense that
1639 * they can't get fire damage and it makes no sense for them to be
1642 if (Is_candle(otmp))
1645 if (objects[otyp].oc_oprop == FIRE_RES || otyp == WAN_FIRE)
1648 return (boolean) ((omat <= WOOD && omat != LIQUID) || omat == PLASTIC);
1653 register struct obj *otmp;
1655 int otyp = otmp->otyp;
1657 return (boolean) (objects[otyp].oc_material <= WOOD
1658 && objects[otyp].oc_material != LIQUID);
1662 * These routines maintain the single-linked lists headed in level.objects[][]
1663 * and threaded through the nexthere fields in the object-instance structure.
1666 /* put the object at the given location */
1668 place_object(otmp, x, y)
1669 register struct obj *otmp;
1672 register struct obj *otmp2 = level.objects[x][y];
1674 if (otmp->where != OBJ_FREE)
1675 panic("place_object: obj not free");
1677 obj_no_longer_held(otmp);
1678 /* (could bypass this vision update if there is already a boulder here) */
1679 if (otmp->otyp == BOULDER)
1680 block_point(x, y); /* vision */
1682 /* obj goes under boulders */
1683 if (otmp2 && (otmp2->otyp == BOULDER)) {
1684 otmp->nexthere = otmp2->nexthere;
1685 otmp2->nexthere = otmp;
1687 otmp->nexthere = otmp2;
1688 level.objects[x][y] = otmp;
1691 /* set the new object's location */
1695 otmp->where = OBJ_FLOOR;
1697 /* add to floor chain */
1701 obj_timer_checks(otmp, x, y, 0);
1704 #define ROT_ICE_ADJUSTMENT 2 /* rotting on ice takes 2 times as long */
1706 /* If ice was affecting any objects correct that now
1707 * Also used for starting ice effects too. [zap.c]
1710 obj_ice_effects(x, y, do_buried)
1716 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) {
1718 obj_timer_checks(otmp, x, y, 0);
1721 for (otmp = level.buriedobjlist; otmp; otmp = otmp->nobj) {
1722 if (otmp->ox == x && otmp->oy == y) {
1724 obj_timer_checks(otmp, x, y, 0);
1731 * Returns an obj->age for a corpse object on ice, that would be the
1732 * actual obj->age if the corpse had just been lifted from the ice.
1733 * This is useful when just using obj->age in a check or calculation because
1734 * rot timers pertaining to the object don't have to be stopped and
1738 peek_at_iced_corpse_age(otmp)
1741 long age, retval = otmp->age;
1743 if (otmp->otyp == CORPSE && otmp->on_ice) {
1744 /* Adjust the age; must be same as obj_timer_checks() for off ice*/
1745 age = monstermoves - otmp->age;
1746 retval += age * (ROT_ICE_ADJUSTMENT - 1) / ROT_ICE_ADJUSTMENT;
1748 "The %s age has ice modifications: otmp->age = %ld, returning %ld.",
1749 s_suffix(doname(otmp)), otmp->age, retval);
1750 debugpline1("Effective age of corpse: %ld.", monstermoves - retval);
1756 obj_timer_checks(otmp, x, y, force)
1759 int force; /* 0 = no force so do checks, <0 = force off, >0 force on */
1762 short action = ROT_CORPSE;
1763 boolean restart_timer = FALSE;
1764 boolean on_floor = (otmp->where == OBJ_FLOOR);
1765 boolean buried = (otmp->where == OBJ_BURIED);
1767 /* Check for corpses just placed on or in ice */
1768 if (otmp->otyp == CORPSE && (on_floor || buried) && is_ice(x, y)) {
1769 tleft = stop_timer(action, obj_to_any(otmp));
1771 action = REVIVE_MON;
1772 tleft = stop_timer(action, obj_to_any(otmp));
1777 /* mark the corpse as being on ice */
1779 debugpline3("%s is now on ice at <%d,%d>.", The(xname(otmp)), x,
1781 /* Adjust the time remaining */
1782 tleft *= ROT_ICE_ADJUSTMENT;
1783 restart_timer = TRUE;
1784 /* Adjust the age; time spent off ice needs to be multiplied
1785 by the ice adjustment and subtracted from the age so that
1786 later calculations behave as if it had been on ice during
1787 that time (longwinded way of saying this is the inverse
1788 of removing it from the ice and of peeking at its age). */
1789 age = monstermoves - otmp->age;
1790 otmp->age = monstermoves - (age * ROT_ICE_ADJUSTMENT);
1793 /* Check for corpses coming off ice */
1794 } else if (force < 0 || (otmp->otyp == CORPSE && otmp->on_ice
1795 && !((on_floor || buried) && is_ice(x, y)))) {
1796 tleft = stop_timer(action, obj_to_any(otmp));
1798 action = REVIVE_MON;
1799 tleft = stop_timer(action, obj_to_any(otmp));
1805 debugpline3("%s is no longer on ice at <%d,%d>.",
1806 The(xname(otmp)), x, y);
1807 /* Adjust the remaining time */
1808 tleft /= ROT_ICE_ADJUSTMENT;
1809 restart_timer = TRUE;
1810 /* Adjust the age */
1811 age = monstermoves - otmp->age;
1812 otmp->age += age * (ROT_ICE_ADJUSTMENT - 1) / ROT_ICE_ADJUSTMENT;
1816 /* now re-start the timer with the appropriate modifications */
1818 (void) start_timer(tleft, TIMER_OBJECT, action, obj_to_any(otmp));
1821 #undef ROT_ICE_ADJUSTMENT
1825 register struct obj *otmp;
1830 if (otmp->where != OBJ_FLOOR)
1831 panic("remove_object: obj not on floor");
1832 extract_nexthere(otmp, &level.objects[x][y]);
1833 extract_nobj(otmp, &fobj);
1834 /* update vision iff this was the only boulder at its spot */
1835 if (otmp->otyp == BOULDER && !sobj_at(BOULDER, x, y))
1836 unblock_point(x, y); /* vision */
1838 obj_timer_checks(otmp, x, y, 0);
1841 /* throw away all of a monster's inventory */
1843 discard_minvent(mtmp)
1846 struct obj *otmp, *mwep = MON_WEP(mtmp);
1847 boolean keeping_mon = (mtmp->mhp > 0);
1849 while ((otmp = mtmp->minvent) != 0) {
1850 /* this has now become very similar to m_useupall()... */
1851 obj_extract_self(otmp);
1852 if (otmp->owornmask) {
1855 mwepgone(mtmp), mwep = 0;
1856 mtmp->misc_worn_check &= ~otmp->owornmask;
1857 update_mon_intrinsics(mtmp, otmp, FALSE, TRUE);
1859 otmp->owornmask = 0L; /* obfree() expects this */
1861 obfree(otmp, (struct obj *) 0); /* dealloc_obj() isn't sufficient */
1866 * Free obj from whatever list it is on in preparation for deleting it
1867 * or moving it elsewhere; obj->where will end up set to OBJ_FREE.
1868 * Doesn't handle unwearing of objects in hero's or monsters' inventories.
1871 * OBJ_FREE not on any list
1872 * OBJ_FLOOR fobj, level.locations[][] chains (use remove_object)
1873 * OBJ_CONTAINED cobj chain of container object
1874 * OBJ_INVENT hero's invent chain (use freeinv)
1875 * OBJ_MINVENT monster's invent chain
1876 * OBJ_MIGRATING migrating chain
1877 * OBJ_BURIED level.buriedobjs chain
1878 * OBJ_ONBILL on billobjs chain
1881 obj_extract_self(obj)
1884 switch (obj->where) {
1891 extract_nobj(obj, &obj->ocontainer->cobj);
1892 container_weight(obj->ocontainer);
1898 extract_nobj(obj, &obj->ocarry->minvent);
1901 extract_nobj(obj, &migrating_objs);
1904 extract_nobj(obj, &level.buriedobjlist);
1907 extract_nobj(obj, &billobjs);
1910 panic("obj_extract_self");
1915 /* Extract the given object from the chain, following nobj chain. */
1917 extract_nobj(obj, head_ptr)
1918 struct obj *obj, **head_ptr;
1920 struct obj *curr, *prev;
1923 for (prev = (struct obj *) 0; curr; prev = curr, curr = curr->nobj) {
1926 prev->nobj = curr->nobj;
1928 *head_ptr = curr->nobj;
1933 panic("extract_nobj: object lost");
1934 obj->where = OBJ_FREE;
1939 * Extract the given object from the chain, following nexthere chain.
1941 * This does not set obj->where, this function is expected to be called
1942 * in tandem with extract_nobj, which does set it.
1945 extract_nexthere(obj, head_ptr)
1946 struct obj *obj, **head_ptr;
1948 struct obj *curr, *prev;
1951 for (prev = (struct obj *) 0; curr; prev = curr, curr = curr->nexthere) {
1954 prev->nexthere = curr->nexthere;
1956 *head_ptr = curr->nexthere;
1961 panic("extract_nexthere: object lost");
1965 * Add obj to mon's inventory. If obj is able to merge with something already
1966 * in the inventory, then the passed obj is deleted and 1 is returned.
1967 * Otherwise 0 is returned.
1970 add_to_minv(mon, obj)
1976 if (obj->where != OBJ_FREE)
1977 panic("add_to_minv: obj not free");
1979 /* merge if possible */
1980 for (otmp = mon->minvent; otmp; otmp = otmp->nobj)
1981 if (merged(&otmp, &obj))
1982 return 1; /* obj merged and then free'd */
1983 /* else insert; don't bother forcing it to end of chain */
1984 obj->where = OBJ_MINVENT;
1986 obj->nobj = mon->minvent;
1988 return 0; /* obj on mon's inventory chain */
1992 * Add obj to container, make sure obj is "free". Returns (merged) obj.
1993 * The input obj may be deleted in the process.
1996 add_to_container(container, obj)
1997 struct obj *container, *obj;
2001 if (obj->where != OBJ_FREE)
2002 panic("add_to_container: obj not free");
2003 if (container->where != OBJ_INVENT && container->where != OBJ_MINVENT)
2004 obj_no_longer_held(obj);
2006 /* merge if possible */
2007 for (otmp = container->cobj; otmp; otmp = otmp->nobj)
2008 if (merged(&otmp, &obj))
2011 obj->where = OBJ_CONTAINED;
2012 obj->ocontainer = container;
2013 obj->nobj = container->cobj;
2014 container->cobj = obj;
2019 add_to_migration(obj)
2022 if (obj->where != OBJ_FREE)
2023 panic("add_to_migration: obj not free");
2025 obj->where = OBJ_MIGRATING;
2026 obj->nobj = migrating_objs;
2027 migrating_objs = obj;
2034 if (obj->where != OBJ_FREE)
2035 panic("add_to_buried: obj not free");
2037 obj->where = OBJ_BURIED;
2038 obj->nobj = level.buriedobjlist;
2039 level.buriedobjlist = obj;
2042 /* Recalculate the weight of this container and all of _its_ containers. */
2044 container_weight(container)
2045 struct obj *container;
2047 container->owt = weight(container);
2048 if (container->where == OBJ_CONTAINED)
2049 container_weight(container->ocontainer);
2051 else if (container->where == OBJ_INVENT)
2052 recalculate load delay here ???
2057 * Deallocate the object. _All_ objects should be run through here for
2058 * them to be deallocated.
2064 if (obj->where != OBJ_FREE)
2065 panic("dealloc_obj: obj not free");
2067 panic("dealloc_obj with nobj");
2069 panic("dealloc_obj with cobj");
2071 /* free up any timers attached to the object */
2073 obj_stop_timers(obj);
2076 * Free up any light sources attached to the object.
2078 * We may want to just call del_light_source() without any
2079 * checks (requires a code change there). Otherwise this
2080 * list must track all objects that can have a light source
2081 * attached to it (and also requires lamplit to be set).
2083 if (obj_sheds_light(obj))
2084 del_light_source(LS_OBJECT, obj_to_any(obj));
2086 if (obj == thrownobj)
2088 if (obj == kickedobj)
2092 dealloc_oextra(obj);
2093 free((genericptr_t) obj);
2096 /* create an object from a horn of plenty; mirrors bagotricks(makemon.c) */
2098 hornoplenty(horn, tipping)
2100 boolean tipping; /* caller emptying entire contents; affects shop handling */
2104 if (!horn || horn->otyp != HORN_OF_PLENTY) {
2105 impossible("bad horn o' plenty");
2106 } else if (horn->spe < 1) {
2107 pline1(nothing_happens);
2112 consume_obj_charge(horn, !tipping);
2114 obj = mkobj(POTION_CLASS, FALSE);
2115 if (objects[obj->otyp].oc_magic)
2117 obj->otyp = rnd_class(POT_BOOZE, POT_WATER);
2118 } while (obj->otyp == POT_SICKNESS);
2120 what = (obj->quan > 1L) ? "Some potions" : "A potion";
2124 obj = mkobj(FOOD_CLASS, FALSE);
2125 if (obj->otyp == FOOD_RATION && !rn2(7))
2126 obj->otyp = LUMP_OF_ROYAL_JELLY;
2130 what = "
\90H
\82×
\95¨";
2134 pline("%s %s out.", what, vtense(what, "spill"));
2136 pline("%s
\82ª
\94ò
\82Ñ
\8fo
\82Ä
\82«
\82½
\81D", what);
2137 obj->blessed = horn->blessed;
2138 obj->cursed = horn->cursed;
2139 obj->owt = weight(obj);
2140 /* using a shop's horn of plenty entails a usage fee and also
2141 confers ownership of the created item to the shopkeeper */
2143 addtobill(obj, FALSE, FALSE, tipping);
2144 /* if it ended up on bill, we don't want "(unpaid, N zorkids)"
2145 being included in its formatted name during next message */
2146 iflags.suppress_price++;
2149 obj = hold_another_object(
2150 obj, u.uswallow ? "Oops! %s out of your reach!"
2151 : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
2152 || levl[u.ux][u.uy].typ < IRONBARS
2153 || levl[u.ux][u.uy].typ >= ICE)
2154 ? "Oops! %s away from you!"
2155 : "Oops! %s to the floor!",
2156 The(aobjnam(obj, "slip")), (const char *) 0);
2158 obj = hold_another_object(
2159 obj, u.uswallow ? "
\82¨
\82Á
\82Æ
\81I%s
\82Í
\93Í
\82©
\82È
\82¢
\81I"
2160 : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
2161 || levl[u.ux][u.uy].typ < IRONBARS
2162 || levl[u.ux][u.uy].typ >= ICE)
2163 ? "
\82¨
\82Á
\82Æ
\81I%s
\82Í
\82 \82È
\82½
\82Ì
\8eè
\82©
\82ç
\8a\8a\82è
\97\8e\82¿
\82½
\81I"
2164 : "
\82¨
\82Á
\82Æ
\81I%s
\82Í
\8f°
\82É
\8a\8a\82è
\97\8e\82¿
\82½
\81I",
2165 xname(obj), (const char *)0);
2168 /* assumes this is taking place at hero's location */
2169 if (!can_reach_floor(TRUE)) {
2170 hitfloor(obj); /* does altar check, message, drop */
2172 if (IS_ALTAR(levl[u.ux][u.uy].typ))
2173 doaltarobj(obj); /* does its own drop message */
2176 pline("%s %s to the %s.", Doname2(obj),
2177 otense(obj, "drop"), surface(u.ux, u.uy));
2179 pline("%s
\82Í%s
\82É
\97\8e\82¿
\82½
\81D", Doname2(obj),
2180 surface(u.ux, u.uy));
2185 iflags.suppress_price--;
2187 makeknown(HORN_OF_PLENTY);
2192 /* support for wizard-mode's `sanity_check' option */
2194 static const char NEARDATA /* pline formats for insane_object() */
2195 ofmt0[] = "%s obj %s %s: %s",
2196 ofmt3[] = "%s [not null] %s %s: %s",
2197 /* " held by mon %p (%s)" will be appended, filled by M,mon_nam(M) */
2198 mfmt1[] = "%s obj %s %s (%s)", mfmt2[] = "%s obj %s %s (%s) *not*";
2200 /* Check all object lists for consistency. */
2207 objlist_sanity(fobj, OBJ_FLOOR, "floor sanity");
2209 /* check that the map's record of floor objects is consistent;
2210 those objects should have already been sanity checked via
2211 the floor list so container contents are skipped here */
2212 for (x = 0; x < COLNO; x++)
2213 for (y = 0; y < ROWNO; y++)
2214 for (obj = level.objects[x][y]; obj; obj = obj->nexthere) {
2215 /* <ox,oy> should match <x,y>; <0,*> should always be empty */
2216 if (obj->where != OBJ_FLOOR || x == 0 || obj->ox != x
2220 Sprintf(at_fmt, "%%s obj@<%d,%d> %%s %%s: %%s@<%d,%d>", x,
2221 y, obj->ox, obj->oy);
2222 insane_object(obj, at_fmt, "location sanity",
2223 (struct monst *) 0);
2227 objlist_sanity(invent, OBJ_INVENT, "invent sanity");
2228 objlist_sanity(migrating_objs, OBJ_MIGRATING, "migrating sanity");
2229 objlist_sanity(level.buriedobjlist, OBJ_BURIED, "buried sanity");
2230 objlist_sanity(billobjs, OBJ_ONBILL, "bill sanity");
2232 mon_obj_sanity(fmon, "minvent sanity");
2233 mon_obj_sanity(migrating_mons, "migrating minvent sanity");
2234 /* monsters temporarily in transit;
2235 they should have arrived with hero by the time we get called */
2237 pline("mydogs sanity [not empty]");
2238 mon_obj_sanity(mydogs, "mydogs minvent sanity");
2241 /* objects temporarily freed from invent/floor lists;
2242 they should have arrived somewhere by the time we get called */
2244 insane_object(thrownobj, ofmt3, "thrownobj sanity",
2245 (struct monst *) 0);
2247 insane_object(kickedobj, ofmt3, "kickedobj sanity",
2248 (struct monst *) 0);
2249 /* [how about current_wand too?] */
2252 /* sanity check for objects on specified list (fobj, &c) */
2254 objlist_sanity(objlist, wheretype, mesg)
2255 struct obj *objlist;
2261 for (obj = objlist; obj; obj = obj->nobj) {
2262 if (obj->where != wheretype)
2263 insane_object(obj, ofmt0, mesg, (struct monst *) 0);
2264 if (Has_contents(obj)) {
2265 if (wheretype == OBJ_ONBILL)
2266 /* containers on shop bill should always be empty */
2267 insane_object(obj, "%s obj contains something! %s %s: %s",
2268 mesg, (struct monst *) 0);
2269 check_contained(obj, mesg);
2271 if (obj->owornmask) {
2273 boolean bc_ok = FALSE;
2275 switch (obj->where) {
2278 sanity_check_worn(obj);
2281 /* migrating objects overload the owornmask field
2282 with a destination code; skip attempt to check it */
2285 /* note: ball and chain can also be OBJ_FREE, but not across
2286 turns so this sanity check shouldn't encounter that */
2290 if ((obj != uchain && obj != uball) || !bc_ok) {
2291 /* discovered an object not in inventory which
2292 erroneously has worn mask set */
2293 Sprintf(maskbuf, "worn mask 0x%08lx", obj->owornmask);
2294 insane_object(obj, ofmt0, maskbuf, (struct monst *) 0);
2302 /* sanity check for objects carried by all monsters in specified list */
2304 mon_obj_sanity(monlist, mesg)
2305 struct monst *monlist;
2309 struct obj *obj, *mwep;
2311 for (mon = monlist; mon; mon = mon->nmon) {
2312 if (DEADMONSTER(mon)) continue;
2313 mwep = MON_WEP(mon);
2315 if (!mcarried(mwep))
2316 insane_object(mwep, mfmt1, mesg, mon);
2317 if (mwep->ocarry != mon)
2318 insane_object(mwep, mfmt2, mesg, mon);
2320 for (obj = mon->minvent; obj; obj = obj->nobj) {
2321 if (obj->where != OBJ_MINVENT)
2322 insane_object(obj, mfmt1, mesg, mon);
2323 if (obj->ocarry != mon)
2324 insane_object(obj, mfmt2, mesg, mon);
2325 check_contained(obj, mesg);
2330 /* This must stay consistent with the defines in obj.h. */
2331 static const char *obj_state_names[NOBJ_STATES] = { "free", "floor",
2332 "contained", "invent",
2333 "minvent", "migrating",
2334 "buried", "onbill" };
2336 STATIC_OVL const char *
2340 static char unknown[32]; /* big enough to handle rogue 64-bit int */
2346 if (where < 0 || where >= NOBJ_STATES || !obj_state_names[where]) {
2347 Sprintf(unknown, "unknown[%d]", where);
2350 return obj_state_names[where];
2354 insane_object(obj, fmt, mesg, mon)
2356 const char *fmt, *mesg;
2359 const char *objnm, *monnm;
2362 objnm = monnm = "null!";
2364 iflags.override_ID++;
2365 objnm = doname(obj);
2366 iflags.override_ID--;
2368 if (mon || (strstri(mesg, "minvent") && !strstri(mesg, "contained"))) {
2369 Strcat(strcpy(altfmt, fmt), " held by mon %s (%s)");
2371 monnm = x_monnam(mon, ARTICLE_A, (char *) 0, EXACT_NAME, TRUE);
2372 pline(altfmt, mesg, fmt_ptr((genericptr_t) obj), where_name(obj),
2373 objnm, fmt_ptr((genericptr_t) mon), monnm);
2375 pline(fmt, mesg, fmt_ptr((genericptr_t) obj), where_name(obj), objnm);
2379 /* obj sanity check: check objects inside container */
2381 check_contained(container, mesg)
2382 struct obj *container;
2386 /* big enough to work with, not too big to blow out stack in recursion */
2387 char mesgbuf[40], nestedmesg[120];
2389 if (!Has_contents(container))
2391 /* change "invent sanity" to "contained invent sanity"
2392 but leave "nested contained invent sanity" as is */
2393 if (!strstri(mesg, "contained"))
2394 mesg = strcat(strcpy(mesgbuf, "contained "), mesg);
2396 for (obj = container->cobj; obj; obj = obj->nobj) {
2397 /* catch direct cycle to avoid unbounded recursion */
2398 if (obj == container)
2399 panic("failed sanity check: container holds itself");
2400 if (obj->where != OBJ_CONTAINED)
2401 insane_object(obj, "%s obj %s %s: %s", mesg, (struct monst *) 0);
2402 else if (obj->ocontainer != container)
2403 pline("%s obj %s in container %s, not %s", mesg,
2404 fmt_ptr((genericptr_t) obj),
2405 fmt_ptr((genericptr_t) obj->ocontainer),
2406 fmt_ptr((genericptr_t) container));
2408 if (Has_contents(obj)) {
2409 /* catch most likely indirect cycle; we won't notice if
2410 parent is present when something comes before it, or
2411 notice more deeply embedded cycles (grandparent, &c) */
2412 if (obj->cobj == container)
2413 panic("failed sanity check: container holds its parent");
2414 /* change "contained... sanity" to "nested contained... sanity"
2415 and "nested contained..." to "nested nested contained..." */
2416 Strcpy(nestedmesg, "nested ");
2417 copynchars(eos(nestedmesg), mesg, (int) sizeof nestedmesg
2418 - (int) strlen(nestedmesg)
2420 /* recursively check contents */
2421 check_contained(obj, nestedmesg);
2426 /* check an object in hero's or monster's inventory which has worn mask set */
2428 sanity_check_worn(obj)
2431 #if defined(BETA) || defined(DEBUG)
2432 static unsigned long wearbits[] = {
2433 W_ARM, W_ARMC, W_ARMH, W_ARMS, W_ARMG, W_ARMF, W_ARMU,
2434 W_WEP, W_QUIVER, W_SWAPWEP, W_AMUL, W_RINGL, W_RINGR, W_TOOL,
2435 W_SADDLE, W_BALL, W_CHAIN, 0
2436 /* [W_ART,W_ARTI are property bits for items which aren't worn] */
2440 unsigned long owornmask, allmask = 0L;
2441 boolean embedded = FALSE;
2444 /* use owornmask for testing and bit twiddling, but use original
2445 obj->owornmask for printing */
2446 owornmask = obj->owornmask;
2447 /* figure out how many bits are set, and also which are viable */
2448 for (i = 0; wearbits[i]; ++i) {
2449 if ((owornmask & wearbits[i]) != 0L)
2451 allmask |= wearbits[i];
2454 /* embedded dragon scales have an extra bit set;
2455 make sure it's set, then suppress it */
2457 if ((owornmask & (W_ARM | I_SPECIAL)) == (W_ARM | I_SPECIAL))
2458 owornmask &= ~I_SPECIAL;
2460 n = 0, owornmask = ~0; /* force insane_object("bogus") below */
2462 if (n == 2 && carried(obj)
2463 && obj == uball && (owornmask & W_BALL) != 0L
2464 && (owornmask & W_WEAPON) != 0L) {
2465 /* chained ball can be wielded/alt-wielded/quivered; if so,
2466 pretend it's not chained in order to check the weapon pointer
2467 (we've already verified the ball pointer by successfully passing
2468 the if-condition to get here...) */
2469 owornmask &= ~W_BALL;
2473 /* multiple bits set */
2474 Sprintf(maskbuf, "worn mask (multiple) 0x%08lx", obj->owornmask);
2475 insane_object(obj, ofmt0, maskbuf, (struct monst *) 0);
2477 if ((owornmask & ~allmask) != 0L
2478 || (carried(obj) && (owornmask & W_SADDLE) != 0L)) {
2479 /* non-wearable bit(s) set */
2480 Sprintf(maskbuf, "worn mask (bogus)) 0x%08lx", obj->owornmask);
2481 insane_object(obj, ofmt0, maskbuf, (struct monst *) 0);
2483 if (n == 1 && (carried(obj) || (owornmask & (W_BALL | W_CHAIN)) != 0L)) {
2485 /* verify that obj in hero's invent (or ball/chain elsewhere)
2486 with owornmask of W_foo is the object pointed to by ufoo */
2487 switch (owornmask) {
2489 if (obj != (embedded ? uskin : uarm))
2490 what = embedded ? "skin" : "suit";
2518 what = "primary weapon";
2525 if (obj != uswapwep)
2526 what = u.twoweap ? "secondary weapon" : "alternate weapon";
2538 what = "right ring";
2544 /* case W_SADDLE: */
2557 Sprintf(maskbuf, "worn mask 0x%08lx != %s", obj->owornmask, what);
2558 insane_object(obj, ofmt0, maskbuf, (struct monst *) 0);
2561 if (n == 1 && (carried(obj) || (owornmask & (W_BALL | W_CHAIN)) != 0L
2562 || mcarried(obj))) {
2563 /* check for items worn in invalid slots; practically anything can
2564 be wielded/alt-wielded/quivered, so tests on those are limited */
2566 if (owornmask & W_ARMOR) {
2567 if (obj->oclass != ARMOR_CLASS)
2569 /* 3.6: dragon scale mail reverts to dragon scales when
2570 becoming embedded in poly'd hero's skin */
2571 if (embedded && !Is_dragon_scales(obj))
2573 } else if (owornmask & W_WEAPON) {
2574 /* monsters don't maintain alternate weapon or quiver */
2575 if (mcarried(obj) && (owornmask & (W_SWAPWEP | W_QUIVER)) != 0L)
2576 what = (owornmask & W_SWAPWEP) != 0L ? "monst alt weapon?"
2578 /* hero can quiver gold but not wield it (hence not alt-wield
2579 it either); also catches monster wielding gold */
2580 else if (obj->oclass == COIN_CLASS
2581 && (owornmask & (W_WEP | W_SWAPWEP)) != 0L)
2582 what = (owornmask & W_WEP) != 0L ? "weapon" : "alt weapon";
2583 } else if (owornmask & W_AMUL) {
2584 if (obj->oclass != AMULET_CLASS)
2586 } else if (owornmask & W_RING) {
2587 if (obj->oclass != RING_CLASS && obj->otyp != MEAT_RING)
2589 } else if (owornmask & W_TOOL) {
2590 if (obj->otyp != BLINDFOLD && obj->otyp != TOWEL
2591 && obj->otyp != LENSES)
2593 } else if (owornmask & W_BALL) {
2594 if (obj->oclass != BALL_CLASS)
2595 what = "chained ball";
2596 } else if (owornmask & W_CHAIN) {
2597 if (obj->oclass != CHAIN_CLASS)
2599 } else if (owornmask & W_SADDLE) {
2600 if (obj->otyp != SADDLE)
2604 char oclassname[30];
2605 struct monst *mon = mcarried(obj) ? obj->ocarry : 0;
2607 /* if we've found a potion worn in the amulet slot,
2608 this yields "worn (potion amulet)" */
2609 Strcpy(oclassname, def_oc_syms[(uchar) obj->oclass].name);
2610 Sprintf(maskbuf, "worn (%s %s)", makesingular(oclassname), what);
2611 insane_object(obj, ofmt0, maskbuf, mon);
2614 #else /* not (BETA || DEBUG) */
2615 /* dummy use of obj to avoid "arg not used" complaint */
2617 insane_object(obj, ofmt0, "<null>", (struct monst *) 0);
2622 * wrapper to make "near this object" convenient
2628 struct obj *otmp2 = (struct obj *) 0;
2631 otmp2 = obj_nexto_xy(otmp->otyp, otmp->ox, otmp->oy, otmp->o_id);
2633 impossible("obj_nexto: wasn't given an object to check");
2640 * looks for objects of a particular type next to x, y
2641 * skips over oid if found (lets us avoid ourselves if
2642 * we're looking for a second type of an existing object)
2644 * TODO: return a list of all objects near us so we can more
2645 * reliably predict which one we want to 'find' first
2648 obj_nexto_xy(otyp, x, y, oid)
2656 /* check under our "feet" first */
2657 otmp = sobj_at(otyp, x, y);
2659 /* don't be clever and find ourselves */
2660 if (otmp->o_id != oid) {
2663 otmp = nxtobj(otmp, otyp, TRUE);
2666 /* search in a random order */
2667 dx = (rn2(2) ? -1 : 1);
2668 dy = (rn2(2) ? -1 : 1);
2672 for (fx = ex; abs(fx - ex) < 3; fx += dx) {
2673 for (fy = ey; abs(fy - ey) < 3; fy += dy) {
2674 /* 0, 0 was checked above */
2675 if (isok(fx, fy) && (fx != x || fy != y)) {
2676 if ((otmp = sobj_at(otyp, fx, fy)) != 0) {
2682 return (struct obj *) 0;
2686 * Causes one object to absorb another, increasing
2687 * weight accordingly. Frees obj2; obj1 remains and
2691 obj_absorb(obj1, obj2)
2692 struct obj **obj1, **obj2;
2694 struct obj *otmp1 = (struct obj *) 0, *otmp2 = (struct obj *) 0;
2697 /* don't let people dumb it up */
2701 if (otmp1 && otmp2) {
2702 extrawt = otmp2->oeaten ? otmp2->oeaten : otmp2->owt;
2703 otmp1->owt += extrawt;
2704 otmp1->oeaten += otmp1->oeaten ? extrawt : 0;
2706 obj_extract_self(otmp2);
2707 newsym(otmp2->ox, otmp2->oy); /* in case of floor */
2709 *obj2 = (struct obj *) 0;
2714 impossible("obj_absorb: not called with two actual objects");
2715 return (struct obj *) 0;
2719 * Causes the heavier object to absorb the lighter object;
2720 * wrapper for obj_absorb so that floor_effects works more
2721 * cleanly (since we don't know which we want to stay around)
2724 obj_meld(obj1, obj2)
2725 struct obj **obj1, **obj2;
2727 struct obj *otmp1 = (struct obj *) 0, *otmp2 = (struct obj *) 0;
2732 if (otmp1 && otmp2) {
2733 if (otmp1->owt > otmp2->owt || rn2(2)) {
2734 return obj_absorb(obj1, obj2);
2736 return obj_absorb(obj2, obj1);
2740 impossible("obj_meld: not called with two actual objects");
2741 return (struct obj *) 0;