1 /* NetHack 3.6 steed.c $NHDT-Date: 1575245090 2019/12/02 00:04:50 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.68 $ */
2 /* Copyright (c) Kevin Hugo, 1998-1999. */
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-2023 */
8 /* JNetHack may be freely redistributed. See license for details. */
12 /* Monsters that might be ridden */
13 static NEARDATA const char steeds[] = { S_QUADRUPED, S_UNICORN, S_ANGEL,
14 S_CENTAUR, S_DRAGON, S_JABBERWOCK,
17 STATIC_DCL boolean FDECL(landing_spot, (coord *, int, int));
18 STATIC_DCL void FDECL(maybewakesteed, (struct monst *));
20 /* caller has decided that hero can't reach something while mounted */
25 You("aren't skilled enough to reach from %s.", y_monnam(u.usteed));
27 You("
\82Ü
\82¾
\8f\
\95ª
\82É
\8bZ
\97Ê
\82ð
\90Ï
\82ñ
\82Å
\82¢
\82È
\82¢
\82Ì
\82Å
\81C%s
\82©
\82ç
\93Í
\82©
\82È
\82¢
\81D", y_monnam(u.usteed));
30 /*** Putting the saddle on ***/
32 /* Can this monster wear a saddle? */
37 struct permonst *ptr = mtmp->data;
39 return (index(steeds, ptr->mlet) && (ptr->msize >= MZ_MEDIUM)
40 && (!humanoid(ptr) || ptr->mlet == S_CENTAUR) && !amorphous(ptr)
41 && !noncorporeal(ptr) && !is_whirly(ptr) && !unsolid(ptr));
56 /* Select an animal */
57 if (u.uswallow || Underwater || !getdir((char *) 0)) {
63 pline("Saddle yourself? Very funny...");
65 pline("
\8e©
\95ª
\8e©
\90g
\82É
\88Æ
\81H
\82¨
\82à
\82µ
\82ë
\82¢
\81D
\81D
\81D");
68 if (!isok(u.ux + u.dx, u.uy + u.dy)
69 || !(mtmp = m_at(u.ux + u.dx, u.uy + u.dy)) || !canspotmon(mtmp)) {
71 pline("I see nobody there.");
73 pline("
\82»
\82±
\82É
\82Í
\92N
\82à
\82¢
\82È
\82¢
\82æ
\82¤
\82É
\8c©
\82¦
\82é
\81D");
77 /* Is this a valid monster? */
78 if (mtmp->misc_worn_check & W_SADDLE || which_armor(mtmp, W_SADDLE)) {
80 pline("%s doesn't need another one.", Monnam(mtmp));
82 pline("%s
\82Í
\82à
\82¤
\88Æ
\82ª
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é
\81D", Monnam(mtmp));
86 if (touch_petrifies(ptr) && !uarmg && !Stone_resistance) {
90 You("touch %s.", mon_nam(mtmp));
92 You("%s
\82É
\90G
\82ê
\82½
\81D", mon_nam(mtmp));
93 if (!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) {
95 Sprintf(kbuf, "attempting to saddle %s", an(mtmp->data->mname));
97 Sprintf(kbuf, "%s
\82É
\88Æ
\82ð
\8eæ
\82è
\82Â
\82¯
\82æ
\82¤
\82Æ
\82µ
\82Ä", mtmp->data->mname);
101 if (ptr == &mons[PM_INCUBUS] || ptr == &mons[PM_SUCCUBUS]) {
103 pline("Shame on you!");
105 pline("
\92p
\82ð
\92m
\82ê
\81I");
106 exercise(A_WIS, FALSE);
109 if (mtmp->isminion || mtmp->isshk || mtmp->ispriest || mtmp->isgd
112 pline("I think %s would mind.", mon_nam(mtmp));
114 pline("%s
\82Í
\8c\99\82ª
\82Á
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", mon_nam(mtmp));
117 if (!can_saddle(mtmp)) {
119 You_cant("saddle such a creature.");
121 You("
\82»
\82Ì
\90¶
\82«
\95¨
\82É
\88Æ
\82Í
\82Æ
\82è
\82Â
\82¯
\82ç
\82ê
\82È
\82¢
\81D");
125 /* Calculate your chance */
126 chance = ACURR(A_DEX) + ACURR(A_CHA) / 2 + 2 * mtmp->mtame;
127 chance += u.ulevel * (mtmp->mtame ? 20 : 5);
129 chance -= 10 * mtmp->m_lev;
130 if (Role_if(PM_KNIGHT))
132 switch (P_SKILL(P_RIDING)) {
147 if (Confusion || Fumbling || Glib)
149 else if (uarmg && (s = OBJ_DESCR(objects[uarmg->otyp])) != (char *) 0
151 && !strncmp(s, "riding ", 7))
153 && !STRNCMP2(s, "
\8fæ
\94n
\97p
\82Ì"))
154 /* Bonus for wearing "riding" (but not fumbling) gloves */
156 else if (uarmf && (s = OBJ_DESCR(objects[uarmf->otyp])) != (char *) 0
158 && !strncmp(s, "riding ", 7))
160 && !STRNCMP2(s, "
\8fæ
\94n
\97p
\82Ì"))
161 /* ... or for "riding boots" */
166 /* [intended] steed becomes alert if possible */
167 maybewakesteed(mtmp);
169 /* Make the attempt */
170 if (rn2(100) < chance) {
172 You("put the saddle on %s.", mon_nam(mtmp));
174 You("
\88Æ
\82ð%s
\82É
\8eæ
\82è
\82Â
\82¯
\82½
\81D", mon_nam(mtmp));
176 remove_worn_item(otmp, FALSE);
178 put_saddle_on_mon(otmp, mtmp);
181 pline("%s resists!", Monnam(mtmp));
183 pline("%s
\82Í
\8b\91\94Û
\82µ
\82½
\81I", Monnam(mtmp));
188 put_saddle_on_mon(saddle, mtmp)
192 if (!can_saddle(mtmp) || which_armor(mtmp, W_SADDLE))
194 if (mpickobj(mtmp, saddle))
195 panic("merged saddle?");
196 mtmp->misc_worn_check |= W_SADDLE;
197 saddle->owornmask = W_SADDLE;
198 saddle->leashmon = mtmp->m_id;
199 update_mon_intrinsics(mtmp, saddle, TRUE, FALSE);
202 /*** Riding the monster ***/
204 /* Can we ride this monster? Caller should also check can_saddle() */
209 return (mtmp->mtame && humanoid(youmonst.data)
210 && !verysmall(youmonst.data) && !bigmonst(youmonst.data)
211 && (!Underwater || is_swimmer(mtmp->data)));
217 boolean forcemount = FALSE;
220 dismount_steed(DISMOUNT_BYCHOICE);
221 } else if (getdir((char *) 0) && isok(u.ux + u.dx, u.uy + u.dy)) {
223 if (wizard && yn("Force the mount to succeed?") == 'y')
225 if (wizard && yn("
\96³
\97\9d\96î
\97\9d\90¬
\8c÷
\82³
\82¹
\82Ü
\82·
\82©
\81H") == 'y')
227 return (mount_steed(m_at(u.ux + u.dx, u.uy + u.dy), forcemount));
234 /* Start riding, with the given monster */
236 mount_steed(mtmp, force)
237 struct monst *mtmp; /* The animal */
238 boolean force; /* Quietly force this animal */
242 struct permonst *ptr;
247 You("are already riding %s.", mon_nam(u.usteed));
249 You("
\82à
\82¤%s
\82É
\8fæ
\82Á
\82Ä
\82¢
\82é
\81D", mon_nam(u.usteed));
253 /* Is the player in the right form? */
254 if (Hallucination && !force) {
256 pline("Maybe you should find a designated driver.");
258 pline("
\82¨
\82»
\82ç
\82
\82 \82È
\82½
\82Í
\8ew
\92è
\83h
\83\89\83C
\83o
\81[
\82ð
\92T
\82·
\82×
\82«
\82¾
\82ë
\82¤
\81D");
262 /* While riding Wounded_legs refers to the steed's,
263 * not the hero's legs.
264 * That opens up a potential abuse where the player
265 * can mount a steed, then dismount immediately to
266 * heal leg damage, because leg damage is always
267 * healed upon dismount (Wounded_legs context switch).
268 * By preventing a hero with Wounded_legs from
269 * mounting a steed, the potential for abuse is
270 * reduced. However, dismounting still immediately
271 * heals the steed's wounded legs. [In 3.4.3 and
272 * earlier, that unintentionally made the hero's
273 * temporary 1 point Dex loss become permanent.]
277 Your("%s are in no shape for riding.", makeplural(body_part(LEG)));
279 pline("%s
\82ð
\89ö
\89ä
\82µ
\82Ä
\82¢
\82é
\82Ì
\82Å
\8fæ
\82ê
\82È
\82¢
\81D", makeplural(body_part(LEG)));
280 if (force && wizard && yn("Heal your legs?") == 'y')
281 HWounded_legs = EWounded_legs = 0L;
286 if (Upolyd && (!humanoid(youmonst.data) || verysmall(youmonst.data)
287 || bigmonst(youmonst.data) || slithy(youmonst.data))) {
289 You("won't fit on a saddle.");
291 You("
\88Æ
\82É
\8d\87\82í
\82È
\82¢
\81D");
294 if (!force && (near_capacity() > SLT_ENCUMBER)) {
296 You_cant("do that while carrying so much stuff.");
298 You("
\91ò
\8eR
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¨
\82è
\8fo
\97\88\82È
\82¢
\81D");
302 /* Can the player reach and see the monster? */
303 if (!mtmp || (!force && ((Blind && !Blind_telepat) || mtmp->mundetected
304 || M_AP_TYPE(mtmp) == M_AP_FURNITURE
305 || M_AP_TYPE(mtmp) == M_AP_OBJECT))) {
307 pline("I see nobody there.");
309 pline("
\82»
\82±
\82É
\82Í
\89½
\82à
\8c©
\82¦
\82È
\82¢
\81D");
312 if (mtmp->data == &mons[PM_LONG_WORM]
313 && (u.ux + u.dx != mtmp->mx || u.uy + u.dy != mtmp->my)) {
314 /* As of 3.6.2: test_move(below) is used to check for trying to mount
315 diagonally into or out of a doorway or through a tight squeeze;
316 attempting to mount a tail segment when hero was not adjacent
317 to worm's head could trigger an impossible() in worm_cross()
318 called from test_move(), so handle not-on-head before that */
320 You("couldn't ride %s, let alone its tail.", a_monnam(mtmp));
322 You("%s
\82É
\82Í
\8fæ
\82ê
\82È
\82¢
\81C
\82à
\82¿
\82ë
\82ñ
\90K
\94ö
\82É
\82à
\8fæ
\82ê
\82È
\82¢
\81D", a_monnam(mtmp));
325 if (u.uswallow || u.ustuck || u.utrap || Punished
326 || !test_move(u.ux, u.uy, mtmp->mx - u.ux, mtmp->my - u.uy,
328 if (Punished || !(u.uswallow || u.ustuck || u.utrap))
330 You("are unable to swing your %s over.", body_part(LEG));
332 You("
\88Æ
\82ð
\82Ü
\82½
\82®
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81D");
335 You("are stuck here for now.");
337 You("
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é
\82Ì
\82Å
\8fo
\97\88\82È
\82¢
\81D");
341 /* Is this a valid monster? */
342 otmp = which_armor(mtmp, W_SADDLE);
345 pline("%s is not saddled.", Monnam(mtmp));
347 pline("%s
\82É
\82Í
\88Æ
\82ª
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82È
\82¢
\81D", Monnam(mtmp));
351 if (touch_petrifies(ptr) && !Stone_resistance) {
355 You("touch %s.", mon_nam(mtmp));
357 You("%s
\82É
\90G
\82ê
\82½
\81D", mon_nam(mtmp));
359 Sprintf(kbuf, "attempting to ride %s", an(mtmp->data->mname));
361 Sprintf(kbuf, "%s
\82É
\8fæ
\82ë
\82¤
\82Æ
\82µ
\82Ä", a_monnam(mtmp));
364 if (!mtmp->mtame || mtmp->isminion) {
366 pline("I think %s would mind.", mon_nam(mtmp));
368 pline("%s
\82Í
\8c\99\82ª
\82Á
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", mon_nam(mtmp));
371 if (mtmp->mtrapped) {
372 struct trap *t = t_at(mtmp->mx, mtmp->my);
375 You_cant("mount %s while %s's trapped in %s.", mon_nam(mtmp),
376 mhe(mtmp), an(defsyms[trap_to_defsym(t->ttyp)].explanation));
378 You("%s
\82É
\95ß
\82Ü
\82Á
\82Ä
\82¢
\82é%s
\82É
\82Í
\8fæ
\82ê
\82È
\82¢
\81D",
379 defsyms[trap_to_defsym(t->ttyp)].explanation, mon_nam(mtmp));
384 if (!force && !Role_if(PM_KNIGHT) && !(--mtmp->mtame)) {
386 newsym(mtmp->mx, mtmp->my);
388 pline("%s resists%s!", Monnam(mtmp),
389 mtmp->mleashed ? " and its leash comes off" : "");
391 pline("%s
\82Í
\8b\91\94Û%s
\81I", Monnam(mtmp),
392 mtmp->mleashed ? "
\82µ
\82Ä
\81C
\95R
\82ð
\82Í
\82¸
\82µ
\82½" : "
\82µ
\82½");
395 m_unleash(mtmp, FALSE);
398 if (!force && Underwater && !is_swimmer(ptr)) {
400 You_cant("ride that creature while under %s.",
402 #else /*
\82Æ
\82è
\82 \82¦
\82¸
\90\85\82¾
\82¯*/
403 You("
\90\85\92\86\82Å
\8fæ
\82é
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D");
407 if (!can_saddle(mtmp) || !can_ride(mtmp)) {
409 You_cant("ride such a creature.");
411 You("
\82»
\82Ì
\90¶
\82«
\95¨
\82É
\8fæ
\82é
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D");
415 /* Is the player impaired? */
416 if (!force && !is_floater(ptr) && !is_flyer(ptr) && Levitation
419 You("cannot reach %s.", mon_nam(mtmp));
421 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81D", mon_nam(mtmp));
424 if (!force && uarm && is_metallic(uarm) && greatest_erosion(uarm)) {
426 Your("%s armor is too stiff to be able to mount %s.",
427 uarm->oeroded ? "rusty" : "corroded", mon_nam(mtmp));
429 Your("%s
\8aZ
\82Í
\83M
\83V
\83M
\83V
\82¢
\82Á
\82Ä
\82¨
\82è%s
\82É
\8fæ
\82ê
\82È
\82¢
\81D",
430 uarm->oeroded ? "
\8eK
\82Ñ
\82½" : "
\95\85\90H
\82µ
\82½", mon_nam(mtmp));
435 && (Confusion || Fumbling || Glib || Wounded_legs || otmp->cursed
436 || (u.ulevel + mtmp->mtame < rnd(MAXULEV / 2 + 5)))) {
439 pline("%s slips away from you.", Monnam(mtmp));
441 pline("%s
\82Í
\82 \82È
\82½
\82©
\82ç
\82Í
\82È
\82ê
\82Ä
\82¢
\82Á
\82½
\81D", Monnam(mtmp));
445 You("slip while trying to get on %s.", mon_nam(mtmp));
447 You("%s
\82É
\8fæ
\82ë
\82¤
\82Æ
\82µ
\82Ä
\82·
\82×
\82Á
\82½
\81D", mon_nam(mtmp));
450 Sprintf(buf, "slipped while mounting %s",
452 Sprintf(buf, "%s
\82É
\8fæ
\82ë
\82¤
\82Æ
\82µ
\82Ä
\82·
\82×
\82è
\97\8e\82¿
\82Ä",
453 /* "a saddled mumak" or "a saddled pony called Dobbin" */
454 x_monnam(mtmp, ARTICLE_A, (char *) 0,
455 SUPPRESS_IT | SUPPRESS_INVISIBLE
456 | SUPPRESS_HALLUCINATION,
459 losehp(Maybe_Half_Phys(rn1(5, 10)), buf, NO_KILLER_PREFIX);
461 losehp(Maybe_Half_Phys(rn1(5, 10)), buf, KILLED_BY);
467 maybewakesteed(mtmp);
469 if (Levitation && !is_floater(ptr) && !is_flyer(ptr))
470 /* Must have Lev_at_will at this point */
472 pline("%s magically floats up!", Monnam(mtmp));
474 pline("%s
\82Í
\96\82\96@
\82Ì
\97Í
\82Å
\95\82\82¢
\82½
\81I", Monnam(mtmp));
476 You("mount %s.", mon_nam(mtmp));
478 You("%s
\82É
\8fæ
\82Á
\82½
\81D", mon_nam(mtmp));
481 You("and %s take flight together.", mon_nam(mtmp));
483 You("
\82Æ%s
\82Í
\88ê
\8f\8f\82É
\8bó
\82ð
\94ò
\82ñ
\82¾
\81D", mon_nam(mtmp));
485 /* setuwep handles polearms differently when you're mounted */
486 if (uwep && is_pole(uwep))
489 remove_monster(mtmp->mx, mtmp->my);
490 teleds(mtmp->mx, mtmp->my, TRUE);
495 /* You and your steed have moved */
502 /* It takes many turns of riding to exercise skill */
503 if (++u.urideturns >= 100) {
505 use_skill(P_RIDING, 1);
510 /* The player kicks or whips the steed */
517 /* role.c Gender.he
\82Ì
\92l
\82ª
\83R
\83s
\81[
\82³
\82ê
\82é */
523 /* [ALI] Various effects of kicking sleeping/paralyzed steeds */
524 if (u.usteed->msleeping || !u.usteed->mcanmove) {
525 /* We assume a message has just been output of the form
526 * "You kick <steed>."
528 Strcpy(He, mhe(u.usteed));
530 if ((u.usteed->mcanmove || u.usteed->mfrozen) && !rn2(2)) {
531 if (u.usteed->mcanmove)
532 u.usteed->msleeping = 0;
533 else if (u.usteed->mfrozen > 2)
534 u.usteed->mfrozen -= 2;
536 u.usteed->mfrozen = 0;
537 u.usteed->mcanmove = 1;
539 if (u.usteed->msleeping || !u.usteed->mcanmove)
541 pline("%s stirs.", He);
543 pline("%s
\82Í
\90g
\82¶
\82ë
\82¬
\82µ
\82½
\81D", He);
547 pline("%s rouses %sself!", He, mhim(u.usteed));
549 pline("%s
\82Í
\95±
\8bN
\82µ
\82½
\81I", He);
553 pline("%s does not respond.", He);
555 pline("%s
\82Í
\94½
\89\9e\82µ
\82È
\82¢
\81D", He);
560 /* Make the steed less tame and check if it resists */
563 if (!u.usteed->mtame && u.usteed->mleashed)
564 m_unleash(u.usteed, TRUE);
566 || (u.ulevel + u.usteed->mtame < rnd(MAXULEV / 2 + 5))) {
567 newsym(u.usteed->mx, u.usteed->my);
568 dismount_steed(DISMOUNT_THROWN);
573 pline("%s gallops!", Monnam(u.usteed));
575 pline("%s
\82Í
\91¬
\91«
\82É
\82È
\82Á
\82½
\81I", Monnam(u.usteed));
576 u.ugallop += rn1(20, 30);
581 * Try to find a dismount point adjacent to the steed's location.
582 * If all else fails, try enexto(). Use enexto() as a last resort because
583 * enexto() chooses its point randomly, possibly even outside the
584 * room's walls, which is not what we want.
585 * Adapted from mail daemon code.
588 landing_spot(spot, reason, forceit)
589 coord *spot; /* landing position (we fill it in) */
593 int i = 0, x, y, distance, min_distance = -1;
594 boolean found = FALSE;
597 /* avoid known traps (i == 0) and boulders, but allow them as a backup */
598 if (reason != DISMOUNT_BYCHOICE || Stunned || Confusion || Fumbling)
600 for (; !found && i < 2; ++i) {
601 for (x = u.ux - 1; x <= u.ux + 1; x++)
602 for (y = u.uy - 1; y <= u.uy + 1; y++) {
603 if (!isok(x, y) || (x == u.ux && y == u.uy))
606 if (accessible(x, y) && !MON_AT(x, y)) {
607 distance = distu(x, y);
608 if (min_distance < 0 || distance < min_distance
609 || (distance == min_distance && rn2(2))) {
610 if (i > 0 || (((t = t_at(x, y)) == 0 || !t->tseen)
611 && (!sobj_at(BOULDER, x, y)
612 || throws_rocks(youmonst.data)))) {
615 min_distance = distance;
623 /* If we didn't find a good spot and forceit is on, try enexto(). */
624 if (forceit && min_distance < 0
625 && !enexto(spot, u.ux, u.uy, youmonst.data))
631 /* Stop riding the current steed */
633 dismount_steed(reason)
634 int reason; /* Player was thrown off etc. */
640 const char *verb = "fall";
642 const char *verb = "
\97\8e\82¿
\82½";
643 boolean repair_leg_damage = (Wounded_legs != 0L);
644 unsigned save_utrap = u.utrap;
645 boolean have_spot = landing_spot(&cc, reason, 0);
647 mtmp = u.usteed; /* make a copy of steed pointer */
649 if (!mtmp) /* Just return silently */
652 /* Check the reason for dismounting */
653 otmp = which_armor(mtmp, W_SADDLE);
655 case DISMOUNT_THROWN:
659 verb = "
\82Ó
\82è
\97\8e\82³
\82ê
\82½";
663 You("%s off of %s!", verb, mon_nam(mtmp));
665 You("%s
\82©
\82ç%s
\81I", mon_nam(mtmp), verb);
667 have_spot = landing_spot(&cc, reason, 1);
669 losehp(Maybe_Half_Phys(rn1(10, 10)), "riding accident", KILLED_BY_AN);
671 losehp(Maybe_Half_Phys(rn1(10, 10)), "
\8bR
\8fæ
\8e\96\8cÌ
\82Å", KILLED_BY_AN);
672 set_wounded_legs(BOTH_SIDES, (int) HWounded_legs + rn1(5, 5));
673 repair_leg_damage = FALSE;
677 You("can no longer ride %s.", mon_nam(u.usteed));
679 You("%s
\82É
\8fæ
\82Á
\82Ä
\82ç
\82ê
\82È
\82¢
\81D", mon_nam(u.usteed));
681 have_spot = landing_spot(&cc, reason, 1);
683 case DISMOUNT_ENGULFED:
684 /* caller displays message */
687 /* hero has just died... */
689 case DISMOUNT_GENERIC:
690 /* no messages, just make it so */
692 case DISMOUNT_BYCHOICE:
694 if (otmp && otmp->cursed) {
696 You("can't. The saddle %s cursed.",
697 otmp->bknown ? "is" : "seems to be");
699 You("
\8d~
\82è
\82ç
\82ê
\82È
\82¢
\81D
\88Æ
\82Í
\8eô
\82í
\82ê
\82Ä
\82¢
\82é%s
\81D",
700 otmp->bknown ? "" : "
\82æ
\82¤
\82¾");
702 otmp->bknown = 1; /* ok to skip set_bknown() here */
707 You("can't. There isn't anywhere for you to stand.");
709 pline("
\82 \82È
\82½
\82Ì
\97§
\82Â
\8fê
\8f\8a\82ª
\82È
\82¢
\82Ì
\82Å
\8d~
\82è
\82ç
\82ê
\82È
\82¢
\81D");
712 if (!has_mname(mtmp)) {
714 pline("You've been through the dungeon on %s with no name.",
716 pline("
\82 \82È
\82½
\82Í
\96¼
\91O
\82Ì
\82È
\82¢%s
\82Æ
\8b¤
\82É
\96À
\8b{
\93à
\82É
\82¢
\82é
\81D",
717 an(mtmp->data->mname));
720 pline("It felt good to get out of the rain.");
722 pline("
\89J
\82ª
\8d~
\82ç
\82È
\82¢
\82Ì
\82Æ
\82¢
\82¤
\82Ì
\82Í
\82¢
\82¢
\8bC
\95ª
\82¾
\82Á
\82½
\81D");
725 You("dismount %s.", mon_nam(mtmp));
727 You("%s
\82©
\82ç
\8d~
\82è
\82½
\81D", mon_nam(mtmp));
729 /* While riding, Wounded_legs refers to the steed's legs;
730 after dismounting, it reverts to the hero's legs. */
731 if (repair_leg_damage)
734 /* Release the steed and saddle */
738 * rloc(), rloc_to(), and monkilled()->mondead()->m_detach() all
739 * expect mtmp to be on the map or else have mtmp->mx be 0, but
740 * setting the latter to 0 here would interfere with dropping
741 * the saddle. Prior to 3.6.2, being off the map didn't matter.
743 * place_monster() expects mtmp to be alive and not be u.usteed.
745 * Unfortunately, <u.ux,u.uy> (former steed's implicit location)
746 * might now be occupied by an engulfer, so we can't just put mtmp
747 * at that spot. An engulfer's previous spot will be unoccupied
748 * but we don't know where that was and even if we did, it might
749 * be hostile terrain.
751 steedcc.x = u.ux, steedcc.y = u.uy;
752 if (m_at(u.ux, u.uy)) {
753 /* hero's spot has a monster in it; hero must have been plucked
754 from saddle as engulfer moved into his spot--other dismounts
755 shouldn't run into this situation; find nearest viable spot */
756 if (!enexto(&steedcc, u.ux, u.uy, mtmp->data)
757 /* no spot? must have been engulfed by a lurker-above over
758 water or lava; try requesting a location for a flyer */
759 && !enexto(&steedcc, u.ux, u.uy, &mons[PM_BAT]))
760 /* still no spot; last resort is any spot within bounds */
761 (void) enexto(&steedcc, u.ux, u.uy, &mons[PM_GHOST]);
763 if (!m_at(steedcc.x, steedcc.y)) {
765 mtmp->mhp = 0; /* make sure it isn't negative */
766 mtmp->mhp++; /* force at least one hit point, possibly resurrecting */
767 place_monster(mtmp, steedcc.x, steedcc.y);
768 mtmp->mhp--; /* take the extra hit point away: cancel resurrection */
770 impossible("Dismounting: can't place former steed on map.");
773 if (!DEADMONSTER(mtmp)) {
774 /* if for bones, there's no reason to place the hero;
775 we want to make room for potential ghost, so move steed */
776 if (reason == DISMOUNT_BONES) {
777 /* move the steed to an adjacent square */
778 if (enexto(&cc, u.ux, u.uy, mtmp->data))
779 rloc_to(mtmp, cc.x, cc.y);
780 else /* evidently no room nearby; move steed elsewhere */
781 (void) rloc(mtmp, FALSE);
785 /* Set hero's and/or steed's positions. Try moving the hero first. */
786 if (!u.uswallow && !u.ustuck && have_spot) {
787 struct permonst *mdat = mtmp->data;
789 /* The steed may drop into water/lava */
790 if (!is_flyer(mdat) && !is_floater(mdat) && !is_clinger(mdat)) {
791 if (is_pool(u.ux, u.uy)) {
794 pline("%s falls into the %s!", Monnam(mtmp),
796 pline("%s
\82Í%s
\82É
\97\8e\82¿
\82½
\81I", Monnam(mtmp),
797 surface(u.ux, u.uy));
798 if (!is_swimmer(mdat) && !amphibious(mdat)) {
802 } else if (is_lava(u.ux, u.uy)) {
804 pline("%s is pulled into the %s!", Monnam(mtmp),
807 pline("%s
\82Í%s
\82Ì
\92\86\82É
\82Ð
\82Á
\82Ï
\82ç
\82ê
\82½
\81I", Monnam(mtmp),
808 hliquid("
\97n
\8aâ"));
810 if (!likes_lava(mdat)) {
816 /* Steed dismounting consists of two steps: being moved to another
817 * square, and descending to the floor. We have functions to do
818 * each of these activities, but they're normally called
819 * individually and include an attempt to look at or pick up the
820 * objects on the floor:
821 * teleds() --> spoteffects() --> pickup()
822 * float_down() --> pickup()
823 * We use this kludge to make sure there is only one such attempt.
825 * Clearly this is not the best way to do it. A full fix would
826 * involve having these functions not call pickup() at all,
828 * calling them first and calling pickup() afterwards. But it
829 * would take a lot of work to keep this change from having any
830 * unforeseen side effects (for instance, you would no longer be
831 * able to walk onto a square with a hole, and autopickup before
832 * falling into the hole).
834 /* [ALI] No need to move the player if the steed died. */
835 if (!DEADMONSTER(mtmp)) {
836 /* Keep steed here, move the player to cc;
837 * teleds() clears u.utrap
839 in_steed_dismounting = TRUE;
840 teleds(cc.x, cc.y, TRUE);
841 in_steed_dismounting = FALSE;
843 /* Put your steed in your trap */
845 (void) mintrap(mtmp);
848 /* Couldn't move hero... try moving the steed. */
849 } else if (enexto(&cc, u.ux, u.uy, mtmp->data)) {
850 /* Keep player here, move the steed to cc */
851 rloc_to(mtmp, cc.x, cc.y);
852 /* Player stays put */
854 /* Otherwise, kill the steed. */
856 if (reason == DISMOUNT_BYCHOICE) {
857 /* [un]#ride: hero gets credit/blame for killing steed */
861 /* other dismount: kill former steed with no penalty;
862 damage type is just "neither AD_DGST nor -AD_RBRE" */
863 monkilled(mtmp, "", -AD_PHYS);
866 } /* !DEADMONST(mtmp) */
868 /* usually return the hero to the surface */
869 if (reason != DISMOUNT_ENGULFED && reason != DISMOUNT_BONES) {
870 in_steed_dismounting = TRUE;
871 (void) float_down(0L, W_SADDLE);
872 in_steed_dismounting = FALSE;
874 (void) encumber_msg();
875 vision_full_recalc = 1;
878 /* polearms behave differently when not mounted */
879 if (uwep && is_pole(uwep))
884 /* when attempting to saddle or mount a sleeping steed, try to wake it up
885 (for the saddling case, it won't be u.usteed yet) */
887 maybewakesteed(steed)
890 int frozen = (int) steed->mfrozen;
891 boolean wasimmobile = steed->msleeping || !steed->mcanmove;
893 steed->msleeping = 0;
895 frozen = (frozen + 1) / 2; /* half */
896 /* might break out of timed sleep or paralysis */
901 /* didn't awake, but remaining duration is halved */
902 steed->mfrozen = frozen;
905 if (wasimmobile && !steed->msleeping && steed->mcanmove)
907 pline("%s wakes up.", Monnam(steed));
909 pline("%s
\82Í
\8bN
\82«
\82½
\81D", Monnam(steed));
910 /* regardless of waking, terminate any meal in progress */
911 finish_meating(steed);
914 /* decide whether hero's steed is able to move;
915 doesn't check for holding traps--those affect the hero directly */
917 stucksteed(checkfeeding)
918 boolean checkfeeding;
920 struct monst *steed = u.usteed;
923 /* check whether steed can move */
924 if (steed->msleeping || !steed->mcanmove) {
926 pline("%s won't move!", upstart(y_monnam(steed)));
928 pline("%s
\82Í
\93®
\82¯
\82È
\82¢
\81I", y_monnam(steed));
931 /* optionally check whether steed is in the midst of a meal */
932 if (checkfeeding && steed->meating) {
934 pline("%s is still eating.", upstart(y_monnam(steed)));
936 pline("%s
\82Í
\82Ü
\82¾
\90H
\82×
\82Ä
\82¢
\82é
\81D", y_monnam(steed));
944 place_monster(mon, x, y)
948 struct monst *othermon;
949 const char *monnm, *othnm;
953 /* normal map bounds are <1..COLNO-1,0..ROWNO-1> but sometimes
954 vault guards (either living or dead) are parked at <0,0> */
955 if (!isok(x, y) && (x != 0 || y != 0 || !mon->isgd)) {
957 impossible("trying to place %s at <%d,%d> mstate:%lx on %s",
958 minimal_monnam(mon, TRUE), x, y, mon->mstate, buf);
962 /* special case is for convoluted vault guard handling */
963 || (DEADMONSTER(mon) && !(mon->isgd && x == 0 && y == 0))) {
965 impossible("placing %s onto map, mstate:%lx, on %s?",
966 (mon == u.usteed) ? "steed" : "defunct monster",
970 if ((othermon = level.monsters[x][y]) != 0) {
972 monnm = minimal_monnam(mon, FALSE);
973 othnm = (mon != othermon) ? minimal_monnam(othermon, TRUE) : "itself";
974 impossible("placing %s over %s at <%d,%d>, mstates:%lx %lx on %s?",
975 monnm, othnm, x, y, othermon->mstate, mon->mstate, buf);
977 mon->mx = x, mon->my = y;
978 level.monsters[x][y] = mon;
979 mon->mstate &= ~(MON_OFFMAP | MON_MIGRATING | MON_LIMBO | MON_BUBBLEMOVE
980 | MON_ENDGAME_FREE | MON_ENDGAME_MIGR);