OSDN Git Service

update year to 2018
[jnethack/source.git] / src / dog.c
1 /* NetHack 3.6  dog.c   $NHDT-Date: 1502753406 2017/08/14 23:30:06 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.60 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2011. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2018            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 STATIC_DCL int NDECL(pet_type);
14
15 void
16 newedog(mtmp)
17 struct monst *mtmp;
18 {
19     if (!mtmp->mextra)
20         mtmp->mextra = newmextra();
21     if (!EDOG(mtmp)) {
22         EDOG(mtmp) = (struct edog *) alloc(sizeof(struct edog));
23         (void) memset((genericptr_t) EDOG(mtmp), 0, sizeof(struct edog));
24     }
25 }
26
27 void
28 free_edog(mtmp)
29 struct monst *mtmp;
30 {
31     if (mtmp->mextra && EDOG(mtmp)) {
32         free((genericptr_t) EDOG(mtmp));
33         EDOG(mtmp) = (struct edog *) 0;
34     }
35     mtmp->mtame = 0;
36 }
37
38 void
39 initedog(mtmp)
40 register struct monst *mtmp;
41 {
42     mtmp->mtame = is_domestic(mtmp->data) ? 10 : 5;
43     mtmp->mpeaceful = 1;
44     mtmp->mavenge = 0;
45     set_malign(mtmp); /* recalc alignment now that it's tamed */
46     mtmp->mleashed = 0;
47     mtmp->meating = 0;
48     EDOG(mtmp)->droptime = 0;
49     EDOG(mtmp)->dropdist = 10000;
50     EDOG(mtmp)->apport = ACURR(A_CHA);
51     EDOG(mtmp)->whistletime = 0;
52     EDOG(mtmp)->hungrytime = 1000 + monstermoves;
53     EDOG(mtmp)->ogoal.x = -1; /* force error if used before set */
54     EDOG(mtmp)->ogoal.y = -1;
55     EDOG(mtmp)->abuse = 0;
56     EDOG(mtmp)->revivals = 0;
57     EDOG(mtmp)->mhpmax_penalty = 0;
58     EDOG(mtmp)->killed_by_u = 0;
59 }
60
61 STATIC_OVL int
62 pet_type()
63 {
64     if (urole.petnum != NON_PM)
65         return  urole.petnum;
66     else if (preferred_pet == 'c')
67         return  PM_KITTEN;
68     else if (preferred_pet == 'd')
69         return  PM_LITTLE_DOG;
70     else
71         return  rn2(2) ? PM_KITTEN : PM_LITTLE_DOG;
72 }
73
74 struct monst *
75 make_familiar(otmp, x, y, quietly)
76 register struct obj *otmp;
77 xchar x, y;
78 boolean quietly;
79 {
80     struct permonst *pm;
81     struct monst *mtmp = 0;
82     int chance, trycnt = 100;
83
84     do {
85         if (otmp) { /* figurine; otherwise spell */
86             int mndx = otmp->corpsenm;
87             pm = &mons[mndx];
88             /* activating a figurine provides one way to exceed the
89                maximum number of the target critter created--unless
90                it has a special limit (erinys, Nazgul) */
91             if ((mvitals[mndx].mvflags & G_EXTINCT)
92                 && mbirth_limit(mndx) != MAXMONNO) {
93                 if (!quietly)
94                     /* have just been given "You <do something with>
95                        the figurine and it transforms." message */
96 /*JP
97                     pline("... into a pile of dust.");
98 */
99                     pline("\81D\81D\81D\82»\82µ\82Ä\82¿\82è\82Ì\8eR\82É\82È\82Á\82½\81D");
100                 break; /* mtmp is null */
101             }
102         } else if (!rn2(3)) {
103             pm = &mons[pet_type()];
104         } else {
105             pm = rndmonst();
106             if (!pm) {
107                 if (!quietly)
108 /*JP
109                     There("seems to be nothing available for a familiar.");
110 */
111                     pline("\89º\96l\82Í\8c»\82ê\82È\82©\82Á\82½\81D");
112                 break;
113             }
114         }
115
116         mtmp = makemon(pm, x, y, MM_EDOG | MM_IGNOREWATER | NO_MINVENT);
117         if (otmp && !mtmp) { /* monster was genocided or square occupied */
118             if (!quietly)
119 /*JP
120                 pline_The("figurine writhes and then shatters into pieces!");
121 */
122                 pline("\90l\8c`\82Í\82à\82ª\82«\81C\82­\82¾\82¯\8eU\82Á\82½\81I");
123             break;
124         }
125     } while (!mtmp && --trycnt > 0);
126
127     if (!mtmp)
128         return (struct monst *) 0;
129
130     if (is_pool(mtmp->mx, mtmp->my) && minliquid(mtmp))
131         return (struct monst *) 0;
132
133     initedog(mtmp);
134     mtmp->msleeping = 0;
135     if (otmp) { /* figurine; resulting monster might not become a pet */
136         chance = rn2(10); /* 0==tame, 1==peaceful, 2==hostile */
137         if (chance > 2)
138             chance = otmp->blessed ? 0 : !otmp->cursed ? 1 : 2;
139         /* 0,1,2:  b=80%,10,10; nc=10%,80,10; c=10%,10,80 */
140         if (chance > 0) {
141             mtmp->mtame = 0;   /* not tame after all */
142             if (chance == 2) { /* hostile (cursed figurine) */
143                 if (!quietly)
144 /*JP
145                     You("get a bad feeling about this.");
146 */
147                     You("\8c\99\82È\97\\8a´\82ª\82µ\82½\81D");
148                 mtmp->mpeaceful = 0;
149                 set_malign(mtmp);
150             }
151         }
152         /* if figurine has been named, give same name to the monster */
153         if (has_oname(otmp))
154             mtmp = christen_monst(mtmp, ONAME(otmp));
155     }
156     set_malign(mtmp); /* more alignment changes */
157     newsym(mtmp->mx, mtmp->my);
158
159     /* must wield weapon immediately since pets will otherwise drop it */
160     if (mtmp->mtame && attacktype(mtmp->data, AT_WEAP)) {
161         mtmp->weapon_check = NEED_HTH_WEAPON;
162         (void) mon_wield_item(mtmp);
163     }
164     return mtmp;
165 }
166
167 struct monst *
168 makedog()
169 {
170     register struct monst *mtmp;
171     register struct obj *otmp;
172     const char *petname;
173     int pettype;
174     static int petname_used = 0;
175
176     if (preferred_pet == 'n')
177         return ((struct monst *) 0);
178
179     pettype = pet_type();
180     if (pettype == PM_LITTLE_DOG)
181         petname = dogname;
182     else if (pettype == PM_PONY)
183         petname = horsename;
184     else
185         petname = catname;
186
187     /* default pet names */
188     if (!*petname && pettype == PM_LITTLE_DOG) {
189         /* All of these names were for dogs. */
190         if (Role_if(PM_CAVEMAN))
191 #if 0 /*JP*/
192             petname = "Slasher"; /* The Warrior */
193 #else
194             petname = "\83X\83\89\83b\83V\83\83\81[";
195 #endif
196         if (Role_if(PM_SAMURAI))
197 #if 0 /*JP*/
198             petname = "Hachi"; /* Shibuya Station */
199 #else
200             petname = "\83n\83`\8cö";
201 #endif
202         if (Role_if(PM_BARBARIAN))
203 #if 0 /*JP*/
204             petname = "Idefix"; /* Obelix */
205 #else
206             petname = "\83C\83f\83t\83B\83N\83X";
207 #endif
208         if (Role_if(PM_RANGER))
209 #if 0 /*JP*/
210             petname = "Sirius"; /* Orion's dog */
211 #else
212             petname = "\83V\83\8a\83E\83X";
213 #endif
214     }
215
216     mtmp = makemon(&mons[pettype], u.ux, u.uy, MM_EDOG);
217
218     if (!mtmp)
219         return ((struct monst *) 0); /* pets were genocided */
220
221     context.startingpet_mid = mtmp->m_id;
222     /* Horses already wear a saddle */
223     if (pettype == PM_PONY && !!(otmp = mksobj(SADDLE, TRUE, FALSE))) {
224         otmp->dknown = otmp->bknown = otmp->rknown = 1;
225         put_saddle_on_mon(otmp, mtmp);
226     }
227
228     if (!petname_used++ && *petname)
229         mtmp = christen_monst(mtmp, petname);
230
231     initedog(mtmp);
232     return  mtmp;
233 }
234
235 /* record `last move time' for all monsters prior to level save so that
236    mon_arrive() can catch up for lost time when they're restored later */
237 void
238 update_mlstmv()
239 {
240     struct monst *mon;
241
242     /* monst->mlstmv used to be updated every time `monst' actually moved,
243        but that is no longer the case so we just do a blanket assignment */
244     for (mon = fmon; mon; mon = mon->nmon) {
245         if (DEADMONSTER(mon))
246             continue;
247         mon->mlstmv = monstermoves;
248     }
249 }
250
251 void
252 losedogs()
253 {
254     register struct monst *mtmp, *mtmp0 = 0, *mtmp2;
255     int dismissKops = 0;
256
257     /*
258      * First, scan migrating_mons for shopkeepers who want to dismiss Kops,
259      * and scan mydogs for shopkeepers who want to retain kops.
260      * Second, dismiss kops if warranted, making more room for arrival.
261      * Third, place monsters accompanying the hero.
262      * Last, place migrating monsters coming to this level.
263      *
264      * Hero might eventually be displaced (due to the third step, but
265      * occurring later), which is the main reason to do the second step
266      * sooner (in turn necessitating the first step, rather than combining
267      * the list scans with monster placement).
268      */
269
270     /* check for returning shk(s) */
271     for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) {
272         if (mtmp->mux != u.uz.dnum || mtmp->muy != u.uz.dlevel)
273             continue;
274         if (mtmp->isshk) {
275             if (ESHK(mtmp)->dismiss_kops) {
276                 if (dismissKops == 0)
277                     dismissKops = 1;
278                 ESHK(mtmp)->dismiss_kops = FALSE; /* reset */
279             } else if (!mtmp->mpeaceful) {
280                 /* an unpacified shk is returning; don't dismiss kops
281                    even if another pacified one is willing to do so */
282                 dismissKops = -1;
283                 /* [keep looping; later monsters might need ESHK reset] */
284             }
285         }
286     }
287     /* make the same check for mydogs */
288     for (mtmp = mydogs; mtmp && dismissKops >= 0; mtmp = mtmp->nmon) {
289         if (mtmp->isshk) {
290             /* hostile shk might accompany hero [ESHK(mtmp)->dismiss_kops
291                can't be set here; it's only used for migrating_mons] */
292             if (!mtmp->mpeaceful)
293                 dismissKops = -1;
294         }
295     }
296
297     /* when a hostile shopkeeper chases hero to another level
298        and then gets paid off there, get rid of summoned kops
299        here now that he has returned to his shop level */
300     if (dismissKops > 0)
301         make_happy_shoppers(TRUE);
302
303     /* place pets and/or any other monsters who accompany hero */
304     while ((mtmp = mydogs) != 0) {
305         mydogs = mtmp->nmon;
306         mon_arrive(mtmp, TRUE);
307     }
308
309     /* time for migrating monsters to arrive */
310     for (mtmp = migrating_mons; mtmp; mtmp = mtmp2) {
311         mtmp2 = mtmp->nmon;
312         if (mtmp->mux == u.uz.dnum && mtmp->muy == u.uz.dlevel) {
313             if (mtmp == migrating_mons)
314                 migrating_mons = mtmp->nmon;
315             else
316                 mtmp0->nmon = mtmp->nmon;
317             mon_arrive(mtmp, FALSE);
318         } else
319             mtmp0 = mtmp;
320     }
321 }
322
323 /* called from resurrect() in addition to losedogs() */
324 void
325 mon_arrive(mtmp, with_you)
326 struct monst *mtmp;
327 boolean with_you;
328 {
329     struct trap *t;
330     xchar xlocale, ylocale, xyloc, xyflags, wander;
331     int num_segs;
332
333     mtmp->nmon = fmon;
334     fmon = mtmp;
335     if (mtmp->isshk)
336         set_residency(mtmp, FALSE);
337
338     num_segs = mtmp->wormno;
339     /* baby long worms have no tail so don't use is_longworm() */
340     if (mtmp->data == &mons[PM_LONG_WORM]) {
341         mtmp->wormno = get_wormno();
342         if (mtmp->wormno)
343             initworm(mtmp, num_segs);
344     } else
345         mtmp->wormno = 0;
346
347     /* some monsters might need to do something special upon arrival
348        _after_ the current level has been fully set up; see dochug() */
349     mtmp->mstrategy |= STRAT_ARRIVE;
350
351     /* make sure mnexto(rloc_to(set_apparxy())) doesn't use stale data */
352     mtmp->mux = u.ux, mtmp->muy = u.uy;
353     xyloc = mtmp->mtrack[0].x;
354     xyflags = mtmp->mtrack[0].y;
355     xlocale = mtmp->mtrack[1].x;
356     ylocale = mtmp->mtrack[1].y;
357     memset(mtmp->mtrack, 0, sizeof(mtmp->mtrack));
358
359     if (mtmp == u.usteed)
360         return; /* don't place steed on the map */
361     if (with_you) {
362         /* When a monster accompanies you, sometimes it will arrive
363            at your intended destination and you'll end up next to
364            that spot.  This code doesn't control the final outcome;
365            goto_level(do.c) decides who ends up at your target spot
366            when there is a monster there too. */
367         if (!MON_AT(u.ux, u.uy)
368             && !rn2(mtmp->mtame ? 10 : mtmp->mpeaceful ? 5 : 2))
369             rloc_to(mtmp, u.ux, u.uy);
370         else
371             mnexto(mtmp);
372         return;
373     }
374     /*
375      * The monster arrived on this level independently of the player.
376      * Its coordinate fields were overloaded for use as flags that
377      * specify its final destination.
378      */
379
380     if (mtmp->mlstmv < monstermoves - 1L) {
381         /* heal monster for time spent in limbo */
382         long nmv = monstermoves - 1L - mtmp->mlstmv;
383
384         mon_catchup_elapsed_time(mtmp, nmv);
385         mtmp->mlstmv = monstermoves - 1L;
386
387         /* let monster move a bit on new level (see placement code below) */
388         wander = (xchar) min(nmv, 8);
389     } else
390         wander = 0;
391
392     switch (xyloc) {
393     case MIGR_APPROX_XY: /* {x,y}locale set above */
394         break;
395     case MIGR_EXACT_XY:
396         wander = 0;
397         break;
398     case MIGR_WITH_HERO:
399         xlocale = u.ux, ylocale = u.uy;
400         break;
401     case MIGR_STAIRS_UP:
402         xlocale = xupstair, ylocale = yupstair;
403         break;
404     case MIGR_STAIRS_DOWN:
405         xlocale = xdnstair, ylocale = ydnstair;
406         break;
407     case MIGR_LADDER_UP:
408         xlocale = xupladder, ylocale = yupladder;
409         break;
410     case MIGR_LADDER_DOWN:
411         xlocale = xdnladder, ylocale = ydnladder;
412         break;
413     case MIGR_SSTAIRS:
414         xlocale = sstairs.sx, ylocale = sstairs.sy;
415         break;
416     case MIGR_PORTAL:
417         if (In_endgame(&u.uz)) {
418             /* there is no arrival portal for endgame levels */
419             /* BUG[?]: for simplicity, this code relies on the fact
420                that we know that the current endgame levels always
421                build upwards and never have any exclusion subregion
422                inside their TELEPORT_REGION settings. */
423             xlocale = rn1(updest.hx - updest.lx + 1, updest.lx);
424             ylocale = rn1(updest.hy - updest.ly + 1, updest.ly);
425             break;
426         }
427         /* find the arrival portal */
428         for (t = ftrap; t; t = t->ntrap)
429             if (t->ttyp == MAGIC_PORTAL)
430                 break;
431         if (t) {
432             xlocale = t->tx, ylocale = t->ty;
433             break;
434         } else {
435             impossible("mon_arrive: no corresponding portal?");
436         } /*FALLTHRU*/
437     default:
438     case MIGR_RANDOM:
439         xlocale = ylocale = 0;
440         break;
441     }
442
443     if (xlocale && wander) {
444         /* monster moved a bit; pick a nearby location */
445         /* mnearto() deals w/stone, et al */
446         char *r = in_rooms(xlocale, ylocale, 0);
447         if (r && *r) {
448             coord c;
449             /* somexy() handles irregular rooms */
450             if (somexy(&rooms[*r - ROOMOFFSET], &c))
451                 xlocale = c.x, ylocale = c.y;
452             else
453                 xlocale = ylocale = 0;
454         } else { /* not in a room */
455             int i, j;
456             i = max(1, xlocale - wander);
457             j = min(COLNO - 1, xlocale + wander);
458             xlocale = rn1(j - i, i);
459             i = max(0, ylocale - wander);
460             j = min(ROWNO - 1, ylocale + wander);
461             ylocale = rn1(j - i, i);
462         }
463     } /* moved a bit */
464
465     mtmp->mx = 0; /*(already is 0)*/
466     mtmp->my = xyflags;
467     if (xlocale) {
468         if (!mnearto(mtmp, xlocale, ylocale, FALSE))
469             goto fail_mon_placement;
470     } else {
471         if (!rloc(mtmp, TRUE)) {
472             /*
473              * Failed to place migrating monster,
474              * probably because the level is full.
475              * Dump the monster's cargo and leave the monster dead.
476              */
477             struct obj *obj;
478 fail_mon_placement:
479             while ((obj = mtmp->minvent) != 0) {
480                 obj_extract_self(obj);
481                 obj_no_longer_held(obj);
482                 if (obj->owornmask & W_WEP)
483                     setmnotwielded(mtmp, obj);
484                 obj->owornmask = 0L;
485                 if (xlocale && ylocale)
486                     place_object(obj, xlocale, ylocale);
487                 else if (rloco(obj)) {
488                     if (!get_obj_location(obj, &xlocale, &ylocale, 0))
489                         impossible("Can't find relocated object.");
490                 }
491             }
492             (void) mkcorpstat(CORPSE, (struct monst *) 0, mtmp->data, xlocale,
493                               ylocale, CORPSTAT_NONE);
494             mongone(mtmp);
495         }
496     }
497 }
498
499 /* heal monster for time spent elsewhere */
500 void
501 mon_catchup_elapsed_time(mtmp, nmv)
502 struct monst *mtmp;
503 long nmv; /* number of moves */
504 {
505     int imv = 0; /* avoid zillions of casts and lint warnings */
506
507 #if defined(DEBUG) || defined(BETA)
508     if (nmv < 0L) { /* crash likely... */
509         panic("catchup from future time?");
510         /*NOTREACHED*/
511         return;
512     } else if (nmv == 0L) { /* safe, but should'nt happen */
513         impossible("catchup from now?");
514     } else
515 #endif
516         if (nmv >= LARGEST_INT) /* paranoia */
517         imv = LARGEST_INT - 1;
518     else
519         imv = (int) nmv;
520
521     /* might stop being afraid, blind or frozen */
522     /* set to 1 and allow final decrement in movemon() */
523     if (mtmp->mblinded) {
524         if (imv >= (int) mtmp->mblinded)
525             mtmp->mblinded = 1;
526         else
527             mtmp->mblinded -= imv;
528     }
529     if (mtmp->mfrozen) {
530         if (imv >= (int) mtmp->mfrozen)
531             mtmp->mfrozen = 1;
532         else
533             mtmp->mfrozen -= imv;
534     }
535     if (mtmp->mfleetim) {
536         if (imv >= (int) mtmp->mfleetim)
537             mtmp->mfleetim = 1;
538         else
539             mtmp->mfleetim -= imv;
540     }
541
542     /* might recover from temporary trouble */
543     if (mtmp->mtrapped && rn2(imv + 1) > 40 / 2)
544         mtmp->mtrapped = 0;
545     if (mtmp->mconf && rn2(imv + 1) > 50 / 2)
546         mtmp->mconf = 0;
547     if (mtmp->mstun && rn2(imv + 1) > 10 / 2)
548         mtmp->mstun = 0;
549
550     /* might finish eating or be able to use special ability again */
551     if (imv > mtmp->meating)
552         finish_meating(mtmp);
553     else
554         mtmp->meating -= imv;
555     if (imv > mtmp->mspec_used)
556         mtmp->mspec_used = 0;
557     else
558         mtmp->mspec_used -= imv;
559
560     /* reduce tameness for every 150 moves you are separated */
561     if (mtmp->mtame) {
562         int wilder = (imv + 75) / 150;
563         if (mtmp->mtame > wilder)
564             mtmp->mtame -= wilder; /* less tame */
565         else if (mtmp->mtame > rn2(wilder))
566             mtmp->mtame = 0; /* untame */
567         else
568             mtmp->mtame = mtmp->mpeaceful = 0; /* hostile! */
569     }
570     /* check to see if it would have died as a pet; if so, go wild instead
571      * of dying the next time we call dog_move()
572      */
573     if (mtmp->mtame && !mtmp->isminion
574         && (carnivorous(mtmp->data) || herbivorous(mtmp->data))) {
575         struct edog *edog = EDOG(mtmp);
576
577         if ((monstermoves > edog->hungrytime + 500 && mtmp->mhp < 3)
578             || (monstermoves > edog->hungrytime + 750))
579             mtmp->mtame = mtmp->mpeaceful = 0;
580     }
581
582     if (!mtmp->mtame && mtmp->mleashed) {
583         /* leashed monsters should always be with hero, consequently
584            never losing any time to be accounted for later */
585         impossible("catching up for leashed monster?");
586         m_unleash(mtmp, FALSE);
587     }
588
589     /* recover lost hit points */
590     if (!regenerates(mtmp->data))
591         imv /= 20;
592     if (mtmp->mhp + imv >= mtmp->mhpmax)
593         mtmp->mhp = mtmp->mhpmax;
594     else
595         mtmp->mhp += imv;
596 }
597
598 /* called when you move to another level */
599 void
600 keepdogs(pets_only)
601 boolean pets_only; /* true for ascension or final escape */
602 {
603     register struct monst *mtmp, *mtmp2;
604     register struct obj *obj;
605     int num_segs;
606     boolean stay_behind;
607
608     for (mtmp = fmon; mtmp; mtmp = mtmp2) {
609         mtmp2 = mtmp->nmon;
610         if (DEADMONSTER(mtmp))
611             continue;
612         if (pets_only) {
613             if (!mtmp->mtame)
614                 continue; /* reject non-pets */
615             /* don't block pets from accompanying hero's dungeon
616                escape or ascension simply due to mundane trifles;
617                unlike level change for steed, don't bother trying
618                to achieve a normal trap escape first */
619             mtmp->mtrapped = 0;
620             mtmp->meating = 0;
621             mtmp->msleeping = 0;
622             mtmp->mfrozen = 0;
623             mtmp->mcanmove = 1;
624         }
625         if (((monnear(mtmp, u.ux, u.uy) && levl_follower(mtmp))
626              /* the wiz will level t-port from anywhere to chase
627                 the amulet; if you don't have it, will chase you
628                 only if in range. -3. */
629              || (u.uhave.amulet && mtmp->iswiz))
630             && ((!mtmp->msleeping && mtmp->mcanmove)
631                 /* eg if level teleport or new trap, steed has no control
632                    to avoid following */
633                 || (mtmp == u.usteed))
634             /* monster won't follow if it hasn't noticed you yet */
635             && !(mtmp->mstrategy & STRAT_WAITFORU)) {
636             stay_behind = FALSE;
637             if (mtmp->mtrapped)
638                 (void) mintrap(mtmp); /* try to escape */
639             if (mtmp == u.usteed) {
640                 /* make sure steed is eligible to accompany hero */
641                 mtmp->mtrapped = 0;       /* escape trap */
642                 mtmp->meating = 0;        /* terminate eating */
643                 mdrop_special_objs(mtmp); /* drop Amulet */
644             } else if (mtmp->meating || mtmp->mtrapped) {
645                 if (canseemon(mtmp))
646 #if 0 /*JP*/
647                     pline("%s is still %s.", Monnam(mtmp),
648                           mtmp->meating ? "eating" : "trapped");
649 #else
650                     pline("%s\82Í\82Ü\82¾%s\81D", Monnam(mtmp),
651                           mtmp->meating ? "\90H\82×\82Ä\82¢\82é" : "ã©\82É\82©\82©\82Á\82½\82Ü\82Ü\82¾");
652 #endif
653                 stay_behind = TRUE;
654             } else if (mon_has_amulet(mtmp)) {
655                 if (canseemon(mtmp))
656 /*JP
657                     pline("%s seems very disoriented for a moment.",
658 */
659                     pline("%s\82Í\88ê\8fu\95û\8cü\8a´\8ao\82ð\8e¸\82Á\82½\82æ\82¤\82¾\81D",
660                           Monnam(mtmp));
661                 stay_behind = TRUE;
662             }
663             if (stay_behind) {
664                 if (mtmp->mleashed) {
665 #if 0 /*JP*/
666                     pline("%s leash suddenly comes loose.",
667                           humanoid(mtmp->data)
668                               ? (mtmp->female ? "Her" : "His")
669                               : "Its");
670 #else
671                     pline("%s\82É\8c\8b\82Î\82ê\82½\95R\82Í\93Ë\91R\82ä\82é\82ñ\82¾\81D",
672                           humanoid(mtmp->data)
673                               ? (mtmp->female ? "\94Þ\8f\97" : "\94Þ")
674                               : "\82»\82Ì\90\95¨");
675 #endif
676                     m_unleash(mtmp, FALSE);
677                 }
678                 if (mtmp == u.usteed) {
679                     /* can't happen unless someone makes a change
680                        which scrambles the stay_behind logic above */
681                     impossible("steed left behind?");
682                     dismount_steed(DISMOUNT_GENERIC);
683                 }
684                 continue;
685             }
686             if (mtmp->isshk)
687                 set_residency(mtmp, TRUE);
688
689             if (mtmp->wormno) {
690                 register int cnt;
691                 /* NOTE: worm is truncated to # segs = max wormno size */
692                 cnt = count_wsegs(mtmp);
693                 num_segs = min(cnt, MAX_NUM_WORMS - 1);
694                 wormgone(mtmp);
695             } else
696                 num_segs = 0;
697
698             /* set minvent's obj->no_charge to 0 */
699             for (obj = mtmp->minvent; obj; obj = obj->nobj) {
700                 if (Has_contents(obj))
701                     picked_container(obj); /* does the right thing */
702                 obj->no_charge = 0;
703             }
704
705             relmon(mtmp, &mydogs);   /* move it from map to mydogs */
706             mtmp->mx = mtmp->my = 0; /* avoid mnexto()/MON_AT() problem */
707             mtmp->wormno = num_segs;
708             mtmp->mlstmv = monstermoves;
709         } else if (mtmp->iswiz) {
710             /* we want to be able to find him when his next resurrection
711                chance comes up, but have him resume his present location
712                if player returns to this level before that time */
713             migrate_to_level(mtmp, ledger_no(&u.uz), MIGR_EXACT_XY,
714                              (coord *) 0);
715         } else if (mtmp->mleashed) {
716             /* this can happen if your quest leader ejects you from the
717                "home" level while a leashed pet isn't next to you */
718 /*JP
719             pline("%s leash goes slack.", s_suffix(Monnam(mtmp)));
720 */
721             pline("%s\82É\8c\8b\82Î\82ê\82½\95R\82Í\82½\82é\82ñ\82¾\81D", Monnam(mtmp));
722             m_unleash(mtmp, FALSE);
723         }
724     }
725 }
726
727 void
728 migrate_to_level(mtmp, tolev, xyloc, cc)
729 register struct monst *mtmp;
730 xchar tolev; /* destination level */
731 xchar xyloc; /* MIGR_xxx destination xy location: */
732 coord *cc;   /* optional destination coordinates */
733 {
734     register struct obj *obj;
735     d_level new_lev;
736     xchar xyflags;
737     int num_segs = 0; /* count of worm segments */
738
739     if (mtmp->isshk)
740         set_residency(mtmp, TRUE);
741
742     if (mtmp->wormno) {
743         register int cnt;
744         /* **** NOTE: worm is truncated to # segs = max wormno size **** */
745         cnt = count_wsegs(mtmp);
746         num_segs = min(cnt, MAX_NUM_WORMS - 1);
747         wormgone(mtmp);
748     }
749
750     /* set minvent's obj->no_charge to 0 */
751     for (obj = mtmp->minvent; obj; obj = obj->nobj) {
752         if (Has_contents(obj))
753             picked_container(obj); /* does the right thing */
754         obj->no_charge = 0;
755     }
756
757     if (mtmp->mleashed) {
758         mtmp->mtame--;
759         m_unleash(mtmp, TRUE);
760     }
761     relmon(mtmp, &migrating_mons); /* move it from map to migrating_mons */
762
763     new_lev.dnum = ledger_to_dnum((xchar) tolev);
764     new_lev.dlevel = ledger_to_dlev((xchar) tolev);
765     /* overload mtmp->[mx,my], mtmp->[mux,muy], and mtmp->mtrack[] as */
766     /* destination codes (setup flag bits before altering mx or my) */
767     xyflags = (depth(&new_lev) < depth(&u.uz)); /* 1 => up */
768     if (In_W_tower(mtmp->mx, mtmp->my, &u.uz))
769         xyflags |= 2;
770     mtmp->wormno = num_segs;
771     mtmp->mlstmv = monstermoves;
772     mtmp->mtrack[1].x = cc ? cc->x : mtmp->mx;
773     mtmp->mtrack[1].y = cc ? cc->y : mtmp->my;
774     mtmp->mtrack[0].x = xyloc;
775     mtmp->mtrack[0].y = xyflags;
776     mtmp->mux = new_lev.dnum;
777     mtmp->muy = new_lev.dlevel;
778     mtmp->mx = mtmp->my = 0; /* this implies migration */
779     if (mtmp == context.polearm.hitmon)
780         context.polearm.hitmon = NULL;
781 }
782
783 /* return quality of food; the lower the better */
784 /* fungi will eat even tainted food */
785 int
786 dogfood(mon, obj)
787 struct monst *mon;
788 register struct obj *obj;
789 {
790     struct permonst *mptr = mon->data, *fptr = 0;
791     boolean carni = carnivorous(mptr), herbi = herbivorous(mptr),
792             starving, mblind;
793
794     if (is_quest_artifact(obj) || obj_resists(obj, 0, 95))
795         return obj->cursed ? TABU : APPORT;
796
797     switch (obj->oclass) {
798     case FOOD_CLASS:
799         if (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG)
800             fptr = &mons[obj->corpsenm];
801
802         if (obj->otyp == CORPSE && is_rider(fptr))
803             return TABU;
804         if ((obj->otyp == CORPSE || obj->otyp == EGG) && touch_petrifies(fptr)
805             && !resists_ston(mon))
806             return POISON;
807         if (!carni && !herbi)
808             return obj->cursed ? UNDEF : APPORT;
809
810         /* a starving pet will eat almost anything */
811         starving = (mon->mtame && !mon->isminion
812                     && EDOG(mon)->mhpmax_penalty);
813         /* even carnivores will eat carrots if they're temporarily blind */
814         mblind = (!mon->mcansee && haseyes(mon->data));
815
816         /* ghouls prefer old corpses and unhatchable eggs, yum!
817            they'll eat fresh non-veggy corpses and hatchable eggs
818            when starving; they never eat stone-to-flesh'd meat */
819         if (mptr == &mons[PM_GHOUL]) {
820             if (obj->otyp == CORPSE)
821                 return (peek_at_iced_corpse_age(obj) + 50L <= monstermoves
822                         && fptr != &mons[PM_LIZARD]
823                         && fptr != &mons[PM_LICHEN])
824                            ? DOGFOOD
825                            : (starving && !vegan(fptr))
826                               ? ACCFOOD
827                               : POISON;
828             if (obj->otyp == EGG)
829                 return stale_egg(obj) ? CADAVER : starving ? ACCFOOD : POISON;
830             return TABU;
831         }
832
833         switch (obj->otyp) {
834         case TRIPE_RATION:
835         case MEATBALL:
836         case MEAT_RING:
837         case MEAT_STICK:
838         case HUGE_CHUNK_OF_MEAT:
839             return carni ? DOGFOOD : MANFOOD;
840         case EGG:
841             return carni ? CADAVER : MANFOOD;
842         case CORPSE:
843             if ((peek_at_iced_corpse_age(obj) + 50L <= monstermoves
844                  && obj->corpsenm != PM_LIZARD && obj->corpsenm != PM_LICHEN
845                  && mptr->mlet != S_FUNGUS)
846                 || (acidic(fptr) && !resists_acid(mon))
847                 || (poisonous(fptr) && !resists_poison(mon)))
848                 return POISON;
849             /* turning into slime is preferable to starvation */
850             else if (fptr == &mons[PM_GREEN_SLIME] && !slimeproof(mon->data))
851                 return starving ? ACCFOOD : POISON;
852             else if (vegan(fptr))
853                 return herbi ? CADAVER : MANFOOD;
854             /* most humanoids will avoid cannibalism unless starving;
855                arbitrary: elves won't eat other elves even then */
856             else if (humanoid(mptr) && same_race(mptr, fptr)
857                      && (!is_undead(mptr) && fptr->mlet != S_KOBOLD
858                          && fptr->mlet != S_ORC && fptr->mlet != S_OGRE))
859                 return (starving && carni && !is_elf(mptr)) ? ACCFOOD : TABU;
860             else
861                 return carni ? CADAVER : MANFOOD;
862         case CLOVE_OF_GARLIC:
863             return (is_undead(mptr) || is_vampshifter(mon))
864                       ? TABU
865                       : (herbi || starving)
866                          ? ACCFOOD
867                          : MANFOOD;
868         case TIN:
869             return metallivorous(mptr) ? ACCFOOD : MANFOOD;
870         case APPLE:
871             return herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
872         case CARROT:
873             return (herbi || mblind) ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
874         case BANANA:
875             return (mptr->mlet == S_YETI && herbi)
876                       ? DOGFOOD /* for monkey and ape (tameable), sasquatch */
877                       : (herbi || starving)
878                          ? ACCFOOD
879                          : MANFOOD;
880         default:
881             if (starving)
882                 return ACCFOOD;
883             return (obj->otyp > SLIME_MOLD) ? (carni ? ACCFOOD : MANFOOD)
884                                             : (herbi ? ACCFOOD : MANFOOD);
885         }
886     default:
887         if (obj->otyp == AMULET_OF_STRANGULATION
888             || obj->otyp == RIN_SLOW_DIGESTION)
889             return TABU;
890         if (mon_hates_silver(mon) && objects[obj->otyp].oc_material == SILVER)
891             return TABU;
892         if (mptr == &mons[PM_GELATINOUS_CUBE] && is_organic(obj))
893             return ACCFOOD;
894         if (metallivorous(mptr) && is_metallic(obj)
895             && (is_rustprone(obj) || mptr != &mons[PM_RUST_MONSTER])) {
896             /* Non-rustproofed ferrous based metals are preferred. */
897             return (is_rustprone(obj) && !obj->oerodeproof) ? DOGFOOD
898                                                             : ACCFOOD;
899         }
900         if (!obj->cursed
901             && obj->oclass != BALL_CLASS
902             && obj->oclass != CHAIN_CLASS)
903             return APPORT;
904         /*FALLTHRU*/
905     case ROCK_CLASS:
906         return UNDEF;
907     }
908 }
909
910 /*
911  * With the separate mextra structure added in 3.6.x this always
912  * operates on the original mtmp. It now returns TRUE if the taming
913  * succeeded.
914  */
915 boolean
916 tamedog(mtmp, obj)
917 register struct monst *mtmp;
918 register struct obj *obj;
919 {
920     /* The Wiz, Medusa and the quest nemeses aren't even made peaceful. */
921     if (mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]
922         || (mtmp->data->mflags3 & M3_WANTSARTI))
923         return FALSE;
924
925     /* worst case, at least it'll be peaceful. */
926     mtmp->mpeaceful = 1;
927     set_malign(mtmp);
928     if (flags.moonphase == FULL_MOON && night() && rn2(6) && obj
929         && mtmp->data->mlet == S_DOG)
930         return FALSE;
931
932     /* If we cannot tame it, at least it's no longer afraid. */
933     mtmp->mflee = 0;
934     mtmp->mfleetim = 0;
935
936     /* make grabber let go now, whether it becomes tame or not */
937     if (mtmp == u.ustuck) {
938         if (u.uswallow)
939             expels(mtmp, mtmp->data, TRUE);
940         else if (!(Upolyd && sticks(youmonst.data)))
941             unstuck(mtmp);
942     }
943
944     /* feeding it treats makes it tamer */
945     if (mtmp->mtame && obj) {
946         int tasty;
947
948         if (mtmp->mcanmove && !mtmp->mconf && !mtmp->meating
949             && ((tasty = dogfood(mtmp, obj)) == DOGFOOD
950                 || (tasty <= ACCFOOD
951                     && EDOG(mtmp)->hungrytime <= monstermoves))) {
952             /* pet will "catch" and eat this thrown food */
953             if (canseemon(mtmp)) {
954                 boolean big_corpse =
955                     (obj->otyp == CORPSE && obj->corpsenm >= LOW_PM
956                      && mons[obj->corpsenm].msize > mtmp->data->msize);
957 #if 0 /*JP*/
958                 pline("%s catches %s%s", Monnam(mtmp), the(xname(obj)),
959                       !big_corpse ? "." : ", or vice versa!");
960 #else
961                 pline("%s\82Í%s\82ð\82Â\82©\82Ü\82¦\82½%s",
962                       Monnam(mtmp), xname(obj),
963                       !big_corpse ? "\81D" : "\81C\82Æ\8c¾\82¤\82æ\82è\82»\82Ì\8bt\82©\81I");
964 #endif
965             } else if (cansee(mtmp->mx, mtmp->my))
966 /*JP
967                 pline("%s.", Tobjnam(obj, "stop"));
968 */
969                 pline("%s\82Í\8e~\82Ü\82Á\82½\81D", xname(obj));
970             /* dog_eat expects a floor object */
971             place_object(obj, mtmp->mx, mtmp->my);
972             (void) dog_eat(mtmp, obj, mtmp->mx, mtmp->my, FALSE);
973             /* eating might have killed it, but that doesn't matter here;
974                a non-null result suppresses "miss" message for thrown
975                food and also implies that the object has been deleted */
976             return TRUE;
977         } else
978             return FALSE;
979     }
980
981     if (mtmp->mtame || !mtmp->mcanmove
982         /* monsters with conflicting structures cannot be tamed */
983         || mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion
984         || is_covetous(mtmp->data) || is_human(mtmp->data)
985         || (is_demon(mtmp->data) && !is_demon(youmonst.data))
986         || (obj && dogfood(mtmp, obj) >= MANFOOD))
987         return FALSE;
988
989     if (mtmp->m_id == quest_status.leader_m_id)
990         return FALSE;
991
992     /* add the pet extension */
993     newedog(mtmp);
994     initedog(mtmp);
995
996     if (obj) { /* thrown food */
997         /* defer eating until the edog extension has been set up */
998         place_object(obj, mtmp->mx, mtmp->my); /* put on floor */
999         /* devour the food (might grow into larger, genocided monster) */
1000         if (dog_eat(mtmp, obj, mtmp->mx, mtmp->my, TRUE) == 2)
1001             return TRUE; /* oops, it died... */
1002         /* `obj' is now obsolete */
1003     }
1004
1005     newsym(mtmp->mx, mtmp->my);
1006     if (attacktype(mtmp->data, AT_WEAP)) {
1007         mtmp->weapon_check = NEED_HTH_WEAPON;
1008         (void) mon_wield_item(mtmp);
1009     }
1010     return TRUE;
1011 }
1012
1013 /*
1014  * Called during pet revival or pet life-saving.
1015  * If you killed the pet, it revives wild.
1016  * If you abused the pet a lot while alive, it revives wild.
1017  * If you abused the pet at all while alive, it revives untame.
1018  * If the pet wasn't abused and was very tame, it might revive tame.
1019  */
1020 void
1021 wary_dog(mtmp, was_dead)
1022 struct monst *mtmp;
1023 boolean was_dead;
1024 {
1025     struct edog *edog;
1026     boolean quietly = was_dead;
1027
1028     finish_meating(mtmp);
1029
1030     if (!mtmp->mtame)
1031         return;
1032     edog = !mtmp->isminion ? EDOG(mtmp) : 0;
1033
1034     /* if monster was starving when it died, undo that now */
1035     if (edog && edog->mhpmax_penalty) {
1036         mtmp->mhpmax += edog->mhpmax_penalty;
1037         mtmp->mhp += edog->mhpmax_penalty; /* heal it */
1038         edog->mhpmax_penalty = 0;
1039     }
1040
1041     if (edog && (edog->killed_by_u == 1 || edog->abuse > 2)) {
1042         mtmp->mpeaceful = mtmp->mtame = 0;
1043         if (edog->abuse >= 0 && edog->abuse < 10)
1044             if (!rn2(edog->abuse + 1))
1045                 mtmp->mpeaceful = 1;
1046         if (!quietly && cansee(mtmp->mx, mtmp->my)) {
1047             if (haseyes(youmonst.data)) {
1048                 if (haseyes(mtmp->data))
1049 #if 0 /*JP*/
1050                     pline("%s %s to look you in the %s.", Monnam(mtmp),
1051                           mtmp->mpeaceful ? "seems unable" : "refuses",
1052                           body_part(EYE));
1053 #else
1054                     pline("%s\82Í\82 \82È\82½\82Ì%s%s\81D", Monnam(mtmp),
1055                           body_part(EYE),
1056                           mtmp->mpeaceful ? "\82ð\8c©\82é\82±\82Æ\82ª\82Å\82«\82È\82¢\82æ\82¤\82¾" :
1057                           "\82©\82ç\96Ú\82ð\82»\82ç\82µ\82½");
1058 #endif
1059                 else
1060 /*JP
1061                     pline("%s avoids your gaze.", Monnam(mtmp));
1062 */
1063                     pline("%s\82Í\82 \82È\82½\82Ì\82É\82ç\82Ý\82ð\89ñ\94ð\82µ\82½\81D", Monnam(mtmp));
1064             }
1065         }
1066     } else {
1067         /* chance it goes wild anyway - Pet Sematary */
1068         mtmp->mtame = rn2(mtmp->mtame + 1);
1069         if (!mtmp->mtame)
1070             mtmp->mpeaceful = rn2(2);
1071     }
1072
1073     if (!mtmp->mtame) {
1074         if (!quietly && canspotmon(mtmp))
1075 #if 0 /*JP*/
1076             pline("%s %s.", Monnam(mtmp),
1077                   mtmp->mpeaceful ? "is no longer tame" : "has become feral");
1078 #else
1079             pline("%s\82Í%s\81D", Monnam(mtmp),
1080                   mtmp->mpeaceful ? "\83y\83b\83g\82Å\82È\82­\82È\82Á\82½" : "\96ì\90\89»\82µ\82½");
1081 #endif
1082         newsym(mtmp->mx, mtmp->my);
1083         /* a life-saved monster might be leashed;
1084            don't leave it that way if it's no longer tame */
1085         if (mtmp->mleashed)
1086             m_unleash(mtmp, TRUE);
1087         if (mtmp == u.usteed)
1088             dismount_steed(DISMOUNT_THROWN);
1089     } else if (edog) {
1090         /* it's still a pet; start a clean pet-slate now */
1091         edog->revivals++;
1092         edog->killed_by_u = 0;
1093         edog->abuse = 0;
1094         edog->ogoal.x = edog->ogoal.y = -1;
1095         if (was_dead || edog->hungrytime < monstermoves + 500L)
1096             edog->hungrytime = monstermoves + 500L;
1097         if (was_dead) {
1098             edog->droptime = 0L;
1099             edog->dropdist = 10000;
1100             edog->whistletime = 0L;
1101             edog->apport = 5;
1102         } /* else lifesaved, so retain current values */
1103     }
1104 }
1105
1106 void
1107 abuse_dog(mtmp)
1108 struct monst *mtmp;
1109 {
1110     if (!mtmp->mtame)
1111         return;
1112
1113     if (Aggravate_monster || Conflict)
1114         mtmp->mtame /= 2;
1115     else
1116         mtmp->mtame--;
1117
1118     if (mtmp->mtame && !mtmp->isminion)
1119         EDOG(mtmp)->abuse++;
1120
1121     if (!mtmp->mtame && mtmp->mleashed)
1122         m_unleash(mtmp, TRUE);
1123
1124     /* don't make a sound if pet is in the middle of leaving the level */
1125     /* newsym isn't necessary in this case either */
1126     if (mtmp->mx != 0) {
1127         if (mtmp->mtame && rn2(mtmp->mtame))
1128             yelp(mtmp);
1129         else
1130             growl(mtmp); /* give them a moment's worry */
1131
1132         if (!mtmp->mtame)
1133             newsym(mtmp->mx, mtmp->my);
1134     }
1135 }
1136
1137 /*dog.c*/