OSDN Git Service

fix #36579
[jnethack/source.git] / src / steed.c
1 /* NetHack 3.6  steed.c $NHDT-Date: 1445906867 2015/10/27 00:47:47 $  $NHDT-Branch: master $:$NHDT-Revision: 1.47 $ */
2 /* Copyright (c) Kevin Hugo, 1998-1999. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
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. */
9
10 #include "hack.h"
11
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,
15                                         '\0' };
16
17 STATIC_DCL boolean FDECL(landing_spot, (coord *, int, int));
18 STATIC_DCL void FDECL(maybewakesteed, (struct monst *));
19
20 /* caller has decided that hero can't reach something while mounted */
21 void
22 rider_cant_reach()
23 {
24 /*JP
25     You("aren't skilled enough to reach from %s.", y_monnam(u.usteed));
26 */
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));
28 }
29
30 /*** Putting the saddle on ***/
31
32 /* Can this monster wear a saddle? */
33 boolean
34 can_saddle(mtmp)
35 struct monst *mtmp;
36 {
37     struct permonst *ptr = mtmp->data;
38
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));
42 }
43
44 int
45 use_saddle(otmp)
46 struct obj *otmp;
47 {
48     struct monst *mtmp;
49     struct permonst *ptr;
50     int chance;
51     const char *s;
52
53     if (!u_handsy())
54         return 0;
55
56     /* Select an animal */
57     if (u.uswallow || Underwater || !getdir((char *) 0)) {
58         pline1(Never_mind);
59         return 0;
60     }
61     if (!u.dx && !u.dy) {
62 /*JP
63         pline("Saddle yourself?  Very funny...");
64 */
65         pline("\8e©\95ª\8e©\90g\82É\88Æ\81H\82¨\82à\82µ\82ë\82¢\81D\81D\81D");
66         return 0;
67     }
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)) {
70 /*JP
71         pline("I see nobody there.");
72 */
73         pline("\82»\82±\82É\82Í\92N\82à\82¢\82È\82¢\82æ\82¤\82É\8c©\82¦\82é\81D");
74         return 1;
75     }
76
77     /* Is this a valid monster? */
78     if (mtmp->misc_worn_check & W_SADDLE || which_armor(mtmp, W_SADDLE)) {
79 /*JP
80         pline("%s doesn't need another one.", Monnam(mtmp));
81 */
82         pline("%s\82Í\82à\82¤\88Æ\82ª\8eæ\82è\82Â\82¯\82ç\82ê\82Ä\82¢\82é\81D", Monnam(mtmp));
83         return 1;
84     }
85     ptr = mtmp->data;
86     if (touch_petrifies(ptr) && !uarmg && !Stone_resistance) {
87         char kbuf[BUFSZ];
88
89 /*JP
90         You("touch %s.", mon_nam(mtmp));
91 */
92         You("%s\82É\90G\82ê\82½\81D", mon_nam(mtmp));
93         if (!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) {
94 /*JP
95             Sprintf(kbuf, "attempting to saddle %s", an(mtmp->data->mname));
96 */
97             Sprintf(kbuf, "%s\82É\88Æ\82ð\8eæ\82è\82Â\82¯\82æ\82¤\82Æ\82µ\82Ä", mtmp->data->mname);
98             instapetrify(kbuf);
99         }
100     }
101     if (ptr == &mons[PM_INCUBUS] || ptr == &mons[PM_SUCCUBUS]) {
102 /*JP
103         pline("Shame on you!");
104 */
105         pline("\92p\82ð\92m\82ê\81I");
106         exercise(A_WIS, FALSE);
107         return 1;
108     }
109     if (mtmp->isminion || mtmp->isshk || mtmp->ispriest || mtmp->isgd
110         || mtmp->iswiz) {
111 /*JP
112         pline("I think %s would mind.", mon_nam(mtmp));
113 */
114         pline("%s\82Í\8c\99\82ª\82Á\82Ä\82¢\82é\82æ\82¤\82¾\81D", mon_nam(mtmp));
115         return 1;
116     }
117     if (!can_saddle(mtmp)) {
118 /*JP
119         You_cant("saddle such a creature.");
120 */
121         You("\82»\82Ì\90\82«\95¨\82É\88Æ\82Í\82Æ\82è\82Â\82¯\82ç\82ê\82È\82¢\81D");
122         return 1;
123     }
124
125     /* Calculate your chance */
126     chance = ACURR(A_DEX) + ACURR(A_CHA) / 2 + 2 * mtmp->mtame;
127     chance += u.ulevel * (mtmp->mtame ? 20 : 5);
128     if (!mtmp->mtame)
129         chance -= 10 * mtmp->m_lev;
130     if (Role_if(PM_KNIGHT))
131         chance += 20;
132     switch (P_SKILL(P_RIDING)) {
133     case P_ISRESTRICTED:
134     case P_UNSKILLED:
135     default:
136         chance -= 20;
137         break;
138     case P_BASIC:
139         break;
140     case P_SKILLED:
141         chance += 15;
142         break;
143     case P_EXPERT:
144         chance += 30;
145         break;
146     }
147     if (Confusion || Fumbling || Glib)
148         chance -= 20;
149     else if (uarmg && (s = OBJ_DESCR(objects[uarmg->otyp])) != (char *) 0
150 /*JP
151              && !strncmp(s, "riding ", 7))
152 */
153              && !strncmp(s, "\8fæ\94n\97p\82Ì", 8))
154         /* Bonus for wearing "riding" (but not fumbling) gloves */
155         chance += 10;
156     else if (uarmf && (s = OBJ_DESCR(objects[uarmf->otyp])) != (char *) 0
157 /*JP
158              && !strncmp(s, "riding ", 7))
159 */
160              && !strncmp(s, "\8fæ\94n\97p\82Ì", 8))
161         /* ... or for "riding boots" */
162         chance += 10;
163     if (otmp->cursed)
164         chance -= 50;
165
166     /* [intended] steed becomes alert if possible */
167     maybewakesteed(mtmp);
168
169     /* Make the attempt */
170     if (rn2(100) < chance) {
171 /*JP
172         You("put the saddle on %s.", mon_nam(mtmp));
173 */
174         You("\88Æ\82ð%s\82É\8eæ\82è\82Â\82¯\82½\81D", mon_nam(mtmp));
175         if (otmp->owornmask)
176             remove_worn_item(otmp, FALSE);
177         freeinv(otmp);
178         /* mpickobj may free otmp it if merges, but we have already
179            checked for a saddle above, so no merger should happen */
180         (void) mpickobj(mtmp, otmp);
181         mtmp->misc_worn_check |= W_SADDLE;
182         otmp->owornmask = W_SADDLE;
183         otmp->leashmon = mtmp->m_id;
184         update_mon_intrinsics(mtmp, otmp, TRUE, FALSE);
185     } else
186 /*JP
187         pline("%s resists!", Monnam(mtmp));
188 */
189         pline("%s\82Í\8b\91\94Û\82µ\82½\81I", Monnam(mtmp));
190     return 1;
191 }
192
193 /*** Riding the monster ***/
194
195 /* Can we ride this monster?  Caller should also check can_saddle() */
196 boolean
197 can_ride(mtmp)
198 struct monst *mtmp;
199 {
200     return (mtmp->mtame && humanoid(youmonst.data)
201             && !verysmall(youmonst.data) && !bigmonst(youmonst.data)
202             && (!Underwater || is_swimmer(mtmp->data)));
203 }
204
205 int
206 doride()
207 {
208     boolean forcemount = FALSE;
209
210     if (u.usteed) {
211         dismount_steed(DISMOUNT_BYCHOICE);
212     } else if (getdir((char *) 0) && isok(u.ux + u.dx, u.uy + u.dy)) {
213 /*JP
214         if (wizard && yn("Force the mount to succeed?") == 'y')
215 */
216         if (wizard && yn("\96³\97\9d\96î\97\9d\90¬\8c÷\82³\82¹\82Ü\82·\82©\81H") == 'y')
217             forcemount = TRUE;
218         return (mount_steed(m_at(u.ux + u.dx, u.uy + u.dy), forcemount));
219     } else {
220         return 0;
221     }
222     return 1;
223 }
224
225 /* Start riding, with the given monster */
226 boolean
227 mount_steed(mtmp, force)
228 struct monst *mtmp; /* The animal */
229 boolean force;      /* Quietly force this animal */
230 {
231     struct obj *otmp;
232     char buf[BUFSZ];
233     struct permonst *ptr;
234
235     /* Sanity checks */
236     if (u.usteed) {
237 /*JP
238         You("are already riding %s.", mon_nam(u.usteed));
239 */
240         You("\82à\82¤%s\82É\8fæ\82Á\82Ä\82¢\82é\81D", mon_nam(u.usteed));
241         return (FALSE);
242     }
243
244     /* Is the player in the right form? */
245     if (Hallucination && !force) {
246 #if 0 /*JP*/
247         pline("Maybe you should find a designated driver.");
248 #else
249         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");
250 #endif
251         return (FALSE);
252     }
253     /* While riding Wounded_legs refers to the steed's,
254      * not the hero's legs.
255      * That opens up a potential abuse where the player
256      * can mount a steed, then dismount immediately to
257      * heal leg damage, because leg damage is always
258      * healed upon dismount (Wounded_legs context switch).
259      * By preventing a hero with Wounded_legs from
260      * mounting a steed, the potential for abuse is
261      * reduced.  However, dismounting still immediately
262      * heals the steed's wounded legs.  [In 3.4.3 and
263      * earlier, that unintentionally made the hero's
264      * temporary 1 point Dex loss become permanent.]
265      */
266     if (Wounded_legs) {
267 /*JP
268         Your("%s are in no shape for riding.", makeplural(body_part(LEG)));
269 */
270         pline("%s\82ð\89ö\89ä\82µ\82Ä\82¢\82é\82Ì\82Å\8fæ\82ê\82È\82¢\81D", makeplural(body_part(LEG)));
271         if (force && wizard && yn("Heal your legs?") == 'y')
272             HWounded_legs = EWounded_legs = 0;
273         else
274             return (FALSE);
275     }
276
277     if (Upolyd && (!humanoid(youmonst.data) || verysmall(youmonst.data)
278                    || bigmonst(youmonst.data) || slithy(youmonst.data))) {
279 /*JP
280         You("won't fit on a saddle.");
281 */
282         You("\88Æ\82É\8d\87\82í\82È\82¢\81D");
283         return (FALSE);
284     }
285     if (!force && (near_capacity() > SLT_ENCUMBER)) {
286 /*JP
287         You_cant("do that while carrying so much stuff.");
288 */
289         You("\91ò\8eR\95¨\82ð\8e\9d\82¿\82·\82¬\82Ä\82¨\82è\8fo\97\88\82È\82¢\81D");
290         return (FALSE);
291     }
292
293     /* Can the player reach and see the monster? */
294     if (!mtmp || (!force && ((Blind && !Blind_telepat) || mtmp->mundetected
295                              || mtmp->m_ap_type == M_AP_FURNITURE
296                              || mtmp->m_ap_type == M_AP_OBJECT))) {
297 /*JP
298         pline("I see nobody there.");
299 */
300         pline("\82»\82±\82É\82Í\89½\82à\8c©\82¦\82È\82¢\81D");
301         return (FALSE);
302     }
303     if (u.uswallow || u.ustuck || u.utrap || Punished
304         || !test_move(u.ux, u.uy, mtmp->mx - u.ux, mtmp->my - u.uy,
305                       TEST_MOVE)) {
306         if (Punished || !(u.uswallow || u.ustuck || u.utrap))
307 /*JP
308             You("are unable to swing your %s over.", body_part(LEG));
309 */
310             You("\88Æ\82ð\82Ü\82½\82®\82±\82Æ\82ª\82Å\82«\82È\82¢\81D");
311         else
312 /*JP
313             You("are stuck here for now.");
314 */
315             You("\82Í\82Ü\82Á\82Ä\82¢\82é\82Ì\82Å\8fo\97\88\82È\82¢\81D");
316         return (FALSE);
317     }
318
319     /* Is this a valid monster? */
320     otmp = which_armor(mtmp, W_SADDLE);
321     if (!otmp) {
322 /*JP
323         pline("%s is not saddled.", Monnam(mtmp));
324 */
325         pline("%s\82É\82Í\88Æ\82ª\8eæ\82è\82Â\82¯\82ç\82ê\82Ä\82¢\82È\82¢\81D", Monnam(mtmp));
326         return (FALSE);
327     }
328     ptr = mtmp->data;
329     if (touch_petrifies(ptr) && !Stone_resistance) {
330         char kbuf[BUFSZ];
331
332 /*JP
333         You("touch %s.", mon_nam(mtmp));
334 */
335         You("%s\82É\90G\82ê\82½\81D", mon_nam(mtmp));
336 /*JP
337         Sprintf(kbuf, "attempting to ride %s", an(mtmp->data->mname));
338 */
339         Sprintf(kbuf, "%s\82É\8fæ\82ë\82¤\82Æ\82µ\82Ä", a_monnam(mtmp));
340         instapetrify(kbuf);
341     }
342     if (!mtmp->mtame || mtmp->isminion) {
343 /*JP
344         pline("I think %s would mind.", mon_nam(mtmp));
345 */
346         pline("%s\82Í\8c\99\82ª\82Á\82Ä\82¢\82é\82æ\82¤\82¾\81D", mon_nam(mtmp));
347         return (FALSE);
348     }
349     if (mtmp->mtrapped) {
350         struct trap *t = t_at(mtmp->mx, mtmp->my);
351
352 #if 0 /*JP*/
353         You_cant("mount %s while %s's trapped in %s.", mon_nam(mtmp),
354                  mhe(mtmp), an(defsyms[trap_to_defsym(t->ttyp)].explanation));
355 #else
356         You("%s\82É\95ß\82Ü\82Á\82Ä\82¢\82é%s\82É\82Í\8fæ\82ê\82È\82¢\81D",
357             defsyms[trap_to_defsym(t->ttyp)].explanation, mon_nam(mtmp));
358 #endif
359         return (FALSE);
360     }
361
362     if (!force && !Role_if(PM_KNIGHT) && !(--mtmp->mtame)) {
363         /* no longer tame */
364         newsym(mtmp->mx, mtmp->my);
365 #if 0 /*JP*/
366         pline("%s resists%s!", Monnam(mtmp),
367               mtmp->mleashed ? " and its leash comes off" : "");
368 #else
369         pline("%s\82Í\8b\91\94Û%s\81I", Monnam(mtmp),
370               mtmp->mleashed ? "\82µ\82Ä\81C\95R\82ð\82Í\82¸\82µ\82½" : "\82µ\82½");
371 #endif
372         if (mtmp->mleashed)
373             m_unleash(mtmp, FALSE);
374         return (FALSE);
375     }
376     if (!force && Underwater && !is_swimmer(ptr)) {
377 /*JP
378         You_cant("ride that creature while under water.");
379 */
380         You("\90\85\92\86\82Å\8fæ\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
381         return (FALSE);
382     }
383     if (!can_saddle(mtmp) || !can_ride(mtmp)) {
384 /*JP
385         You_cant("ride such a creature.");
386 */
387         You("\82»\82Ì\90\82«\95¨\82É\8fæ\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
388         return (0);
389     }
390
391     /* Is the player impaired? */
392     if (!force && !is_floater(ptr) && !is_flyer(ptr) && Levitation
393         && !Lev_at_will) {
394 /*JP
395         You("cannot reach %s.", mon_nam(mtmp));
396 */
397         You("%s\82É\93Í\82©\82È\82¢\81D", mon_nam(mtmp));
398         return (FALSE);
399     }
400     if (!force && uarm && is_metallic(uarm) && greatest_erosion(uarm)) {
401 #if 0 /*JP*/
402         Your("%s armor is too stiff to be able to mount %s.",
403              uarm->oeroded ? "rusty" : "corroded", mon_nam(mtmp));
404 #else
405         Your("%s\8aZ\82Í\83M\83V\83M\83V\82¢\82Á\82Ä\82¨\82è%s\82É\8fæ\82ê\82È\82¢\81D",
406              uarm->oeroded ? "\8eK\82Ñ\82½" : "\95\85\90H\82µ\82½", mon_nam(mtmp));
407 #endif
408         return (FALSE);
409     }
410     if (!force
411         && (Confusion || Fumbling || Glib || Wounded_legs || otmp->cursed
412             || (u.ulevel + mtmp->mtame < rnd(MAXULEV / 2 + 5)))) {
413         if (Levitation) {
414 /*JP
415             pline("%s slips away from you.", Monnam(mtmp));
416 */
417             pline("%s\82Í\82 \82È\82½\82©\82ç\82Í\82È\82ê\82Ä\82¢\82Á\82½\81D", Monnam(mtmp));
418             return FALSE;
419         }
420 /*JP
421         You("slip while trying to get on %s.", mon_nam(mtmp));
422 */
423         You("%s\82É\8fæ\82ë\82¤\82Æ\82µ\82Ä\82·\82×\82Á\82½\81D", mon_nam(mtmp));
424
425 /*JP
426         Sprintf(buf, "slipped while mounting %s",
427 */
428         Sprintf(buf, "%s\82É\8fæ\82ë\82¤\82Æ\82µ\82Ä\82·\82×\82è\97\8e\82¿\82Ä",
429                 /* "a saddled mumak" or "a saddled pony called Dobbin" */
430                 x_monnam(mtmp, ARTICLE_A, (char *) 0,
431                          SUPPRESS_IT | SUPPRESS_INVISIBLE
432                              | SUPPRESS_HALLUCINATION,
433                          TRUE));
434 #if 0 /*JP*/
435         losehp(Maybe_Half_Phys(rn1(5, 10)), buf, NO_KILLER_PREFIX);
436 #else
437         losehp(Maybe_Half_Phys(rn1(5, 10)), buf, KILLED_BY);
438 #endif
439         return (FALSE);
440     }
441
442     /* Success */
443     maybewakesteed(mtmp);
444     if (!force) {
445         if (Levitation && !is_floater(ptr) && !is_flyer(ptr))
446             /* Must have Lev_at_will at this point */
447 /*JP
448             pline("%s magically floats up!", Monnam(mtmp));
449 */
450             pline("%s\82Í\96\82\96@\82Ì\97Í\82Å\95\82\82¢\82½\81I", Monnam(mtmp));
451 /*JP
452         You("mount %s.", mon_nam(mtmp));
453 */
454         You("%s\82É\8fæ\82Á\82½\81D", mon_nam(mtmp));
455     }
456     /* setuwep handles polearms differently when you're mounted */
457     if (uwep && is_pole(uwep))
458         unweapon = FALSE;
459     u.usteed = mtmp;
460     remove_monster(mtmp->mx, mtmp->my);
461     teleds(mtmp->mx, mtmp->my, TRUE);
462     return (TRUE);
463 }
464
465 /* You and your steed have moved */
466 void
467 exercise_steed()
468 {
469     if (!u.usteed)
470         return;
471
472     /* It takes many turns of riding to exercise skill */
473     if (u.urideturns++ >= 100) {
474         u.urideturns = 0;
475         use_skill(P_RIDING, 1);
476     }
477     return;
478 }
479
480 /* The player kicks or whips the steed */
481 void
482 kick_steed()
483 {
484 #if 0 /*JP*/
485     char He[4];
486 #else
487     /* role.c Gender.he \82Ì\92l\82ª\83R\83s\81[\82³\82ê\82é */
488     char He[16];
489 #endif
490     if (!u.usteed)
491         return;
492
493     /* [ALI] Various effects of kicking sleeping/paralyzed steeds */
494     if (u.usteed->msleeping || !u.usteed->mcanmove) {
495         /* We assume a message has just been output of the form
496          * "You kick <steed>."
497          */
498         Strcpy(He, mhe(u.usteed));
499         *He = highc(*He);
500         if ((u.usteed->mcanmove || u.usteed->mfrozen) && !rn2(2)) {
501             if (u.usteed->mcanmove)
502                 u.usteed->msleeping = 0;
503             else if (u.usteed->mfrozen > 2)
504                 u.usteed->mfrozen -= 2;
505             else {
506                 u.usteed->mfrozen = 0;
507                 u.usteed->mcanmove = 1;
508             }
509             if (u.usteed->msleeping || !u.usteed->mcanmove)
510 #if 0 /*JP*/
511                 pline("%s stirs.", He);
512 #else
513                 pline("%s\82Í\90g\82\82ë\82¬\82µ\82½\81D", He);
514 #endif
515             else
516 #if 0 /*JP*/
517                 pline("%s rouses %sself!", He, mhim(u.usteed));
518 #else
519                 pline("%s\82Í\95±\8bN\82µ\82½\81I", He);
520 #endif
521         } else
522 #if 0 /*JP*/
523             pline("%s does not respond.", He);
524 #else
525             pline("%s\82Í\94½\89\9e\82µ\82È\82¢\81D", He);
526 #endif
527         return;
528     }
529
530     /* Make the steed less tame and check if it resists */
531     if (u.usteed->mtame)
532         u.usteed->mtame--;
533     if (!u.usteed->mtame && u.usteed->mleashed)
534         m_unleash(u.usteed, TRUE);
535     if (!u.usteed->mtame
536         || (u.ulevel + u.usteed->mtame < rnd(MAXULEV / 2 + 5))) {
537         newsym(u.usteed->mx, u.usteed->my);
538         dismount_steed(DISMOUNT_THROWN);
539         return;
540     }
541
542 /*JP
543     pline("%s gallops!", Monnam(u.usteed));
544 */
545     pline("%s\82Í\91¬\91«\82É\82È\82Á\82½\81I", Monnam(u.usteed));
546     u.ugallop += rn1(20, 30);
547     return;
548 }
549
550 /*
551  * Try to find a dismount point adjacent to the steed's location.
552  * If all else fails, try enexto().  Use enexto() as a last resort because
553  * enexto() chooses its point randomly, possibly even outside the
554  * room's walls, which is not what we want.
555  * Adapted from mail daemon code.
556  */
557 STATIC_OVL boolean
558 landing_spot(spot, reason, forceit)
559 coord *spot; /* landing position (we fill it in) */
560 int reason;
561 int forceit;
562 {
563     int i = 0, x, y, distance, min_distance = -1;
564     boolean found = FALSE;
565     struct trap *t;
566
567     /* avoid known traps (i == 0) and boulders, but allow them as a backup */
568     if (reason != DISMOUNT_BYCHOICE || Stunned || Confusion || Fumbling)
569         i = 1;
570     for (; !found && i < 2; ++i) {
571         for (x = u.ux - 1; x <= u.ux + 1; x++)
572             for (y = u.uy - 1; y <= u.uy + 1; y++) {
573                 if (!isok(x, y) || (x == u.ux && y == u.uy))
574                     continue;
575
576                 if (accessible(x, y) && !MON_AT(x, y)) {
577                     distance = distu(x, y);
578                     if (min_distance < 0 || distance < min_distance
579                         || (distance == min_distance && rn2(2))) {
580                         if (i > 0 || (((t = t_at(x, y)) == 0 || !t->tseen)
581                                       && (!sobj_at(BOULDER, x, y)
582                                           || throws_rocks(youmonst.data)))) {
583                             spot->x = x;
584                             spot->y = y;
585                             min_distance = distance;
586                             found = TRUE;
587                         }
588                     }
589                 }
590             }
591     }
592
593     /* If we didn't find a good spot and forceit is on, try enexto(). */
594     if (forceit && min_distance < 0
595         && !enexto(spot, u.ux, u.uy, youmonst.data))
596         return FALSE;
597
598     return found;
599 }
600
601 /* Stop riding the current steed */
602 void
603 dismount_steed(reason)
604 int reason; /* Player was thrown off etc. */
605 {
606     struct monst *mtmp;
607     struct obj *otmp;
608     coord cc;
609 /*JP
610     const char *verb = "fall";
611 */
612     const char *verb = "\97\8e\82¿\82½";
613     boolean repair_leg_damage = (Wounded_legs != 0L);
614     unsigned save_utrap = u.utrap;
615     boolean have_spot = landing_spot(&cc, reason, 0);
616
617     mtmp = u.usteed; /* make a copy of steed pointer */
618     /* Sanity check */
619     if (!mtmp) /* Just return silently */
620         return;
621
622     /* Check the reason for dismounting */
623     otmp = which_armor(mtmp, W_SADDLE);
624     switch (reason) {
625     case DISMOUNT_THROWN:
626 /*JP
627         verb = "are thrown";
628 */
629         verb = "\82Ó\82è\97\8e\82³\82ê\82½";
630     case DISMOUNT_FELL:
631 /*JP
632         You("%s off of %s!", verb, mon_nam(mtmp));
633 */
634         You("%s\82©\82ç%s\81I", mon_nam(mtmp), verb);
635         if (!have_spot)
636             have_spot = landing_spot(&cc, reason, 1);
637 /*JP
638         losehp(Maybe_Half_Phys(rn1(10, 10)), "riding accident", KILLED_BY_AN);
639 */
640         losehp(Maybe_Half_Phys(rn1(10, 10)), "\8bR\8fæ\8e\96\8cÌ\82Å", KILLED_BY_AN);
641         set_wounded_legs(BOTH_SIDES, (int) HWounded_legs + rn1(5, 5));
642         repair_leg_damage = FALSE;
643         break;
644     case DISMOUNT_POLY:
645 /*JP
646         You("can no longer ride %s.", mon_nam(u.usteed));
647 */
648         You("%s\82É\8fæ\82Á\82Ä\82ç\82ê\82È\82¢\81D", mon_nam(u.usteed));
649         if (!have_spot)
650             have_spot = landing_spot(&cc, reason, 1);
651         break;
652     case DISMOUNT_ENGULFED:
653         /* caller displays message */
654         break;
655     case DISMOUNT_BONES:
656         /* hero has just died... */
657         break;
658     case DISMOUNT_GENERIC:
659         /* no messages, just make it so */
660         break;
661     case DISMOUNT_BYCHOICE:
662     default:
663         if (otmp && otmp->cursed) {
664 #if 0 /*JP*/
665             You("can't.  The saddle %s cursed.",
666                 otmp->bknown ? "is" : "seems to be");
667 #else
668             You("\8d~\82è\82ç\82ê\82È\82¢\81D\88Æ\82Í\8eô\82í\82ê\82Ä\82¢\82é%s\81D",
669                 otmp->bknown ? "" : "\82æ\82¤\82¾");
670 #endif
671             otmp->bknown = TRUE;
672             return;
673         }
674         if (!have_spot) {
675 /*JP
676             You("can't. There isn't anywhere for you to stand.");
677 */
678             pline("\82 \82È\82½\82Ì\97§\82Â\8fê\8f\8a\82ª\82È\82¢\82Ì\82Å\8d~\82è\82ç\82ê\82È\82¢\81D");
679             return;
680         }
681         if (!has_mname(mtmp)) {
682 /*JP
683             pline("You've been through the dungeon on %s with no name.",
684 */
685             pline("\82 \82È\82½\82Í\96¼\91O\82Ì\82È\82¢%s\82Æ\8b¤\82É\96À\8b{\93à\82É\82¢\82é\81D",
686                   an(mtmp->data->mname));
687             if (Hallucination)
688 /*JP
689                 pline("It felt good to get out of the rain.");
690 */
691                 pline("\89J\82ª\8d~\82ç\82È\82¢\82Ì\82Æ\82¢\82¤\82Ì\82Í\82¢\82¢\8bC\95ª\82¾\82Á\82½\81D");
692         } else
693 /*JP
694             You("dismount %s.", mon_nam(mtmp));
695 */
696             You("%s\82©\82ç\8d~\82è\82½\81D", mon_nam(mtmp));
697     }
698     /* While riding, Wounded_legs refers to the steed's legs;
699        after dismounting, it reverts to the hero's legs. */
700     if (repair_leg_damage) {
701         /* [TODO: make heal_legs() take a parameter to handle this] */
702         in_steed_dismounting = TRUE;
703         heal_legs();
704         in_steed_dismounting = FALSE;
705     }
706
707     /* Release the steed and saddle */
708     u.usteed = 0;
709     u.ugallop = 0L;
710
711     /* Set player and steed's position.  Try moving the player first
712        unless we're in the midst of creating a bones file. */
713     if (reason == DISMOUNT_BONES) {
714         /* move the steed to an adjacent square */
715         if (enexto(&cc, u.ux, u.uy, mtmp->data))
716             rloc_to(mtmp, cc.x, cc.y);
717         else /* evidently no room nearby; move steed elsewhere */
718             (void) rloc(mtmp, FALSE);
719         return;
720     }
721     if (mtmp->mhp > 0) {
722         place_monster(mtmp, u.ux, u.uy);
723         if (!u.uswallow && !u.ustuck && have_spot) {
724             struct permonst *mdat = mtmp->data;
725
726             /* The steed may drop into water/lava */
727             if (!is_flyer(mdat) && !is_floater(mdat) && !is_clinger(mdat)) {
728                 if (is_pool(u.ux, u.uy)) {
729                     if (!Underwater)
730 /*JP
731                         pline("%s falls into the %s!", Monnam(mtmp),
732 */
733                         pline("%s\82Í%s\82É\97\8e\82¿\82½\81I", Monnam(mtmp),
734                               surface(u.ux, u.uy));
735                     if (!is_swimmer(mdat) && !amphibious(mdat)) {
736                         killed(mtmp);
737                         adjalign(-1);
738                     }
739                 } else if (is_lava(u.ux, u.uy)) {
740 /*JP
741                     pline("%s is pulled into the lava!", Monnam(mtmp));
742 */
743                     pline("%s\82Í\97n\8aâ\82Ì\92\86\82É\82Ð\82Á\82Ï\82ç\82ê\82½\81I", Monnam(mtmp));
744                     if (!likes_lava(mdat)) {
745                         killed(mtmp);
746                         adjalign(-1);
747                     }
748                 }
749             }
750             /* Steed dismounting consists of two steps: being moved to another
751              * square, and descending to the floor.  We have functions to do
752              * each of these activities, but they're normally called
753              * individually and include an attempt to look at or pick up the
754              * objects on the floor:
755              * teleds() --> spoteffects() --> pickup()
756              * float_down() --> pickup()
757              * We use this kludge to make sure there is only one such attempt.
758              *
759              * Clearly this is not the best way to do it.  A full fix would
760              * involve having these functions not call pickup() at all,
761              * instead
762              * calling them first and calling pickup() afterwards.  But it
763              * would take a lot of work to keep this change from having any
764              * unforeseen side effects (for instance, you would no longer be
765              * able to walk onto a square with a hole, and autopickup before
766              * falling into the hole).
767              */
768             /* [ALI] No need to move the player if the steed died. */
769             if (mtmp->mhp > 0) {
770                 /* Keep steed here, move the player to cc;
771                  * teleds() clears u.utrap
772                  */
773                 in_steed_dismounting = TRUE;
774                 teleds(cc.x, cc.y, TRUE);
775                 in_steed_dismounting = FALSE;
776
777                 /* Put your steed in your trap */
778                 if (save_utrap)
779                     (void) mintrap(mtmp);
780             }
781             /* Couldn't... try placing the steed */
782         } else if (enexto(&cc, u.ux, u.uy, mtmp->data)) {
783             /* Keep player here, move the steed to cc */
784             rloc_to(mtmp, cc.x, cc.y);
785             /* Player stays put */
786             /* Otherwise, kill the steed */
787         } else {
788             killed(mtmp);
789             adjalign(-1);
790         }
791     }
792
793     /* Return the player to the floor */
794     if (reason != DISMOUNT_ENGULFED) {
795         in_steed_dismounting = TRUE;
796         (void) float_down(0L, W_SADDLE);
797         in_steed_dismounting = FALSE;
798         context.botl = 1;
799         (void) encumber_msg();
800         vision_full_recalc = 1;
801     } else
802         context.botl = 1;
803     /* polearms behave differently when not mounted */
804     if (uwep && is_pole(uwep))
805         unweapon = TRUE;
806     return;
807 }
808
809 /* when attempting to saddle or mount a sleeping steed, try to wake it up
810    (for the saddling case, it won't be u.usteed yet) */
811 STATIC_OVL void
812 maybewakesteed(steed)
813 struct monst *steed;
814 {
815     int frozen = (int) steed->mfrozen;
816     boolean wasimmobile = steed->msleeping || !steed->mcanmove;
817
818     steed->msleeping = 0;
819     if (frozen) {
820         frozen = (frozen + 1) / 2; /* half */
821         /* might break out of timed sleep or paralysis */
822         if (!rn2(frozen)) {
823             steed->mfrozen = 0;
824             steed->mcanmove = 1;
825         } else {
826             /* didn't awake, but remaining duration is halved */
827             steed->mfrozen = frozen;
828         }
829     }
830     if (wasimmobile && !steed->msleeping && steed->mcanmove)
831 /*JP
832         pline("%s wakes up.", Monnam(steed));
833 */
834         pline("%s\82Í\8bN\82«\82½\81D", Monnam(steed));
835     /* regardless of waking, terminate any meal in progress */
836     finish_meating(steed);
837 }
838
839 /* decide whether hero's steed is able to move;
840    doesn't check for holding traps--those affect the hero directly */
841 boolean
842 stucksteed(checkfeeding)
843 boolean checkfeeding;
844 {
845     struct monst *steed = u.usteed;
846
847     if (steed) {
848         /* check whether steed can move */
849         if (steed->msleeping || !steed->mcanmove) {
850 /*JP
851             pline("%s won't move!", upstart(y_monnam(steed)));
852 */
853             pline("%s\82Í\93®\82¯\82È\82¢\81I", y_monnam(steed));
854             return TRUE;
855         }
856         /* optionally check whether steed is in the midst of a meal */
857         if (checkfeeding && steed->meating) {
858 /*JP
859             pline("%s is still eating.", upstart(y_monnam(steed)));
860 */
861             pline("%s\82Í\82Ü\82¾\90H\82×\82Ä\82¢\82é\81D", y_monnam(steed));
862             return TRUE;
863         }
864     }
865     return FALSE;
866 }
867
868 void
869 place_monster(mon, x, y)
870 struct monst *mon;
871 int x, y;
872 {
873     if (mon == u.usteed
874         /* special case is for convoluted vault guard handling */
875         || (DEADMONSTER(mon) && !(mon->isgd && x == 0 && y == 0))) {
876         impossible("placing %s onto map?",
877                    (mon == u.usteed) ? "steed" : "defunct monster");
878         return;
879     }
880     mon->mx = x, mon->my = y;
881     level.monsters[x][y] = mon;
882 }
883
884 /*steed.c*/