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 otmp
->dknown
= otmp
->bknown
= otmp
->rknown
= 1;
191 put_saddle_on_mon(otmp
, mtmp
);
194 if (!petname_used
++ && *petname
)
195 mtmp
= christen_monst(mtmp
, petname
);
201 /* record `last move time' for all monsters prior to level save so that
202 mon_arrive() can catch up for lost time when they're restored later */
208 /* monst->mlstmv used to be updated every time `monst' actually moved,
209 but that is no longer the case so we just do a blanket assignment */
210 for (mon
= fmon
; mon
; mon
= mon
->nmon
) {
211 if (DEADMONSTER(mon
))
213 mon
->mlstmv
= monstermoves
;
220 register struct monst
*mtmp
, *mtmp0
= 0, *mtmp2
;
224 * First, scan migrating_mons for shopkeepers who want to dismiss Kops,
225 * and scan mydogs for shopkeepers who want to retain kops.
226 * Second, dismiss kops if warranted, making more room for arrival.
227 * Third, place monsters accompanying the hero.
228 * Last, place migrating monsters coming to this level.
230 * Hero might eventually be displaced (due to the third step, but
231 * occurring later), which is the main reason to do the second step
232 * sooner (in turn necessitating the first step, rather than combining
233 * the list scans with monster placement).
236 /* check for returning shk(s) */
237 for (mtmp
= migrating_mons
; mtmp
; mtmp
= mtmp
->nmon
) {
238 if (mtmp
->mux
!= u
.uz
.dnum
|| mtmp
->muy
!= u
.uz
.dlevel
)
241 if (ESHK(mtmp
)->dismiss_kops
) {
242 if (dismissKops
== 0)
244 ESHK(mtmp
)->dismiss_kops
= FALSE
; /* reset */
245 } else if (!mtmp
->mpeaceful
) {
246 /* an unpacified shk is returning; don't dismiss kops
247 even if another pacified one is willing to do so */
249 /* [keep looping; later monsters might need ESHK reset] */
253 /* make the same check for mydogs */
254 for (mtmp
= mydogs
; mtmp
&& dismissKops
>= 0; mtmp
= mtmp
->nmon
) {
256 /* hostile shk might accompany hero [ESHK(mtmp)->dismiss_kops
257 can't be set here; it's only used for migrating_mons] */
258 if (!mtmp
->mpeaceful
)
263 /* when a hostile shopkeeper chases hero to another level
264 and then gets paid off there, get rid of summoned kops
265 here now that he has returned to his shop level */
267 make_happy_shoppers(TRUE
);
269 /* place pets and/or any other monsters who accompany hero */
270 while ((mtmp
= mydogs
) != 0) {
272 mon_arrive(mtmp
, TRUE
);
275 /* time for migrating monsters to arrive */
276 for (mtmp
= migrating_mons
; mtmp
; mtmp
= mtmp2
) {
278 if (mtmp
->mux
== u
.uz
.dnum
&& mtmp
->muy
== u
.uz
.dlevel
) {
279 if (mtmp
== migrating_mons
)
280 migrating_mons
= mtmp
->nmon
;
282 mtmp0
->nmon
= mtmp
->nmon
;
283 mon_arrive(mtmp
, FALSE
);
289 /* called from resurrect() in addition to losedogs() */
291 mon_arrive(mtmp
, with_you
)
296 xchar xlocale
, ylocale
, xyloc
, xyflags
, wander
;
302 set_residency(mtmp
, FALSE
);
304 num_segs
= mtmp
->wormno
;
305 /* baby long worms have no tail so don't use is_longworm() */
306 if (mtmp
->data
== &mons
[PM_LONG_WORM
]) {
307 mtmp
->wormno
= get_wormno();
309 initworm(mtmp
, num_segs
);
313 /* some monsters might need to do something special upon arrival
314 _after_ the current level has been fully set up; see dochug() */
315 mtmp
->mstrategy
|= STRAT_ARRIVE
;
317 /* make sure mnexto(rloc_to(set_apparxy())) doesn't use stale data */
318 mtmp
->mux
= u
.ux
, mtmp
->muy
= u
.uy
;
319 xyloc
= mtmp
->mtrack
[0].x
;
320 xyflags
= mtmp
->mtrack
[0].y
;
321 xlocale
= mtmp
->mtrack
[1].x
;
322 ylocale
= mtmp
->mtrack
[1].y
;
323 memset(mtmp
->mtrack
, 0, sizeof(mtmp
->mtrack
));
325 if (mtmp
== u
.usteed
)
326 return; /* don't place steed on the map */
328 /* When a monster accompanies you, sometimes it will arrive
329 at your intended destination and you'll end up next to
330 that spot. This code doesn't control the final outcome;
331 goto_level(do.c) decides who ends up at your target spot
332 when there is a monster there too. */
333 if (!MON_AT(u
.ux
, u
.uy
)
334 && !rn2(mtmp
->mtame
? 10 : mtmp
->mpeaceful
? 5 : 2))
335 rloc_to(mtmp
, u
.ux
, u
.uy
);
341 * The monster arrived on this level independently of the player.
342 * Its coordinate fields were overloaded for use as flags that
343 * specify its final destination.
346 if (mtmp
->mlstmv
< monstermoves
- 1L) {
347 /* heal monster for time spent in limbo */
348 long nmv
= monstermoves
- 1L - mtmp
->mlstmv
;
350 mon_catchup_elapsed_time(mtmp
, nmv
);
351 mtmp
->mlstmv
= monstermoves
- 1L;
353 /* let monster move a bit on new level (see placement code below) */
354 wander
= (xchar
) min(nmv
, 8);
359 case MIGR_APPROX_XY
: /* {x,y}locale set above */
365 xlocale
= u
.ux
, ylocale
= u
.uy
;
368 xlocale
= xupstair
, ylocale
= yupstair
;
370 case MIGR_STAIRS_DOWN
:
371 xlocale
= xdnstair
, ylocale
= ydnstair
;
374 xlocale
= xupladder
, ylocale
= yupladder
;
376 case MIGR_LADDER_DOWN
:
377 xlocale
= xdnladder
, ylocale
= ydnladder
;
380 xlocale
= sstairs
.sx
, ylocale
= sstairs
.sy
;
383 if (In_endgame(&u
.uz
)) {
384 /* there is no arrival portal for endgame levels */
385 /* BUG[?]: for simplicity, this code relies on the fact
386 that we know that the current endgame levels always
387 build upwards and never have any exclusion subregion
388 inside their TELEPORT_REGION settings. */
389 xlocale
= rn1(updest
.hx
- updest
.lx
+ 1, updest
.lx
);
390 ylocale
= rn1(updest
.hy
- updest
.ly
+ 1, updest
.ly
);
393 /* find the arrival portal */
394 for (t
= ftrap
; t
; t
= t
->ntrap
)
395 if (t
->ttyp
== MAGIC_PORTAL
)
398 xlocale
= t
->tx
, ylocale
= t
->ty
;
401 impossible("mon_arrive: no corresponding portal?");
405 xlocale
= ylocale
= 0;
409 if (xlocale
&& wander
) {
410 /* monster moved a bit; pick a nearby location */
411 /* mnearto() deals w/stone, et al */
412 char *r
= in_rooms(xlocale
, ylocale
, 0);
415 /* somexy() handles irregular rooms */
416 if (somexy(&rooms
[*r
- ROOMOFFSET
], &c
))
417 xlocale
= c
.x
, ylocale
= c
.y
;
419 xlocale
= ylocale
= 0;
420 } else { /* not in a room */
422 i
= max(1, xlocale
- wander
);
423 j
= min(COLNO
- 1, xlocale
+ wander
);
424 xlocale
= rn1(j
- i
, i
);
425 i
= max(0, ylocale
- wander
);
426 j
= min(ROWNO
- 1, ylocale
+ wander
);
427 ylocale
= rn1(j
- i
, i
);
431 mtmp
->mx
= 0; /*(already is 0)*/
434 (void) mnearto(mtmp
, xlocale
, ylocale
, FALSE
);
436 if (!rloc(mtmp
, TRUE
)) {
438 * Failed to place migrating monster,
439 * probably because the level is full.
440 * Dump the monster's cargo and leave the monster dead.
443 while ((obj
= mtmp
->minvent
) != 0) {
444 obj_extract_self(obj
);
445 obj_no_longer_held(obj
);
446 if (obj
->owornmask
& W_WEP
)
447 setmnotwielded(mtmp
, obj
);
449 if (xlocale
&& ylocale
)
450 place_object(obj
, xlocale
, ylocale
);
451 else if (rloco(obj
)) {
452 if (!get_obj_location(obj
, &xlocale
, &ylocale
, 0))
453 impossible("Can't find relocated object.");
456 (void) mkcorpstat(CORPSE
, (struct monst
*) 0, mtmp
->data
, xlocale
,
457 ylocale
, CORPSTAT_NONE
);
463 /* heal monster for time spent elsewhere */
465 mon_catchup_elapsed_time(mtmp
, nmv
)
467 long nmv
; /* number of moves */
469 int imv
= 0; /* avoid zillions of casts and lint warnings */
471 #if defined(DEBUG) || defined(BETA)
472 if (nmv
< 0L) { /* crash likely... */
473 panic("catchup from future time?");
476 } else if (nmv
== 0L) { /* safe, but should'nt happen */
477 impossible("catchup from now?");
480 if (nmv
>= LARGEST_INT
) /* paranoia */
481 imv
= LARGEST_INT
- 1;
485 /* might stop being afraid, blind or frozen */
486 /* set to 1 and allow final decrement in movemon() */
487 if (mtmp
->mblinded
) {
488 if (imv
>= (int) mtmp
->mblinded
)
491 mtmp
->mblinded
-= imv
;
494 if (imv
>= (int) mtmp
->mfrozen
)
497 mtmp
->mfrozen
-= imv
;
499 if (mtmp
->mfleetim
) {
500 if (imv
>= (int) mtmp
->mfleetim
)
503 mtmp
->mfleetim
-= imv
;
506 /* might recover from temporary trouble */
507 if (mtmp
->mtrapped
&& rn2(imv
+ 1) > 40 / 2)
509 if (mtmp
->mconf
&& rn2(imv
+ 1) > 50 / 2)
511 if (mtmp
->mstun
&& rn2(imv
+ 1) > 10 / 2)
514 /* might finish eating or be able to use special ability again */
515 if (imv
> mtmp
->meating
)
516 finish_meating(mtmp
);
518 mtmp
->meating
-= imv
;
519 if (imv
> mtmp
->mspec_used
)
520 mtmp
->mspec_used
= 0;
522 mtmp
->mspec_used
-= imv
;
524 /* reduce tameness for every 150 moves you are separated */
526 int wilder
= (imv
+ 75) / 150;
527 if (mtmp
->mtame
> wilder
)
528 mtmp
->mtame
-= wilder
; /* less tame */
529 else if (mtmp
->mtame
> rn2(wilder
))
530 mtmp
->mtame
= 0; /* untame */
532 mtmp
->mtame
= mtmp
->mpeaceful
= 0; /* hostile! */
534 /* check to see if it would have died as a pet; if so, go wild instead
535 * of dying the next time we call dog_move()
537 if (mtmp
->mtame
&& !mtmp
->isminion
538 && (carnivorous(mtmp
->data
) || herbivorous(mtmp
->data
))) {
539 struct edog
*edog
= EDOG(mtmp
);
541 if ((monstermoves
> edog
->hungrytime
+ 500 && mtmp
->mhp
< 3)
542 || (monstermoves
> edog
->hungrytime
+ 750))
543 mtmp
->mtame
= mtmp
->mpeaceful
= 0;
546 if (!mtmp
->mtame
&& mtmp
->mleashed
) {
547 /* leashed monsters should always be with hero, consequently
548 never losing any time to be accounted for later */
549 impossible("catching up for leashed monster?");
550 m_unleash(mtmp
, FALSE
);
553 /* recover lost hit points */
554 if (!regenerates(mtmp
->data
))
556 if (mtmp
->mhp
+ imv
>= mtmp
->mhpmax
)
557 mtmp
->mhp
= mtmp
->mhpmax
;
562 /* called when you move to another level */
565 boolean pets_only
; /* true for ascension or final escape */
567 register struct monst
*mtmp
, *mtmp2
;
568 register struct obj
*obj
;
572 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp2
) {
574 if (DEADMONSTER(mtmp
))
578 continue; /* reject non-pets */
579 /* don't block pets from accompanying hero's dungeon
580 escape or ascension simply due to mundane trifles;
581 unlike level change for steed, don't bother trying
582 to achieve a normal trap escape first */
589 if (((monnear(mtmp
, u
.ux
, u
.uy
) && levl_follower(mtmp
))
590 /* the wiz will level t-port from anywhere to chase
591 the amulet; if you don't have it, will chase you
592 only if in range. -3. */
593 || (u
.uhave
.amulet
&& mtmp
->iswiz
))
594 && ((!mtmp
->msleeping
&& mtmp
->mcanmove
)
595 /* eg if level teleport or new trap, steed has no control
596 to avoid following */
597 || (mtmp
== u
.usteed
))
598 /* monster won't follow if it hasn't noticed you yet */
599 && !(mtmp
->mstrategy
& STRAT_WAITFORU
)) {
602 (void) mintrap(mtmp
); /* try to escape */
603 if (mtmp
== u
.usteed
) {
604 /* make sure steed is eligible to accompany hero */
605 mtmp
->mtrapped
= 0; /* escape trap */
606 mtmp
->meating
= 0; /* terminate eating */
607 mdrop_special_objs(mtmp
); /* drop Amulet */
608 } else if (mtmp
->meating
|| mtmp
->mtrapped
) {
610 pline("%s is still %s.", Monnam(mtmp
),
611 mtmp
->meating
? "eating" : "trapped");
613 } else if (mon_has_amulet(mtmp
)) {
615 pline("%s seems very disoriented for a moment.",
620 if (mtmp
->mleashed
) {
621 pline("%s leash suddenly comes loose.",
623 ? (mtmp
->female
? "Her" : "His")
625 m_unleash(mtmp
, FALSE
);
627 if (mtmp
== u
.usteed
) {
628 /* can't happen unless someone makes a change
629 which scrambles the stay_behind logic above */
630 impossible("steed left behind?");
631 dismount_steed(DISMOUNT_GENERIC
);
636 set_residency(mtmp
, TRUE
);
640 /* NOTE: worm is truncated to # segs = max wormno size */
641 cnt
= count_wsegs(mtmp
);
642 num_segs
= min(cnt
, MAX_NUM_WORMS
- 1);
647 /* set minvent's obj->no_charge to 0 */
648 for (obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
) {
649 if (Has_contents(obj
))
650 picked_container(obj
); /* does the right thing */
654 relmon(mtmp
, &mydogs
); /* move it from map to mydogs */
655 mtmp
->mx
= mtmp
->my
= 0; /* avoid mnexto()/MON_AT() problem */
656 mtmp
->wormno
= num_segs
;
657 mtmp
->mlstmv
= monstermoves
;
658 } else if (mtmp
->iswiz
) {
659 /* we want to be able to find him when his next resurrection
660 chance comes up, but have him resume his present location
661 if player returns to this level before that time */
662 migrate_to_level(mtmp
, ledger_no(&u
.uz
), MIGR_EXACT_XY
,
664 } else if (mtmp
->mleashed
) {
665 /* this can happen if your quest leader ejects you from the
666 "home" level while a leashed pet isn't next to you */
667 pline("%s leash goes slack.", s_suffix(Monnam(mtmp
)));
668 m_unleash(mtmp
, FALSE
);
674 migrate_to_level(mtmp
, tolev
, xyloc
, cc
)
675 register struct monst
*mtmp
;
676 xchar tolev
; /* destination level */
677 xchar xyloc
; /* MIGR_xxx destination xy location: */
678 coord
*cc
; /* optional destination coordinates */
680 register struct obj
*obj
;
683 int num_segs
= 0; /* count of worm segments */
686 set_residency(mtmp
, TRUE
);
690 /* **** NOTE: worm is truncated to # segs = max wormno size **** */
691 cnt
= count_wsegs(mtmp
);
692 num_segs
= min(cnt
, MAX_NUM_WORMS
- 1);
696 /* set minvent's obj->no_charge to 0 */
697 for (obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
) {
698 if (Has_contents(obj
))
699 picked_container(obj
); /* does the right thing */
703 if (mtmp
->mleashed
) {
705 m_unleash(mtmp
, TRUE
);
707 relmon(mtmp
, &migrating_mons
); /* move it from map to migrating_mons */
709 new_lev
.dnum
= ledger_to_dnum((xchar
) tolev
);
710 new_lev
.dlevel
= ledger_to_dlev((xchar
) tolev
);
711 /* overload mtmp->[mx,my], mtmp->[mux,muy], and mtmp->mtrack[] as */
712 /* destination codes (setup flag bits before altering mx or my) */
713 xyflags
= (depth(&new_lev
) < depth(&u
.uz
)); /* 1 => up */
714 if (In_W_tower(mtmp
->mx
, mtmp
->my
, &u
.uz
))
716 mtmp
->wormno
= num_segs
;
717 mtmp
->mlstmv
= monstermoves
;
718 mtmp
->mtrack
[1].x
= cc
? cc
->x
: mtmp
->mx
;
719 mtmp
->mtrack
[1].y
= cc
? cc
->y
: mtmp
->my
;
720 mtmp
->mtrack
[0].x
= xyloc
;
721 mtmp
->mtrack
[0].y
= xyflags
;
722 mtmp
->mux
= new_lev
.dnum
;
723 mtmp
->muy
= new_lev
.dlevel
;
724 mtmp
->mx
= mtmp
->my
= 0; /* this implies migration */
725 if (mtmp
== context
.polearm
.hitmon
)
726 context
.polearm
.hitmon
= NULL
;
729 /* return quality of food; the lower the better */
730 /* fungi will eat even tainted food */
734 register struct obj
*obj
;
736 struct permonst
*mptr
= mon
->data
, *fptr
= 0;
737 boolean carni
= carnivorous(mptr
), herbi
= herbivorous(mptr
), starving
;
739 if (is_quest_artifact(obj
) || obj_resists(obj
, 0, 95))
740 return obj
->cursed
? TABU
: APPORT
;
742 switch (obj
->oclass
) {
744 if (obj
->otyp
== CORPSE
|| obj
->otyp
== TIN
|| obj
->otyp
== EGG
)
745 fptr
= &mons
[obj
->corpsenm
];
747 if (obj
->otyp
== CORPSE
&& is_rider(fptr
))
749 if ((obj
->otyp
== CORPSE
|| obj
->otyp
== EGG
) && touch_petrifies(fptr
)
750 && !resists_ston(mon
))
752 if (!carni
&& !herbi
)
753 return obj
->cursed
? UNDEF
: APPORT
;
755 /* a starving pet will eat almost anything */
757 (mon
->mtame
&& !mon
->isminion
&& EDOG(mon
)->mhpmax_penalty
);
759 /* ghouls prefer old corpses and unhatchable eggs, yum!
760 they'll eat fresh non-veggy corpses and hatchable eggs
761 when starving; they never eat stone-to-flesh'd meat */
762 if (mptr
== &mons
[PM_GHOUL
]) {
763 if (obj
->otyp
== CORPSE
)
764 return (peek_at_iced_corpse_age(obj
) + 50L <= monstermoves
765 && fptr
!= &mons
[PM_LIZARD
]
766 && fptr
!= &mons
[PM_LICHEN
])
768 : (starving
&& !vegan(fptr
))
771 if (obj
->otyp
== EGG
)
772 return stale_egg(obj
) ? CADAVER
: starving
? ACCFOOD
: POISON
;
781 case HUGE_CHUNK_OF_MEAT
:
782 return carni
? DOGFOOD
: MANFOOD
;
784 return carni
? CADAVER
: MANFOOD
;
786 if ((peek_at_iced_corpse_age(obj
) + 50L <= monstermoves
787 && obj
->corpsenm
!= PM_LIZARD
&& obj
->corpsenm
!= PM_LICHEN
788 && mptr
->mlet
!= S_FUNGUS
)
789 || (acidic(fptr
) && !resists_acid(mon
))
790 || (poisonous(fptr
) && !resists_poison(mon
)))
792 /* turning into slime is preferable to starvation */
793 else if (fptr
== &mons
[PM_GREEN_SLIME
] && !slimeproof(mon
->data
))
794 return starving
? ACCFOOD
: POISON
;
795 else if (vegan(fptr
))
796 return herbi
? CADAVER
: MANFOOD
;
797 /* most humanoids will avoid cannibalism unless starving;
798 arbitrary: elves won't eat other elves even then */
799 else if (humanoid(mptr
) && same_race(mptr
, fptr
)
800 && (!is_undead(mptr
) && fptr
->mlet
!= S_KOBOLD
801 && fptr
->mlet
!= S_ORC
&& fptr
->mlet
!= S_OGRE
))
802 return (starving
&& carni
&& !is_elf(mptr
)) ? ACCFOOD
: TABU
;
804 return carni
? CADAVER
: MANFOOD
;
805 case CLOVE_OF_GARLIC
:
806 return (is_undead(mptr
) || is_vampshifter(mon
))
808 : (herbi
|| starving
)
812 return metallivorous(mptr
) ? ACCFOOD
: MANFOOD
;
815 return herbi
? DOGFOOD
: starving
? ACCFOOD
: MANFOOD
;
817 return (mptr
->mlet
== S_YETI
)
819 : (herbi
|| starving
)
825 return (obj
->otyp
> SLIME_MOLD
) ? (carni
? ACCFOOD
: MANFOOD
)
826 : (herbi
? ACCFOOD
: MANFOOD
);
829 if (obj
->otyp
== AMULET_OF_STRANGULATION
830 || obj
->otyp
== RIN_SLOW_DIGESTION
)
832 if (mon_hates_silver(mon
) && objects
[obj
->otyp
].oc_material
== SILVER
)
834 if (mptr
== &mons
[PM_GELATINOUS_CUBE
] && is_organic(obj
))
836 if (metallivorous(mptr
) && is_metallic(obj
)
837 && (is_rustprone(obj
) || mptr
!= &mons
[PM_RUST_MONSTER
])) {
838 /* Non-rustproofed ferrous based metals are preferred. */
839 return (is_rustprone(obj
) && !obj
->oerodeproof
) ? DOGFOOD
843 && obj
->oclass
!= BALL_CLASS
844 && obj
->oclass
!= CHAIN_CLASS
)
853 * With the separate mextra structure added in 3.6.x this always
854 * operates on the original mtmp. It now returns TRUE if the taming
859 register struct monst
*mtmp
;
860 register struct obj
*obj
;
862 /* The Wiz, Medusa and the quest nemeses aren't even made peaceful. */
863 if (mtmp
->iswiz
|| mtmp
->data
== &mons
[PM_MEDUSA
]
864 || (mtmp
->data
->mflags3
& M3_WANTSARTI
))
867 /* worst case, at least it'll be peaceful. */
870 if (flags
.moonphase
== FULL_MOON
&& night() && rn2(6) && obj
871 && mtmp
->data
->mlet
== S_DOG
)
874 /* If we cannot tame it, at least it's no longer afraid. */
878 /* make grabber let go now, whether it becomes tame or not */
879 if (mtmp
== u
.ustuck
) {
881 expels(mtmp
, mtmp
->data
, TRUE
);
882 else if (!(Upolyd
&& sticks(youmonst
.data
)))
886 /* feeding it treats makes it tamer */
887 if (mtmp
->mtame
&& obj
) {
890 if (mtmp
->mcanmove
&& !mtmp
->mconf
&& !mtmp
->meating
891 && ((tasty
= dogfood(mtmp
, obj
)) == DOGFOOD
893 && EDOG(mtmp
)->hungrytime
<= monstermoves
))) {
894 /* pet will "catch" and eat this thrown food */
895 if (canseemon(mtmp
)) {
897 (obj
->otyp
== CORPSE
&& obj
->corpsenm
>= LOW_PM
898 && mons
[obj
->corpsenm
].msize
> mtmp
->data
->msize
);
899 pline("%s catches %s%s", Monnam(mtmp
), the(xname(obj
)),
900 !big_corpse
? "." : ", or vice versa!");
901 } else if (cansee(mtmp
->mx
, mtmp
->my
))
902 pline("%s.", Tobjnam(obj
, "stop"));
903 /* dog_eat expects a floor object */
904 place_object(obj
, mtmp
->mx
, mtmp
->my
);
905 (void) dog_eat(mtmp
, obj
, mtmp
->mx
, mtmp
->my
, FALSE
);
906 /* eating might have killed it, but that doesn't matter here;
907 a non-null result suppresses "miss" message for thrown
908 food and also implies that the object has been deleted */
914 if (mtmp
->mtame
|| !mtmp
->mcanmove
915 /* monsters with conflicting structures cannot be tamed */
916 || mtmp
->isshk
|| mtmp
->isgd
|| mtmp
->ispriest
|| mtmp
->isminion
917 || is_covetous(mtmp
->data
) || is_human(mtmp
->data
)
918 || (is_demon(mtmp
->data
) && !is_demon(youmonst
.data
))
919 || (obj
&& dogfood(mtmp
, obj
) >= MANFOOD
))
922 if (mtmp
->m_id
== quest_status
.leader_m_id
)
925 /* add the pet extension */
929 if (obj
) { /* thrown food */
930 /* defer eating until the edog extension has been set up */
931 place_object(obj
, mtmp
->mx
, mtmp
->my
); /* put on floor */
932 /* devour the food (might grow into larger, genocided monster) */
933 if (dog_eat(mtmp
, obj
, mtmp
->mx
, mtmp
->my
, TRUE
) == 2)
934 return TRUE
; /* oops, it died... */
935 /* `obj' is now obsolete */
938 newsym(mtmp
->mx
, mtmp
->my
);
939 if (attacktype(mtmp
->data
, AT_WEAP
)) {
940 mtmp
->weapon_check
= NEED_HTH_WEAPON
;
941 (void) mon_wield_item(mtmp
);
947 * Called during pet revival or pet life-saving.
948 * If you killed the pet, it revives wild.
949 * If you abused the pet a lot while alive, it revives wild.
950 * If you abused the pet at all while alive, it revives untame.
951 * If the pet wasn't abused and was very tame, it might revive tame.
954 wary_dog(mtmp
, was_dead
)
959 boolean quietly
= was_dead
;
961 finish_meating(mtmp
);
965 edog
= !mtmp
->isminion
? EDOG(mtmp
) : 0;
967 /* if monster was starving when it died, undo that now */
968 if (edog
&& edog
->mhpmax_penalty
) {
969 mtmp
->mhpmax
+= edog
->mhpmax_penalty
;
970 mtmp
->mhp
+= edog
->mhpmax_penalty
; /* heal it */
971 edog
->mhpmax_penalty
= 0;
974 if (edog
&& (edog
->killed_by_u
== 1 || edog
->abuse
> 2)) {
975 mtmp
->mpeaceful
= mtmp
->mtame
= 0;
976 if (edog
->abuse
>= 0 && edog
->abuse
< 10)
977 if (!rn2(edog
->abuse
+ 1))
979 if (!quietly
&& cansee(mtmp
->mx
, mtmp
->my
)) {
980 if (haseyes(youmonst
.data
)) {
981 if (haseyes(mtmp
->data
))
982 pline("%s %s to look you in the %s.", Monnam(mtmp
),
983 mtmp
->mpeaceful
? "seems unable" : "refuses",
986 pline("%s avoids your gaze.", Monnam(mtmp
));
990 /* chance it goes wild anyway - Pet Sematary */
991 mtmp
->mtame
= rn2(mtmp
->mtame
+ 1);
993 mtmp
->mpeaceful
= rn2(2);
997 if (!quietly
&& canspotmon(mtmp
))
998 pline("%s %s.", Monnam(mtmp
),
999 mtmp
->mpeaceful
? "is no longer tame" : "has become feral");
1000 newsym(mtmp
->mx
, mtmp
->my
);
1001 /* a life-saved monster might be leashed;
1002 don't leave it that way if it's no longer tame */
1004 m_unleash(mtmp
, TRUE
);
1005 if (mtmp
== u
.usteed
)
1006 dismount_steed(DISMOUNT_THROWN
);
1008 /* it's still a pet; start a clean pet-slate now */
1010 edog
->killed_by_u
= 0;
1012 edog
->ogoal
.x
= edog
->ogoal
.y
= -1;
1013 if (was_dead
|| edog
->hungrytime
< monstermoves
+ 500L)
1014 edog
->hungrytime
= monstermoves
+ 500L;
1016 edog
->droptime
= 0L;
1017 edog
->dropdist
= 10000;
1018 edog
->whistletime
= 0L;
1020 } /* else lifesaved, so retain current values */
1031 if (Aggravate_monster
|| Conflict
)
1036 if (mtmp
->mtame
&& !mtmp
->isminion
)
1037 EDOG(mtmp
)->abuse
++;
1039 if (!mtmp
->mtame
&& mtmp
->mleashed
)
1040 m_unleash(mtmp
, TRUE
);
1042 /* don't make a sound if pet is in the middle of leaving the level */
1043 /* newsym isn't necessary in this case either */
1044 if (mtmp
->mx
!= 0) {
1045 if (mtmp
->mtame
&& rn2(mtmp
->mtame
))
1048 growl(mtmp
); /* give them a moment's worry */
1051 newsym(mtmp
->mx
, mtmp
->my
);