OSDN Git Service

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