OSDN Git Service

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