OSDN Git Service

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