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. */
7 STATIC_DCL int NDECL(pet_type);
14 mtmp->mextra = newmextra();
16 EDOG(mtmp) = (struct edog *) alloc(sizeof(struct edog));
17 (void) memset((genericptr_t) EDOG(mtmp), 0, sizeof(struct edog));
25 if (mtmp->mextra && EDOG(mtmp)) {
26 free((genericptr_t) EDOG(mtmp));
27 EDOG(mtmp) = (struct edog *) 0;
34 register struct monst *mtmp;
36 mtmp->mtame = is_domestic(mtmp->data) ? 10 : 5;
39 set_malign(mtmp); /* recalc alignment now that it's tamed */
42 EDOG(mtmp)->droptime = 0;
43 EDOG(mtmp)->dropdist = 10000;
44 EDOG(mtmp)->apport = 10;
45 EDOG(mtmp)->whistletime = 0;
46 EDOG(mtmp)->hungrytime = 1000 + monstermoves;
47 EDOG(mtmp)->ogoal.x = -1; /* force error if used before set */
48 EDOG(mtmp)->ogoal.y = -1;
49 EDOG(mtmp)->abuse = 0;
50 EDOG(mtmp)->revivals = 0;
51 EDOG(mtmp)->mhpmax_penalty = 0;
52 EDOG(mtmp)->killed_by_u = 0;
58 if (urole.petnum != NON_PM)
60 else if (preferred_pet == 'c')
62 else if (preferred_pet == 'd')
65 return rn2(2) ? PM_KITTEN : PM_LITTLE_DOG;
69 make_familiar(otmp, x, y, quietly)
70 register struct obj *otmp;
75 struct monst *mtmp = 0;
76 int chance, trycnt = 100;
79 if (otmp) { /* figurine; otherwise spell */
80 int mndx = otmp->corpsenm;
82 /* activating a figurine provides one way to exceed the
83 maximum number of the target critter created--unless
84 it has a special limit (erinys, Nazgul) */
85 if ((mvitals[mndx].mvflags & G_EXTINCT)
86 && mbirth_limit(mndx) != MAXMONNO) {
88 /* have just been given "You <do something with>
89 the figurine and it transforms." message */
90 pline("... into a pile of dust.");
91 break; /* mtmp is null */
94 pm = &mons[pet_type()];
99 There("seems to be nothing available for a familiar.");
104 mtmp = makemon(pm, x, y, MM_EDOG | MM_IGNOREWATER | NO_MINVENT);
105 if (otmp && !mtmp) { /* monster was genocided or square occupied */
107 pline_The("figurine writhes and then shatters into pieces!");
110 } while (!mtmp && --trycnt > 0);
113 return (struct monst *) 0;
115 if (is_pool(mtmp->mx, mtmp->my) && minliquid(mtmp))
116 return (struct monst *) 0;
120 if (otmp) { /* figurine; resulting monster might not become a pet */
121 chance = rn2(10); /* 0==tame, 1==peaceful, 2==hostile */
123 chance = otmp->blessed ? 0 : !otmp->cursed ? 1 : 2;
124 /* 0,1,2: b=80%,10,10; nc=10%,80,10; c=10%,10,80 */
126 mtmp->mtame = 0; /* not tame after all */
127 if (chance == 2) { /* hostile (cursed figurine) */
129 You("get a bad feeling about this.");
134 /* if figurine has been named, give same name to the monster */
136 mtmp = christen_monst(mtmp, ONAME(otmp));
138 set_malign(mtmp); /* more alignment changes */
139 newsym(mtmp->mx, mtmp->my);
141 /* must wield weapon immediately since pets will otherwise drop it */
142 if (mtmp->mtame && attacktype(mtmp->data, AT_WEAP)) {
143 mtmp->weapon_check = NEED_HTH_WEAPON;
144 (void) mon_wield_item(mtmp);
152 register struct monst *mtmp;
153 register struct obj *otmp;
156 static int petname_used = 0;
158 if (preferred_pet == 'n')
159 return ((struct monst *) 0);
161 pettype = pet_type();
162 if (pettype == PM_LITTLE_DOG)
164 else if (pettype == PM_PONY)
169 /* default pet names */
170 if (!*petname && pettype == PM_LITTLE_DOG) {
171 /* All of these names were for dogs. */
172 if (Role_if(PM_CAVEMAN))
173 petname = "Slasher"; /* The Warrior */
174 if (Role_if(PM_SAMURAI))
175 petname = "Hachi"; /* Shibuya Station */
176 if (Role_if(PM_BARBARIAN))
177 petname = "Idefix"; /* Obelix */
178 if (Role_if(PM_RANGER))
179 petname = "Sirius"; /* Orion's dog */
182 mtmp = makemon(&mons[pettype], u.ux, u.uy, MM_EDOG);
185 return ((struct monst *) 0); /* pets were genocided */
187 context.startingpet_mid = mtmp->m_id;
188 /* Horses already wear a saddle */
189 if (pettype == PM_PONY && !!(otmp = mksobj(SADDLE, TRUE, FALSE))) {
190 if (mpickobj(mtmp, otmp))
191 panic("merged saddle?");
192 mtmp->misc_worn_check |= W_SADDLE;
193 otmp->dknown = otmp->bknown = otmp->rknown = 1;
194 otmp->owornmask = W_SADDLE;
195 otmp->leashmon = mtmp->m_id;
196 update_mon_intrinsics(mtmp, otmp, TRUE, TRUE);
199 if (!petname_used++ && *petname)
200 mtmp = christen_monst(mtmp, petname);
206 /* record `last move time' for all monsters prior to level save so that
207 mon_arrive() can catch up for lost time when they're restored later */
213 /* monst->mlstmv used to be updated every time `monst' actually moved,
214 but that is no longer the case so we just do a blanket assignment */
215 for (mon = fmon; mon; mon = mon->nmon) {
216 if (DEADMONSTER(mon))
218 mon->mlstmv = monstermoves;
225 register struct monst *mtmp, *mtmp0 = 0, *mtmp2;
229 * First, scan migrating_mons for shopkeepers who want to dismiss Kops,
230 * and scan mydogs for shopkeepers who want to retain kops.
231 * Second, dismiss kops if warranted, making more room for arrival.
232 * Third, place monsters accompanying the hero.
233 * Last, place migrating monsters coming to this level.
235 * Hero might eventually be displaced (due to the third step, but
236 * occurring later), which is the main reason to do the second step
237 * sooner (in turn necessitating the first step, rather than combining
238 * the list scans with monster placement).
241 /* check for returning shk(s) */
242 for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) {
243 if (mtmp->mux != u.uz.dnum || mtmp->muy != u.uz.dlevel)
246 if (ESHK(mtmp)->dismiss_kops) {
247 if (dismissKops == 0)
249 ESHK(mtmp)->dismiss_kops = FALSE; /* reset */
250 } else if (!mtmp->mpeaceful) {
251 /* an unpacified shk is returning; don't dismiss kops
252 even if another pacified one is willing to do so */
254 /* [keep looping; later monsters might need ESHK reset] */
258 /* make the same check for mydogs */
259 for (mtmp = mydogs; mtmp && dismissKops >= 0; mtmp = mtmp->nmon) {
261 /* hostile shk might accompany hero [ESHK(mtmp)->dismiss_kops
262 can't be set here; it's only used for migrating_mons] */
263 if (!mtmp->mpeaceful)
268 /* when a hostile shopkeeper chases hero to another level
269 and then gets paid off there, get rid of summoned kops
270 here now that he has returned to his shop level */
272 make_happy_shoppers(TRUE);
274 /* place pets and/or any other monsters who accompany hero */
275 while ((mtmp = mydogs) != 0) {
277 mon_arrive(mtmp, TRUE);
280 /* time for migrating monsters to arrive */
281 for (mtmp = migrating_mons; mtmp; mtmp = mtmp2) {
283 if (mtmp->mux == u.uz.dnum && mtmp->muy == u.uz.dlevel) {
284 if (mtmp == migrating_mons)
285 migrating_mons = mtmp->nmon;
287 mtmp0->nmon = mtmp->nmon;
288 mon_arrive(mtmp, FALSE);
294 /* called from resurrect() in addition to losedogs() */
296 mon_arrive(mtmp, with_you)
301 xchar xlocale, ylocale, xyloc, xyflags, wander;
307 set_residency(mtmp, FALSE);
309 num_segs = mtmp->wormno;
310 /* baby long worms have no tail so don't use is_longworm() */
311 if (mtmp->data == &mons[PM_LONG_WORM]) {
312 mtmp->wormno = get_wormno();
314 initworm(mtmp, num_segs);
318 /* some monsters might need to do something special upon arrival
319 _after_ the current level has been fully set up; see dochug() */
320 mtmp->mstrategy |= STRAT_ARRIVE;
322 /* make sure mnexto(rloc_to(set_apparxy())) doesn't use stale data */
323 mtmp->mux = u.ux, mtmp->muy = u.uy;
324 xyloc = mtmp->mtrack[0].x;
325 xyflags = mtmp->mtrack[0].y;
326 xlocale = mtmp->mtrack[1].x;
327 ylocale = mtmp->mtrack[1].y;
328 mtmp->mtrack[0].x = mtmp->mtrack[0].y = 0;
329 mtmp->mtrack[1].x = mtmp->mtrack[1].y = 0;
331 if (mtmp == u.usteed)
332 return; /* don't place steed on the map */
334 /* When a monster accompanies you, sometimes it will arrive
335 at your intended destination and you'll end up next to
336 that spot. This code doesn't control the final outcome;
337 goto_level(do.c) decides who ends up at your target spot
338 when there is a monster there too. */
339 if (!MON_AT(u.ux, u.uy)
340 && !rn2(mtmp->mtame ? 10 : mtmp->mpeaceful ? 5 : 2))
341 rloc_to(mtmp, u.ux, u.uy);
347 * The monster arrived on this level independently of the player.
348 * Its coordinate fields were overloaded for use as flags that
349 * specify its final destination.
352 if (mtmp->mlstmv < monstermoves - 1L) {
353 /* heal monster for time spent in limbo */
354 long nmv = monstermoves - 1L - mtmp->mlstmv;
356 mon_catchup_elapsed_time(mtmp, nmv);
357 mtmp->mlstmv = monstermoves - 1L;
359 /* let monster move a bit on new level (see placement code below) */
360 wander = (xchar) min(nmv, 8);
365 case MIGR_APPROX_XY: /* {x,y}locale set above */
371 xlocale = u.ux, ylocale = u.uy;
374 xlocale = xupstair, ylocale = yupstair;
376 case MIGR_STAIRS_DOWN:
377 xlocale = xdnstair, ylocale = ydnstair;
380 xlocale = xupladder, ylocale = yupladder;
382 case MIGR_LADDER_DOWN:
383 xlocale = xdnladder, ylocale = ydnladder;
386 xlocale = sstairs.sx, ylocale = sstairs.sy;
389 if (In_endgame(&u.uz)) {
390 /* there is no arrival portal for endgame levels */
391 /* BUG[?]: for simplicity, this code relies on the fact
392 that we know that the current endgame levels always
393 build upwards and never have any exclusion subregion
394 inside their TELEPORT_REGION settings. */
395 xlocale = rn1(updest.hx - updest.lx + 1, updest.lx);
396 ylocale = rn1(updest.hy - updest.ly + 1, updest.ly);
399 /* find the arrival portal */
400 for (t = ftrap; t; t = t->ntrap)
401 if (t->ttyp == MAGIC_PORTAL)
404 xlocale = t->tx, ylocale = t->ty;
407 impossible("mon_arrive: no corresponding portal?");
411 xlocale = ylocale = 0;
415 if (xlocale && wander) {
416 /* monster moved a bit; pick a nearby location */
417 /* mnearto() deals w/stone, et al */
418 char *r = in_rooms(xlocale, ylocale, 0);
421 /* somexy() handles irregular rooms */
422 if (somexy(&rooms[*r - ROOMOFFSET], &c))
423 xlocale = c.x, ylocale = c.y;
425 xlocale = ylocale = 0;
426 } else { /* not in a room */
428 i = max(1, xlocale - wander);
429 j = min(COLNO - 1, xlocale + wander);
430 xlocale = rn1(j - i, i);
431 i = max(0, ylocale - wander);
432 j = min(ROWNO - 1, ylocale + wander);
433 ylocale = rn1(j - i, i);
437 mtmp->mx = 0; /*(already is 0)*/
440 (void) mnearto(mtmp, xlocale, ylocale, FALSE);
442 if (!rloc(mtmp, TRUE)) {
444 * Failed to place migrating monster,
445 * probably because the level is full.
446 * Dump the monster's cargo and leave the monster dead.
449 while ((obj = mtmp->minvent) != 0) {
450 obj_extract_self(obj);
451 obj_no_longer_held(obj);
452 if (obj->owornmask & W_WEP)
453 setmnotwielded(mtmp, obj);
455 if (xlocale && ylocale)
456 place_object(obj, xlocale, ylocale);
457 else if (rloco(obj)) {
458 if (!get_obj_location(obj, &xlocale, &ylocale, 0))
459 impossible("Can't find relocated object.");
462 (void) mkcorpstat(CORPSE, (struct monst *) 0, mtmp->data, xlocale,
463 ylocale, CORPSTAT_NONE);
469 /* heal monster for time spent elsewhere */
471 mon_catchup_elapsed_time(mtmp, nmv)
473 long nmv; /* number of moves */
475 int imv = 0; /* avoid zillions of casts and lint warnings */
477 #if defined(DEBUG) || defined(BETA)
478 if (nmv < 0L) { /* crash likely... */
479 panic("catchup from future time?");
482 } else if (nmv == 0L) { /* safe, but should'nt happen */
483 impossible("catchup from now?");
486 if (nmv >= LARGEST_INT) /* paranoia */
487 imv = LARGEST_INT - 1;
491 /* might stop being afraid, blind or frozen */
492 /* set to 1 and allow final decrement in movemon() */
493 if (mtmp->mblinded) {
494 if (imv >= (int) mtmp->mblinded)
497 mtmp->mblinded -= imv;
500 if (imv >= (int) mtmp->mfrozen)
503 mtmp->mfrozen -= imv;
505 if (mtmp->mfleetim) {
506 if (imv >= (int) mtmp->mfleetim)
509 mtmp->mfleetim -= imv;
512 /* might recover from temporary trouble */
513 if (mtmp->mtrapped && rn2(imv + 1) > 40 / 2)
515 if (mtmp->mconf && rn2(imv + 1) > 50 / 2)
517 if (mtmp->mstun && rn2(imv + 1) > 10 / 2)
520 /* might finish eating or be able to use special ability again */
521 if (imv > mtmp->meating)
522 finish_meating(mtmp);
524 mtmp->meating -= imv;
525 if (imv > mtmp->mspec_used)
526 mtmp->mspec_used = 0;
528 mtmp->mspec_used -= imv;
530 /* reduce tameness for every 150 moves you are separated */
532 int wilder = (imv + 75) / 150;
533 if (mtmp->mtame > wilder)
534 mtmp->mtame -= wilder; /* less tame */
535 else if (mtmp->mtame > rn2(wilder))
536 mtmp->mtame = 0; /* untame */
538 mtmp->mtame = mtmp->mpeaceful = 0; /* hostile! */
540 /* check to see if it would have died as a pet; if so, go wild instead
541 * of dying the next time we call dog_move()
543 if (mtmp->mtame && !mtmp->isminion
544 && (carnivorous(mtmp->data) || herbivorous(mtmp->data))) {
545 struct edog *edog = EDOG(mtmp);
547 if ((monstermoves > edog->hungrytime + 500 && mtmp->mhp < 3)
548 || (monstermoves > edog->hungrytime + 750))
549 mtmp->mtame = mtmp->mpeaceful = 0;
552 if (!mtmp->mtame && mtmp->mleashed) {
553 /* leashed monsters should always be with hero, consequently
554 never losing any time to be accounted for later */
555 impossible("catching up for leashed monster?");
556 m_unleash(mtmp, FALSE);
559 /* recover lost hit points */
560 if (!regenerates(mtmp->data))
562 if (mtmp->mhp + imv >= mtmp->mhpmax)
563 mtmp->mhp = mtmp->mhpmax;
568 /* called when you move to another level */
571 boolean pets_only; /* true for ascension or final escape */
573 register struct monst *mtmp, *mtmp2;
574 register struct obj *obj;
578 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
580 if (DEADMONSTER(mtmp))
584 continue; /* reject non-pets */
585 /* don't block pets from accompanying hero's dungeon
586 escape or ascension simply due to mundane trifles;
587 unlike level change for steed, don't bother trying
588 to achieve a normal trap escape first */
595 if (((monnear(mtmp, u.ux, u.uy) && levl_follower(mtmp))
596 /* the wiz will level t-port from anywhere to chase
597 the amulet; if you don't have it, will chase you
598 only if in range. -3. */
599 || (u.uhave.amulet && mtmp->iswiz))
600 && ((!mtmp->msleeping && mtmp->mcanmove)
601 /* eg if level teleport or new trap, steed has no control
602 to avoid following */
603 || (mtmp == u.usteed))
604 /* monster won't follow if it hasn't noticed you yet */
605 && !(mtmp->mstrategy & STRAT_WAITFORU)) {
608 (void) mintrap(mtmp); /* try to escape */
609 if (mtmp == u.usteed) {
610 /* make sure steed is eligible to accompany hero */
611 mtmp->mtrapped = 0; /* escape trap */
612 mtmp->meating = 0; /* terminate eating */
613 mdrop_special_objs(mtmp); /* drop Amulet */
614 } else if (mtmp->meating || mtmp->mtrapped) {
616 pline("%s is still %s.", Monnam(mtmp),
617 mtmp->meating ? "eating" : "trapped");
619 } else if (mon_has_amulet(mtmp)) {
621 pline("%s seems very disoriented for a moment.",
626 if (mtmp->mleashed) {
627 pline("%s leash suddenly comes loose.",
629 ? (mtmp->female ? "Her" : "His")
631 m_unleash(mtmp, FALSE);
633 if (mtmp == u.usteed) {
634 /* can't happen unless someone makes a change
635 which scrambles the stay_behind logic above */
636 impossible("steed left behind?");
637 dismount_steed(DISMOUNT_GENERIC);
642 set_residency(mtmp, TRUE);
646 /* NOTE: worm is truncated to # segs = max wormno size */
647 cnt = count_wsegs(mtmp);
648 num_segs = min(cnt, MAX_NUM_WORMS - 1);
653 /* set minvent's obj->no_charge to 0 */
654 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
655 if (Has_contents(obj))
656 picked_container(obj); /* does the right thing */
660 relmon(mtmp, &mydogs); /* move it from map to mydogs */
661 mtmp->mx = mtmp->my = 0; /* avoid mnexto()/MON_AT() problem */
662 mtmp->wormno = num_segs;
663 mtmp->mlstmv = monstermoves;
664 } else if (mtmp->iswiz) {
665 /* we want to be able to find him when his next resurrection
666 chance comes up, but have him resume his present location
667 if player returns to this level before that time */
668 migrate_to_level(mtmp, ledger_no(&u.uz), MIGR_EXACT_XY,
670 } else if (mtmp->mleashed) {
671 /* this can happen if your quest leader ejects you from the
672 "home" level while a leashed pet isn't next to you */
673 pline("%s leash goes slack.", s_suffix(Monnam(mtmp)));
674 m_unleash(mtmp, FALSE);
680 migrate_to_level(mtmp, tolev, xyloc, cc)
681 register struct monst *mtmp;
682 xchar tolev; /* destination level */
683 xchar xyloc; /* MIGR_xxx destination xy location: */
684 coord *cc; /* optional destination coordinates */
686 register struct obj *obj;
689 int num_segs = 0; /* count of worm segments */
692 set_residency(mtmp, TRUE);
696 /* **** NOTE: worm is truncated to # segs = max wormno size **** */
697 cnt = count_wsegs(mtmp);
698 num_segs = min(cnt, MAX_NUM_WORMS - 1);
702 /* set minvent's obj->no_charge to 0 */
703 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
704 if (Has_contents(obj))
705 picked_container(obj); /* does the right thing */
709 if (mtmp->mleashed) {
711 m_unleash(mtmp, TRUE);
713 relmon(mtmp, &migrating_mons); /* move it from map to migrating_mons */
715 new_lev.dnum = ledger_to_dnum((xchar) tolev);
716 new_lev.dlevel = ledger_to_dlev((xchar) tolev);
717 /* overload mtmp->[mx,my], mtmp->[mux,muy], and mtmp->mtrack[] as */
718 /* destination codes (setup flag bits before altering mx or my) */
719 xyflags = (depth(&new_lev) < depth(&u.uz)); /* 1 => up */
720 if (In_W_tower(mtmp->mx, mtmp->my, &u.uz))
722 mtmp->wormno = num_segs;
723 mtmp->mlstmv = monstermoves;
724 mtmp->mtrack[1].x = cc ? cc->x : mtmp->mx;
725 mtmp->mtrack[1].y = cc ? cc->y : mtmp->my;
726 mtmp->mtrack[0].x = xyloc;
727 mtmp->mtrack[0].y = xyflags;
728 mtmp->mux = new_lev.dnum;
729 mtmp->muy = new_lev.dlevel;
730 mtmp->mx = mtmp->my = 0; /* this implies migration */
731 if (mtmp == context.polearm.hitmon)
732 context.polearm.hitmon = NULL;
735 /* return quality of food; the lower the better */
736 /* fungi will eat even tainted food */
740 register struct obj *obj;
742 struct permonst *mptr = mon->data, *fptr = 0;
743 boolean carni = carnivorous(mptr), herbi = herbivorous(mptr), starving;
745 if (is_quest_artifact(obj) || obj_resists(obj, 0, 95))
746 return obj->cursed ? TABU : APPORT;
748 switch (obj->oclass) {
750 if (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG)
751 fptr = &mons[obj->corpsenm];
753 if (obj->otyp == CORPSE && is_rider(fptr))
755 if ((obj->otyp == CORPSE || obj->otyp == EGG) && touch_petrifies(fptr)
756 && !resists_ston(mon))
758 if (!carni && !herbi)
759 return obj->cursed ? UNDEF : APPORT;
761 /* a starving pet will eat almost anything */
763 (mon->mtame && !mon->isminion && EDOG(mon)->mhpmax_penalty);
765 /* ghouls prefer old corpses and unhatchable eggs, yum!
766 they'll eat fresh non-veggy corpses and hatchable eggs
767 when starving; they never eat stone-to-flesh'd meat */
768 if (mptr == &mons[PM_GHOUL]) {
769 if (obj->otyp == CORPSE)
770 return (peek_at_iced_corpse_age(obj) + 50L <= monstermoves
771 && fptr != &mons[PM_LIZARD]
772 && fptr != &mons[PM_LICHEN])
774 : (starving && !vegan(fptr))
777 if (obj->otyp == EGG)
778 return stale_egg(obj) ? CADAVER : starving ? ACCFOOD : POISON;
787 case HUGE_CHUNK_OF_MEAT:
788 return carni ? DOGFOOD : MANFOOD;
790 return carni ? CADAVER : MANFOOD;
792 if ((peek_at_iced_corpse_age(obj) + 50L <= monstermoves
793 && obj->corpsenm != PM_LIZARD && obj->corpsenm != PM_LICHEN
794 && mptr->mlet != S_FUNGUS)
795 || (acidic(fptr) && !resists_acid(mon))
796 || (poisonous(fptr) && !resists_poison(mon)))
798 /* turning into slime is preferable to starvation */
799 else if (fptr == &mons[PM_GREEN_SLIME] && !slimeproof(mon->data))
800 return starving ? ACCFOOD : POISON;
801 else if (vegan(fptr))
802 return herbi ? CADAVER : MANFOOD;
803 /* most humanoids will avoid cannibalism unless starving;
804 arbitrary: elves won't eat other elves even then */
805 else if (humanoid(mptr) && same_race(mptr, fptr)
806 && (!is_undead(mptr) && fptr->mlet != S_KOBOLD
807 && fptr->mlet != S_ORC && fptr->mlet != S_OGRE))
808 return (starving && carni && !is_elf(mptr)) ? ACCFOOD : TABU;
810 return carni ? CADAVER : MANFOOD;
811 case CLOVE_OF_GARLIC:
812 return (is_undead(mptr) || is_vampshifter(mon))
814 : (herbi || starving)
818 return metallivorous(mptr) ? ACCFOOD : MANFOOD;
821 return herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
823 return (mptr->mlet == S_YETI)
825 : (herbi || starving)
831 return (obj->otyp > SLIME_MOLD) ? (carni ? ACCFOOD : MANFOOD)
832 : (herbi ? ACCFOOD : MANFOOD);
835 if (obj->otyp == AMULET_OF_STRANGULATION
836 || obj->otyp == RIN_SLOW_DIGESTION)
838 if (mon_hates_silver(mon) && objects[obj->otyp].oc_material == SILVER)
840 if (mptr == &mons[PM_GELATINOUS_CUBE] && is_organic(obj))
842 if (metallivorous(mptr) && is_metallic(obj)
843 && (is_rustprone(obj) || mptr != &mons[PM_RUST_MONSTER])) {
844 /* Non-rustproofed ferrous based metals are preferred. */
845 return (is_rustprone(obj) && !obj->oerodeproof) ? DOGFOOD
849 && obj->oclass != BALL_CLASS
850 && obj->oclass != CHAIN_CLASS)
859 * With the separate mextra structure added in 3.6.x this always
860 * operates on the original mtmp. It now returns TRUE if the taming
865 register struct monst *mtmp;
866 register struct obj *obj;
868 /* The Wiz, Medusa and the quest nemeses aren't even made peaceful. */
869 if (mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]
870 || (mtmp->data->mflags3 & M3_WANTSARTI))
873 /* worst case, at least it'll be peaceful. */
876 if (flags.moonphase == FULL_MOON && night() && rn2(6) && obj
877 && mtmp->data->mlet == S_DOG)
880 /* If we cannot tame it, at least it's no longer afraid. */
884 /* make grabber let go now, whether it becomes tame or not */
885 if (mtmp == u.ustuck) {
887 expels(mtmp, mtmp->data, TRUE);
888 else if (!(Upolyd && sticks(youmonst.data)))
892 /* feeding it treats makes it tamer */
893 if (mtmp->mtame && obj) {
896 if (mtmp->mcanmove && !mtmp->mconf && !mtmp->meating
897 && ((tasty = dogfood(mtmp, obj)) == DOGFOOD
899 && EDOG(mtmp)->hungrytime <= monstermoves))) {
900 /* pet will "catch" and eat this thrown food */
901 if (canseemon(mtmp)) {
903 (obj->otyp == CORPSE && obj->corpsenm >= LOW_PM
904 && mons[obj->corpsenm].msize > mtmp->data->msize);
905 pline("%s catches %s%s", Monnam(mtmp), the(xname(obj)),
906 !big_corpse ? "." : ", or vice versa!");
907 } else if (cansee(mtmp->mx, mtmp->my))
908 pline("%s.", Tobjnam(obj, "stop"));
909 /* dog_eat expects a floor object */
910 place_object(obj, mtmp->mx, mtmp->my);
911 (void) dog_eat(mtmp, obj, mtmp->mx, mtmp->my, FALSE);
912 /* eating might have killed it, but that doesn't matter here;
913 a non-null result suppresses "miss" message for thrown
914 food and also implies that the object has been deleted */
920 if (mtmp->mtame || !mtmp->mcanmove
921 /* monsters with conflicting structures cannot be tamed */
922 || mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion
923 || is_covetous(mtmp->data) || is_human(mtmp->data)
924 || (is_demon(mtmp->data) && !is_demon(youmonst.data))
925 || (obj && dogfood(mtmp, obj) >= MANFOOD))
928 if (mtmp->m_id == quest_status.leader_m_id)
931 /* add the pet extension */
935 if (obj) { /* thrown food */
936 /* defer eating until the edog extension has been set up */
937 place_object(obj, mtmp->mx, mtmp->my); /* put on floor */
938 /* devour the food (might grow into larger, genocided monster) */
939 if (dog_eat(mtmp, obj, mtmp->mx, mtmp->my, TRUE) == 2)
940 return TRUE; /* oops, it died... */
941 /* `obj' is now obsolete */
944 newsym(mtmp->mx, mtmp->my);
945 if (attacktype(mtmp->data, AT_WEAP)) {
946 mtmp->weapon_check = NEED_HTH_WEAPON;
947 (void) mon_wield_item(mtmp);
953 * Called during pet revival or pet life-saving.
954 * If you killed the pet, it revives wild.
955 * If you abused the pet a lot while alive, it revives wild.
956 * If you abused the pet at all while alive, it revives untame.
957 * If the pet wasn't abused and was very tame, it might revive tame.
960 wary_dog(mtmp, was_dead)
965 boolean quietly = was_dead;
967 finish_meating(mtmp);
971 edog = !mtmp->isminion ? EDOG(mtmp) : 0;
973 /* if monster was starving when it died, undo that now */
974 if (edog && edog->mhpmax_penalty) {
975 mtmp->mhpmax += edog->mhpmax_penalty;
976 mtmp->mhp += edog->mhpmax_penalty; /* heal it */
977 edog->mhpmax_penalty = 0;
980 if (edog && (edog->killed_by_u == 1 || edog->abuse > 2)) {
981 mtmp->mpeaceful = mtmp->mtame = 0;
982 if (edog->abuse >= 0 && edog->abuse < 10)
983 if (!rn2(edog->abuse + 1))
985 if (!quietly && cansee(mtmp->mx, mtmp->my)) {
986 if (haseyes(youmonst.data)) {
987 if (haseyes(mtmp->data))
988 pline("%s %s to look you in the %s.", Monnam(mtmp),
989 mtmp->mpeaceful ? "seems unable" : "refuses",
992 pline("%s avoids your gaze.", Monnam(mtmp));
996 /* chance it goes wild anyway - Pet Sematary */
997 mtmp->mtame = rn2(mtmp->mtame + 1);
999 mtmp->mpeaceful = rn2(2);
1003 if (!quietly && canspotmon(mtmp))
1004 pline("%s %s.", Monnam(mtmp),
1005 mtmp->mpeaceful ? "is no longer tame" : "has become feral");
1006 newsym(mtmp->mx, mtmp->my);
1007 /* a life-saved monster might be leashed;
1008 don't leave it that way if it's no longer tame */
1010 m_unleash(mtmp, TRUE);
1011 if (mtmp == u.usteed)
1012 dismount_steed(DISMOUNT_THROWN);
1014 /* it's still a pet; start a clean pet-slate now */
1016 edog->killed_by_u = 0;
1018 edog->ogoal.x = edog->ogoal.y = -1;
1019 if (was_dead || edog->hungrytime < monstermoves + 500L)
1020 edog->hungrytime = monstermoves + 500L;
1022 edog->droptime = 0L;
1023 edog->dropdist = 10000;
1024 edog->whistletime = 0L;
1026 } /* else lifesaved, so retain current values */
1037 if (Aggravate_monster || Conflict)
1042 if (mtmp->mtame && !mtmp->isminion)
1043 EDOG(mtmp)->abuse++;
1045 if (!mtmp->mtame && mtmp->mleashed)
1046 m_unleash(mtmp, TRUE);
1048 /* don't make a sound if pet is in the middle of leaving the level */
1049 /* newsym isn't necessary in this case either */
1050 if (mtmp->mx != 0) {
1051 if (mtmp->mtame && rn2(mtmp->mtame))
1054 growl(mtmp); /* give them a moment's worry */
1057 newsym(mtmp->mx, mtmp->my);