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. */
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. */
13 STATIC_DCL int NDECL(pet_type);
20 mtmp->mextra = newmextra();
22 EDOG(mtmp) = (struct edog *) alloc(sizeof(struct edog));
23 (void) memset((genericptr_t) EDOG(mtmp), 0, sizeof(struct edog));
31 if (mtmp->mextra && EDOG(mtmp)) {
32 free((genericptr_t) EDOG(mtmp));
33 EDOG(mtmp) = (struct edog *) 0;
40 register struct monst *mtmp;
42 mtmp->mtame = is_domestic(mtmp->data) ? 10 : 5;
45 set_malign(mtmp); /* recalc alignment now that it's tamed */
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;
64 if (urole.petnum != NON_PM)
66 else if (preferred_pet == 'c')
68 else if (preferred_pet == 'd')
71 return rn2(2) ? PM_KITTEN : PM_LITTLE_DOG;
75 make_familiar(otmp, x, y, quietly)
76 register struct obj *otmp;
81 struct monst *mtmp = 0;
82 int chance, trycnt = 100;
85 if (otmp) { /* figurine; otherwise spell */
86 int mndx = otmp->corpsenm;
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) {
94 /* have just been given "You <do something with>
95 the figurine and it transforms." message */
97 pline("... into a pile of dust.");
99 pline("
\81D
\81D
\81D
\82»
\82µ
\82Ä
\82¿
\82è
\82Ì
\8eR
\82É
\82È
\82Á
\82½
\81D");
100 break; /* mtmp is null */
102 } else if (!rn2(3)) {
103 pm = &mons[pet_type()];
109 There("seems to be nothing available for a familiar.");
111 pline("
\89º
\96l
\82Í
\8c»
\82ê
\82È
\82©
\82Á
\82½
\81D");
116 mtmp = makemon(pm, x, y, MM_EDOG | MM_IGNOREWATER | NO_MINVENT);
117 if (otmp && !mtmp) { /* monster was genocided or square occupied */
120 pline_The("figurine writhes and then shatters into pieces!");
122 pline("
\90l
\8c`
\82Í
\82à
\82ª
\82«
\81C
\82
\82¾
\82¯
\8eU
\82Á
\82½
\81I");
125 } while (!mtmp && --trycnt > 0);
128 return (struct monst *) 0;
130 if (is_pool(mtmp->mx, mtmp->my) && minliquid(mtmp))
131 return (struct monst *) 0;
135 if (otmp) { /* figurine; resulting monster might not become a pet */
136 chance = rn2(10); /* 0==tame, 1==peaceful, 2==hostile */
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 */
141 mtmp->mtame = 0; /* not tame after all */
142 if (chance == 2) { /* hostile (cursed figurine) */
145 You("get a bad feeling about this.");
147 You("
\8c\99\82È
\97\
\8a´
\82ª
\82µ
\82½
\81D");
152 /* if figurine has been named, give same name to the monster */
154 mtmp = christen_monst(mtmp, ONAME(otmp));
156 set_malign(mtmp); /* more alignment changes */
157 newsym(mtmp->mx, mtmp->my);
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);
170 register struct monst *mtmp;
171 register struct obj *otmp;
174 static int petname_used = 0;
176 if (preferred_pet == 'n')
177 return ((struct monst *) 0);
179 pettype = pet_type();
180 if (pettype == PM_LITTLE_DOG)
182 else if (pettype == PM_PONY)
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))
192 petname = "Slasher"; /* The Warrior */
194 petname = "
\83X
\83\89\83b
\83V
\83\83\81[";
196 if (Role_if(PM_SAMURAI))
198 petname = "Hachi"; /* Shibuya Station */
200 petname = "
\83n
\83`
\8cö";
202 if (Role_if(PM_BARBARIAN))
204 petname = "Idefix"; /* Obelix */
206 petname = "
\83C
\83f
\83t
\83B
\83N
\83X";
208 if (Role_if(PM_RANGER))
210 petname = "Sirius"; /* Orion's dog */
212 petname = "
\83V
\83\8a\83E
\83X";
216 mtmp = makemon(&mons[pettype], u.ux, u.uy, MM_EDOG);
219 return ((struct monst *) 0); /* pets were genocided */
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);
228 if (!petname_used++ && *petname)
229 mtmp = christen_monst(mtmp, petname);
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 */
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))
247 mon->mlstmv = monstermoves;
254 register struct monst *mtmp, *mtmp0 = 0, *mtmp2;
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.
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).
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)
275 if (ESHK(mtmp)->dismiss_kops) {
276 if (dismissKops == 0)
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 */
283 /* [keep looping; later monsters might need ESHK reset] */
287 /* make the same check for mydogs */
288 for (mtmp = mydogs; mtmp && dismissKops >= 0; mtmp = mtmp->nmon) {
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)
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 */
301 make_happy_shoppers(TRUE);
303 /* place pets and/or any other monsters who accompany hero */
304 while ((mtmp = mydogs) != 0) {
306 mon_arrive(mtmp, TRUE);
309 /* time for migrating monsters to arrive */
310 for (mtmp = migrating_mons; mtmp; mtmp = mtmp2) {
312 if (mtmp->mux == u.uz.dnum && mtmp->muy == u.uz.dlevel) {
313 if (mtmp == migrating_mons)
314 migrating_mons = mtmp->nmon;
316 mtmp0->nmon = mtmp->nmon;
317 mon_arrive(mtmp, FALSE);
323 /* called from resurrect() in addition to losedogs() */
325 mon_arrive(mtmp, with_you)
330 xchar xlocale, ylocale, xyloc, xyflags, wander;
336 set_residency(mtmp, FALSE);
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();
343 initworm(mtmp, num_segs);
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;
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));
359 if (mtmp == u.usteed)
360 return; /* don't place steed on the map */
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);
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.
380 if (mtmp->mlstmv < monstermoves - 1L) {
381 /* heal monster for time spent in limbo */
382 long nmv = monstermoves - 1L - mtmp->mlstmv;
384 mon_catchup_elapsed_time(mtmp, nmv);
385 mtmp->mlstmv = monstermoves - 1L;
387 /* let monster move a bit on new level (see placement code below) */
388 wander = (xchar) min(nmv, 8);
393 case MIGR_APPROX_XY: /* {x,y}locale set above */
399 xlocale = u.ux, ylocale = u.uy;
402 xlocale = xupstair, ylocale = yupstair;
404 case MIGR_STAIRS_DOWN:
405 xlocale = xdnstair, ylocale = ydnstair;
408 xlocale = xupladder, ylocale = yupladder;
410 case MIGR_LADDER_DOWN:
411 xlocale = xdnladder, ylocale = ydnladder;
414 xlocale = sstairs.sx, ylocale = sstairs.sy;
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);
427 /* find the arrival portal */
428 for (t = ftrap; t; t = t->ntrap)
429 if (t->ttyp == MAGIC_PORTAL)
432 xlocale = t->tx, ylocale = t->ty;
435 impossible("mon_arrive: no corresponding portal?");
439 xlocale = ylocale = 0;
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);
449 /* somexy() handles irregular rooms */
450 if (somexy(&rooms[*r - ROOMOFFSET], &c))
451 xlocale = c.x, ylocale = c.y;
453 xlocale = ylocale = 0;
454 } else { /* not in a room */
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);
465 mtmp->mx = 0; /*(already is 0)*/
468 if (!mnearto(mtmp, xlocale, ylocale, FALSE))
469 goto fail_mon_placement;
471 if (!rloc(mtmp, TRUE)) {
473 * Failed to place migrating monster,
474 * probably because the level is full.
475 * Dump the monster's cargo and leave the monster dead.
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);
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.");
492 (void) mkcorpstat(CORPSE, (struct monst *) 0, mtmp->data, xlocale,
493 ylocale, CORPSTAT_NONE);
499 /* heal monster for time spent elsewhere */
501 mon_catchup_elapsed_time(mtmp, nmv)
503 long nmv; /* number of moves */
505 int imv = 0; /* avoid zillions of casts and lint warnings */
507 #if defined(DEBUG) || defined(BETA)
508 if (nmv < 0L) { /* crash likely... */
509 panic("catchup from future time?");
512 } else if (nmv == 0L) { /* safe, but should'nt happen */
513 impossible("catchup from now?");
516 if (nmv >= LARGEST_INT) /* paranoia */
517 imv = LARGEST_INT - 1;
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)
527 mtmp->mblinded -= imv;
530 if (imv >= (int) mtmp->mfrozen)
533 mtmp->mfrozen -= imv;
535 if (mtmp->mfleetim) {
536 if (imv >= (int) mtmp->mfleetim)
539 mtmp->mfleetim -= imv;
542 /* might recover from temporary trouble */
543 if (mtmp->mtrapped && rn2(imv + 1) > 40 / 2)
545 if (mtmp->mconf && rn2(imv + 1) > 50 / 2)
547 if (mtmp->mstun && rn2(imv + 1) > 10 / 2)
550 /* might finish eating or be able to use special ability again */
551 if (imv > mtmp->meating)
552 finish_meating(mtmp);
554 mtmp->meating -= imv;
555 if (imv > mtmp->mspec_used)
556 mtmp->mspec_used = 0;
558 mtmp->mspec_used -= imv;
560 /* reduce tameness for every 150 moves you are separated */
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 */
568 mtmp->mtame = mtmp->mpeaceful = 0; /* hostile! */
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()
573 if (mtmp->mtame && !mtmp->isminion
574 && (carnivorous(mtmp->data) || herbivorous(mtmp->data))) {
575 struct edog *edog = EDOG(mtmp);
577 if ((monstermoves > edog->hungrytime + 500 && mtmp->mhp < 3)
578 || (monstermoves > edog->hungrytime + 750))
579 mtmp->mtame = mtmp->mpeaceful = 0;
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);
589 /* recover lost hit points */
590 if (!regenerates(mtmp->data))
592 if (mtmp->mhp + imv >= mtmp->mhpmax)
593 mtmp->mhp = mtmp->mhpmax;
598 /* called when you move to another level */
601 boolean pets_only; /* true for ascension or final escape */
603 register struct monst *mtmp, *mtmp2;
604 register struct obj *obj;
608 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
610 if (DEADMONSTER(mtmp))
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 */
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)) {
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) {
647 pline("%s is still %s.", Monnam(mtmp),
648 mtmp->meating ? "eating" : "trapped");
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¾");
654 } else if (mon_has_amulet(mtmp)) {
657 pline("%s seems very disoriented for a moment.",
659 pline("%s
\82Í
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\82æ
\82¤
\82¾
\81D",
664 if (mtmp->mleashed) {
666 pline("%s leash suddenly comes loose.",
668 ? (mtmp->female ? "Her" : "His")
671 pline("%s
\82É
\8c\8b\82Î
\82ê
\82½
\95R
\82Í
\93Ë
\91R
\82ä
\82é
\82ñ
\82¾
\81D",
673 ? (mtmp->female ? "
\94Þ
\8f\97" : "
\94Þ")
674 : "
\82»
\82Ì
\90¶
\95¨");
676 m_unleash(mtmp, FALSE);
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);
687 set_residency(mtmp, TRUE);
691 /* NOTE: worm is truncated to # segs = max wormno size */
692 cnt = count_wsegs(mtmp);
693 num_segs = min(cnt, MAX_NUM_WORMS - 1);
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 */
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,
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 */
719 pline("%s leash goes slack.", s_suffix(Monnam(mtmp)));
721 pline("%s
\82É
\8c\8b\82Î
\82ê
\82½
\95R
\82Í
\82½
\82é
\82ñ
\82¾
\81D", Monnam(mtmp));
722 m_unleash(mtmp, FALSE);
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 */
734 register struct obj *obj;
737 int num_segs = 0; /* count of worm segments */
740 set_residency(mtmp, TRUE);
744 /* **** NOTE: worm is truncated to # segs = max wormno size **** */
745 cnt = count_wsegs(mtmp);
746 num_segs = min(cnt, MAX_NUM_WORMS - 1);
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 */
757 if (mtmp->mleashed) {
759 m_unleash(mtmp, TRUE);
761 relmon(mtmp, &migrating_mons); /* move it from map to migrating_mons */
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))
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;
783 /* return quality of food; the lower the better */
784 /* fungi will eat even tainted food */
788 register struct obj *obj;
790 struct permonst *mptr = mon->data, *fptr = 0;
791 boolean carni = carnivorous(mptr), herbi = herbivorous(mptr),
794 if (is_quest_artifact(obj) || obj_resists(obj, 0, 95))
795 return obj->cursed ? TABU : APPORT;
797 switch (obj->oclass) {
799 if (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG)
800 fptr = &mons[obj->corpsenm];
802 if (obj->otyp == CORPSE && is_rider(fptr))
804 if ((obj->otyp == CORPSE || obj->otyp == EGG) && touch_petrifies(fptr)
805 && !resists_ston(mon))
807 if (!carni && !herbi)
808 return obj->cursed ? UNDEF : APPORT;
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));
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])
825 : (starving && !vegan(fptr))
828 if (obj->otyp == EGG)
829 return stale_egg(obj) ? CADAVER : starving ? ACCFOOD : POISON;
838 case HUGE_CHUNK_OF_MEAT:
839 return carni ? DOGFOOD : MANFOOD;
841 return carni ? CADAVER : MANFOOD;
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)))
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;
861 return carni ? CADAVER : MANFOOD;
862 case CLOVE_OF_GARLIC:
863 return (is_undead(mptr) || is_vampshifter(mon))
865 : (herbi || starving)
869 return metallivorous(mptr) ? ACCFOOD : MANFOOD;
871 return herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
873 return (herbi || mblind) ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
875 return (mptr->mlet == S_YETI && herbi)
876 ? DOGFOOD /* for monkey and ape (tameable), sasquatch */
877 : (herbi || starving)
883 return (obj->otyp > SLIME_MOLD) ? (carni ? ACCFOOD : MANFOOD)
884 : (herbi ? ACCFOOD : MANFOOD);
887 if (obj->otyp == AMULET_OF_STRANGULATION
888 || obj->otyp == RIN_SLOW_DIGESTION)
890 if (mon_hates_silver(mon) && objects[obj->otyp].oc_material == SILVER)
892 if (mptr == &mons[PM_GELATINOUS_CUBE] && is_organic(obj))
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
901 && obj->oclass != BALL_CLASS
902 && obj->oclass != CHAIN_CLASS)
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
917 register struct monst *mtmp;
918 register struct obj *obj;
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))
925 /* worst case, at least it'll be peaceful. */
928 if (flags.moonphase == FULL_MOON && night() && rn2(6) && obj
929 && mtmp->data->mlet == S_DOG)
932 /* If we cannot tame it, at least it's no longer afraid. */
936 /* make grabber let go now, whether it becomes tame or not */
937 if (mtmp == u.ustuck) {
939 expels(mtmp, mtmp->data, TRUE);
940 else if (!(Upolyd && sticks(youmonst.data)))
944 /* feeding it treats makes it tamer */
945 if (mtmp->mtame && obj) {
948 if (mtmp->mcanmove && !mtmp->mconf && !mtmp->meating
949 && ((tasty = dogfood(mtmp, obj)) == DOGFOOD
951 && EDOG(mtmp)->hungrytime <= monstermoves))) {
952 /* pet will "catch" and eat this thrown food */
953 if (canseemon(mtmp)) {
955 (obj->otyp == CORPSE && obj->corpsenm >= LOW_PM
956 && mons[obj->corpsenm].msize > mtmp->data->msize);
958 pline("%s catches %s%s", Monnam(mtmp), the(xname(obj)),
959 !big_corpse ? "." : ", or vice versa!");
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");
965 } else if (cansee(mtmp->mx, mtmp->my))
967 pline("%s.", Tobjnam(obj, "stop"));
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 */
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))
989 if (mtmp->m_id == quest_status.leader_m_id)
992 /* add the pet extension */
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 */
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);
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.
1021 wary_dog(mtmp, was_dead)
1026 boolean quietly = was_dead;
1028 finish_meating(mtmp);
1032 edog = !mtmp->isminion ? EDOG(mtmp) : 0;
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;
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))
1050 pline("%s %s to look you in the %s.", Monnam(mtmp),
1051 mtmp->mpeaceful ? "seems unable" : "refuses",
1054 pline("%s
\82Í
\82 \82È
\82½
\82Ì%s%s
\81D", Monnam(mtmp),
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½");
1061 pline("%s avoids your gaze.", Monnam(mtmp));
1063 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\82É
\82ç
\82Ý
\82ð
\89ñ
\94ð
\82µ
\82½
\81D", Monnam(mtmp));
1067 /* chance it goes wild anyway - Pet Sematary */
1068 mtmp->mtame = rn2(mtmp->mtame + 1);
1070 mtmp->mpeaceful = rn2(2);
1074 if (!quietly && canspotmon(mtmp))
1076 pline("%s %s.", Monnam(mtmp),
1077 mtmp->mpeaceful ? "is no longer tame" : "has become feral");
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½");
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 */
1086 m_unleash(mtmp, TRUE);
1087 if (mtmp == u.usteed)
1088 dismount_steed(DISMOUNT_THROWN);
1090 /* it's still a pet; start a clean pet-slate now */
1092 edog->killed_by_u = 0;
1094 edog->ogoal.x = edog->ogoal.y = -1;
1095 if (was_dead || edog->hungrytime < monstermoves + 500L)
1096 edog->hungrytime = monstermoves + 500L;
1098 edog->droptime = 0L;
1099 edog->dropdist = 10000;
1100 edog->whistletime = 0L;
1102 } /* else lifesaved, so retain current values */
1113 if (Aggravate_monster || Conflict)
1118 if (mtmp->mtame && !mtmp->isminion)
1119 EDOG(mtmp)->abuse++;
1121 if (!mtmp->mtame && mtmp->mleashed)
1122 m_unleash(mtmp, TRUE);
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))
1130 growl(mtmp); /* give them a moment's worry */
1133 newsym(mtmp->mx, mtmp->my);