1 /* NetHack 3.6 dog.c $NHDT-Date: 1446808440 2015/11/06 11:14:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.52 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
12 STATIC_DCL int NDECL(pet_type);
19 mtmp->mextra = newmextra();
21 EDOG(mtmp) = (struct edog *) alloc(sizeof(struct edog));
22 (void) memset((genericptr_t) EDOG(mtmp), 0, sizeof(struct edog));
30 if (mtmp->mextra && EDOG(mtmp)) {
31 free((genericptr_t) EDOG(mtmp));
32 EDOG(mtmp) = (struct edog *) 0;
39 register struct monst *mtmp;
41 mtmp->mtame = is_domestic(mtmp->data) ? 10 : 5;
44 set_malign(mtmp); /* recalc alignment now that it's tamed */
47 EDOG(mtmp)->droptime = 0;
48 EDOG(mtmp)->dropdist = 10000;
49 EDOG(mtmp)->apport = 10;
50 EDOG(mtmp)->whistletime = 0;
51 EDOG(mtmp)->hungrytime = 1000 + monstermoves;
52 EDOG(mtmp)->ogoal.x = -1; /* force error if used before set */
53 EDOG(mtmp)->ogoal.y = -1;
54 EDOG(mtmp)->abuse = 0;
55 EDOG(mtmp)->revivals = 0;
56 EDOG(mtmp)->mhpmax_penalty = 0;
57 EDOG(mtmp)->killed_by_u = 0;
63 if (urole.petnum != NON_PM)
65 else if (preferred_pet == 'c')
67 else if (preferred_pet == 'd')
70 return rn2(2) ? PM_KITTEN : PM_LITTLE_DOG;
74 make_familiar(otmp, x, y, quietly)
75 register struct obj *otmp;
80 struct monst *mtmp = 0;
81 int chance, trycnt = 100;
84 if (otmp) { /* figurine; otherwise spell */
85 int mndx = otmp->corpsenm;
87 /* activating a figurine provides one way to exceed the
88 maximum number of the target critter created--unless
89 it has a special limit (erinys, Nazgul) */
90 if ((mvitals[mndx].mvflags & G_EXTINCT)
91 && mbirth_limit(mndx) != MAXMONNO) {
93 /* have just been given "You <do something with>
94 the figurine and it transforms." message */
96 pline("... into a pile of dust.");
98 pline("
\81D
\81D
\81D
\82»
\82µ
\82Ä
\82¿
\82è
\82Ì
\8eR
\82É
\82È
\82Á
\82½
\81D");
99 break; /* mtmp is null */
101 } else if (!rn2(3)) {
102 pm = &mons[pet_type()];
108 There("seems to be nothing available for a familiar.");
110 pline("
\89º
\96l
\82Í
\8c»
\82ê
\82È
\82©
\82Á
\82½
\81D");
115 mtmp = makemon(pm, x, y, MM_EDOG | MM_IGNOREWATER | NO_MINVENT);
116 if (otmp && !mtmp) { /* monster was genocided or square occupied */
119 pline_The("figurine writhes and then shatters into pieces!");
121 pline("
\90l
\8c`
\82Í
\82à
\82ª
\82«
\81C
\82
\82¾
\82¯
\8eU
\82Á
\82½
\81I");
124 } while (!mtmp && --trycnt > 0);
127 return (struct monst *) 0;
129 if (is_pool(mtmp->mx, mtmp->my) && minliquid(mtmp))
130 return (struct monst *) 0;
134 if (otmp) { /* figurine; resulting monster might not become a pet */
135 chance = rn2(10); /* 0==tame, 1==peaceful, 2==hostile */
137 chance = otmp->blessed ? 0 : !otmp->cursed ? 1 : 2;
138 /* 0,1,2: b=80%,10,10; nc=10%,80,10; c=10%,10,80 */
140 mtmp->mtame = 0; /* not tame after all */
141 if (chance == 2) { /* hostile (cursed figurine) */
144 You("get a bad feeling about this.");
146 You("
\8c\99\82È
\97\
\8a´
\82ª
\82µ
\82½
\81D");
151 /* if figurine has been named, give same name to the monster */
153 mtmp = christen_monst(mtmp, ONAME(otmp));
155 set_malign(mtmp); /* more alignment changes */
156 newsym(mtmp->mx, mtmp->my);
158 /* must wield weapon immediately since pets will otherwise drop it */
159 if (mtmp->mtame && attacktype(mtmp->data, AT_WEAP)) {
160 mtmp->weapon_check = NEED_HTH_WEAPON;
161 (void) mon_wield_item(mtmp);
169 register struct monst *mtmp;
170 register struct obj *otmp;
173 static int petname_used = 0;
175 if (preferred_pet == 'n')
176 return ((struct monst *) 0);
178 pettype = pet_type();
179 if (pettype == PM_LITTLE_DOG)
181 else if (pettype == PM_PONY)
186 /* default pet names */
187 if (!*petname && pettype == PM_LITTLE_DOG) {
188 /* All of these names were for dogs. */
189 if (Role_if(PM_CAVEMAN))
191 petname = "Slasher"; /* The Warrior */
193 petname = "
\83X
\83\89\83b
\83V
\83\83\81[";
195 if (Role_if(PM_SAMURAI))
197 petname = "Hachi"; /* Shibuya Station */
199 petname = "
\83n
\83`
\8cö";
201 if (Role_if(PM_BARBARIAN))
203 petname = "Idefix"; /* Obelix */
205 petname = "
\83C
\83f
\83t
\83B
\83N
\83X";
207 if (Role_if(PM_RANGER))
209 petname = "Sirius"; /* Orion's dog */
211 petname = "
\83V
\83\8a\83E
\83X";
215 mtmp = makemon(&mons[pettype], u.ux, u.uy, MM_EDOG);
218 return ((struct monst *) 0); /* pets were genocided */
220 context.startingpet_mid = mtmp->m_id;
221 /* Horses already wear a saddle */
222 if (pettype == PM_PONY && !!(otmp = mksobj(SADDLE, TRUE, FALSE))) {
223 if (mpickobj(mtmp, otmp))
224 panic("merged saddle?");
225 mtmp->misc_worn_check |= W_SADDLE;
226 otmp->dknown = otmp->bknown = otmp->rknown = 1;
227 otmp->owornmask = W_SADDLE;
228 otmp->leashmon = mtmp->m_id;
229 update_mon_intrinsics(mtmp, otmp, TRUE, TRUE);
232 if (!petname_used++ && *petname)
233 mtmp = christen_monst(mtmp, petname);
239 /* record `last move time' for all monsters prior to level save so that
240 mon_arrive() can catch up for lost time when they're restored later */
246 /* monst->mlstmv used to be updated every time `monst' actually moved,
247 but that is no longer the case so we just do a blanket assignment */
248 for (mon = fmon; mon; mon = mon->nmon) {
249 if (DEADMONSTER(mon))
251 mon->mlstmv = monstermoves;
258 register struct monst *mtmp, *mtmp0 = 0, *mtmp2;
262 * First, scan migrating_mons for shopkeepers who want to dismiss Kops,
263 * and scan mydogs for shopkeepers who want to retain kops.
264 * Second, dismiss kops if warranted, making more room for arrival.
265 * Third, place monsters accompanying the hero.
266 * Last, place migrating monsters coming to this level.
268 * Hero might eventually be displaced (due to the third step, but
269 * occurring later), which is the main reason to do the second step
270 * sooner (in turn necessitating the first step, rather than combining
271 * the list scans with monster placement).
274 /* check for returning shk(s) */
275 for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) {
276 if (mtmp->mux != u.uz.dnum || mtmp->muy != u.uz.dlevel)
279 if (ESHK(mtmp)->dismiss_kops) {
280 if (dismissKops == 0)
282 ESHK(mtmp)->dismiss_kops = FALSE; /* reset */
283 } else if (!mtmp->mpeaceful) {
284 /* an unpacified shk is returning; don't dismiss kops
285 even if another pacified one is willing to do so */
287 /* [keep looping; later monsters might need ESHK reset] */
291 /* make the same check for mydogs */
292 for (mtmp = mydogs; mtmp && dismissKops >= 0; mtmp = mtmp->nmon) {
294 /* hostile shk might accompany hero [ESHK(mtmp)->dismiss_kops
295 can't be set here; it's only used for migrating_mons] */
296 if (!mtmp->mpeaceful)
301 /* when a hostile shopkeeper chases hero to another level
302 and then gets paid off there, get rid of summoned kops
303 here now that he has returned to his shop level */
305 make_happy_shoppers(TRUE);
307 /* place pets and/or any other monsters who accompany hero */
308 while ((mtmp = mydogs) != 0) {
310 mon_arrive(mtmp, TRUE);
313 /* time for migrating monsters to arrive */
314 for (mtmp = migrating_mons; mtmp; mtmp = mtmp2) {
316 if (mtmp->mux == u.uz.dnum && mtmp->muy == u.uz.dlevel) {
317 if (mtmp == migrating_mons)
318 migrating_mons = mtmp->nmon;
320 mtmp0->nmon = mtmp->nmon;
321 mon_arrive(mtmp, FALSE);
327 /* called from resurrect() in addition to losedogs() */
329 mon_arrive(mtmp, with_you)
334 xchar xlocale, ylocale, xyloc, xyflags, wander;
340 set_residency(mtmp, FALSE);
342 num_segs = mtmp->wormno;
343 /* baby long worms have no tail so don't use is_longworm() */
344 if (mtmp->data == &mons[PM_LONG_WORM]) {
345 mtmp->wormno = get_wormno();
347 initworm(mtmp, num_segs);
351 /* some monsters might need to do something special upon arrival
352 _after_ the current level has been fully set up; see dochug() */
353 mtmp->mstrategy |= STRAT_ARRIVE;
355 /* make sure mnexto(rloc_to(set_apparxy())) doesn't use stale data */
356 mtmp->mux = u.ux, mtmp->muy = u.uy;
357 xyloc = mtmp->mtrack[0].x;
358 xyflags = mtmp->mtrack[0].y;
359 xlocale = mtmp->mtrack[1].x;
360 ylocale = mtmp->mtrack[1].y;
361 mtmp->mtrack[0].x = mtmp->mtrack[0].y = 0;
362 mtmp->mtrack[1].x = mtmp->mtrack[1].y = 0;
364 if (mtmp == u.usteed)
365 return; /* don't place steed on the map */
367 /* When a monster accompanies you, sometimes it will arrive
368 at your intended destination and you'll end up next to
369 that spot. This code doesn't control the final outcome;
370 goto_level(do.c) decides who ends up at your target spot
371 when there is a monster there too. */
372 if (!MON_AT(u.ux, u.uy)
373 && !rn2(mtmp->mtame ? 10 : mtmp->mpeaceful ? 5 : 2))
374 rloc_to(mtmp, u.ux, u.uy);
380 * The monster arrived on this level independently of the player.
381 * Its coordinate fields were overloaded for use as flags that
382 * specify its final destination.
385 if (mtmp->mlstmv < monstermoves - 1L) {
386 /* heal monster for time spent in limbo */
387 long nmv = monstermoves - 1L - mtmp->mlstmv;
389 mon_catchup_elapsed_time(mtmp, nmv);
390 mtmp->mlstmv = monstermoves - 1L;
392 /* let monster move a bit on new level (see placement code below) */
393 wander = (xchar) min(nmv, 8);
398 case MIGR_APPROX_XY: /* {x,y}locale set above */
404 xlocale = u.ux, ylocale = u.uy;
407 xlocale = xupstair, ylocale = yupstair;
409 case MIGR_STAIRS_DOWN:
410 xlocale = xdnstair, ylocale = ydnstair;
413 xlocale = xupladder, ylocale = yupladder;
415 case MIGR_LADDER_DOWN:
416 xlocale = xdnladder, ylocale = ydnladder;
419 xlocale = sstairs.sx, ylocale = sstairs.sy;
422 if (In_endgame(&u.uz)) {
423 /* there is no arrival portal for endgame levels */
424 /* BUG[?]: for simplicity, this code relies on the fact
425 that we know that the current endgame levels always
426 build upwards and never have any exclusion subregion
427 inside their TELEPORT_REGION settings. */
428 xlocale = rn1(updest.hx - updest.lx + 1, updest.lx);
429 ylocale = rn1(updest.hy - updest.ly + 1, updest.ly);
432 /* find the arrival portal */
433 for (t = ftrap; t; t = t->ntrap)
434 if (t->ttyp == MAGIC_PORTAL)
437 xlocale = t->tx, ylocale = t->ty;
440 impossible("mon_arrive: no corresponding portal?");
444 xlocale = ylocale = 0;
448 if (xlocale && wander) {
449 /* monster moved a bit; pick a nearby location */
450 /* mnearto() deals w/stone, et al */
451 char *r = in_rooms(xlocale, ylocale, 0);
454 /* somexy() handles irregular rooms */
455 if (somexy(&rooms[*r - ROOMOFFSET], &c))
456 xlocale = c.x, ylocale = c.y;
458 xlocale = ylocale = 0;
459 } else { /* not in a room */
461 i = max(1, xlocale - wander);
462 j = min(COLNO - 1, xlocale + wander);
463 xlocale = rn1(j - i, i);
464 i = max(0, ylocale - wander);
465 j = min(ROWNO - 1, ylocale + wander);
466 ylocale = rn1(j - i, i);
470 mtmp->mx = 0; /*(already is 0)*/
473 (void) mnearto(mtmp, xlocale, ylocale, FALSE);
475 if (!rloc(mtmp, TRUE)) {
477 * Failed to place migrating monster,
478 * probably because the level is full.
479 * Dump the monster's cargo and leave the monster dead.
482 while ((obj = mtmp->minvent) != 0) {
483 obj_extract_self(obj);
484 obj_no_longer_held(obj);
485 if (obj->owornmask & W_WEP)
486 setmnotwielded(mtmp, obj);
488 if (xlocale && ylocale)
489 place_object(obj, xlocale, ylocale);
490 else if (rloco(obj)) {
491 if (!get_obj_location(obj, &xlocale, &ylocale, 0))
492 impossible("Can't find relocated object.");
495 (void) mkcorpstat(CORPSE, (struct monst *) 0, mtmp->data, xlocale,
496 ylocale, CORPSTAT_NONE);
502 /* heal monster for time spent elsewhere */
504 mon_catchup_elapsed_time(mtmp, nmv)
506 long nmv; /* number of moves */
508 int imv = 0; /* avoid zillions of casts and lint warnings */
510 #if defined(DEBUG) || defined(BETA)
511 if (nmv < 0L) { /* crash likely... */
512 panic("catchup from future time?");
515 } else if (nmv == 0L) { /* safe, but should'nt happen */
516 impossible("catchup from now?");
519 if (nmv >= LARGEST_INT) /* paranoia */
520 imv = LARGEST_INT - 1;
524 /* might stop being afraid, blind or frozen */
525 /* set to 1 and allow final decrement in movemon() */
526 if (mtmp->mblinded) {
527 if (imv >= (int) mtmp->mblinded)
530 mtmp->mblinded -= imv;
533 if (imv >= (int) mtmp->mfrozen)
536 mtmp->mfrozen -= imv;
538 if (mtmp->mfleetim) {
539 if (imv >= (int) mtmp->mfleetim)
542 mtmp->mfleetim -= imv;
545 /* might recover from temporary trouble */
546 if (mtmp->mtrapped && rn2(imv + 1) > 40 / 2)
548 if (mtmp->mconf && rn2(imv + 1) > 50 / 2)
550 if (mtmp->mstun && rn2(imv + 1) > 10 / 2)
553 /* might finish eating or be able to use special ability again */
554 if (imv > mtmp->meating)
555 finish_meating(mtmp);
557 mtmp->meating -= imv;
558 if (imv > mtmp->mspec_used)
559 mtmp->mspec_used = 0;
561 mtmp->mspec_used -= imv;
563 /* reduce tameness for every 150 moves you are separated */
565 int wilder = (imv + 75) / 150;
566 if (mtmp->mtame > wilder)
567 mtmp->mtame -= wilder; /* less tame */
568 else if (mtmp->mtame > rn2(wilder))
569 mtmp->mtame = 0; /* untame */
571 mtmp->mtame = mtmp->mpeaceful = 0; /* hostile! */
573 /* check to see if it would have died as a pet; if so, go wild instead
574 * of dying the next time we call dog_move()
576 if (mtmp->mtame && !mtmp->isminion
577 && (carnivorous(mtmp->data) || herbivorous(mtmp->data))) {
578 struct edog *edog = EDOG(mtmp);
580 if ((monstermoves > edog->hungrytime + 500 && mtmp->mhp < 3)
581 || (monstermoves > edog->hungrytime + 750))
582 mtmp->mtame = mtmp->mpeaceful = 0;
585 if (!mtmp->mtame && mtmp->mleashed) {
586 /* leashed monsters should always be with hero, consequently
587 never losing any time to be accounted for later */
588 impossible("catching up for leashed monster?");
589 m_unleash(mtmp, FALSE);
592 /* recover lost hit points */
593 if (!regenerates(mtmp->data))
595 if (mtmp->mhp + imv >= mtmp->mhpmax)
596 mtmp->mhp = mtmp->mhpmax;
601 /* called when you move to another level */
604 boolean pets_only; /* true for ascension or final escape */
606 register struct monst *mtmp, *mtmp2;
607 register struct obj *obj;
611 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
613 if (DEADMONSTER(mtmp))
617 continue; /* reject non-pets */
618 /* don't block pets from accompanying hero's dungeon
619 escape or ascension simply due to mundane trifles;
620 unlike level change for steed, don't bother trying
621 to achieve a normal trap escape first */
628 if (((monnear(mtmp, u.ux, u.uy) && levl_follower(mtmp))
629 /* the wiz will level t-port from anywhere to chase
630 the amulet; if you don't have it, will chase you
631 only if in range. -3. */
632 || (u.uhave.amulet && mtmp->iswiz))
633 && ((!mtmp->msleeping && mtmp->mcanmove)
634 /* eg if level teleport or new trap, steed has no control
635 to avoid following */
636 || (mtmp == u.usteed))
637 /* monster won't follow if it hasn't noticed you yet */
638 && !(mtmp->mstrategy & STRAT_WAITFORU)) {
641 (void) mintrap(mtmp); /* try to escape */
642 if (mtmp == u.usteed) {
643 /* make sure steed is eligible to accompany hero */
644 mtmp->mtrapped = 0; /* escape trap */
645 mtmp->meating = 0; /* terminate eating */
646 mdrop_special_objs(mtmp); /* drop Amulet */
647 } else if (mtmp->meating || mtmp->mtrapped) {
650 pline("%s is still %s.", Monnam(mtmp),
651 mtmp->meating ? "eating" : "trapped");
653 pline("%s
\82Í
\82Ü
\82¾%s
\81D", Monnam(mtmp),
654 mtmp->meating ? "
\90H
\82×
\82Ä
\82¢
\82é" : "ã©
\82É
\82©
\82©
\82Á
\82½
\82Ü
\82Ü
\82¾");
657 } else if (mon_has_amulet(mtmp)) {
660 pline("%s seems very disoriented for a moment.",
662 pline("%s
\82Í
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\82æ
\82¤
\82¾
\81D",
667 if (mtmp->mleashed) {
669 pline("%s leash suddenly comes loose.",
671 ? (mtmp->female ? "Her" : "His")
674 pline("%s
\82É
\8c\8b\82Î
\82ê
\82½
\95R
\82Í
\93Ë
\91R
\82ä
\82é
\82ñ
\82¾
\81D",
676 ? (mtmp->female ? "
\94Þ
\8f\97" : "
\94Þ")
677 : "
\82»
\82Ì
\90¶
\95¨");
679 m_unleash(mtmp, FALSE);
681 if (mtmp == u.usteed) {
682 /* can't happen unless someone makes a change
683 which scrambles the stay_behind logic above */
684 impossible("steed left behind?");
685 dismount_steed(DISMOUNT_GENERIC);
690 set_residency(mtmp, TRUE);
694 /* NOTE: worm is truncated to # segs = max wormno size */
695 cnt = count_wsegs(mtmp);
696 num_segs = min(cnt, MAX_NUM_WORMS - 1);
701 /* set minvent's obj->no_charge to 0 */
702 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
703 if (Has_contents(obj))
704 picked_container(obj); /* does the right thing */
708 relmon(mtmp, &mydogs); /* move it from map to mydogs */
709 mtmp->mx = mtmp->my = 0; /* avoid mnexto()/MON_AT() problem */
710 mtmp->wormno = num_segs;
711 mtmp->mlstmv = monstermoves;
712 } else if (mtmp->iswiz) {
713 /* we want to be able to find him when his next resurrection
714 chance comes up, but have him resume his present location
715 if player returns to this level before that time */
716 migrate_to_level(mtmp, ledger_no(&u.uz), MIGR_EXACT_XY,
718 } else if (mtmp->mleashed) {
719 /* this can happen if your quest leader ejects you from the
720 "home" level while a leashed pet isn't next to you */
722 pline("%s leash goes slack.", s_suffix(Monnam(mtmp)));
724 pline("%s
\82É
\8c\8b\82Î
\82ê
\82½
\95R
\82Í
\82½
\82é
\82ñ
\82¾
\81D", Monnam(mtmp));
725 m_unleash(mtmp, FALSE);
731 migrate_to_level(mtmp, tolev, xyloc, cc)
732 register struct monst *mtmp;
733 xchar tolev; /* destination level */
734 xchar xyloc; /* MIGR_xxx destination xy location: */
735 coord *cc; /* optional destination coordinates */
737 register struct obj *obj;
740 int num_segs = 0; /* count of worm segments */
743 set_residency(mtmp, TRUE);
747 /* **** NOTE: worm is truncated to # segs = max wormno size **** */
748 cnt = count_wsegs(mtmp);
749 num_segs = min(cnt, MAX_NUM_WORMS - 1);
753 /* set minvent's obj->no_charge to 0 */
754 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
755 if (Has_contents(obj))
756 picked_container(obj); /* does the right thing */
760 if (mtmp->mleashed) {
762 m_unleash(mtmp, TRUE);
764 relmon(mtmp, &migrating_mons); /* move it from map to migrating_mons */
766 new_lev.dnum = ledger_to_dnum((xchar) tolev);
767 new_lev.dlevel = ledger_to_dlev((xchar) tolev);
768 /* overload mtmp->[mx,my], mtmp->[mux,muy], and mtmp->mtrack[] as */
769 /* destination codes (setup flag bits before altering mx or my) */
770 xyflags = (depth(&new_lev) < depth(&u.uz)); /* 1 => up */
771 if (In_W_tower(mtmp->mx, mtmp->my, &u.uz))
773 mtmp->wormno = num_segs;
774 mtmp->mlstmv = monstermoves;
775 mtmp->mtrack[1].x = cc ? cc->x : mtmp->mx;
776 mtmp->mtrack[1].y = cc ? cc->y : mtmp->my;
777 mtmp->mtrack[0].x = xyloc;
778 mtmp->mtrack[0].y = xyflags;
779 mtmp->mux = new_lev.dnum;
780 mtmp->muy = new_lev.dlevel;
781 mtmp->mx = mtmp->my = 0; /* this implies migration */
782 if (mtmp == context.polearm.hitmon)
783 context.polearm.hitmon = NULL;
786 /* return quality of food; the lower the better */
787 /* fungi will eat even tainted food */
791 register struct obj *obj;
793 struct permonst *mptr = mon->data, *fptr = 0;
794 boolean carni = carnivorous(mptr), herbi = herbivorous(mptr), starving;
796 if (is_quest_artifact(obj) || obj_resists(obj, 0, 95))
797 return obj->cursed ? TABU : APPORT;
799 switch (obj->oclass) {
801 if (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG)
802 fptr = &mons[obj->corpsenm];
804 if (obj->otyp == CORPSE && is_rider(fptr))
806 if ((obj->otyp == CORPSE || obj->otyp == EGG) && touch_petrifies(fptr)
807 && !resists_ston(mon))
809 if (!carni && !herbi)
810 return obj->cursed ? UNDEF : APPORT;
812 /* a starving pet will eat almost anything */
814 (mon->mtame && !mon->isminion && EDOG(mon)->mhpmax_penalty);
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;
872 return herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
874 return (mptr->mlet == S_YETI)
876 : (herbi || starving)
882 return (obj->otyp > SLIME_MOLD) ? (carni ? ACCFOOD : MANFOOD)
883 : (herbi ? ACCFOOD : MANFOOD);
886 if (obj->otyp == AMULET_OF_STRANGULATION
887 || obj->otyp == RIN_SLOW_DIGESTION)
889 if (mon_hates_silver(mon) && objects[obj->otyp].oc_material == SILVER)
891 if (mptr == &mons[PM_GELATINOUS_CUBE] && is_organic(obj))
893 if (metallivorous(mptr) && is_metallic(obj)
894 && (is_rustprone(obj) || mptr != &mons[PM_RUST_MONSTER])) {
895 /* Non-rustproofed ferrous based metals are preferred. */
896 return (is_rustprone(obj) && !obj->oerodeproof) ? DOGFOOD
900 && obj->oclass != BALL_CLASS
901 && obj->oclass != CHAIN_CLASS)
910 * With the separate mextra structure added in 3.6.x this always
911 * operates on the original mtmp. It now returns TRUE if the taming
916 register struct monst *mtmp;
917 register struct obj *obj;
919 /* The Wiz, Medusa and the quest nemeses aren't even made peaceful. */
920 if (mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]
921 || (mtmp->data->mflags3 & M3_WANTSARTI))
924 /* worst case, at least it'll be peaceful. */
927 if (flags.moonphase == FULL_MOON && night() && rn2(6) && obj
928 && mtmp->data->mlet == S_DOG)
931 /* If we cannot tame it, at least it's no longer afraid. */
935 /* make grabber let go now, whether it becomes tame or not */
936 if (mtmp == u.ustuck) {
938 expels(mtmp, mtmp->data, TRUE);
939 else if (!(Upolyd && sticks(youmonst.data)))
943 /* feeding it treats makes it tamer */
944 if (mtmp->mtame && obj) {
947 if (mtmp->mcanmove && !mtmp->mconf && !mtmp->meating
948 && ((tasty = dogfood(mtmp, obj)) == DOGFOOD
950 && EDOG(mtmp)->hungrytime <= monstermoves))) {
951 /* pet will "catch" and eat this thrown food */
952 if (canseemon(mtmp)) {
954 (obj->otyp == CORPSE && obj->corpsenm >= LOW_PM
955 && mons[obj->corpsenm].msize > mtmp->data->msize);
957 pline("%s catches %s%s", Monnam(mtmp), the(xname(obj)),
958 !big_corpse ? "." : ", or vice versa!");
960 pline("%s
\82Í%s
\82ð
\82Â
\82©
\82Ü
\82¦
\82½%s",
961 Monnam(mtmp), xname(obj),
962 !big_corpse ? "
\81D" : "
\81C
\82Æ
\8c¾
\82¤
\82æ
\82è
\82»
\82Ì
\8bt
\82©
\81I");
964 } else if (cansee(mtmp->mx, mtmp->my))
966 pline("%s.", Tobjnam(obj, "stop"));
968 pline("%s
\82Í
\8e~
\82Ü
\82Á
\82½
\81D", xname(obj));
969 /* dog_eat expects a floor object */
970 place_object(obj, mtmp->mx, mtmp->my);
971 (void) dog_eat(mtmp, obj, mtmp->mx, mtmp->my, FALSE);
972 /* eating might have killed it, but that doesn't matter here;
973 a non-null result suppresses "miss" message for thrown
974 food and also implies that the object has been deleted */
980 if (mtmp->mtame || !mtmp->mcanmove
981 /* monsters with conflicting structures cannot be tamed */
982 || mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion
983 || is_covetous(mtmp->data) || is_human(mtmp->data)
984 || (is_demon(mtmp->data) && !is_demon(youmonst.data))
985 || (obj && dogfood(mtmp, obj) >= MANFOOD))
988 if (mtmp->m_id == quest_status.leader_m_id)
991 /* add the pet extension */
995 if (obj) { /* thrown food */
996 /* defer eating until the edog extension has been set up */
997 place_object(obj, mtmp->mx, mtmp->my); /* put on floor */
998 /* devour the food (might grow into larger, genocided monster) */
999 if (dog_eat(mtmp, obj, mtmp->mx, mtmp->my, TRUE) == 2)
1000 return TRUE; /* oops, it died... */
1001 /* `obj' is now obsolete */
1004 newsym(mtmp->mx, mtmp->my);
1005 if (attacktype(mtmp->data, AT_WEAP)) {
1006 mtmp->weapon_check = NEED_HTH_WEAPON;
1007 (void) mon_wield_item(mtmp);
1013 * Called during pet revival or pet life-saving.
1014 * If you killed the pet, it revives wild.
1015 * If you abused the pet a lot while alive, it revives wild.
1016 * If you abused the pet at all while alive, it revives untame.
1017 * If the pet wasn't abused and was very tame, it might revive tame.
1020 wary_dog(mtmp, was_dead)
1025 boolean quietly = was_dead;
1027 finish_meating(mtmp);
1031 edog = !mtmp->isminion ? EDOG(mtmp) : 0;
1033 /* if monster was starving when it died, undo that now */
1034 if (edog && edog->mhpmax_penalty) {
1035 mtmp->mhpmax += edog->mhpmax_penalty;
1036 mtmp->mhp += edog->mhpmax_penalty; /* heal it */
1037 edog->mhpmax_penalty = 0;
1040 if (edog && (edog->killed_by_u == 1 || edog->abuse > 2)) {
1041 mtmp->mpeaceful = mtmp->mtame = 0;
1042 if (edog->abuse >= 0 && edog->abuse < 10)
1043 if (!rn2(edog->abuse + 1))
1044 mtmp->mpeaceful = 1;
1045 if (!quietly && cansee(mtmp->mx, mtmp->my)) {
1046 if (haseyes(youmonst.data)) {
1047 if (haseyes(mtmp->data))
1049 pline("%s %s to look you in the %s.", Monnam(mtmp),
1050 mtmp->mpeaceful ? "seems unable" : "refuses",
1053 pline("%s
\82Í
\82 \82È
\82½
\82Ì%s%s
\81D", Monnam(mtmp),
1055 mtmp->mpeaceful ? "
\82ð
\8c©
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\82æ
\82¤
\82¾" :
1056 "
\82©
\82ç
\96Ú
\82ð
\82»
\82ç
\82µ
\82½");
1060 pline("%s avoids your gaze.", Monnam(mtmp));
1062 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\82É
\82ç
\82Ý
\82ð
\89ñ
\94ð
\82µ
\82½
\81D", Monnam(mtmp));
1066 /* chance it goes wild anyway - Pet Sematary */
1067 mtmp->mtame = rn2(mtmp->mtame + 1);
1069 mtmp->mpeaceful = rn2(2);
1073 if (!quietly && canspotmon(mtmp))
1074 pline("%s %s.", Monnam(mtmp),
1075 mtmp->mpeaceful ? "is no longer tame" : "has become feral");
1076 newsym(mtmp->mx, mtmp->my);
1077 /* a life-saved monster might be leashed;
1078 don't leave it that way if it's no longer tame */
1080 m_unleash(mtmp, TRUE);
1081 if (mtmp == u.usteed)
1082 dismount_steed(DISMOUNT_THROWN);
1084 /* it's still a pet; start a clean pet-slate now */
1086 edog->killed_by_u = 0;
1088 edog->ogoal.x = edog->ogoal.y = -1;
1089 if (was_dead || edog->hungrytime < monstermoves + 500L)
1090 edog->hungrytime = monstermoves + 500L;
1092 edog->droptime = 0L;
1093 edog->dropdist = 10000;
1094 edog->whistletime = 0L;
1096 } /* else lifesaved, so retain current values */
1107 if (Aggravate_monster || Conflict)
1112 if (mtmp->mtame && !mtmp->isminion)
1113 EDOG(mtmp)->abuse++;
1115 if (!mtmp->mtame && mtmp->mleashed)
1116 m_unleash(mtmp, TRUE);
1118 /* don't make a sound if pet is in the middle of leaving the level */
1119 /* newsym isn't necessary in this case either */
1120 if (mtmp->mx != 0) {
1121 if (mtmp->mtame && rn2(mtmp->mtame))
1124 growl(mtmp); /* give them a moment's worry */
1127 newsym(mtmp->mx, mtmp->my);