OSDN Git Service

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