OSDN Git Service

933cdd1317354cb57d0dcc7fc6697ef3f547233d
[jnethack/source.git] / src / mkobj.c
1 /* NetHack 3.6  mkobj.c $NHDT-Date: 1548978605 2019/01/31 23:50:05 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.142 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Derek S. Ray, 2015. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 #include "hack.h"
7
8 STATIC_DCL void FDECL(mkbox_cnts, (struct obj *));
9 STATIC_DCL unsigned FDECL(nextoid, (struct obj *, struct obj *));
10 STATIC_DCL void FDECL(maybe_adjust_light, (struct obj *, int));
11 STATIC_DCL void FDECL(obj_timer_checks, (struct obj *,
12                                          XCHAR_P, XCHAR_P, int));
13 STATIC_DCL void FDECL(container_weight, (struct obj *));
14 STATIC_DCL struct obj *FDECL(save_mtraits, (struct obj *, struct monst *));
15 STATIC_DCL void FDECL(objlist_sanity, (struct obj *, int, const char *));
16 STATIC_DCL void FDECL(mon_obj_sanity, (struct monst *, const char *));
17 STATIC_DCL const char *FDECL(where_name, (struct obj *));
18 STATIC_DCL void FDECL(insane_object, (struct obj *, const char *,
19                                       const char *, struct monst *));
20 STATIC_DCL void FDECL(check_contained, (struct obj *, const char *));
21 STATIC_DCL void FDECL(sanity_check_worn, (struct obj *));
22
23 struct icp {
24     int iprob;   /* probability of an item type */
25     char iclass; /* item class */
26 };
27
28 static const struct icp mkobjprobs[] = { { 10, WEAPON_CLASS },
29                                          { 10, ARMOR_CLASS },
30                                          { 20, FOOD_CLASS },
31                                          { 8, TOOL_CLASS },
32                                          { 8, GEM_CLASS },
33                                          { 16, POTION_CLASS },
34                                          { 16, SCROLL_CLASS },
35                                          { 4, SPBOOK_CLASS },
36                                          { 4, WAND_CLASS },
37                                          { 3, RING_CLASS },
38                                          { 1, AMULET_CLASS } };
39
40 static const struct icp boxiprobs[] = { { 18, GEM_CLASS },
41                                         { 15, FOOD_CLASS },
42                                         { 18, POTION_CLASS },
43                                         { 18, SCROLL_CLASS },
44                                         { 12, SPBOOK_CLASS },
45                                         { 7, COIN_CLASS },
46                                         { 6, WAND_CLASS },
47                                         { 5, RING_CLASS },
48                                         { 1, AMULET_CLASS } };
49
50 static const struct icp rogueprobs[] = { { 12, WEAPON_CLASS },
51                                          { 12, ARMOR_CLASS },
52                                          { 22, FOOD_CLASS },
53                                          { 22, POTION_CLASS },
54                                          { 22, SCROLL_CLASS },
55                                          { 5, WAND_CLASS },
56                                          { 5, RING_CLASS } };
57
58 static const struct icp hellprobs[] = { { 20, WEAPON_CLASS },
59                                         { 20, ARMOR_CLASS },
60                                         { 16, FOOD_CLASS },
61                                         { 12, TOOL_CLASS },
62                                         { 10, GEM_CLASS },
63                                         { 1, POTION_CLASS },
64                                         { 1, SCROLL_CLASS },
65                                         { 8, WAND_CLASS },
66                                         { 8, RING_CLASS },
67                                         { 4, AMULET_CLASS } };
68
69 struct oextra *
70 newoextra()
71 {
72     struct oextra *oextra;
73
74     oextra = (struct oextra *) alloc(sizeof (struct oextra));
75     oextra->oname = 0;
76     oextra->omonst = 0;
77     oextra->omid = 0;
78     oextra->olong = 0;
79     oextra->omailcmd = 0;
80     return oextra;
81 }
82
83 void
84 dealloc_oextra(o)
85 struct obj *o;
86 {
87     struct oextra *x = o->oextra;
88
89     if (x) {
90         if (x->oname)
91             free((genericptr_t) x->oname);
92         if (x->omonst)
93             free_omonst(o);     /* 'o' rather than 'x' */
94         if (x->omid)
95             free((genericptr_t) x->omid);
96         if (x->olong)
97             free((genericptr_t) x->olong);
98         if (x->omailcmd)
99             free((genericptr_t) x->omailcmd);
100
101         free((genericptr_t) x);
102         o->oextra = (struct oextra *) 0;
103     }
104 }
105
106 void
107 newomonst(otmp)
108 struct obj *otmp;
109 {
110     if (!otmp->oextra)
111         otmp->oextra = newoextra();
112
113     if (!OMONST(otmp)) {
114         struct monst *m = newmonst();
115
116         *m = zeromonst;
117         OMONST(otmp) = m;
118     }
119 }
120
121 void
122 free_omonst(otmp)
123 struct obj *otmp;
124 {
125     if (otmp->oextra) {
126         struct monst *m = OMONST(otmp);
127
128         if (m) {
129             if (m->mextra)
130                 dealloc_mextra(m);
131             free((genericptr_t) m);
132             OMONST(otmp) = (struct monst *) 0;
133         }
134     }
135 }
136
137 void
138 newomid(otmp)
139 struct obj *otmp;
140 {
141     if (!otmp->oextra)
142         otmp->oextra = newoextra();
143     if (!OMID(otmp)) {
144         OMID(otmp) = (unsigned *) alloc(sizeof (unsigned));
145         (void) memset((genericptr_t) OMID(otmp), 0, sizeof (unsigned));
146     }
147 }
148
149 void
150 free_omid(otmp)
151 struct obj *otmp;
152 {
153     if (otmp->oextra && OMID(otmp)) {
154         free((genericptr_t) OMID(otmp));
155         OMID(otmp) = (unsigned *) 0;
156     }
157 }
158
159 void
160 newolong(otmp)
161 struct obj *otmp;
162 {
163     if (!otmp->oextra)
164         otmp->oextra = newoextra();
165     if (!OLONG(otmp)) {
166         OLONG(otmp) = (long *) alloc(sizeof (long));
167         (void) memset((genericptr_t) OLONG(otmp), 0, sizeof (long));
168     }
169 }
170
171 void
172 free_olong(otmp)
173 struct obj *otmp;
174 {
175     if (otmp->oextra && OLONG(otmp)) {
176         free((genericptr_t) OLONG(otmp));
177         OLONG(otmp) = (long *) 0;
178     }
179 }
180
181 void
182 new_omailcmd(otmp, response_cmd)
183 struct obj *otmp;
184 const char *response_cmd;
185 {
186     if (!otmp->oextra)
187         otmp->oextra = newoextra();
188     if (OMAILCMD(otmp))
189         free_omailcmd(otmp);
190     OMAILCMD(otmp) = dupstr(response_cmd);
191 }
192
193 void
194 free_omailcmd(otmp)
195 struct obj *otmp;
196 {
197     if (otmp->oextra && OMAILCMD(otmp)) {
198         free((genericptr_t) OMAILCMD(otmp));
199         OMAILCMD(otmp) = (char *) 0;
200     }
201 }
202
203 struct obj *
204 mkobj_at(let, x, y, artif)
205 char let;
206 int x, y;
207 boolean artif;
208 {
209     struct obj *otmp;
210
211     otmp = mkobj(let, artif);
212     place_object(otmp, x, y);
213     return otmp;
214 }
215
216 struct obj *
217 mksobj_at(otyp, x, y, init, artif)
218 int otyp, x, y;
219 boolean init, artif;
220 {
221     struct obj *otmp;
222
223     otmp = mksobj(otyp, init, artif);
224     place_object(otmp, x, y);
225     return otmp;
226 }
227
228 struct obj *
229 mksobj_migr_to_species(otyp, mflags2, init, artif)
230 int otyp;
231 unsigned mflags2;
232 boolean init, artif;
233 {
234     struct obj *otmp;
235
236     otmp = mksobj(otyp, init, artif);
237     if (otmp) {
238         add_to_migration(otmp);
239         otmp->owornmask = (long) MIGR_TO_SPECIES;
240         otmp->corpsenm = mflags2;
241     }
242     return otmp;
243 }
244
245 /* mkobj(): select a type of item from a class, use mksobj() to create it */
246 struct obj *
247 mkobj(oclass, artif)
248 char oclass;
249 boolean artif;
250 {
251     int tprob, i, prob = rnd(1000);
252
253     if (oclass == RANDOM_CLASS) {
254         const struct icp *iprobs = Is_rogue_level(&u.uz)
255                                    ? (const struct icp *) rogueprobs
256                                    : Inhell ? (const struct icp *) hellprobs
257                                             : (const struct icp *) mkobjprobs;
258
259         for (tprob = rnd(100); (tprob -= iprobs->iprob) > 0; iprobs++)
260             ;
261         oclass = iprobs->iclass;
262     }
263
264     i = bases[(int) oclass];
265     while ((prob -= objects[i].oc_prob) > 0)
266         i++;
267
268     if (objects[i].oc_class != oclass || !OBJ_NAME(objects[i]))
269         panic("probtype error, oclass=%d i=%d", (int) oclass, i);
270
271     return mksobj(i, TRUE, artif);
272 }
273
274 STATIC_OVL void
275 mkbox_cnts(box)
276 struct obj *box;
277 {
278     register int n;
279     register struct obj *otmp;
280
281     box->cobj = (struct obj *) 0;
282
283     switch (box->otyp) {
284     case ICE_BOX:
285         n = 20;
286         break;
287     case CHEST:
288         n = box->olocked ? 7 : 5;
289         break;
290     case LARGE_BOX:
291         n = box->olocked ? 5 : 3;
292         break;
293     case SACK:
294     case OILSKIN_SACK:
295         /* initial inventory: sack starts out empty */
296         if (moves <= 1 && !in_mklev) {
297             n = 0;
298             break;
299         }
300         /*FALLTHRU*/
301     case BAG_OF_HOLDING:
302         n = 1;
303         break;
304     default:
305         n = 0;
306         break;
307     }
308
309     for (n = rn2(n + 1); n > 0; n--) {
310         if (box->otyp == ICE_BOX) {
311             if (!(otmp = mksobj(CORPSE, TRUE, TRUE)))
312                 continue;
313             /* Note: setting age to 0 is correct.  Age has a different
314              * from usual meaning for objects stored in ice boxes. -KAA
315              */
316             otmp->age = 0L;
317             if (otmp->timed) {
318                 (void) stop_timer(ROT_CORPSE, obj_to_any(otmp));
319                 (void) stop_timer(REVIVE_MON, obj_to_any(otmp));
320             }
321         } else {
322             register int tprob;
323             const struct icp *iprobs = boxiprobs;
324
325             for (tprob = rnd(100); (tprob -= iprobs->iprob) > 0; iprobs++)
326                 ;
327             if (!(otmp = mkobj(iprobs->iclass, TRUE)))
328                 continue;
329
330             /* handle a couple of special cases */
331             if (otmp->oclass == COIN_CLASS) {
332                 /* 2.5 x level's usual amount; weight adjusted below */
333                 otmp->quan = (long) (rnd(level_difficulty() + 2) * rnd(75));
334                 otmp->owt = weight(otmp);
335             } else
336                 while (otmp->otyp == ROCK) {
337                     otmp->otyp = rnd_class(DILITHIUM_CRYSTAL, LOADSTONE);
338                     if (otmp->quan > 2L)
339                         otmp->quan = 1L;
340                     otmp->owt = weight(otmp);
341                 }
342             if (box->otyp == BAG_OF_HOLDING) {
343                 if (Is_mbag(otmp)) {
344                     otmp->otyp = SACK;
345                     otmp->spe = 0;
346                     otmp->owt = weight(otmp);
347                 } else
348                     while (otmp->otyp == WAN_CANCELLATION)
349                         otmp->otyp = rnd_class(WAN_LIGHT, WAN_LIGHTNING);
350             }
351         }
352         (void) add_to_container(box, otmp);
353     }
354 }
355
356 /* select a random, common monster type */
357 int
358 rndmonnum()
359 {
360     register struct permonst *ptr;
361     register int i;
362     unsigned short excludeflags;
363
364     /* Plan A: get a level-appropriate common monster */
365     ptr = rndmonst();
366     if (ptr)
367         return monsndx(ptr);
368
369     /* Plan B: get any common monster */
370     excludeflags = G_UNIQ | G_NOGEN | (Inhell ? G_NOHELL : G_HELL);
371     do {
372         i = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
373         ptr = &mons[i];
374     } while ((ptr->geno & excludeflags) != 0);
375
376     return i;
377 }
378
379 void
380 copy_oextra(obj2, obj1)
381 struct obj *obj2, *obj1;
382 {
383     if (!obj2 || !obj1 || !obj1->oextra)
384         return;
385
386     if (!obj2->oextra)
387         obj2->oextra = newoextra();
388     if (has_oname(obj1))
389         oname(obj2, ONAME(obj1));
390     if (has_omonst(obj1)) {
391         if (!OMONST(obj2))
392             newomonst(obj2);
393         (void) memcpy((genericptr_t) OMONST(obj2),
394                       (genericptr_t) OMONST(obj1), sizeof (struct monst));
395         OMONST(obj2)->mextra = (struct mextra *) 0;
396         OMONST(obj2)->nmon = (struct monst *) 0;
397 #if 0
398         OMONST(obj2)->m_id = context.ident++;
399         if (OMONST(obj2)->m_id) /* ident overflowed */
400             OMONST(obj2)->m_id = context.ident++;
401 #endif
402         if (OMONST(obj1)->mextra)
403             copy_mextra(OMONST(obj2), OMONST(obj1));
404     }
405     if (has_omid(obj1)) {
406         if (!OMID(obj2))
407             newomid(obj2);
408         (void) memcpy((genericptr_t) OMID(obj2), (genericptr_t) OMID(obj1),
409                       sizeof (unsigned));
410     }
411     if (has_olong(obj1)) {
412         if (!OLONG(obj2))
413             newolong(obj2);
414         (void) memcpy((genericptr_t) OLONG(obj2), (genericptr_t) OLONG(obj1),
415                       sizeof (long));
416     }
417     if (has_omailcmd(obj1)) {
418         new_omailcmd(obj2, OMAILCMD(obj1));
419     }
420 }
421
422 /*
423  * Split obj so that it gets size gets reduced by num. The quantity num is
424  * put in the object structure delivered by this call.  The returned object
425  * has its wornmask cleared and is positioned just following the original
426  * in the nobj chain (and nexthere chain when on the floor).
427  */
428 struct obj *
429 splitobj(obj, num)
430 struct obj *obj;
431 long num;
432 {
433     struct obj *otmp;
434
435     if (obj->cobj || num <= 0L || obj->quan <= num)
436         panic("splitobj"); /* can't split containers */
437     otmp = newobj();
438     *otmp = *obj; /* copies whole structure */
439     otmp->oextra = (struct oextra *) 0;
440     otmp->o_id = nextoid(obj, otmp);
441     otmp->timed = 0;                  /* not timed, yet */
442     otmp->lamplit = 0;                /* ditto */
443     otmp->owornmask = 0L;             /* new object isn't worn */
444     obj->quan -= num;
445     obj->owt = weight(obj);
446     otmp->quan = num;
447     otmp->owt = weight(otmp); /* -= obj->owt ? */
448
449     context.objsplit.parent_oid = obj->o_id;
450     context.objsplit.child_oid = otmp->o_id;
451     obj->nobj = otmp;
452     /* Only set nexthere when on the floor, nexthere is also used */
453     /* as a back pointer to the container object when contained. */
454     if (obj->where == OBJ_FLOOR)
455         obj->nexthere = otmp;
456     copy_oextra(otmp, obj);
457     if (has_omid(otmp))
458         free_omid(otmp); /* only one association with m_id*/
459     if (obj->unpaid)
460         splitbill(obj, otmp);
461     if (obj->timed)
462         obj_split_timers(obj, otmp);
463     if (obj_sheds_light(obj))
464         obj_split_light_source(obj, otmp);
465     return otmp;
466 }
467
468 /* when splitting a stack that has o_id-based shop prices, pick an
469    o_id value for the new stack that will maintain the same price */
470 STATIC_OVL unsigned
471 nextoid(oldobj, newobj)
472 struct obj *oldobj, *newobj;
473 {
474     int olddif, newdif, trylimit = 256; /* limit of 4 suffices at present */
475     unsigned oid = context.ident - 1; /* loop increment will reverse -1 */
476
477     olddif = oid_price_adjustment(oldobj, oldobj->o_id);
478     do {
479         ++oid;
480         if (!oid) /* avoid using 0 (in case value wrapped) */
481             ++oid;
482         newdif = oid_price_adjustment(newobj, oid);
483     } while (newdif != olddif && --trylimit >= 0);
484     context.ident = oid + 1; /* ready for next new object */
485     return oid;
486 }
487
488 /* try to find the stack obj was split from, then merge them back together;
489    returns the combined object if unsplit is successful, null otherwise */
490 struct obj *
491 unsplitobj(obj)
492 struct obj *obj;
493 {
494     unsigned target_oid = 0;
495     struct obj *oparent = 0, *ochild = 0, *list = 0;
496
497     /*
498      * We don't operate on floor objects (we're following o->nobj rather
499      * than o->nexthere), on free objects (don't know which list to use when
500      * looking for obj's parent or child), on bill objects (too complicated,
501      * not needed), or on buried or migrating objects (not needed).
502      * [This could be improved, but at present additional generality isn't
503      * necessary.]
504      */
505     switch (obj->where) {
506     case OBJ_FREE:
507     case OBJ_FLOOR:
508     case OBJ_ONBILL:
509     case OBJ_MIGRATING:
510     case OBJ_BURIED:
511     default:
512         return (struct obj *) 0;
513     case OBJ_INVENT:
514         list = invent;
515         break;
516     case OBJ_MINVENT:
517         list = obj->ocarry->minvent;
518         break;
519     case OBJ_CONTAINED:
520         list = obj->ocontainer->cobj;
521         break;
522     }
523
524     /* first try the expected case; obj is split from another stack */
525     if (obj->o_id == context.objsplit.child_oid) {
526         /* parent probably precedes child and will require list traversal */
527         ochild = obj;
528         target_oid = context.objsplit.parent_oid;
529         if (obj->nobj && obj->nobj->o_id == target_oid)
530             oparent = obj->nobj;
531     } else if (obj->o_id == context.objsplit.parent_oid) {
532         /* alternate scenario: another stack was split from obj;
533            child probably follows parent and will be found here */
534         oparent = obj;
535         target_oid = context.objsplit.child_oid;
536         if (obj->nobj && obj->nobj->o_id == target_oid)
537             ochild = obj->nobj;
538     }
539     /* if we have only half the split, scan obj's list to find other half */
540     if (ochild && !oparent) {
541         /* expected case */
542         for (obj = list; obj; obj = obj->nobj)
543             if (obj->o_id == target_oid) {
544                 oparent = obj;
545                 break;
546             }
547     } else if (oparent && !ochild) {
548         /* alternate scenario */
549         for (obj = list; obj; obj = obj->nobj)
550             if (obj->o_id == target_oid) {
551                 ochild = obj;
552                 break;
553             }
554     }
555     /* if we have both parent and child, try to merge them;
556        if successful, return the combined stack, otherwise return null */
557     return (oparent && ochild && merged(&oparent, &ochild)) ? oparent : 0;
558 }
559
560 /* reset splitobj()/unsplitobj() context */
561 void
562 clear_splitobjs()
563 {
564     context.objsplit.parent_oid = context.objsplit.child_oid = 0;
565 }
566
567 /*
568  * Insert otmp right after obj in whatever chain(s) it is on.  Then extract
569  * obj from the chain(s).  This function does a literal swap.  It is up to
570  * the caller to provide a valid context for the swap.  When done, obj will
571  * still exist, but not on any chain.
572  *
573  * Note:  Don't use use obj_extract_self() -- we are doing an in-place swap,
574  * not actually moving something.
575  */
576 void
577 replace_object(obj, otmp)
578 struct obj *obj;
579 struct obj *otmp;
580 {
581     otmp->where = obj->where;
582     switch (obj->where) {
583     case OBJ_FREE:
584         /* do nothing */
585         break;
586     case OBJ_INVENT:
587         otmp->nobj = obj->nobj;
588         obj->nobj = otmp;
589         extract_nobj(obj, &invent);
590         break;
591     case OBJ_CONTAINED:
592         otmp->nobj = obj->nobj;
593         otmp->ocontainer = obj->ocontainer;
594         obj->nobj = otmp;
595         extract_nobj(obj, &obj->ocontainer->cobj);
596         break;
597     case OBJ_MINVENT:
598         otmp->nobj = obj->nobj;
599         otmp->ocarry = obj->ocarry;
600         obj->nobj = otmp;
601         extract_nobj(obj, &obj->ocarry->minvent);
602         break;
603     case OBJ_FLOOR:
604         otmp->nobj = obj->nobj;
605         otmp->nexthere = obj->nexthere;
606         otmp->ox = obj->ox;
607         otmp->oy = obj->oy;
608         obj->nobj = otmp;
609         obj->nexthere = otmp;
610         extract_nobj(obj, &fobj);
611         extract_nexthere(obj, &level.objects[obj->ox][obj->oy]);
612         break;
613     default:
614         panic("replace_object: obj position");
615         break;
616     }
617 }
618
619 /* is 'obj' inside a container whose contents aren't known?
620    if so, return the outermost container meeting that criterium */
621 struct obj *
622 unknwn_contnr_contents(obj)
623 struct obj *obj;
624 {
625     struct obj *result = 0, *parent;
626
627     while (obj->where == OBJ_CONTAINED) {
628         parent = obj->ocontainer;
629         if (!parent->cknown)
630             result = parent;
631         obj = parent;
632     }
633     return result;
634 }
635
636 /*
637  * Create a dummy duplicate to put on shop bill.  The duplicate exists
638  * only in the billobjs chain.  This function is used when a shop object
639  * is being altered, and a copy of the original is needed for billing
640  * purposes.  For example, when eating, where an interruption will yield
641  * an object which is different from what it started out as; the "I x"
642  * command needs to display the original object.
643  *
644  * The caller is responsible for checking otmp->unpaid and
645  * costly_spot(u.ux, u.uy).  This function will make otmp no charge.
646  *
647  * Note that check_unpaid_usage() should be used instead for partial
648  * usage of an object.
649  */
650 void
651 bill_dummy_object(otmp)
652 register struct obj *otmp;
653 {
654     register struct obj *dummy;
655     long cost = 0L;
656
657     if (otmp->unpaid) {
658         cost = unpaid_cost(otmp, FALSE);
659         subfrombill(otmp, shop_keeper(*u.ushops));
660     }
661     dummy = newobj();
662     *dummy = *otmp;
663     dummy->oextra = (struct oextra *) 0;
664     dummy->where = OBJ_FREE;
665     dummy->o_id = context.ident++;
666     if (!dummy->o_id)
667         dummy->o_id = context.ident++; /* ident overflowed */
668     dummy->timed = 0;
669     copy_oextra(dummy, otmp);
670     if (has_omid(dummy))
671         free_omid(dummy); /* only one association with m_id*/
672     if (Is_candle(dummy))
673         dummy->lamplit = 0;
674     dummy->owornmask = 0L; /* dummy object is not worn */
675     addtobill(dummy, FALSE, TRUE, TRUE);
676     if (cost)
677         alter_cost(dummy, -cost);
678     /* no_charge is only valid for some locations */
679     otmp->no_charge =
680         (otmp->where == OBJ_FLOOR || otmp->where == OBJ_CONTAINED) ? 1 : 0;
681     otmp->unpaid = 0;
682     return;
683 }
684
685 /* alteration types; must match COST_xxx macros in hack.h */
686 static const char *const alteration_verbs[] = {
687 #if 0 /*JP*/
688     "cancel", "drain", "uncharge", "unbless", "uncurse", "disenchant",
689     "degrade", "dilute", "erase", "burn", "neutralize", "destroy", "splatter",
690     "bite", "open", "break the lock on", "rust", "rot", "tarnish"
691 #else
692     "\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½",
693     "\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½",
694     "\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½"
695 #endif
696 };
697
698 /* possibly bill for an object which the player has just modified */
699 void
700 costly_alteration(obj, alter_type)
701 struct obj *obj;
702 int alter_type;
703 {
704     xchar ox, oy;
705     char objroom;
706     boolean set_bknown;
707 #if 0 /*JP*//*\8eg\82í\82È\82¢*/
708     const char *those, *them;
709 #endif
710     struct monst *shkp = 0;
711
712     if (alter_type < 0 || alter_type >= SIZE(alteration_verbs)) {
713         impossible("invalid alteration type (%d)", alter_type);
714         alter_type = 0;
715     }
716
717     ox = oy = 0;    /* lint suppression */
718     objroom = '\0'; /* ditto */
719     if (carried(obj) || obj->where == OBJ_FREE) {
720         /* OBJ_FREE catches obj_no_longer_held()'s transformation
721            of crysknife back into worm tooth; the object has been
722            removed from inventory but not necessarily placed at
723            its new location yet--the unpaid flag will still be set
724            if this item is owned by a shop */
725         if (!obj->unpaid)
726             return;
727     } else {
728         /* this get_obj_location shouldn't fail, but if it does,
729            use hero's location */
730         if (!get_obj_location(obj, &ox, &oy, CONTAINED_TOO))
731             ox = u.ux, oy = u.uy;
732         if (!costly_spot(ox, oy))
733             return;
734         objroom = *in_rooms(ox, oy, SHOPBASE);
735         /* if no shop cares about it, we're done */
736         if (!billable(&shkp, obj, objroom, FALSE))
737             return;
738     }
739
740 #if 0 /*JP*//*\93ú\96{\8cê\82Å\82Í\95s\97v*/
741     if (obj->quan == 1L)
742         those = "that", them = "it";
743     else
744         those = "those", them = "them";
745 #endif
746
747     /* when shopkeeper describes the object as being uncursed or unblessed
748        hero will know that it is now uncursed; will also make the feedback
749        from `I x' after bill_dummy_object() be more specific for this item */
750     set_bknown = (alter_type == COST_UNCURS || alter_type == COST_UNBLSS);
751
752     switch (obj->where) {
753     case OBJ_FREE: /* obj_no_longer_held() */
754     case OBJ_INVENT:
755         if (set_bknown)
756             obj->bknown = 1;
757 #if 0 /*JP*/
758         verbalize("You %s %s %s, you pay for %s!",
759                   alteration_verbs[alter_type], those, simpleonames(obj),
760                   them);
761 #else
762         verbalize("%s\82ð%s\82Ì\82È\82ç\81C\94\83\82Á\82Ä\82à\82ç\82¤\82æ\81I",
763                   simpleonames(obj), alteration_verbs[alter_type]);
764 #endif
765         bill_dummy_object(obj);
766         break;
767     case OBJ_FLOOR:
768         if (set_bknown)
769             obj->bknown = 1;
770         if (costly_spot(u.ux, u.uy) && objroom == *u.ushops) {
771 #if 0 /*JP*/
772             verbalize("You %s %s, you pay for %s!",
773                       alteration_verbs[alter_type], those, them);
774 #else
775             verbalize("%s\82Ì\82È\82ç\81C\94\83\82Á\82Ä\82à\82ç\82¤\82æ\81I",
776                       alteration_verbs[alter_type]);
777 #endif
778             bill_dummy_object(obj);
779         } else {
780             (void) stolen_value(obj, ox, oy, FALSE, FALSE);
781         }
782         break;
783     }
784 }
785
786 static const char dknowns[] = { WAND_CLASS,   RING_CLASS, POTION_CLASS,
787                                 SCROLL_CLASS, GEM_CLASS,  SPBOOK_CLASS,
788                                 WEAPON_CLASS, TOOL_CLASS, 0 };
789
790 /* mksobj(): create a specific type of object */
791 struct obj *
792 mksobj(otyp, init, artif)
793 int otyp;
794 boolean init;
795 boolean artif;
796 {
797     int mndx, tryct;
798     struct obj *otmp;
799     char let = objects[otyp].oc_class;
800
801     otmp = newobj();
802     *otmp = zeroobj;
803     otmp->age = monstermoves;
804     otmp->o_id = context.ident++;
805     if (!otmp->o_id)
806         otmp->o_id = context.ident++; /* ident overflowed */
807     otmp->quan = 1L;
808     otmp->oclass = let;
809     otmp->otyp = otyp;
810     otmp->where = OBJ_FREE;
811     otmp->dknown = index(dknowns, let) ? 0 : 1;
812     if ((otmp->otyp >= ELVEN_SHIELD && otmp->otyp <= ORCISH_SHIELD)
813         || otmp->otyp == SHIELD_OF_REFLECTION
814         || objects[otmp->otyp].oc_merge)
815         otmp->dknown = 0;
816     if (!objects[otmp->otyp].oc_uses_known)
817         otmp->known = 1;
818     otmp->lknown = 0;
819     otmp->cknown = 0;
820     otmp->corpsenm = NON_PM;
821
822     if (init) {
823         switch (let) {
824         case WEAPON_CLASS:
825             otmp->quan = is_multigen(otmp) ? (long) rn1(6, 6) : 1L;
826             if (!rn2(11)) {
827                 otmp->spe = rne(3);
828                 otmp->blessed = rn2(2);
829             } else if (!rn2(10)) {
830                 curse(otmp);
831                 otmp->spe = -rne(3);
832             } else
833                 blessorcurse(otmp, 10);
834             if (is_poisonable(otmp) && !rn2(100))
835                 otmp->opoisoned = 1;
836
837             if (artif && !rn2(20))
838                 otmp = mk_artifact(otmp, (aligntyp) A_NONE);
839             break;
840         case FOOD_CLASS:
841             otmp->oeaten = 0;
842             switch (otmp->otyp) {
843             case CORPSE:
844                 /* possibly overridden by mkcorpstat() */
845                 tryct = 50;
846                 do
847                     otmp->corpsenm = undead_to_corpse(rndmonnum());
848                 while ((mvitals[otmp->corpsenm].mvflags & G_NOCORPSE)
849                        && (--tryct > 0));
850                 if (tryct == 0) {
851                     /* perhaps rndmonnum() only wants to make G_NOCORPSE
852                        monsters on this level; create an adventurer's
853                        corpse instead, then */
854                     otmp->corpsenm = PM_HUMAN;
855                 }
856                 /* timer set below */
857                 break;
858             case EGG:
859                 otmp->corpsenm = NON_PM; /* generic egg */
860                 if (!rn2(3))
861                     for (tryct = 200; tryct > 0; --tryct) {
862                         mndx = can_be_hatched(rndmonnum());
863                         if (mndx != NON_PM && !dead_species(mndx, TRUE)) {
864                             otmp->corpsenm = mndx; /* typed egg */
865                             break;
866                         }
867                     }
868                 /* timer set below */
869                 break;
870             case TIN:
871                 otmp->corpsenm = NON_PM; /* empty (so far) */
872                 if (!rn2(6))
873                     set_tin_variety(otmp, SPINACH_TIN);
874                 else
875                     for (tryct = 200; tryct > 0; --tryct) {
876                         mndx = undead_to_corpse(rndmonnum());
877                         if (mons[mndx].cnutrit
878                             && !(mvitals[mndx].mvflags & G_NOCORPSE)) {
879                             otmp->corpsenm = mndx;
880                             set_tin_variety(otmp, RANDOM_TIN);
881                             break;
882                         }
883                     }
884                 blessorcurse(otmp, 10);
885                 break;
886             case SLIME_MOLD:
887                 otmp->spe = context.current_fruit;
888                 flags.made_fruit = TRUE;
889                 break;
890             case KELP_FROND:
891                 otmp->quan = (long) rnd(2);
892                 break;
893             }
894             if (Is_pudding(otmp)) {
895                 otmp->globby = 1;
896                 otmp->known = otmp->dknown = 1;
897                 otmp->corpsenm = PM_GRAY_OOZE
898                                  + (otmp->otyp - GLOB_OF_GRAY_OOZE);
899             } else {
900                 if (otmp->otyp != CORPSE && otmp->otyp != MEAT_RING
901                     && otmp->otyp != KELP_FROND && !rn2(6)) {
902                     otmp->quan = 2L;
903                 }
904             }
905             break;
906         case GEM_CLASS:
907             otmp->corpsenm = 0; /* LOADSTONE hack */
908             if (otmp->otyp == LOADSTONE)
909                 curse(otmp);
910             else if (otmp->otyp == ROCK)
911                 otmp->quan = (long) rn1(6, 6);
912             else if (otmp->otyp != LUCKSTONE && !rn2(6))
913                 otmp->quan = 2L;
914             else
915                 otmp->quan = 1L;
916             break;
917         case TOOL_CLASS:
918             switch (otmp->otyp) {
919             case TALLOW_CANDLE:
920             case WAX_CANDLE:
921                 otmp->spe = 1;
922                 otmp->age = 20L * /* 400 or 200 */
923                             (long) objects[otmp->otyp].oc_cost;
924                 otmp->lamplit = 0;
925                 otmp->quan = 1L + (long) (rn2(2) ? rn2(7) : 0);
926                 blessorcurse(otmp, 5);
927                 break;
928             case BRASS_LANTERN:
929             case OIL_LAMP:
930                 otmp->spe = 1;
931                 otmp->age = (long) rn1(500, 1000);
932                 otmp->lamplit = 0;
933                 blessorcurse(otmp, 5);
934                 break;
935             case MAGIC_LAMP:
936                 otmp->spe = 1;
937                 otmp->lamplit = 0;
938                 blessorcurse(otmp, 2);
939                 break;
940             case CHEST:
941             case LARGE_BOX:
942                 otmp->olocked = !!(rn2(5));
943                 otmp->otrapped = !(rn2(10));
944                 /*FALLTHRU*/
945             case ICE_BOX:
946             case SACK:
947             case OILSKIN_SACK:
948             case BAG_OF_HOLDING:
949                 mkbox_cnts(otmp);
950                 break;
951             case EXPENSIVE_CAMERA:
952             case TINNING_KIT:
953             case MAGIC_MARKER:
954                 otmp->spe = rn1(70, 30);
955                 break;
956             case CAN_OF_GREASE:
957                 otmp->spe = rnd(25);
958                 blessorcurse(otmp, 10);
959                 break;
960             case CRYSTAL_BALL:
961                 otmp->spe = rnd(5);
962                 blessorcurse(otmp, 2);
963                 break;
964             case HORN_OF_PLENTY:
965             case BAG_OF_TRICKS:
966                 otmp->spe = rnd(20);
967                 break;
968             case FIGURINE:
969                 tryct = 0;
970                 do
971                     otmp->corpsenm = rndmonnum();
972                 while (is_human(&mons[otmp->corpsenm]) && tryct++ < 30);
973                 blessorcurse(otmp, 4);
974                 break;
975             case BELL_OF_OPENING:
976                 otmp->spe = 3;
977                 break;
978             case MAGIC_FLUTE:
979             case MAGIC_HARP:
980             case FROST_HORN:
981             case FIRE_HORN:
982             case DRUM_OF_EARTHQUAKE:
983                 otmp->spe = rn1(5, 4);
984                 break;
985             }
986             break;
987         case AMULET_CLASS:
988             if (otmp->otyp == AMULET_OF_YENDOR)
989                 context.made_amulet = TRUE;
990             if (rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION
991                             || otmp->otyp == AMULET_OF_CHANGE
992                             || otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) {
993                 curse(otmp);
994             } else
995                 blessorcurse(otmp, 10);
996             break;
997         case VENOM_CLASS:
998         case CHAIN_CLASS:
999         case BALL_CLASS:
1000             break;
1001         case POTION_CLASS: /* note: potions get some additional init below */
1002         case SCROLL_CLASS:
1003 #ifdef MAIL
1004             if (otmp->otyp != SCR_MAIL)
1005 #endif
1006                 blessorcurse(otmp, 4);
1007             break;
1008         case SPBOOK_CLASS:
1009             otmp->spestudied = 0;
1010             blessorcurse(otmp, 17);
1011             break;
1012         case ARMOR_CLASS:
1013             if (rn2(10)
1014                 && (otmp->otyp == FUMBLE_BOOTS
1015                     || otmp->otyp == LEVITATION_BOOTS
1016                     || otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT
1017                     || otmp->otyp == GAUNTLETS_OF_FUMBLING || !rn2(11))) {
1018                 curse(otmp);
1019                 otmp->spe = -rne(3);
1020             } else if (!rn2(10)) {
1021                 otmp->blessed = rn2(2);
1022                 otmp->spe = rne(3);
1023             } else
1024                 blessorcurse(otmp, 10);
1025             if (artif && !rn2(40))
1026                 otmp = mk_artifact(otmp, (aligntyp) A_NONE);
1027             /* simulate lacquered armor for samurai */
1028             if (Role_if(PM_SAMURAI) && otmp->otyp == SPLINT_MAIL
1029                 && (moves <= 1 || In_quest(&u.uz))) {
1030 #ifdef UNIXPC
1031                 /* optimizer bitfield bug */
1032                 otmp->oerodeproof = 1;
1033                 otmp->rknown = 1;
1034 #else
1035                 otmp->oerodeproof = otmp->rknown = 1;
1036 #endif
1037             }
1038             break;
1039         case WAND_CLASS:
1040             if (otmp->otyp == WAN_WISHING)
1041                 otmp->spe = rnd(3);
1042             else
1043                 otmp->spe =
1044                     rn1(5, (objects[otmp->otyp].oc_dir == NODIR) ? 11 : 4);
1045             blessorcurse(otmp, 17);
1046             otmp->recharged = 0; /* used to control recharging */
1047             break;
1048         case RING_CLASS:
1049             if (objects[otmp->otyp].oc_charged) {
1050                 blessorcurse(otmp, 3);
1051                 if (rn2(10)) {
1052                     if (rn2(10) && bcsign(otmp))
1053                         otmp->spe = bcsign(otmp) * rne(3);
1054                     else
1055                         otmp->spe = rn2(2) ? rne(3) : -rne(3);
1056                 }
1057                 /* make useless +0 rings much less common */
1058                 if (otmp->spe == 0)
1059                     otmp->spe = rn2(4) - rn2(3);
1060                 /* negative rings are usually cursed */
1061                 if (otmp->spe < 0 && rn2(5))
1062                     curse(otmp);
1063             } else if (rn2(10) && (otmp->otyp == RIN_TELEPORTATION
1064                                    || otmp->otyp == RIN_POLYMORPH
1065                                    || otmp->otyp == RIN_AGGRAVATE_MONSTER
1066                                    || otmp->otyp == RIN_HUNGER || !rn2(9))) {
1067                 curse(otmp);
1068             }
1069             break;
1070         case ROCK_CLASS:
1071             switch (otmp->otyp) {
1072             case STATUE:
1073                 /* possibly overridden by mkcorpstat() */
1074                 otmp->corpsenm = rndmonnum();
1075                 if (!verysmall(&mons[otmp->corpsenm])
1076                     && rn2(level_difficulty() / 2 + 10) > 10)
1077                     (void) add_to_container(otmp, mkobj(SPBOOK_CLASS, FALSE));
1078             }
1079             break;
1080         case COIN_CLASS:
1081             break; /* do nothing */
1082         default:
1083             impossible("impossible mkobj %d, sym '%c'.", otmp->otyp,
1084                        objects[otmp->otyp].oc_class);
1085             return (struct obj *) 0;
1086         }
1087     }
1088
1089     /* some things must get done (corpsenm, timers) even if init = 0 */
1090     switch ((otmp->oclass == POTION_CLASS && otmp->otyp != POT_OIL)
1091             ? POT_WATER
1092             : otmp->otyp) {
1093     case CORPSE:
1094         if (otmp->corpsenm == NON_PM) {
1095             otmp->corpsenm = undead_to_corpse(rndmonnum());
1096             if (mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE | G_GONE))
1097                 otmp->corpsenm = urole.malenum;
1098         }
1099         /*FALLTHRU*/
1100     case STATUE:
1101     case FIGURINE:
1102         if (otmp->corpsenm == NON_PM)
1103             otmp->corpsenm = rndmonnum();
1104         /*FALLTHRU*/
1105     case EGG:
1106     /* case TIN: */
1107         set_corpsenm(otmp, otmp->corpsenm);
1108         break;
1109     case POT_OIL:
1110         otmp->age = MAX_OIL_IN_FLASK; /* amount of oil */
1111         /*FALLTHRU*/
1112     case POT_WATER: /* POTION_CLASS */
1113         otmp->fromsink = 0; /* overloads corpsenm, which was set to NON_PM */
1114         break;
1115     case LEASH:
1116         otmp->leashmon = 0; /* overloads corpsenm, which was set to NON_PM */
1117         break;
1118     case SPE_NOVEL:
1119         otmp->novelidx = -1; /* "none of the above"; will be changed */
1120         otmp = oname(otmp, noveltitle(&otmp->novelidx));
1121         break;
1122     }
1123
1124     /* unique objects may have an associated artifact entry */
1125     if (objects[otyp].oc_unique && !otmp->oartifact)
1126         otmp = mk_artifact(otmp, (aligntyp) A_NONE);
1127     otmp->owt = weight(otmp);
1128     return otmp;
1129 }
1130
1131 /*
1132  * Several areas of the code made direct reassignments
1133  * to obj->corpsenm. Because some special handling is
1134  * required in certain cases, place that handling here
1135  * and call this routine in place of the direct assignment.
1136  *
1137  * If the object was a lizard or lichen corpse:
1138  *     - ensure that you don't end up with some
1139  *       other corpse type which has no rot-away timer.
1140  *
1141  * If the object was a troll corpse:
1142  *     - ensure that you don't end up with some other
1143  *       corpse type which resurrects from the dead.
1144  *
1145  * Re-calculates the weight of figurines and corpses to suit the
1146  * new species.
1147  *
1148  * Existing timeout value for egg hatch is preserved.
1149  *
1150  */
1151 void
1152 set_corpsenm(obj, id)
1153 struct obj *obj;
1154 int id;
1155 {
1156     long when = 0L;
1157
1158     if (obj->timed) {
1159         if (obj->otyp == EGG)
1160             when = stop_timer(HATCH_EGG, obj_to_any(obj));
1161         else {
1162             when = 0L;
1163             obj_stop_timers(obj); /* corpse or figurine */
1164         }
1165     }
1166     obj->corpsenm = id;
1167     switch (obj->otyp) {
1168     case CORPSE:
1169         start_corpse_timeout(obj);
1170         obj->owt = weight(obj);
1171         break;
1172     case FIGURINE:
1173         if (obj->corpsenm != NON_PM && !dead_species(obj->corpsenm, TRUE)
1174             && (carried(obj) || mcarried(obj)))
1175             attach_fig_transform_timeout(obj);
1176         obj->owt = weight(obj);
1177         break;
1178     case EGG:
1179         if (obj->corpsenm != NON_PM && !dead_species(obj->corpsenm, TRUE))
1180             attach_egg_hatch_timeout(obj, when);
1181         break;
1182     default: /* tin, etc. */
1183         obj->owt = weight(obj);
1184         break;
1185     }
1186 }
1187
1188 /*
1189  * Start a corpse decay or revive timer.
1190  * This takes the age of the corpse into consideration as of 3.4.0.
1191  */
1192 void
1193 start_corpse_timeout(body)
1194 struct obj *body;
1195 {
1196     long when;       /* rot away when this old */
1197     long corpse_age; /* age of corpse          */
1198     int rot_adjust;
1199     short action;
1200
1201 #define TAINT_AGE (50L)        /* age when corpses go bad */
1202 #define TROLL_REVIVE_CHANCE 37 /* 1/37 chance for 50 turns ~ 75% chance */
1203 #define ROT_AGE (250L)         /* age when corpses rot away */
1204
1205     /* lizards and lichen don't rot or revive */
1206     if (body->corpsenm == PM_LIZARD || body->corpsenm == PM_LICHEN)
1207         return;
1208
1209     action = ROT_CORPSE;             /* default action: rot away */
1210     rot_adjust = in_mklev ? 25 : 10; /* give some variation */
1211     corpse_age = monstermoves - body->age;
1212     if (corpse_age > ROT_AGE)
1213         when = rot_adjust;
1214     else
1215         when = ROT_AGE - corpse_age;
1216     when += (long) (rnz(rot_adjust) - rot_adjust);
1217
1218     if (is_rider(&mons[body->corpsenm])) {
1219         /*
1220          * Riders always revive.  They have a 1/3 chance per turn
1221          * of reviving after 12 turns.  Always revive by 500.
1222          */
1223         action = REVIVE_MON;
1224         for (when = 12L; when < 500L; when++)
1225             if (!rn2(3))
1226                 break;
1227
1228     } else if (mons[body->corpsenm].mlet == S_TROLL && !body->norevive) {
1229         long age;
1230         for (age = 2; age <= TAINT_AGE; age++)
1231             if (!rn2(TROLL_REVIVE_CHANCE)) { /* troll revives */
1232                 action = REVIVE_MON;
1233                 when = age;
1234                 break;
1235             }
1236     }
1237
1238     if (body->norevive)
1239         body->norevive = 0;
1240     (void) start_timer(when, TIMER_OBJECT, action, obj_to_any(body));
1241 }
1242
1243 STATIC_OVL void
1244 maybe_adjust_light(obj, old_range)
1245 struct obj *obj;
1246 int old_range;
1247 {
1248     char buf[BUFSZ];
1249     xchar ox, oy;
1250     int new_range = arti_light_radius(obj), delta = new_range - old_range;
1251
1252     /* radius of light emitting artifact varies by curse/bless state
1253        so will change after blessing or cursing */
1254     if (delta) {
1255         obj_adjust_light_radius(obj, new_range);
1256         /* simplifying assumptions:  hero is wielding this object;
1257            artifacts have to be in use to emit light and monsters'
1258            gear won't change bless or curse state */
1259         if (!Blind && get_obj_location(obj, &ox, &oy, 0)) {
1260             *buf = '\0';
1261             if (iflags.last_msg == PLNMSG_OBJ_GLOWS)
1262                 /* we just saw "The <obj> glows <color>." from dipping */
1263 #if 0 /*JP*/
1264                 Strcpy(buf, (obj->quan == 1L) ? "It" : "They");
1265 #else
1266                 Strcpy(buf, "\82»\82ê");
1267 #endif
1268             else if (carried(obj) || cansee(ox, oy))
1269                 Strcpy(buf, Yname2(obj));
1270             if (*buf) {
1271                 /* initial activation says "dimly" if cursed,
1272                    "brightly" if uncursed, and "brilliantly" if blessed;
1273                    when changing intensity, using "less brightly" is
1274                    straightforward for dimming, but we need "brighter"
1275                    rather than "more brightly" for brightening; ugh */
1276 #if 0 /*JP*/
1277                 pline("%s %s %s%s.", buf, otense(obj, "shine"),
1278                       (abs(delta) > 1) ? "much " : "",
1279                       (delta > 0) ? "brighter" : "less brightly");
1280 #else
1281                 pline("%s\82Ì\8bP\82«\82Í%s%s\81D", buf,
1282                       (abs(delta) > 1) ? "\82©\82È\82è" : "",
1283                       (delta > 0) ? "\91\9d\82µ\82½" : "\8c¸\82Á\82½");
1284 #endif
1285             }
1286         }
1287     }
1288 }
1289
1290 /*
1291  *      bless(), curse(), unbless(), uncurse() -- any relevant message
1292  *      about glowing amber/black/&c should be delivered prior to calling
1293  *      these routines to make the actual curse/bless state change.
1294  */
1295
1296 void
1297 bless(otmp)
1298 register struct obj *otmp;
1299 {
1300     int old_light = 0;
1301
1302     if (otmp->oclass == COIN_CLASS)
1303         return;
1304     if (otmp->lamplit)
1305         old_light = arti_light_radius(otmp);
1306     otmp->cursed = 0;
1307     otmp->blessed = 1;
1308     if (carried(otmp) && confers_luck(otmp))
1309         set_moreluck();
1310     else if (otmp->otyp == BAG_OF_HOLDING)
1311         otmp->owt = weight(otmp);
1312     else if (otmp->otyp == FIGURINE && otmp->timed)
1313         (void) stop_timer(FIG_TRANSFORM, obj_to_any(otmp));
1314     if (otmp->lamplit)
1315         maybe_adjust_light(otmp, old_light);
1316     return;
1317 }
1318
1319 void
1320 unbless(otmp)
1321 register struct obj *otmp;
1322 {
1323     int old_light = 0;
1324
1325     if (otmp->lamplit)
1326         old_light = arti_light_radius(otmp);
1327     otmp->blessed = 0;
1328     if (carried(otmp) && confers_luck(otmp))
1329         set_moreluck();
1330     else if (otmp->otyp == BAG_OF_HOLDING)
1331         otmp->owt = weight(otmp);
1332     if (otmp->lamplit)
1333         maybe_adjust_light(otmp, old_light);
1334 }
1335
1336 void
1337 curse(otmp)
1338 register struct obj *otmp;
1339 {
1340     unsigned already_cursed;
1341     int old_light = 0;
1342
1343     if (otmp->oclass == COIN_CLASS)
1344         return;
1345     if (otmp->lamplit)
1346         old_light = arti_light_radius(otmp);
1347     already_cursed = otmp->cursed;
1348     otmp->blessed = 0;
1349     otmp->cursed = 1;
1350     /* welded two-handed weapon interferes with some armor removal */
1351     if (otmp == uwep && bimanual(uwep))
1352         reset_remarm();
1353     /* rules at top of wield.c state that twoweapon cannot be done
1354        with cursed alternate weapon */
1355     if (otmp == uswapwep && u.twoweap)
1356         drop_uswapwep();
1357     /* some cursed items need immediate updating */
1358     if (carried(otmp) && confers_luck(otmp)) {
1359         set_moreluck();
1360     } else if (otmp->otyp == BAG_OF_HOLDING) {
1361         otmp->owt = weight(otmp);
1362     } else if (otmp->otyp == FIGURINE) {
1363         if (otmp->corpsenm != NON_PM && !dead_species(otmp->corpsenm, TRUE)
1364             && (carried(otmp) || mcarried(otmp)))
1365             attach_fig_transform_timeout(otmp);
1366     } else if (otmp->oclass == SPBOOK_CLASS) {
1367         /* if book hero is reading becomes cursed, interrupt */
1368         if (!already_cursed)
1369             book_cursed(otmp);
1370     }
1371     if (otmp->lamplit)
1372         maybe_adjust_light(otmp, old_light);
1373     return;
1374 }
1375
1376 void
1377 uncurse(otmp)
1378 register struct obj *otmp;
1379 {
1380     int old_light = 0;
1381
1382     if (otmp->lamplit)
1383         old_light = arti_light_radius(otmp);
1384     otmp->cursed = 0;
1385     if (carried(otmp) && confers_luck(otmp))
1386         set_moreluck();
1387     else if (otmp->otyp == BAG_OF_HOLDING)
1388         otmp->owt = weight(otmp);
1389     else if (otmp->otyp == FIGURINE && otmp->timed)
1390         (void) stop_timer(FIG_TRANSFORM, obj_to_any(otmp));
1391     if (otmp->lamplit)
1392         maybe_adjust_light(otmp, old_light);
1393     return;
1394 }
1395
1396 void
1397 blessorcurse(otmp, chance)
1398 register struct obj *otmp;
1399 register int chance;
1400 {
1401     if (otmp->blessed || otmp->cursed)
1402         return;
1403
1404     if (!rn2(chance)) {
1405         if (!rn2(2)) {
1406             curse(otmp);
1407         } else {
1408             bless(otmp);
1409         }
1410     }
1411     return;
1412 }
1413
1414 int
1415 bcsign(otmp)
1416 register struct obj *otmp;
1417 {
1418     return (!!otmp->blessed - !!otmp->cursed);
1419 }
1420
1421 /*
1422  *  Calculate the weight of the given object.  This will recursively follow
1423  *  and calculate the weight of any containers.
1424  *
1425  *  Note:  It is possible to end up with an incorrect weight if some part
1426  *         of the code messes with a contained object and doesn't update the
1427  *         container's weight.
1428  */
1429 int
1430 weight(obj)
1431 register struct obj *obj;
1432 {
1433     int wt = (int) objects[obj->otyp].oc_weight;
1434
1435     /* glob absorpsion means that merging globs accumulates weight while
1436        quantity stays 1, so update 'wt' to reflect that, unless owt is 0,
1437        when we assume this is a brand new glob so use objects[].oc_weight */
1438     if (obj->globby && obj->owt > 0)
1439         wt = obj->owt;
1440     if (Is_container(obj) || obj->otyp == STATUE) {
1441         struct obj *contents;
1442         register int cwt = 0;
1443
1444         if (obj->otyp == STATUE && obj->corpsenm >= LOW_PM)
1445             wt = (int) obj->quan * ((int) mons[obj->corpsenm].cwt * 3 / 2);
1446
1447         for (contents = obj->cobj; contents; contents = contents->nobj)
1448             cwt += weight(contents);
1449         /*
1450          *  The weight of bags of holding is calculated as the weight
1451          *  of the bag plus the weight of the bag's contents modified
1452          *  as follows:
1453          *
1454          *      Bag status      Weight of contents
1455          *      ----------      ------------------
1456          *      cursed                  2x
1457          *      blessed                 x/4 [rounded up: (x+3)/4]
1458          *      otherwise               x/2 [rounded up: (x+1)/2]
1459          *
1460          *  The macro DELTA_CWT in pickup.c also implements these
1461          *  weight equations.
1462          */
1463         if (obj->otyp == BAG_OF_HOLDING)
1464             cwt = obj->cursed ? (cwt * 2) : obj->blessed ? ((cwt + 3) / 4)
1465                                                          : ((cwt + 1) / 2);
1466
1467         return wt + cwt;
1468     }
1469     if (obj->otyp == CORPSE && obj->corpsenm >= LOW_PM) {
1470         long long_wt = obj->quan * (long) mons[obj->corpsenm].cwt;
1471
1472         wt = (long_wt > LARGEST_INT) ? LARGEST_INT : (int) long_wt;
1473         if (obj->oeaten)
1474             wt = eaten_stat(wt, obj);
1475         return wt;
1476     } else if (obj->oclass == FOOD_CLASS && obj->oeaten) {
1477         return eaten_stat((int) obj->quan * wt, obj);
1478     } else if (obj->oclass == COIN_CLASS) {
1479         return (int) ((obj->quan + 50L) / 100L);
1480     } else if (obj->otyp == HEAVY_IRON_BALL && obj->owt != 0) {
1481         return (int) obj->owt; /* kludge for "very" heavy iron ball */
1482     } else if (obj->otyp == CANDELABRUM_OF_INVOCATION && obj->spe) {
1483         return wt + obj->spe * (int) objects[TALLOW_CANDLE].oc_weight;
1484     }
1485     return (wt ? wt * (int) obj->quan : ((int) obj->quan + 1) >> 1);
1486 }
1487
1488 static int treefruits[] = { APPLE, ORANGE, PEAR, BANANA, EUCALYPTUS_LEAF };
1489
1490 struct obj *
1491 rnd_treefruit_at(x, y)
1492 int x, y;
1493 {
1494     return mksobj_at(treefruits[rn2(SIZE(treefruits))], x, y, TRUE, FALSE);
1495 }
1496
1497 struct obj *
1498 mkgold(amount, x, y)
1499 long amount;
1500 int x, y;
1501 {
1502     register struct obj *gold = g_at(x, y);
1503
1504     if (amount <= 0L) {
1505         long mul = rnd(30 / max(12-depth(&u.uz), 2));
1506         amount = (long) (1 + rnd(level_difficulty() + 2) * mul);
1507     }
1508     if (gold) {
1509         gold->quan += amount;
1510     } else {
1511         gold = mksobj_at(GOLD_PIECE, x, y, TRUE, FALSE);
1512         gold->quan = amount;
1513     }
1514     gold->owt = weight(gold);
1515     return gold;
1516 }
1517
1518 /* return TRUE if the corpse has special timing */
1519 #define special_corpse(num)                                                 \
1520     (((num) == PM_LIZARD) || ((num) == PM_LICHEN) || (is_rider(&mons[num])) \
1521      || (mons[num].mlet == S_TROLL))
1522
1523 /*
1524  * OEXTRA note: Passing mtmp causes mtraits to be saved
1525  * even if ptr passed as well, but ptr is always used for
1526  * the corpse type (corpsenm). That allows the corpse type
1527  * to be different from the original monster,
1528  *      i.e.  vampire -> human corpse
1529  * yet still allow restoration of the original monster upon
1530  * resurrection.
1531  */
1532 struct obj *
1533 mkcorpstat(objtype, mtmp, ptr, x, y, corpstatflags)
1534 int objtype; /* CORPSE or STATUE */
1535 struct monst *mtmp;
1536 struct permonst *ptr;
1537 int x, y;
1538 unsigned corpstatflags;
1539 {
1540     register struct obj *otmp;
1541     boolean init = ((corpstatflags & CORPSTAT_INIT) != 0);
1542
1543     if (objtype != CORPSE && objtype != STATUE)
1544         impossible("making corpstat type %d", objtype);
1545     if (x == 0 && y == 0) { /* special case - random placement */
1546         otmp = mksobj(objtype, init, FALSE);
1547         if (otmp)
1548             (void) rloco(otmp);
1549     } else
1550         otmp = mksobj_at(objtype, x, y, init, FALSE);
1551     if (otmp) {
1552         if (mtmp) {
1553             struct obj *otmp2;
1554
1555             if (!ptr)
1556                 ptr = mtmp->data;
1557             /* save_mtraits frees original data pointed to by otmp */
1558             otmp2 = save_mtraits(otmp, mtmp);
1559             if (otmp2)
1560                 otmp = otmp2;
1561         }
1562         /* use the corpse or statue produced by mksobj() as-is
1563            unless `ptr' is non-null */
1564         if (ptr) {
1565             int old_corpsenm = otmp->corpsenm;
1566
1567             otmp->corpsenm = monsndx(ptr);
1568             otmp->owt = weight(otmp);
1569             if (otmp->otyp == CORPSE && (special_corpse(old_corpsenm)
1570                                          || special_corpse(otmp->corpsenm))) {
1571                 obj_stop_timers(otmp);
1572                 start_corpse_timeout(otmp);
1573             }
1574         }
1575     }
1576     return otmp;
1577 }
1578
1579 /*
1580  * Return the type of monster that this corpse will
1581  * revive as, even if it has a monster structure
1582  * attached to it. In that case, you can't just
1583  * use obj->corpsenm, because the stored monster
1584  * type can, and often is, different.
1585  * The return value is an index into mons[].
1586  */
1587 int
1588 corpse_revive_type(obj)
1589 struct obj *obj;
1590 {
1591     int revivetype;
1592     struct monst *mtmp;
1593     if (has_omonst(obj)
1594         && ((mtmp = get_mtraits(obj, FALSE)) != (struct monst *) 0)) {
1595         /* mtmp is a temporary pointer to a monster's stored
1596         attributes, not a real monster */
1597         revivetype = mtmp->mnum;
1598     } else
1599         revivetype = obj->corpsenm;
1600     return revivetype;
1601 }
1602
1603 /*
1604  * Attach a monster id to an object, to provide
1605  * a lasting association between the two.
1606  */
1607 struct obj *
1608 obj_attach_mid(obj, mid)
1609 struct obj *obj;
1610 unsigned mid;
1611 {
1612     if (!mid || !obj)
1613         return (struct obj *) 0;
1614     newomid(obj);
1615     *OMID(obj) = mid;
1616     return obj;
1617 }
1618
1619 static struct obj *
1620 save_mtraits(obj, mtmp)
1621 struct obj *obj;
1622 struct monst *mtmp;
1623 {
1624     if (mtmp->ispriest)
1625         forget_temple_entry(mtmp); /* EPRI() */
1626     if (!has_omonst(obj))
1627         newomonst(obj);
1628     if (has_omonst(obj)) {
1629         struct monst *mtmp2 = OMONST(obj);
1630
1631         *mtmp2 = *mtmp;
1632         mtmp2->mextra = (struct mextra *) 0;
1633         if (mtmp->data)
1634             mtmp2->mnum = monsndx(mtmp->data);
1635         /* invalidate pointers */
1636         /* m_id is needed to know if this is a revived quest leader */
1637         /* but m_id must be cleared when loading bones */
1638         mtmp2->nmon = (struct monst *) 0;
1639         mtmp2->data = (struct permonst *) 0;
1640         mtmp2->minvent = (struct obj *) 0;
1641         if (mtmp->mextra)
1642             copy_mextra(mtmp2, mtmp);
1643     }
1644     return obj;
1645 }
1646
1647 /* returns a pointer to a new monst structure based on
1648  * the one contained within the obj.
1649  */
1650 struct monst *
1651 get_mtraits(obj, copyof)
1652 struct obj *obj;
1653 boolean copyof;
1654 {
1655     struct monst *mtmp = (struct monst *) 0;
1656     struct monst *mnew = (struct monst *) 0;
1657
1658     if (has_omonst(obj))
1659         mtmp = OMONST(obj);
1660     if (mtmp) {
1661         if (copyof) {
1662             mnew = newmonst();
1663             *mnew = *mtmp;
1664             mnew->mextra = (struct mextra *) 0;
1665             if (mtmp->mextra)
1666                 copy_mextra(mnew, mtmp);
1667         } else {
1668             /* Never insert this returned pointer into mon chains! */
1669             mnew = mtmp;
1670         }
1671     }
1672     return mnew;
1673 }
1674
1675 /* make an object named after someone listed in the scoreboard file */
1676 struct obj *
1677 mk_tt_object(objtype, x, y)
1678 int objtype; /* CORPSE or STATUE */
1679 register int x, y;
1680 {
1681     register struct obj *otmp, *otmp2;
1682     boolean initialize_it;
1683
1684     /* player statues never contain books */
1685     initialize_it = (objtype != STATUE);
1686     if ((otmp = mksobj_at(objtype, x, y, initialize_it, FALSE)) != 0) {
1687         /* tt_oname will return null if the scoreboard is empty */
1688         if ((otmp2 = tt_oname(otmp)) != 0)
1689             otmp = otmp2;
1690     }
1691     return otmp;
1692 }
1693
1694 /* make a new corpse or statue, uninitialized if a statue (i.e. no books) */
1695 struct obj *
1696 mk_named_object(objtype, ptr, x, y, nm)
1697 int objtype; /* CORPSE or STATUE */
1698 struct permonst *ptr;
1699 int x, y;
1700 const char *nm;
1701 {
1702     struct obj *otmp;
1703     unsigned corpstatflags =
1704         (objtype != STATUE) ? CORPSTAT_INIT : CORPSTAT_NONE;
1705
1706     otmp = mkcorpstat(objtype, (struct monst *) 0, ptr, x, y, corpstatflags);
1707     if (nm)
1708         otmp = oname(otmp, nm);
1709     return otmp;
1710 }
1711
1712 boolean
1713 is_flammable(otmp)
1714 register struct obj *otmp;
1715 {
1716     int otyp = otmp->otyp;
1717     int omat = objects[otyp].oc_material;
1718
1719     /* Candles can be burned, but they're not flammable in the sense that
1720      * they can't get fire damage and it makes no sense for them to be
1721      * fireproofed.
1722      */
1723     if (Is_candle(otmp))
1724         return FALSE;
1725
1726     if (objects[otyp].oc_oprop == FIRE_RES || otyp == WAN_FIRE)
1727         return FALSE;
1728
1729     return (boolean) ((omat <= WOOD && omat != LIQUID) || omat == PLASTIC);
1730 }
1731
1732 boolean
1733 is_rottable(otmp)
1734 register struct obj *otmp;
1735 {
1736     int otyp = otmp->otyp;
1737
1738     return (boolean) (objects[otyp].oc_material <= WOOD
1739                       && objects[otyp].oc_material != LIQUID);
1740 }
1741
1742 /*
1743  * These routines maintain the single-linked lists headed in level.objects[][]
1744  * and threaded through the nexthere fields in the object-instance structure.
1745  */
1746
1747 /* put the object at the given location */
1748 void
1749 place_object(otmp, x, y)
1750 register struct obj *otmp;
1751 int x, y;
1752 {
1753     register struct obj *otmp2 = level.objects[x][y];
1754
1755     if (otmp->where != OBJ_FREE)
1756         panic("place_object: obj not free");
1757
1758     obj_no_longer_held(otmp);
1759     /* (could bypass this vision update if there is already a boulder here) */
1760     if (otmp->otyp == BOULDER)
1761         block_point(x, y); /* vision */
1762
1763     /* obj goes under boulders */
1764     if (otmp2 && (otmp2->otyp == BOULDER)) {
1765         otmp->nexthere = otmp2->nexthere;
1766         otmp2->nexthere = otmp;
1767     } else {
1768         otmp->nexthere = otmp2;
1769         level.objects[x][y] = otmp;
1770     }
1771
1772     /* set the new object's location */
1773     otmp->ox = x;
1774     otmp->oy = y;
1775
1776     otmp->where = OBJ_FLOOR;
1777
1778     /* add to floor chain */
1779     otmp->nobj = fobj;
1780     fobj = otmp;
1781     if (otmp->timed)
1782         obj_timer_checks(otmp, x, y, 0);
1783 }
1784
1785 #define ROT_ICE_ADJUSTMENT 2 /* rotting on ice takes 2 times as long */
1786
1787 /* If ice was affecting any objects correct that now
1788  * Also used for starting ice effects too. [zap.c]
1789  */
1790 void
1791 obj_ice_effects(x, y, do_buried)
1792 int x, y;
1793 boolean do_buried;
1794 {
1795     struct obj *otmp;
1796
1797     for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) {
1798         if (otmp->timed)
1799             obj_timer_checks(otmp, x, y, 0);
1800     }
1801     if (do_buried) {
1802         for (otmp = level.buriedobjlist; otmp; otmp = otmp->nobj) {
1803             if (otmp->ox == x && otmp->oy == y) {
1804                 if (otmp->timed)
1805                     obj_timer_checks(otmp, x, y, 0);
1806             }
1807         }
1808     }
1809 }
1810
1811 /*
1812  * Returns an obj->age for a corpse object on ice, that would be the
1813  * actual obj->age if the corpse had just been lifted from the ice.
1814  * This is useful when just using obj->age in a check or calculation because
1815  * rot timers pertaining to the object don't have to be stopped and
1816  * restarted etc.
1817  */
1818 long
1819 peek_at_iced_corpse_age(otmp)
1820 struct obj *otmp;
1821 {
1822     long age, retval = otmp->age;
1823
1824     if (otmp->otyp == CORPSE && otmp->on_ice) {
1825         /* Adjust the age; must be same as obj_timer_checks() for off ice*/
1826         age = monstermoves - otmp->age;
1827         retval += age * (ROT_ICE_ADJUSTMENT - 1) / ROT_ICE_ADJUSTMENT;
1828         debugpline3(
1829           "The %s age has ice modifications: otmp->age = %ld, returning %ld.",
1830                     s_suffix(doname(otmp)), otmp->age, retval);
1831         debugpline1("Effective age of corpse: %ld.", monstermoves - retval);
1832     }
1833     return retval;
1834 }
1835
1836 STATIC_OVL void
1837 obj_timer_checks(otmp, x, y, force)
1838 struct obj *otmp;
1839 xchar x, y;
1840 int force; /* 0 = no force so do checks, <0 = force off, >0 force on */
1841 {
1842     long tleft = 0L;
1843     short action = ROT_CORPSE;
1844     boolean restart_timer = FALSE;
1845     boolean on_floor = (otmp->where == OBJ_FLOOR);
1846     boolean buried = (otmp->where == OBJ_BURIED);
1847
1848     /* Check for corpses just placed on or in ice */
1849     if (otmp->otyp == CORPSE && (on_floor || buried) && is_ice(x, y)) {
1850         tleft = stop_timer(action, obj_to_any(otmp));
1851         if (tleft == 0L) {
1852             action = REVIVE_MON;
1853             tleft = stop_timer(action, obj_to_any(otmp));
1854         }
1855         if (tleft != 0L) {
1856             long age;
1857
1858             /* mark the corpse as being on ice */
1859             otmp->on_ice = 1;
1860             debugpline3("%s is now on ice at <%d,%d>.", The(xname(otmp)), x,
1861                         y);
1862             /* Adjust the time remaining */
1863             tleft *= ROT_ICE_ADJUSTMENT;
1864             restart_timer = TRUE;
1865             /* Adjust the age; time spent off ice needs to be multiplied
1866                by the ice adjustment and subtracted from the age so that
1867                later calculations behave as if it had been on ice during
1868                that time (longwinded way of saying this is the inverse
1869                of removing it from the ice and of peeking at its age). */
1870             age = monstermoves - otmp->age;
1871             otmp->age = monstermoves - (age * ROT_ICE_ADJUSTMENT);
1872         }
1873
1874     /* Check for corpses coming off ice */
1875     } else if (force < 0 || (otmp->otyp == CORPSE && otmp->on_ice
1876                              && !((on_floor || buried) && is_ice(x, y)))) {
1877         tleft = stop_timer(action, obj_to_any(otmp));
1878         if (tleft == 0L) {
1879             action = REVIVE_MON;
1880             tleft = stop_timer(action, obj_to_any(otmp));
1881         }
1882         if (tleft != 0L) {
1883             long age;
1884
1885             otmp->on_ice = 0;
1886             debugpline3("%s is no longer on ice at <%d,%d>.",
1887                         The(xname(otmp)), x, y);
1888             /* Adjust the remaining time */
1889             tleft /= ROT_ICE_ADJUSTMENT;
1890             restart_timer = TRUE;
1891             /* Adjust the age */
1892             age = monstermoves - otmp->age;
1893             otmp->age += age * (ROT_ICE_ADJUSTMENT - 1) / ROT_ICE_ADJUSTMENT;
1894         }
1895     }
1896
1897     /* now re-start the timer with the appropriate modifications */
1898     if (restart_timer)
1899         (void) start_timer(tleft, TIMER_OBJECT, action, obj_to_any(otmp));
1900 }
1901
1902 #undef ROT_ICE_ADJUSTMENT
1903
1904 void
1905 remove_object(otmp)
1906 register struct obj *otmp;
1907 {
1908     xchar x = otmp->ox;
1909     xchar y = otmp->oy;
1910
1911     if (otmp->where != OBJ_FLOOR)
1912         panic("remove_object: obj not on floor");
1913     extract_nexthere(otmp, &level.objects[x][y]);
1914     extract_nobj(otmp, &fobj);
1915     /* update vision iff this was the only boulder at its spot */
1916     if (otmp->otyp == BOULDER && !sobj_at(BOULDER, x, y))
1917         unblock_point(x, y); /* vision */
1918     if (otmp->timed)
1919         obj_timer_checks(otmp, x, y, 0);
1920 }
1921
1922 /* throw away all of a monster's inventory */
1923 void
1924 discard_minvent(mtmp)
1925 struct monst *mtmp;
1926 {
1927     struct obj *otmp, *mwep = MON_WEP(mtmp);
1928     boolean keeping_mon = (!DEADMONSTER(mtmp));
1929
1930     while ((otmp = mtmp->minvent) != 0) {
1931         /* this has now become very similar to m_useupall()... */
1932         obj_extract_self(otmp);
1933         if (otmp->owornmask) {
1934             if (keeping_mon) {
1935                 if (otmp == mwep)
1936                     mwepgone(mtmp), mwep = 0;
1937                 mtmp->misc_worn_check &= ~otmp->owornmask;
1938                 update_mon_intrinsics(mtmp, otmp, FALSE, TRUE);
1939             }
1940             otmp->owornmask = 0L; /* obfree() expects this */
1941         }
1942         obfree(otmp, (struct obj *) 0); /* dealloc_obj() isn't sufficient */
1943     }
1944 }
1945
1946 /*
1947  * Free obj from whatever list it is on in preparation for deleting it
1948  * or moving it elsewhere; obj->where will end up set to OBJ_FREE.
1949  * Doesn't handle unwearing of objects in hero's or monsters' inventories.
1950  *
1951  * Object positions:
1952  *      OBJ_FREE        not on any list
1953  *      OBJ_FLOOR       fobj, level.locations[][] chains (use remove_object)
1954  *      OBJ_CONTAINED   cobj chain of container object
1955  *      OBJ_INVENT      hero's invent chain (use freeinv)
1956  *      OBJ_MINVENT     monster's invent chain
1957  *      OBJ_MIGRATING   migrating chain
1958  *      OBJ_BURIED      level.buriedobjs chain
1959  *      OBJ_ONBILL      on billobjs chain
1960  */
1961 void
1962 obj_extract_self(obj)
1963 struct obj *obj;
1964 {
1965     switch (obj->where) {
1966     case OBJ_FREE:
1967         break;
1968     case OBJ_FLOOR:
1969         remove_object(obj);
1970         break;
1971     case OBJ_CONTAINED:
1972         extract_nobj(obj, &obj->ocontainer->cobj);
1973         container_weight(obj->ocontainer);
1974         obj->ocontainer = (struct obj *) 0; /* clear stale back-link */
1975         break;
1976     case OBJ_INVENT:
1977         freeinv(obj);
1978         break;
1979     case OBJ_MINVENT:
1980         extract_nobj(obj, &obj->ocarry->minvent);
1981         obj->ocarry = (struct monst *) 0; /* clear stale back-link */
1982         break;
1983     case OBJ_MIGRATING:
1984         extract_nobj(obj, &migrating_objs);
1985         break;
1986     case OBJ_BURIED:
1987         extract_nobj(obj, &level.buriedobjlist);
1988         break;
1989     case OBJ_ONBILL:
1990         extract_nobj(obj, &billobjs);
1991         break;
1992     default:
1993         panic("obj_extract_self");
1994         break;
1995     }
1996 }
1997
1998 /* Extract the given object from the chain, following nobj chain. */
1999 void
2000 extract_nobj(obj, head_ptr)
2001 struct obj *obj, **head_ptr;
2002 {
2003     struct obj *curr, *prev;
2004
2005     curr = *head_ptr;
2006     for (prev = (struct obj *) 0; curr; prev = curr, curr = curr->nobj) {
2007         if (curr == obj) {
2008             if (prev)
2009                 prev->nobj = curr->nobj;
2010             else
2011                 *head_ptr = curr->nobj;
2012             break;
2013         }
2014     }
2015     if (!curr)
2016         panic("extract_nobj: object lost");
2017     obj->where = OBJ_FREE;
2018     obj->nobj = (struct obj *) 0;
2019 }
2020
2021 /*
2022  * Extract the given object from the chain, following nexthere chain.
2023  *
2024  * This does not set obj->where, this function is expected to be called
2025  * in tandem with extract_nobj, which does set it.
2026  */
2027 void
2028 extract_nexthere(obj, head_ptr)
2029 struct obj *obj, **head_ptr;
2030 {
2031     struct obj *curr, *prev;
2032
2033     curr = *head_ptr;
2034     for (prev = (struct obj *) 0; curr; prev = curr, curr = curr->nexthere) {
2035         if (curr == obj) {
2036             if (prev)
2037                 prev->nexthere = curr->nexthere;
2038             else
2039                 *head_ptr = curr->nexthere;
2040             break;
2041         }
2042     }
2043     if (!curr)
2044         panic("extract_nexthere: object lost");
2045     obj->nexthere = (struct obj *) 0;
2046 }
2047
2048 /*
2049  * Add obj to mon's inventory.  If obj is able to merge with something already
2050  * in the inventory, then the passed obj is deleted and 1 is returned.
2051  * Otherwise 0 is returned.
2052  */
2053 int
2054 add_to_minv(mon, obj)
2055 struct monst *mon;
2056 struct obj *obj;
2057 {
2058     struct obj *otmp;
2059
2060     if (obj->where != OBJ_FREE)
2061         panic("add_to_minv: obj not free");
2062
2063     /* merge if possible */
2064     for (otmp = mon->minvent; otmp; otmp = otmp->nobj)
2065         if (merged(&otmp, &obj))
2066             return 1; /* obj merged and then free'd */
2067     /* else insert; don't bother forcing it to end of chain */
2068     obj->where = OBJ_MINVENT;
2069     obj->ocarry = mon;
2070     obj->nobj = mon->minvent;
2071     mon->minvent = obj;
2072     return 0; /* obj on mon's inventory chain */
2073 }
2074
2075 /*
2076  * Add obj to container, make sure obj is "free".  Returns (merged) obj.
2077  * The input obj may be deleted in the process.
2078  */
2079 struct obj *
2080 add_to_container(container, obj)
2081 struct obj *container, *obj;
2082 {
2083     struct obj *otmp;
2084
2085     if (obj->where != OBJ_FREE)
2086         panic("add_to_container: obj not free");
2087     if (container->where != OBJ_INVENT && container->where != OBJ_MINVENT)
2088         obj_no_longer_held(obj);
2089
2090     /* merge if possible */
2091     for (otmp = container->cobj; otmp; otmp = otmp->nobj)
2092         if (merged(&otmp, &obj))
2093             return otmp;
2094
2095     obj->where = OBJ_CONTAINED;
2096     obj->ocontainer = container;
2097     obj->nobj = container->cobj;
2098     container->cobj = obj;
2099     return obj;
2100 }
2101
2102 void
2103 add_to_migration(obj)
2104 struct obj *obj;
2105 {
2106     if (obj->where != OBJ_FREE)
2107         panic("add_to_migration: obj not free");
2108
2109     /* lock picking context becomes stale if it's for this object */
2110     if (Is_container(obj))
2111         maybe_reset_pick(obj);
2112
2113     obj->where = OBJ_MIGRATING;
2114     obj->nobj = migrating_objs;
2115     migrating_objs = obj;
2116 }
2117
2118 void
2119 add_to_buried(obj)
2120 struct obj *obj;
2121 {
2122     if (obj->where != OBJ_FREE)
2123         panic("add_to_buried: obj not free");
2124
2125     obj->where = OBJ_BURIED;
2126     obj->nobj = level.buriedobjlist;
2127     level.buriedobjlist = obj;
2128 }
2129
2130 /* Recalculate the weight of this container and all of _its_ containers. */
2131 STATIC_OVL void
2132 container_weight(container)
2133 struct obj *container;
2134 {
2135     container->owt = weight(container);
2136     if (container->where == OBJ_CONTAINED)
2137         container_weight(container->ocontainer);
2138     /*
2139         else if (container->where == OBJ_INVENT)
2140         recalculate load delay here ???
2141     */
2142 }
2143
2144 /*
2145  * Deallocate the object.  _All_ objects should be run through here for
2146  * them to be deallocated.
2147  */
2148 void
2149 dealloc_obj(obj)
2150 struct obj *obj;
2151 {
2152     if (obj->where != OBJ_FREE)
2153         panic("dealloc_obj: obj not free");
2154     if (obj->nobj)
2155         panic("dealloc_obj with nobj");
2156     if (obj->cobj)
2157         panic("dealloc_obj with cobj");
2158
2159     /* free up any timers attached to the object */
2160     if (obj->timed)
2161         obj_stop_timers(obj);
2162
2163     /*
2164      * Free up any light sources attached to the object.
2165      *
2166      * We may want to just call del_light_source() without any
2167      * checks (requires a code change there).  Otherwise this
2168      * list must track all objects that can have a light source
2169      * attached to it (and also requires lamplit to be set).
2170      */
2171     if (obj_sheds_light(obj))
2172         del_light_source(LS_OBJECT, obj_to_any(obj));
2173
2174     if (obj == thrownobj)
2175         thrownobj = 0;
2176     if (obj == kickedobj)
2177         kickedobj = 0;
2178
2179     if (obj->oextra)
2180         dealloc_oextra(obj);
2181     free((genericptr_t) obj);
2182 }
2183
2184 /* create an object from a horn of plenty; mirrors bagotricks(makemon.c) */
2185 int
2186 hornoplenty(horn, tipping)
2187 struct obj *horn;
2188 boolean tipping; /* caller emptying entire contents; affects shop handling */
2189 {
2190     int objcount = 0;
2191
2192     if (!horn || horn->otyp != HORN_OF_PLENTY) {
2193         impossible("bad horn o' plenty");
2194     } else if (horn->spe < 1) {
2195         pline1(nothing_happens);
2196     } else {
2197         struct obj *obj;
2198         const char *what;
2199
2200         consume_obj_charge(horn, !tipping);
2201         if (!rn2(13)) {
2202             obj = mkobj(POTION_CLASS, FALSE);
2203             if (objects[obj->otyp].oc_magic)
2204                 do {
2205                     obj->otyp = rnd_class(POT_BOOZE, POT_WATER);
2206                 } while (obj->otyp == POT_SICKNESS);
2207 /*JP
2208             what = (obj->quan > 1L) ? "Some potions" : "A potion";
2209 */
2210             what = "\96ò";
2211         } else {
2212             obj = mkobj(FOOD_CLASS, FALSE);
2213             if (obj->otyp == FOOD_RATION && !rn2(7))
2214                 obj->otyp = LUMP_OF_ROYAL_JELLY;
2215 /*JP
2216             what = "Some food";
2217 */
2218             what = "\90H\82×\95¨";
2219         }
2220         ++objcount;
2221 /*JP
2222         pline("%s %s out.", what, vtense(what, "spill"));
2223 */
2224         pline("%s\82ª\94ò\82Ñ\8fo\82Ä\82«\82½\81D", what);
2225         obj->blessed = horn->blessed;
2226         obj->cursed = horn->cursed;
2227         obj->owt = weight(obj);
2228         /* using a shop's horn of plenty entails a usage fee and also
2229            confers ownership of the created item to the shopkeeper */
2230         if (horn->unpaid)
2231             addtobill(obj, FALSE, FALSE, tipping);
2232         /* if it ended up on bill, we don't want "(unpaid, N zorkids)"
2233            being included in its formatted name during next message */
2234         iflags.suppress_price++;
2235         if (!tipping) {
2236 #if 0 /*JP*/
2237             obj = hold_another_object(obj,
2238                                       u.uswallow
2239                                         ? "Oops!  %s out of your reach!"
2240                                         : (Is_airlevel(&u.uz)
2241                                            || Is_waterlevel(&u.uz)
2242                                            || levl[u.ux][u.uy].typ < IRONBARS
2243                                            || levl[u.ux][u.uy].typ >= ICE)
2244                                           ? "Oops!  %s away from you!"
2245                                           : "Oops!  %s to the floor!",
2246                                       The(aobjnam(obj, "slip")), (char *) 0);
2247 #else
2248             obj = hold_another_object(obj,
2249                                       u.uswallow
2250                                         ? "\82¨\82Á\82Æ\81I%s\82Í\93Í\82©\82È\82¢\81I"
2251                                         : (Is_airlevel(&u.uz)
2252                                            || Is_waterlevel(&u.uz)
2253                                            || levl[u.ux][u.uy].typ < IRONBARS
2254                                            || levl[u.ux][u.uy].typ >= ICE)
2255                                           ? "\82¨\82Á\82Æ\81I%s\82Í\82 \82È\82½\82Ì\8eè\82©\82ç\8a\8a\82è\97\8e\82¿\82½\81I"
2256                                           : "\82¨\82Á\82Æ\81I%s\82Í\8f°\82É\8a\8a\82è\97\8e\82¿\82½\81I",
2257                                       xname(obj), (char *)0);
2258 #endif
2259             nhUse(obj);
2260         } else {
2261             /* assumes this is taking place at hero's location */
2262             if (!can_reach_floor(TRUE)) {
2263                 hitfloor(obj, TRUE); /* does altar check, message, drop */
2264             } else {
2265                 if (IS_ALTAR(levl[u.ux][u.uy].typ))
2266                     doaltarobj(obj); /* does its own drop message */
2267                 else
2268 #if 0 /*JP*/
2269                     pline("%s %s to the %s.", Doname2(obj),
2270                           otense(obj, "drop"), surface(u.ux, u.uy));
2271 #else
2272                     pline("%s\82Í%s\82É\97\8e\82¿\82½\81D", Doname2(obj),
2273                           surface(u.ux, u.uy));
2274 #endif
2275                 dropy(obj);
2276             }
2277         }
2278         iflags.suppress_price--;
2279         if (horn->dknown)
2280             makeknown(HORN_OF_PLENTY);
2281     }
2282     return objcount;
2283 }
2284
2285 /* support for wizard-mode's `sanity_check' option */
2286
2287 static const char NEARDATA /* pline formats for insane_object() */
2288     ofmt0[] = "%s obj %s %s: %s",
2289     ofmt3[] = "%s [not null] %s %s: %s",
2290     /* " held by mon %p (%s)" will be appended, filled by M,mon_nam(M) */
2291     mfmt1[] = "%s obj %s %s (%s)",
2292     mfmt2[] = "%s obj %s %s (%s) *not*";
2293
2294 /* Check all object lists for consistency. */
2295 void
2296 obj_sanity_check()
2297 {
2298     int x, y;
2299     struct obj *obj;
2300
2301     /*
2302      * TODO:
2303      *  Should check whether the obj->bypass and/or obj->nomerge bits
2304      *  are set.  Those are both used for temporary purposes and should
2305      *  be clear between moves.
2306      */
2307
2308     objlist_sanity(fobj, OBJ_FLOOR, "floor sanity");
2309
2310     /* check that the map's record of floor objects is consistent;
2311        those objects should have already been sanity checked via
2312        the floor list so container contents are skipped here */
2313     for (x = 0; x < COLNO; x++)
2314         for (y = 0; y < ROWNO; y++)
2315             for (obj = level.objects[x][y]; obj; obj = obj->nexthere) {
2316                 /* <ox,oy> should match <x,y>; <0,*> should always be empty */
2317                 if (obj->where != OBJ_FLOOR || x == 0
2318                     || obj->ox != x || obj->oy != y) {
2319                     char at_fmt[BUFSZ];
2320
2321                     Sprintf(at_fmt, "%%s obj@<%d,%d> %%s %%s: %%s@<%d,%d>",
2322                             x, y, obj->ox, obj->oy);
2323                     insane_object(obj, at_fmt, "location sanity",
2324                                   (struct monst *) 0);
2325                 }
2326             }
2327
2328     objlist_sanity(invent, OBJ_INVENT, "invent sanity");
2329     objlist_sanity(migrating_objs, OBJ_MIGRATING, "migrating sanity");
2330     objlist_sanity(level.buriedobjlist, OBJ_BURIED, "buried sanity");
2331     objlist_sanity(billobjs, OBJ_ONBILL, "bill sanity");
2332
2333     mon_obj_sanity(fmon, "minvent sanity");
2334     mon_obj_sanity(migrating_mons, "migrating minvent sanity");
2335     /* monsters temporarily in transit;
2336        they should have arrived with hero by the time we get called */
2337     if (mydogs) {
2338         impossible("mydogs sanity [not empty]");
2339         mon_obj_sanity(mydogs, "mydogs minvent sanity");
2340     }
2341
2342     /* objects temporarily freed from invent/floor lists;
2343        they should have arrived somewhere by the time we get called */
2344     if (thrownobj)
2345         insane_object(thrownobj, ofmt3, "thrownobj sanity",
2346                       (struct monst *) 0);
2347     if (kickedobj)
2348         insane_object(kickedobj, ofmt3, "kickedobj sanity",
2349                       (struct monst *) 0);
2350     /* current_wand isn't removed from invent while in use, but should
2351        be Null between moves when we're called */
2352     if (current_wand)
2353         insane_object(current_wand, ofmt3, "current_wand sanity",
2354                       (struct monst *) 0);
2355 }
2356
2357 /* sanity check for objects on specified list (fobj, &c) */
2358 STATIC_OVL void
2359 objlist_sanity(objlist, wheretype, mesg)
2360 struct obj *objlist;
2361 int wheretype;
2362 const char *mesg;
2363 {
2364     struct obj *obj;
2365
2366     for (obj = objlist; obj; obj = obj->nobj) {
2367         if (obj->where != wheretype)
2368             insane_object(obj, ofmt0, mesg, (struct monst *) 0);
2369         if (Has_contents(obj)) {
2370             if (wheretype == OBJ_ONBILL)
2371                 /* containers on shop bill should always be empty */
2372                 insane_object(obj, "%s obj contains something! %s %s: %s",
2373                               mesg, (struct monst *) 0);
2374             check_contained(obj, mesg);
2375         }
2376         if (obj->owornmask) {
2377             char maskbuf[40];
2378             boolean bc_ok = FALSE;
2379
2380             switch (obj->where) {
2381             case OBJ_INVENT:
2382             case OBJ_MINVENT:
2383                 sanity_check_worn(obj);
2384                 break;
2385             case OBJ_MIGRATING:
2386                 /* migrating objects overload the owornmask field
2387                    with a destination code; skip attempt to check it */
2388                 break;
2389             case OBJ_FLOOR:
2390                 /* note: ball and chain can also be OBJ_FREE, but not across
2391                    turns so this sanity check shouldn't encounter that */
2392                 bc_ok = TRUE;
2393             /*FALLTHRU*/
2394             default:
2395                 if ((obj != uchain && obj != uball) || !bc_ok) {
2396                     /* discovered an object not in inventory which
2397                        erroneously has worn mask set */
2398                     Sprintf(maskbuf, "worn mask 0x%08lx", obj->owornmask);
2399                     insane_object(obj, ofmt0, maskbuf, (struct monst *) 0);
2400                 }
2401                 break;
2402             }
2403         }
2404     }
2405 }
2406
2407 /* sanity check for objects carried by all monsters in specified list */
2408 STATIC_OVL void
2409 mon_obj_sanity(monlist, mesg)
2410 struct monst *monlist;
2411 const char *mesg;
2412 {
2413     struct monst *mon;
2414     struct obj *obj, *mwep;
2415
2416     for (mon = monlist; mon; mon = mon->nmon) {
2417         if (DEADMONSTER(mon)) continue;
2418         mwep = MON_WEP(mon);
2419         if (mwep) {
2420             if (!mcarried(mwep))
2421                 insane_object(mwep, mfmt1, mesg, mon);
2422             if (mwep->ocarry != mon)
2423                 insane_object(mwep, mfmt2, mesg, mon);
2424         }
2425         for (obj = mon->minvent; obj; obj = obj->nobj) {
2426             if (obj->where != OBJ_MINVENT)
2427                 insane_object(obj, mfmt1, mesg, mon);
2428             if (obj->ocarry != mon)
2429                 insane_object(obj, mfmt2, mesg, mon);
2430             check_contained(obj, mesg);
2431         }
2432     }
2433 }
2434
2435 /* This must stay consistent with the defines in obj.h. */
2436 static const char *obj_state_names[NOBJ_STATES] = { "free",      "floor",
2437                                                     "contained", "invent",
2438                                                     "minvent",   "migrating",
2439                                                     "buried",    "onbill" };
2440
2441 STATIC_OVL const char *
2442 where_name(obj)
2443 struct obj *obj;
2444 {
2445     static char unknown[32]; /* big enough to handle rogue 64-bit int */
2446     int where;
2447
2448     if (!obj)
2449         return "nowhere";
2450     where = obj->where;
2451     if (where < 0 || where >= NOBJ_STATES || !obj_state_names[where]) {
2452         Sprintf(unknown, "unknown[%d]", where);
2453         return unknown;
2454     }
2455     return obj_state_names[where];
2456 }
2457
2458 STATIC_OVL void
2459 insane_object(obj, fmt, mesg, mon)
2460 struct obj *obj;
2461 const char *fmt, *mesg;
2462 struct monst *mon;
2463 {
2464     const char *objnm, *monnm;
2465     char altfmt[BUFSZ];
2466
2467     objnm = monnm = "null!";
2468     if (obj) {
2469         iflags.override_ID++;
2470         objnm = doname(obj);
2471         iflags.override_ID--;
2472     }
2473     if (mon || (strstri(mesg, "minvent") && !strstri(mesg, "contained"))) {
2474         Strcat(strcpy(altfmt, fmt), " held by mon %s (%s)");
2475         if (mon)
2476             monnm = x_monnam(mon, ARTICLE_A, (char *) 0, EXACT_NAME, TRUE);
2477         impossible(altfmt, mesg, fmt_ptr((genericptr_t) obj), where_name(obj),
2478               objnm, fmt_ptr((genericptr_t) mon), monnm);
2479     } else {
2480         impossible(fmt, mesg, fmt_ptr((genericptr_t) obj), where_name(obj), objnm);
2481     }
2482 }
2483
2484 /* obj sanity check: check objects inside container */
2485 STATIC_OVL void
2486 check_contained(container, mesg)
2487 struct obj *container;
2488 const char *mesg;
2489 {
2490     struct obj *obj;
2491     /* big enough to work with, not too big to blow out stack in recursion */
2492     char mesgbuf[40], nestedmesg[120];
2493
2494     if (!Has_contents(container))
2495         return;
2496     /* change "invent sanity" to "contained invent sanity"
2497        but leave "nested contained invent sanity" as is */
2498     if (!strstri(mesg, "contained"))
2499         mesg = strcat(strcpy(mesgbuf, "contained "), mesg);
2500
2501     for (obj = container->cobj; obj; obj = obj->nobj) {
2502         /* catch direct cycle to avoid unbounded recursion */
2503         if (obj == container)
2504             panic("failed sanity check: container holds itself");
2505         if (obj->where != OBJ_CONTAINED)
2506             insane_object(obj, "%s obj %s %s: %s", mesg, (struct monst *) 0);
2507         else if (obj->ocontainer != container)
2508             impossible("%s obj %s in container %s, not %s", mesg,
2509                   fmt_ptr((genericptr_t) obj),
2510                   fmt_ptr((genericptr_t) obj->ocontainer),
2511                   fmt_ptr((genericptr_t) container));
2512
2513         if (Has_contents(obj)) {
2514             /* catch most likely indirect cycle; we won't notice if
2515                parent is present when something comes before it, or
2516                notice more deeply embedded cycles (grandparent, &c) */
2517             if (obj->cobj == container)
2518                 panic("failed sanity check: container holds its parent");
2519             /* change "contained... sanity" to "nested contained... sanity"
2520                and "nested contained..." to "nested nested contained..." */
2521             Strcpy(nestedmesg, "nested ");
2522             copynchars(eos(nestedmesg), mesg, (int) sizeof nestedmesg
2523                                                   - (int) strlen(nestedmesg)
2524                                                   - 1);
2525             /* recursively check contents */
2526             check_contained(obj, nestedmesg);
2527         }
2528     }
2529 }
2530
2531 /* check an object in hero's or monster's inventory which has worn mask set */
2532 STATIC_OVL void
2533 sanity_check_worn(obj)
2534 struct obj *obj;
2535 {
2536 #if defined(BETA) || defined(DEBUG)
2537     static unsigned long wearbits[] = {
2538         W_ARM,    W_ARMC,   W_ARMH,    W_ARMS, W_ARMG,  W_ARMF,  W_ARMU,
2539         W_WEP,    W_QUIVER, W_SWAPWEP, W_AMUL, W_RINGL, W_RINGR, W_TOOL,
2540         W_SADDLE, W_BALL,   W_CHAIN,   0
2541         /* [W_ART,W_ARTI are property bits for items which aren't worn] */
2542     };
2543     char maskbuf[60];
2544     const char *what;
2545     unsigned long owornmask, allmask = 0L;
2546     boolean embedded = FALSE;
2547     int i, n = 0;
2548
2549     /* use owornmask for testing and bit twiddling, but use original
2550        obj->owornmask for printing */
2551     owornmask = obj->owornmask;
2552     /* figure out how many bits are set, and also which are viable */
2553     for (i = 0; wearbits[i]; ++i) {
2554         if ((owornmask & wearbits[i]) != 0L)
2555             ++n;
2556         allmask |= wearbits[i];
2557     }
2558     if (obj == uskin) {
2559         /* embedded dragon scales have an extra bit set;
2560            make sure it's set, then suppress it */
2561         embedded = TRUE;
2562         if ((owornmask & (W_ARM | I_SPECIAL)) == (W_ARM | I_SPECIAL))
2563             owornmask &= ~I_SPECIAL;
2564         else
2565             n = 0,  owornmask = ~0; /* force insane_object("bogus") below */
2566     }
2567     if (n == 2 && carried(obj)
2568         && obj == uball && (owornmask & W_BALL) != 0L
2569         && (owornmask & W_WEAPON) != 0L) {
2570         /* chained ball can be wielded/alt-wielded/quivered; if so,
2571           pretend it's not chained in order to check the weapon pointer
2572           (we've already verified the ball pointer by successfully passing
2573           the if-condition to get here...) */
2574         owornmask &= ~W_BALL;
2575         n = 1;
2576     }
2577     if (n > 1) {
2578         /* multiple bits set */
2579         Sprintf(maskbuf, "worn mask (multiple) 0x%08lx", obj->owornmask);
2580         insane_object(obj, ofmt0, maskbuf, (struct monst *) 0);
2581     }
2582     if ((owornmask & ~allmask) != 0L
2583         || (carried(obj) && (owornmask & W_SADDLE) != 0L)) {
2584         /* non-wearable bit(s) set */
2585         Sprintf(maskbuf, "worn mask (bogus)) 0x%08lx", obj->owornmask);
2586         insane_object(obj, ofmt0, maskbuf, (struct monst *) 0);
2587     }
2588     if (n == 1 && (carried(obj) || (owornmask & (W_BALL | W_CHAIN)) != 0L)) {
2589         what = 0;
2590         /* verify that obj in hero's invent (or ball/chain elsewhere)
2591            with owornmask of W_foo is the object pointed to by ufoo */
2592         switch (owornmask) {
2593         case W_ARM:
2594             if (obj != (embedded ? uskin : uarm))
2595                 what = embedded ? "skin" : "suit";
2596             break;
2597         case W_ARMC:
2598             if (obj != uarmc)
2599                 what = "cloak";
2600             break;
2601         case W_ARMH:
2602             if (obj != uarmh)
2603                 what = "helm";
2604             break;
2605         case W_ARMS:
2606             if (obj != uarms)
2607                 what = "shield";
2608             break;
2609         case W_ARMG:
2610             if (obj != uarmg)
2611                 what = "gloves";
2612             break;
2613         case W_ARMF:
2614             if (obj != uarmf)
2615                 what = "boots";
2616             break;
2617         case W_ARMU:
2618             if (obj != uarmu)
2619                 what = "shirt";
2620             break;
2621         case W_WEP:
2622             if (obj != uwep)
2623                 what = "primary weapon";
2624             break;
2625         case W_QUIVER:
2626             if (obj != uquiver)
2627                 what = "quiver";
2628             break;
2629         case W_SWAPWEP:
2630             if (obj != uswapwep)
2631                 what = u.twoweap ? "secondary weapon" : "alternate weapon";
2632             break;
2633         case W_AMUL:
2634             if (obj != uamul)
2635                 what = "amulet";
2636             break;
2637         case W_RINGL:
2638             if (obj != uleft)
2639                 what = "left ring";
2640             break;
2641         case W_RINGR:
2642             if (obj != uright)
2643                 what = "right ring";
2644             break;
2645         case W_TOOL:
2646             if (obj != ublindf)
2647                 what = "blindfold";
2648             break;
2649         /* case W_SADDLE: */
2650         case W_BALL:
2651             if (obj != uball)
2652                 what = "ball";
2653             break;
2654         case W_CHAIN:
2655             if (obj != uchain)
2656                 what = "chain";
2657             break;
2658         default:
2659             break;
2660         }
2661         if (what) {
2662             Sprintf(maskbuf, "worn mask 0x%08lx != %s", obj->owornmask, what);
2663             insane_object(obj, ofmt0, maskbuf, (struct monst *) 0);
2664         }
2665     }
2666     if (n == 1 && (carried(obj) || (owornmask & (W_BALL | W_CHAIN)) != 0L
2667                    || mcarried(obj))) {
2668         /* check for items worn in invalid slots; practically anything can
2669            be wielded/alt-wielded/quivered, so tests on those are limited */
2670         what = 0;
2671         if (owornmask & W_ARMOR) {
2672             if (obj->oclass != ARMOR_CLASS)
2673                 what = "armor";
2674             /* 3.6: dragon scale mail reverts to dragon scales when
2675                becoming embedded in poly'd hero's skin */
2676             if (embedded && !Is_dragon_scales(obj))
2677                 what = "skin";
2678         } else if (owornmask & W_WEAPON) {
2679             /* monsters don't maintain alternate weapon or quiver */
2680             if (mcarried(obj) && (owornmask & (W_SWAPWEP | W_QUIVER)) != 0L)
2681                 what = (owornmask & W_SWAPWEP) != 0L ? "monst alt weapon?"
2682                                                      : "monst quiver?";
2683             /* hero can quiver gold but not wield it (hence not alt-wield
2684                it either); also catches monster wielding gold */
2685             else if (obj->oclass == COIN_CLASS
2686                      && (owornmask & (W_WEP | W_SWAPWEP)) != 0L)
2687                 what = (owornmask & W_WEP) != 0L ? "weapon" : "alt weapon";
2688         } else if (owornmask & W_AMUL) {
2689             if (obj->oclass != AMULET_CLASS)
2690                 what = "amulet";
2691         } else if (owornmask & W_RING) {
2692             if (obj->oclass != RING_CLASS && obj->otyp != MEAT_RING)
2693                 what = "ring";
2694         } else if (owornmask & W_TOOL) {
2695             if (obj->otyp != BLINDFOLD && obj->otyp != TOWEL
2696                 && obj->otyp != LENSES)
2697                 what = "blindfold";
2698         } else if (owornmask & W_BALL) {
2699             if (obj->oclass != BALL_CLASS)
2700                 what = "chained ball";
2701         } else if (owornmask & W_CHAIN) {
2702             if (obj->oclass != CHAIN_CLASS)
2703                 what = "chain";
2704         } else if (owornmask & W_SADDLE) {
2705             if (obj->otyp != SADDLE)
2706                 what = "saddle";
2707         }
2708         if (what) {
2709             char oclassname[30];
2710             struct monst *mon = mcarried(obj) ? obj->ocarry : 0;
2711
2712             /* if we've found a potion worn in the amulet slot,
2713                this yields "worn (potion amulet)" */
2714             Strcpy(oclassname, def_oc_syms[(uchar) obj->oclass].name);
2715             Sprintf(maskbuf, "worn (%s %s)", makesingular(oclassname), what);
2716             insane_object(obj, ofmt0, maskbuf, mon);
2717         }
2718     }
2719 #else /* not (BETA || DEBUG) */
2720     /* dummy use of obj to avoid "arg not used" complaint */
2721     if (!obj)
2722         insane_object(obj, ofmt0, "<null>", (struct monst *) 0);
2723 #endif
2724 }
2725
2726 /*
2727  * wrapper to make "near this object" convenient
2728  */
2729 struct obj *
2730 obj_nexto(otmp)
2731 struct obj *otmp;
2732 {
2733     if (!otmp) {
2734         impossible("obj_nexto: wasn't given an object to check");
2735         return (struct obj *) 0;
2736     }
2737     return obj_nexto_xy(otmp, otmp->ox, otmp->oy, TRUE);
2738 }
2739
2740 /*
2741  * looks for objects of a particular type next to x, y
2742  * skips over oid if found (lets us avoid ourselves if
2743  * we're looking for a second type of an existing object)
2744  *
2745  * TODO: return a list of all objects near us so we can more
2746  * reliably predict which one we want to 'find' first
2747  */
2748 struct obj *
2749 obj_nexto_xy(obj, x, y, recurs)
2750 struct obj *obj;
2751 int x, y;
2752 boolean recurs;
2753 {
2754     struct obj *otmp;
2755     int fx, fy, ex, ey, otyp = obj->otyp;
2756     short dx, dy;
2757
2758     /* check under our "feet" first */
2759     otmp = sobj_at(otyp, x, y);
2760     while (otmp) {
2761         /* don't be clever and find ourselves */
2762         if (otmp != obj && mergable(otmp, obj))
2763             return otmp;
2764         otmp = nxtobj(otmp, otyp, TRUE);
2765     }
2766
2767     if (!recurs)
2768         return (struct obj *) 0;
2769
2770     /* search in a random order */
2771     dx = (rn2(2) ? -1 : 1);
2772     dy = (rn2(2) ? -1 : 1);
2773     ex = x - dx;
2774     ey = y - dy;
2775
2776     for (fx = ex; abs(fx - ex) < 3; fx += dx) {
2777         for (fy = ey; abs(fy - ey) < 3; fy += dy) {
2778             /* 0, 0 was checked above */
2779             if (isok(fx, fy) && (fx != x || fy != y)) {
2780                 if ((otmp = obj_nexto_xy(obj, fx, fy, FALSE)) != 0)
2781                     return otmp;
2782             }
2783         }
2784     }
2785     return (struct obj *) 0;
2786 }
2787
2788 /*
2789  * Causes one object to absorb another, increasing
2790  * weight accordingly. Frees obj2; obj1 remains and
2791  * is returned.
2792  */
2793 struct obj *
2794 obj_absorb(obj1, obj2)
2795 struct obj **obj1, **obj2;
2796 {
2797     struct obj *otmp1, *otmp2;
2798     int o1wt, o2wt;
2799     long agetmp;
2800
2801     /* don't let people dumb it up */
2802     if (obj1 && obj2) {
2803         otmp1 = *obj1;
2804         otmp2 = *obj2;
2805         if (otmp1 && otmp2 && otmp1 != otmp2) {
2806             if (otmp1->bknown != otmp2->bknown)
2807                 otmp1->bknown = otmp2->bknown = 0;
2808             if (otmp1->rknown != otmp2->rknown)
2809                 otmp1->rknown = otmp2->rknown = 0;
2810             if (otmp1->greased != otmp2->greased)
2811                 otmp1->greased = otmp2->greased = 0;
2812             if (otmp1->orotten || otmp2->orotten)
2813                 otmp1->orotten = otmp2->orotten = 1;
2814             o1wt = otmp1->oeaten ? otmp1->oeaten : otmp1->owt;
2815             o2wt = otmp2->oeaten ? otmp2->oeaten : otmp2->owt;
2816             /* averaging the relative ages is less likely to overflow
2817                than averaging the absolute ages directly */
2818             agetmp = (((moves - otmp1->age) * o1wt
2819                        + (moves - otmp2->age) * o2wt)
2820                       / (o1wt + o2wt));
2821             otmp1->age = moves - agetmp; /* conv. relative back to absolute */
2822             otmp1->owt += o2wt;
2823             if (otmp1->oeaten)
2824                 otmp1->oeaten += o2wt;
2825             otmp1->quan = 1L;
2826             obj_extract_self(otmp2);
2827             newsym(otmp2->ox, otmp2->oy); /* in case of floor */
2828             dealloc_obj(otmp2);
2829             *obj2 = (struct obj *) 0;
2830             return otmp1;
2831         }
2832     }
2833
2834     impossible("obj_absorb: not called with two actual objects");
2835     return (struct obj *) 0;
2836 }
2837
2838 /*
2839  * Causes the heavier object to absorb the lighter object;
2840  * wrapper for obj_absorb so that floor_effects works more
2841  * cleanly (since we don't know which we want to stay around)
2842  */
2843 struct obj *
2844 obj_meld(obj1, obj2)
2845 struct obj **obj1, **obj2;
2846 {
2847     struct obj *otmp1, *otmp2;
2848
2849     if (obj1 && obj2) {
2850         otmp1 = *obj1;
2851         otmp2 = *obj2;
2852         if (otmp1 && otmp2 && otmp1 != otmp2) {
2853             if (otmp1->owt > otmp2->owt
2854                 || (otmp1->owt == otmp2->owt && rn2(2))) {
2855                 return obj_absorb(obj1, obj2);
2856             }
2857             return obj_absorb(obj2, obj1);
2858         }
2859     }
2860
2861     impossible("obj_meld: not called with two actual objects");
2862     return (struct obj *) 0;
2863 }
2864
2865 /* give a message if hero notices two globs merging [used to be in pline.c] */
2866 void
2867 pudding_merge_message(otmp, otmp2)
2868 struct obj *otmp;
2869 struct obj *otmp2;
2870 {
2871     boolean visible = (cansee(otmp->ox, otmp->oy)
2872                        || cansee(otmp2->ox, otmp2->oy)),
2873             onfloor = (otmp->where == OBJ_FLOOR || otmp2->where == OBJ_FLOOR),
2874             inpack = (carried(otmp) || carried(otmp2));
2875
2876     /* the player will know something happened inside his own inventory */
2877     if ((!Blind && visible) || inpack) {
2878         if (Hallucination) {
2879             if (onfloor) {
2880 /*JP
2881                 You_see("parts of the floor melting!");
2882 */
2883                 You_see("\8f°\82Ì\88ê\95\94\82ª\97n\82¯\82Ä\82¢\82é\82Ì\82ð\8c©\82½\81I");
2884             } else if (inpack) {
2885 /*JP
2886                 Your("pack reaches out and grabs something!");
2887 */
2888                 Your("\82©\82Î\82ñ\82ª\8eè\82ð\90L\82Î\82µ\82Ä\89½\82©\82ð\82Â\82©\82ñ\82¾\81I");
2889             }
2890             /* even though we can see where they should be,
2891              * they'll be out of our view (minvent or container)
2892              * so don't actually show anything */
2893         } else if (onfloor || inpack) {
2894 #if 0 /*JP*/
2895             pline("The %s coalesce%s.", makeplural(obj_typename(otmp->otyp)),
2896                   inpack ? " inside your pack" : "");
2897 #else
2898             pline("%s\82ª%s\8d\87\91Ì\82µ\82½\81D", obj_typename(otmp->otyp),
2899                   inpack ? "\82 \82È\82½\82Ì\82©\82Î\82ñ\82Ì\92\86\82Å" : "");
2900 #endif
2901         }
2902     } else {
2903 /*JP
2904         You_hear("a faint sloshing sound.");
2905 */
2906         You_hear("\82©\82·\82©\82È\83o\83V\83\83\83o\83V\83\83\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
2907     }
2908 }
2909
2910 /*mkobj.c*/