OSDN Git Service

eliminate warnings
[jnethack/source.git] / src / steal.c
1 /* NetHack 3.6  steal.c $NHDT-Date: 1446713643 2015/11/05 08:54:03 $  $NHDT-Branch: master $:$NHDT-Revision: 1.65 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
8 /* JNetHack may be freely redistributed.  See license for details. */
9
10 #include "hack.h"
11
12 STATIC_PTR int NDECL(stealarm);
13
14 STATIC_DCL const char *FDECL(equipname, (struct obj *));
15
16 STATIC_OVL const char *
17 equipname(otmp)
18 register struct obj *otmp;
19 {
20     return ((otmp == uarmu)
21 /*JP
22                 ? "shirt"
23 */
24                 ? "\83V\83\83\83c"
25                 : (otmp == uarmf)
26 /*JP
27                       ? "boots"
28 */
29                       ? "\8cC"
30                       : (otmp == uarms)
31 /*JP
32                             ? "shield"
33 */
34                             ? "\8f\82"
35                             : (otmp == uarmg)
36 /*JP
37                                   ? "gloves"
38 */
39                                   ? "\8f¬\8eè"
40                                   : (otmp == uarmc)
41                                         ? cloak_simple_name(otmp)
42                                         : (otmp == uarmh)
43                                               ? helm_simple_name(otmp)
44                                               : suit_simple_name(otmp));
45 }
46
47 /* proportional subset of gold; return value actually fits in an int */
48 long
49 somegold(lmoney)
50 long lmoney;
51 {
52 #ifdef LINT /* long conv. ok */
53     int igold = 0;
54 #else
55     int igold = (lmoney >= (long) LARGEST_INT) ? LARGEST_INT : (int) lmoney;
56 #endif
57
58     if (igold < 50)
59         ; /* all gold */
60     else if (igold < 100)
61         igold = rn1(igold - 25 + 1, 25);
62     else if (igold < 500)
63         igold = rn1(igold - 50 + 1, 50);
64     else if (igold < 1000)
65         igold = rn1(igold - 100 + 1, 100);
66     else if (igold < 5000)
67         igold = rn1(igold - 500 + 1, 500);
68     else if (igold < 10000)
69         igold = rn1(igold - 1000 + 1, 1000);
70     else
71         igold = rn1(igold - 5000 + 1, 5000);
72
73     return (long) igold;
74 }
75
76 /*
77  * Find the first (and hopefully only) gold object in a chain.
78  * Used when leprechaun (or you as leprechaun) looks for
79  * someone else's gold.  Returns a pointer so the gold may
80  * be seized without further searching.
81  * May search containers too.
82  * Deals in gold only, as leprechauns don't care for lesser coins.
83 */
84 struct obj *
85 findgold(chain)
86 register struct obj *chain;
87 {
88     while (chain && chain->otyp != GOLD_PIECE)
89         chain = chain->nobj;
90     return chain;
91 }
92
93 /*
94  * Steal gold coins only.  Leprechauns don't care for lesser coins.
95 */
96 void
97 stealgold(mtmp)
98 register struct monst *mtmp;
99 {
100     register struct obj *fgold = g_at(u.ux, u.uy);
101     register struct obj *ygold;
102     register long tmp;
103 #if 0 /*JP*/
104     struct monst *who;
105     const char *whose, *what;
106 #endif
107
108     /* skip lesser coins on the floor */
109     while (fgold && fgold->otyp != GOLD_PIECE)
110         fgold = fgold->nexthere;
111
112     /* Do you have real gold? */
113     ygold = findgold(invent);
114
115     if (fgold && (!ygold || fgold->quan > ygold->quan || !rn2(5))) {
116         obj_extract_self(fgold);
117         add_to_minv(mtmp, fgold);
118         newsym(u.ux, u.uy);
119 #if 0 /*JP*/
120         if (u.usteed) {
121             who = u.usteed;
122             whose = s_suffix(y_monnam(who));
123             what = makeplural(mbodypart(who, FOOT));
124         } else {
125             who = &youmonst;
126             whose = "your";
127             what = makeplural(body_part(FOOT));
128         }
129         /* [ avoid "between your rear regions" :-] */
130         if (slithy(who->data))
131             what = "coils";
132         /* reduce "rear hooves/claws" to "hooves/claws" */
133         if (!strncmp(what, "rear ", 5))
134             what += 5;
135         pline("%s quickly snatches some gold from %s %s %s!", Monnam(mtmp),
136               (Levitation || Flying) ? "beneath" : "between", whose, what);
137 #else /*JP:\91«\82ª\96³\82­\82Ä\82à\81u\91«\8c³\81v\82Å\82æ\82µ\82Æ\82·\82é*/
138         pline("%s\82Í\91f\91\81\82­\82 \82È\82½\82Ì%s\82©\82ç\8bà\82ð\82Ð\82Á\82½\82­\82Á\82½\81I", Monnam(mtmp),
139               (Levitation || Flying) ? "\89º" : "\91«\8c³");
140 #endif
141         if (!ygold || !rn2(5)) {
142             if (!tele_restrict(mtmp))
143                 (void) rloc(mtmp, TRUE);
144             monflee(mtmp, 0, FALSE, FALSE);
145         }
146     } else if (ygold) {
147         const int gold_price = objects[GOLD_PIECE].oc_cost;
148
149         tmp = (somegold(money_cnt(invent)) + gold_price - 1) / gold_price;
150         tmp = min(tmp, ygold->quan);
151         if (tmp < ygold->quan)
152             ygold = splitobj(ygold, tmp);
153         else
154             setnotworn(ygold);
155         freeinv(ygold);
156         add_to_minv(mtmp, ygold);
157 /*JP
158         Your("purse feels lighter.");
159 */
160         Your("\8dà\95z\82Í\8cy\82­\82È\82Á\82½\81D");
161         if (!tele_restrict(mtmp))
162             (void) rloc(mtmp, TRUE);
163         monflee(mtmp, 0, FALSE, FALSE);
164         context.botl = 1;
165     }
166 }
167
168 /* steal armor after you finish taking it off */
169 unsigned int stealoid; /* object to be stolen */
170 unsigned int stealmid; /* monster doing the stealing */
171
172 STATIC_PTR int
173 stealarm(VOID_ARGS)
174 {
175     register struct monst *mtmp;
176     register struct obj *otmp;
177
178     for (otmp = invent; otmp; otmp = otmp->nobj) {
179         if (otmp->o_id == stealoid) {
180             for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
181                 if (mtmp->m_id == stealmid) {
182                     if (DEADMONSTER(mtmp))
183                         impossible("stealarm(): dead monster stealing");
184                     if (!dmgtype(mtmp->data, AD_SITM)) /* polymorphed */
185                         goto botm;
186                     if (otmp->unpaid)
187                         subfrombill(otmp, shop_keeper(*u.ushops));
188                     freeinv(otmp);
189 /*JP
190                     pline("%s steals %s!", Monnam(mtmp), doname(otmp));
191 */
192                     pline("%s\82Í%s\82ð\93\90\82ñ\82¾\81I", Monnam(mtmp), doname(otmp));
193                     (void) mpickobj(mtmp, otmp); /* may free otmp */
194                     /* Implies seduction, "you gladly hand over ..."
195                        so we don't set mavenge bit here. */
196                     monflee(mtmp, 0, FALSE, FALSE);
197                     if (!tele_restrict(mtmp))
198                         (void) rloc(mtmp, TRUE);
199                     break;
200                 }
201             }
202             break;
203         }
204     }
205 botm:
206     stealoid = 0;
207     return 0;
208 }
209
210 /* An object you're wearing has been taken off by a monster (theft or
211    seduction).  Also used if a worn item gets transformed (stone to flesh). */
212 void
213 remove_worn_item(obj, unchain_ball)
214 struct obj *obj;
215 boolean unchain_ball; /* whether to unpunish or just unwield */
216 {
217     if (donning(obj))
218         cancel_don();
219     if (!obj->owornmask)
220         return;
221
222     if (obj->owornmask & W_ARMOR) {
223         if (obj == uskin) {
224             impossible("Removing embedded scales?");
225             skinback(TRUE); /* uarm = uskin; uskin = 0; */
226         }
227         if (obj == uarm)
228             (void) Armor_off();
229         else if (obj == uarmc)
230             (void) Cloak_off();
231         else if (obj == uarmf)
232             (void) Boots_off();
233         else if (obj == uarmg)
234             (void) Gloves_off();
235         else if (obj == uarmh)
236             (void) Helmet_off();
237         else if (obj == uarms)
238             (void) Shield_off();
239         else if (obj == uarmu)
240             (void) Shirt_off();
241         /* catchall -- should never happen */
242         else
243             setworn((struct obj *) 0, obj->owornmask & W_ARMOR);
244     } else if (obj->owornmask & W_AMUL) {
245         Amulet_off();
246     } else if (obj->owornmask & W_RING) {
247         Ring_gone(obj);
248     } else if (obj->owornmask & W_TOOL) {
249         Blindf_off(obj);
250     } else if (obj->owornmask & W_WEAPON) {
251         if (obj == uwep)
252             uwepgone();
253         if (obj == uswapwep)
254             uswapwepgone();
255         if (obj == uquiver)
256             uqwepgone();
257     }
258
259     if (obj->owornmask & (W_BALL | W_CHAIN)) {
260         if (unchain_ball)
261             unpunish();
262     } else if (obj->owornmask) {
263         /* catchall */
264         setnotworn(obj);
265     }
266 }
267
268 /* Returns 1 when something was stolen (or at least, when N should flee now)
269  * Returns -1 if the monster died in the attempt
270  * Avoid stealing the object stealoid
271  * Nymphs and monkeys won't steal coins
272  */
273 int
274 steal(mtmp, objnambuf)
275 struct monst *mtmp;
276 char *objnambuf;
277 {
278     struct obj *otmp;
279     int tmp, could_petrify, armordelay, olddelay, named = 0, retrycnt = 0;
280     boolean monkey_business, /* true iff an animal is doing the thievery */
281         was_doffing;
282
283     if (objnambuf)
284         *objnambuf = '\0';
285     /* the following is true if successful on first of two attacks. */
286     if (!monnear(mtmp, u.ux, u.uy))
287         return 0;
288
289     /* food being eaten might already be used up but will not have
290        been removed from inventory yet; we don't want to steal that,
291        so this will cause it to be removed now */
292     if (occupation)
293         (void) maybe_finished_meal(FALSE);
294
295     if (!invent || (inv_cnt(FALSE) == 1 && uskin)) {
296     nothing_to_steal:
297         /* Not even a thousand men in armor can strip a naked man. */
298         if (Blind)
299 /*JP
300             pline("Somebody tries to rob you, but finds nothing to steal.");
301 */
302             pline("\92N\82©\82ª\82 \82È\82½\82©\82ç\93\90\82à\82¤\82Æ\82µ\82½\82ª\81C\93\90\82Þ\82à\82Ì\82ª\82È\82¢\82±\82Æ\82É\8bC\82ª\82Â\82¢\82½\81D");
303         else
304 /*JP
305             pline("%s tries to rob you, but there is nothing to steal!",
306 */
307             pline("%s\82Í\82 \82È\82½\82©\82ç\93\90\82à\82¤\82Æ\82µ\82½\82ª\81C\93\90\82Þ\82à\82Ì\82ª\82È\82¢\82±\82Æ\82É\8bC\82ª\82Â\82¢\82½\81I",
308                   Monnam(mtmp));
309         return 1; /* let her flee */
310     }
311
312     monkey_business = is_animal(mtmp->data);
313     if (monkey_business || uarmg) {
314         ; /* skip ring special cases */
315     } else if (Adornment & LEFT_RING) {
316         otmp = uleft;
317         goto gotobj;
318     } else if (Adornment & RIGHT_RING) {
319         otmp = uright;
320         goto gotobj;
321     }
322
323 retry:
324     tmp = 0;
325     for (otmp = invent; otmp; otmp = otmp->nobj)
326         if ((!uarm || otmp != uarmc) && otmp != uskin
327             && otmp->oclass != COIN_CLASS)
328             tmp += (otmp->owornmask & (W_ARMOR | W_ACCESSORY)) ? 5 : 1;
329     if (!tmp)
330         goto nothing_to_steal;
331     tmp = rn2(tmp);
332     for (otmp = invent; otmp; otmp = otmp->nobj)
333         if ((!uarm || otmp != uarmc) && otmp != uskin
334             && otmp->oclass != COIN_CLASS) {
335             tmp -= (otmp->owornmask & (W_ARMOR | W_ACCESSORY)) ? 5 : 1;
336             if (tmp < 0)
337                 break;
338         }
339     if (!otmp) {
340         impossible("Steal fails!");
341         return 0;
342     }
343     /* can't steal ring(s) while wearing gloves */
344     if ((otmp == uleft || otmp == uright) && uarmg)
345         otmp = uarmg;
346     /* can't steal gloves while wielding - so steal the wielded item. */
347     if (otmp == uarmg && uwep)
348         otmp = uwep;
349     /* can't steal armor while wearing cloak - so steal the cloak. */
350     else if (otmp == uarm && uarmc)
351         otmp = uarmc;
352     /* can't steal shirt while wearing cloak or suit */
353     else if (otmp == uarmu && uarmc)
354         otmp = uarmc;
355     else if (otmp == uarmu && uarm)
356         otmp = uarm;
357
358 gotobj:
359     if (otmp->o_id == stealoid)
360         return 0;
361
362     if (otmp->otyp == BOULDER && !throws_rocks(mtmp->data)) {
363         if (!retrycnt++)
364             goto retry;
365         goto cant_take;
366     }
367     /* animals can't overcome curse stickiness nor unlock chains */
368     if (monkey_business) {
369         boolean ostuck;
370         /* is the player prevented from voluntarily giving up this item?
371            (ignores loadstones; the !can_carry() check will catch those) */
372         if (otmp == uball)
373             ostuck = TRUE; /* effectively worn; curse is implicit */
374         else if (otmp == uquiver || (otmp == uswapwep && !u.twoweap))
375             ostuck = FALSE; /* not really worn; curse doesn't matter */
376         else
377             ostuck = ((otmp->cursed && otmp->owornmask)
378                       /* nymphs can steal rings from under
379                          cursed weapon but animals can't */
380                       || (otmp == uright && welded(uwep))
381                       || (otmp == uleft && welded(uwep) && bimanual(uwep)));
382
383         if (ostuck || can_carry(mtmp, otmp) == 0) {
384 #if 0 /*JP*/
385             static const char *const how[] = { "steal", "snatch", "grab",
386                                                "take" };
387         cant_take:
388             pline("%s tries to %s %s%s but gives up.", Monnam(mtmp),
389                   how[rn2(SIZE(how))],
390                   (otmp->owornmask & W_ARMOR) ? "your " : "",
391                   (otmp->owornmask & W_ARMOR) ? equipname(otmp)
392                                               : yname(otmp));
393 #else
394         cant_take:
395             pline("%s\82Í%s\82ð\93\90\82à\82¤\82Æ\82µ\82½\82ª\92ú\82ß\82½\81D", Monnam(mtmp),
396                   (otmp->owornmask & W_ARMOR) ? equipname(otmp)
397                                               : yname(otmp));
398 #endif
399             /* the fewer items you have, the less likely the thief
400                is going to stick around to try again (0) instead of
401                running away (1) */
402             return !rn2(inv_cnt(FALSE) / 5 + 2);
403         }
404     }
405
406     if (otmp->otyp == LEASH && otmp->leashmon) {
407         if (monkey_business && otmp->cursed)
408             goto cant_take;
409         o_unleash(otmp);
410     }
411
412     was_doffing = doffing(otmp);
413     /* stop donning/doffing now so that afternmv won't be clobbered
414        below; stop_occupation doesn't handle donning/doffing */
415     olddelay = stop_donning(otmp);
416     /* you're going to notice the theft... */
417     stop_occupation();
418
419     if (otmp->owornmask & (W_ARMOR | W_ACCESSORY)) {
420         switch (otmp->oclass) {
421         case TOOL_CLASS:
422         case AMULET_CLASS:
423         case RING_CLASS:
424         case FOOD_CLASS: /* meat ring */
425             remove_worn_item(otmp, TRUE);
426             break;
427         case ARMOR_CLASS:
428             armordelay = objects[otmp->otyp].oc_delay;
429             if (olddelay > 0 && olddelay < armordelay)
430                 armordelay = olddelay;
431             if (monkey_business) {
432                 /* animals usually don't have enough patience
433                    to take off items which require extra time */
434                 if (armordelay >= 1 && !olddelay && rn2(10))
435                     goto cant_take;
436                 remove_worn_item(otmp, TRUE);
437                 break;
438             } else {
439                 int curssv = otmp->cursed;
440                 int slowly;
441                 boolean seen = canspotmon(mtmp);
442
443                 otmp->cursed = 0;
444                 /* can't charm you without first waking you */
445                 if (Unaware)
446                     unmul((char *) 0);
447                 slowly = (armordelay >= 1 || multi < 0);
448                 if (flags.female)
449 #if 0 /*JP*/
450                     pline("%s charms you.  You gladly %s your %s.",
451                           !seen ? "She" : Monnam(mtmp),
452                           curssv ? "let her take"
453                                  : !slowly ? "hand over"
454                                            : was_doffing ? "continue removing"
455                                                          : "start removing",
456                           equipname(otmp));
457 #else
458                     pline("%s\82Í\82 \82È\82½\82ð\96£\97¹\82µ\82½\81D\82 \82È\82½\82Í\82æ\82ë\82±\82ñ\82Å%s\82ð%s\82½\81D",
459                           !seen ? "\94Þ\8f\97" : Monnam(mtmp),
460                           equipname(otmp),
461                           curssv ? "\82Í\82¸\82µ\82Ä\82à\82ç\82Á"
462                                  : !slowly ? "\82Í\82¸\82µ\82Ä\8eè\93n\82µ"
463                                            : was_doffing ? "\82Í\82¸\82µ\91±\82¯"
464                                                          : "\82Í\82¸\82µ\8en\82ß");
465 #endif
466                 else
467 #if 0 /*JP*/
468                     pline("%s seduces you and %s off your %s.",
469                           !seen ? "She" : Adjmonnam(mtmp, "beautiful"),
470                           curssv
471                               ? "helps you to take"
472                               : !slowly ? "you take"
473                                         : was_doffing ? "you continue taking"
474                                                       : "you start taking",
475                           equipname(otmp));
476 #else
477                     pline("%s\82Í\82 \82È\82½\82ð\97U\98f\82µ\82½\81D\82 \82È\82½\82Í%s\82ð%s\81D",
478                           !seen ? "\94Þ\8f\97" : Adjmonnam(mtmp, "\94ü\82µ\82¢"),
479                           equipname(otmp),
480                           curssv
481                               ? "\82Í\82¸\82µ\82Ä\82à\82ç\82Á"
482                               : !slowly ? "\82Í\82¸\82µ"
483                                         : was_doffing ? "\82Í\82¸\82µ\91±\82¯"
484                                                       : "\82Í\82¸\82µ\8en\82ß");
485 #endif
486                 named++;
487                 /* the following is to set multi for later on */
488                 nomul(-armordelay);
489 /*JP
490                 multi_reason = "taking off clothes";
491 */
492                 multi_reason = "\95\9e\82ð\92E\82¢\82Å\82¢\82é\8e\9e\82É";
493                 nomovemsg = 0;
494                 remove_worn_item(otmp, TRUE);
495                 otmp->cursed = curssv;
496                 if (multi < 0) {
497                     /*
498                     multi = 0;
499                     afternmv = 0;
500                     */
501                     stealoid = otmp->o_id;
502                     stealmid = mtmp->m_id;
503                     afternmv = stealarm;
504                     return 0;
505                 }
506             }
507             break;
508         default:
509             impossible("Tried to steal a strange worn thing. [%d]",
510                        otmp->oclass);
511         }
512     } else if (otmp->owornmask)
513         remove_worn_item(otmp, TRUE);
514
515     /* do this before removing it from inventory */
516     if (objnambuf)
517         Strcpy(objnambuf, yname(otmp));
518     /* set mavenge bit so knights won't suffer an
519      * alignment penalty during retaliation;
520      */
521     mtmp->mavenge = 1;
522
523     if (otmp->unpaid)
524         subfrombill(otmp, shop_keeper(*u.ushops));
525     freeinv(otmp);
526 /*JP
527     pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
528 */
529     pline("%s\82Í%s\82ð\93\90\82ñ\82¾\81D", named ? "\94Þ\8f\97" : Monnam(mtmp), doname(otmp));
530     could_petrify =
531         (otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]));
532     (void) mpickobj(mtmp, otmp); /* may free otmp */
533     if (could_petrify && !(mtmp->misc_worn_check & W_ARMG)) {
534         minstapetrify(mtmp, TRUE);
535         return -1;
536     }
537     return (multi < 0) ? 0 : 1;
538 }
539
540 /* Returns 1 if otmp is free'd, 0 otherwise. */
541 int
542 mpickobj(mtmp, otmp)
543 register struct monst *mtmp;
544 register struct obj *otmp;
545 {
546     int freed_otmp;
547     boolean snuff_otmp = FALSE;
548
549     /* if monster is acquiring a thrown or kicked object, the throwing
550        or kicking code shouldn't continue to track and place it */
551     if (otmp == thrownobj)
552         thrownobj = 0;
553     else if (otmp == kickedobj)
554         kickedobj = 0;
555     /* don't want hidden light source inside the monster; assumes that
556        engulfers won't have external inventories; whirly monsters cause
557        the light to be extinguished rather than letting it shine thru */
558     if (obj_sheds_light(otmp) && attacktype(mtmp->data, AT_ENGL)) {
559         /* this is probably a burning object that you dropped or threw */
560         if (u.uswallow && mtmp == u.ustuck && !Blind)
561 /*JP
562             pline("%s out.", Tobjnam(otmp, "go"));
563 */
564             pline("%s\82Í\94ò\82Ñ\82¾\82µ\82½\81D", xname(otmp));
565         snuff_otmp = TRUE;
566     }
567     /* for hero owned object on shop floor, mtmp is taking possession
568        and if it's eventually dropped in a shop, shk will claim it */
569     if (!mtmp->mtame)
570         otmp->no_charge = 0;
571     /* Must do carrying effects on object prior to add_to_minv() */
572     carry_obj_effects(otmp);
573     /* add_to_minv() might free otmp [if merged with something else],
574        so we have to call it after doing the object checks */
575     freed_otmp = add_to_minv(mtmp, otmp);
576     /* and we had to defer this until object is in mtmp's inventory */
577     if (snuff_otmp)
578         snuff_light_source(mtmp->mx, mtmp->my);
579     return freed_otmp;
580 }
581
582 void
583 stealamulet(mtmp)
584 struct monst *mtmp;
585 {
586     struct obj *otmp = (struct obj *) 0;
587     int real = 0, fake = 0;
588
589     /* select the artifact to steal */
590     if (u.uhave.amulet) {
591         real = AMULET_OF_YENDOR;
592         fake = FAKE_AMULET_OF_YENDOR;
593     } else if (u.uhave.questart) {
594         for (otmp = invent; otmp; otmp = otmp->nobj)
595             if (is_quest_artifact(otmp))
596                 break;
597         if (!otmp)
598             return; /* should we panic instead? */
599     } else if (u.uhave.bell) {
600         real = BELL_OF_OPENING;
601         fake = BELL;
602     } else if (u.uhave.book) {
603         real = SPE_BOOK_OF_THE_DEAD;
604     } else if (u.uhave.menorah) {
605         real = CANDELABRUM_OF_INVOCATION;
606     } else
607         return; /* you have nothing of special interest */
608
609     if (!otmp) {
610         /* If we get here, real and fake have been set up. */
611         for (otmp = invent; otmp; otmp = otmp->nobj)
612             if (otmp->otyp == real || (otmp->otyp == fake && !mtmp->iswiz))
613                 break;
614     }
615
616     if (otmp) { /* we have something to snatch */
617         if (otmp->owornmask)
618             remove_worn_item(otmp, TRUE);
619         if (otmp->unpaid)
620             subfrombill(otmp, shop_keeper(*u.ushops));
621         freeinv(otmp);
622         /* mpickobj wont merge otmp because none of the above things
623            to steal are mergable */
624         (void) mpickobj(mtmp, otmp); /* may merge and free otmp */
625 /*JP
626         pline("%s stole %s!", Monnam(mtmp), doname(otmp));
627 */
628         pline("%s\82Í%s\82ð\93\90\82ñ\82¾\81I", Monnam(mtmp), doname(otmp));
629         if (can_teleport(mtmp->data) && !tele_restrict(mtmp))
630             (void) rloc(mtmp, TRUE);
631     }
632 }
633
634 /* when a mimic gets poked with something, it might take that thing
635    (at present, only implemented for when the hero does the poking) */
636 void
637 maybe_absorb_item(mon, obj, ochance, achance)
638 struct monst *mon;
639 struct obj *obj;
640 int ochance, achance; /* percent chance for ordinary item, artifact */
641 {
642     if (obj == uball || obj == uchain || obj->oclass == ROCK_CLASS
643         || obj_resists(obj, 100 - ochance, 100 - achance)
644         || !touch_artifact(obj, mon))
645         return;
646
647     if (carried(obj)) {
648         if (obj->owornmask)
649             remove_worn_item(obj, TRUE);
650         if (obj->unpaid)
651             subfrombill(obj, shop_keeper(*u.ushops));
652         if (cansee(mon->mx, mon->my)) {
653             const char *MonName = Monnam(mon);
654
655 #if 0 /*JP*//*\93ú\96{\8cê\82Å\82Í\95s\97v*/
656             /* mon might be invisible; avoid "It pulls ... and absorbs it!" */
657             if (!strcmp(MonName, "It"))
658                 MonName = "Something";
659 #endif
660 #if 0 /*JP*/
661             pline("%s pulls %s away from you and absorbs %s!", MonName,
662                   yname(obj), (obj->quan > 1L) ? "them" : "it");
663 #else
664             pline("%s\82Í%s\82ð\88ø\82Á\82Ï\82è\8d\9e\82ñ\82Å\8bz\8eû\82µ\82½\81I", MonName,
665                   yname(obj));
666 #endif
667         } else {
668             const char *hand_s = body_part(HAND);
669
670             if (bimanual(obj))
671                 hand_s = makeplural(hand_s);
672 #if 0 /*JP*/
673             pline("%s %s pulled from your %s!", upstart(yname(obj)),
674                   otense(obj, "are"), hand_s);
675 #else
676             pline("%s\82Í\82 \82È\82½\82Ì%s\82©\82ç\88ø\82Á\82Ï\82è\8d\9e\82Ü\82ê\82½\81I", upstart(yname(obj)),
677                   hand_s);
678 #endif
679         }
680         freeinv(obj);
681     } else {
682         /* not carried; presumably thrown or kicked */
683         if (canspotmon(mon))
684 /*JP
685             pline("%s absorbs %s!", Monnam(mon), yname(obj));
686 */
687             pline("%s\82Í%s\82ð\8bz\8eû\82µ\82½\81I", Monnam(mon), yname(obj));
688     }
689     /* add to mon's inventory */
690     (void) mpickobj(mon, obj);
691 }
692
693 /* drop one object taken from a (possibly dead) monster's inventory */
694 void
695 mdrop_obj(mon, obj, verbosely)
696 struct monst *mon;
697 struct obj *obj;
698 boolean verbosely;
699 {
700     int omx = mon->mx, omy = mon->my;
701     boolean update_mon = FALSE;
702
703     if (obj->owornmask) {
704         /* perform worn item handling if the monster is still alive */
705         if (mon->mhp > 0) {
706             mon->misc_worn_check &= ~obj->owornmask;
707             update_mon = TRUE;
708             /* don't charge for an owned saddle on dead steed (provided
709                that the hero is within the same shop at the time) */
710         } else if (mon->mtame && (obj->owornmask & W_SADDLE) && !obj->unpaid
711                    && costly_spot(omx, omy)
712                    /* being at costly_spot guarantees lev->roomno is not 0 */
713                    && index(in_rooms(u.ux, u.uy, SHOPBASE),
714                             levl[omx][omy].roomno)) {
715             obj->no_charge = 1;
716         }
717         /* this should be done even if the monster has died */
718         if (obj->owornmask & W_WEP)
719             setmnotwielded(mon, obj);
720         obj->owornmask = 0L;
721     }
722     /* obj_no_longer_held(obj); -- done by place_object */
723     if (verbosely && cansee(omx, omy))
724 /*JP
725         pline("%s drops %s.", Monnam(mon), distant_name(obj, doname));
726 */
727         pline("%s\82Í%s\82ð\92u\82¢\82½\81D", Monnam(mon), distant_name(obj, doname));
728 /*JP
729     if (!flooreffects(obj, omx, omy, "fall")) {
730 */
731     if (!flooreffects(obj, omx, omy, "\97\8e\82¿\82é")) {
732         place_object(obj, omx, omy);
733         stackobj(obj);
734     }
735     /* do this last, after placing obj on floor; removing steed's saddle
736        throws rider, possibly inflicting fatal damage and producing bones */
737     if (update_mon)
738         update_mon_intrinsics(mon, obj, FALSE, TRUE);
739 }
740
741 /* some monsters bypass the normal rules for moving between levels or
742    even leaving the game entirely; when that happens, prevent them from
743    taking the Amulet or invocation tools with them */
744 void
745 mdrop_special_objs(mon)
746 struct monst *mon;
747 {
748     struct obj *obj, *otmp;
749
750     for (obj = mon->minvent; obj; obj = otmp) {
751         otmp = obj->nobj;
752         /* the Amulet, invocation tools, and Rider corpses resist even when
753            artifacts and ordinary objects are given 0% resistance chance */
754         if (obj_resists(obj, 0, 0)) {
755             obj_extract_self(obj);
756             mdrop_obj(mon, obj, FALSE);
757         }
758     }
759 }
760
761 /* release the objects the creature is carrying */
762 void
763 relobj(mtmp, show, is_pet)
764 struct monst *mtmp;
765 int show;
766 boolean is_pet; /* If true, pet should keep wielded/worn items */
767 {
768     struct obj *otmp;
769     int omx = mtmp->mx, omy = mtmp->my;
770
771     /* vault guard's gold goes away rather than be dropped... */
772     if (mtmp->isgd && (otmp = findgold(mtmp->minvent)) != 0) {
773         if (canspotmon(mtmp))
774 #if 0 /*JP*/
775             pline("%s gold %s.", s_suffix(Monnam(mtmp)),
776                   canseemon(mtmp) ? "vanishes" : "seems to vanish");
777 #else
778             pline("%s\82Ì\8bà\82Í\8fÁ\82¦\82½%s\81D", Monnam(mtmp),
779                   canseemon(mtmp) ? "" : "\82æ\82¤\82¾");
780 #endif
781         obj_extract_self(otmp);
782         obfree(otmp, (struct obj *) 0);
783     } /* isgd && has gold */
784
785     while ((otmp = (is_pet ? droppables(mtmp) : mtmp->minvent)) != 0) {
786         obj_extract_self(otmp);
787         mdrop_obj(mtmp, otmp, is_pet && flags.verbose);
788     }
789
790     if (show && cansee(omx, omy))
791         newsym(omx, omy);
792 }
793
794 /*steal.c*/