OSDN Git Service

patch src/
[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         losehp(Maybe_Half_Phys(rn1(5, 10)), buf, NO_KILLER_PREFIX);
435         return (FALSE);
436     }
437
438     /* Success */
439     maybewakesteed(mtmp);
440     if (!force) {
441         if (Levitation && !is_floater(ptr) && !is_flyer(ptr))
442             /* Must have Lev_at_will at this point */
443 /*JP
444             pline("%s magically floats up!", Monnam(mtmp));
445 */
446             pline("%s\82Í\96\82\96@\82Ì\97Í\82Å\95\82\82¢\82½\81I", Monnam(mtmp));
447 /*JP
448         You("mount %s.", mon_nam(mtmp));
449 */
450         You("%s\82É\8fæ\82Á\82½\81D", mon_nam(mtmp));
451     }
452     /* setuwep handles polearms differently when you're mounted */
453     if (uwep && is_pole(uwep))
454         unweapon = FALSE;
455     u.usteed = mtmp;
456     remove_monster(mtmp->mx, mtmp->my);
457     teleds(mtmp->mx, mtmp->my, TRUE);
458     return (TRUE);
459 }
460
461 /* You and your steed have moved */
462 void
463 exercise_steed()
464 {
465     if (!u.usteed)
466         return;
467
468     /* It takes many turns of riding to exercise skill */
469     if (u.urideturns++ >= 100) {
470         u.urideturns = 0;
471         use_skill(P_RIDING, 1);
472     }
473     return;
474 }
475
476 /* The player kicks or whips the steed */
477 void
478 kick_steed()
479 {
480 #if 0 /*JP*/
481     char He[4];
482 #else
483     /* role.c Gender.he \82Ì\92l\82ª\83R\83s\81[\82³\82ê\82é */
484     char He[16];
485 #endif
486     if (!u.usteed)
487         return;
488
489     /* [ALI] Various effects of kicking sleeping/paralyzed steeds */
490     if (u.usteed->msleeping || !u.usteed->mcanmove) {
491         /* We assume a message has just been output of the form
492          * "You kick <steed>."
493          */
494         Strcpy(He, mhe(u.usteed));
495         *He = highc(*He);
496         if ((u.usteed->mcanmove || u.usteed->mfrozen) && !rn2(2)) {
497             if (u.usteed->mcanmove)
498                 u.usteed->msleeping = 0;
499             else if (u.usteed->mfrozen > 2)
500                 u.usteed->mfrozen -= 2;
501             else {
502                 u.usteed->mfrozen = 0;
503                 u.usteed->mcanmove = 1;
504             }
505             if (u.usteed->msleeping || !u.usteed->mcanmove)
506 #if 0 /*JP*/
507                 pline("%s stirs.", He);
508 #else
509                 pline("%s\82Í\90g\82\82ë\82¬\82µ\82½\81D", He);
510 #endif
511             else
512 #if 0 /*JP*/
513                 pline("%s rouses %sself!", He, mhim(u.usteed));
514 #else
515                 pline("%s\82Í\95±\8bN\82µ\82½\81I", He);
516 #endif
517         } else
518 #if 0 /*JP*/
519             pline("%s does not respond.", He);
520 #else
521             pline("%s\82Í\94½\89\9e\82µ\82È\82¢\81D", He);
522 #endif
523         return;
524     }
525
526     /* Make the steed less tame and check if it resists */
527     if (u.usteed->mtame)
528         u.usteed->mtame--;
529     if (!u.usteed->mtame && u.usteed->mleashed)
530         m_unleash(u.usteed, TRUE);
531     if (!u.usteed->mtame
532         || (u.ulevel + u.usteed->mtame < rnd(MAXULEV / 2 + 5))) {
533         newsym(u.usteed->mx, u.usteed->my);
534         dismount_steed(DISMOUNT_THROWN);
535         return;
536     }
537
538 /*JP
539     pline("%s gallops!", Monnam(u.usteed));
540 */
541     pline("%s\82Í\91¬\91«\82É\82È\82Á\82½\81I", Monnam(u.usteed));
542     u.ugallop += rn1(20, 30);
543     return;
544 }
545
546 /*
547  * Try to find a dismount point adjacent to the steed's location.
548  * If all else fails, try enexto().  Use enexto() as a last resort because
549  * enexto() chooses its point randomly, possibly even outside the
550  * room's walls, which is not what we want.
551  * Adapted from mail daemon code.
552  */
553 STATIC_OVL boolean
554 landing_spot(spot, reason, forceit)
555 coord *spot; /* landing position (we fill it in) */
556 int reason;
557 int forceit;
558 {
559     int i = 0, x, y, distance, min_distance = -1;
560     boolean found = FALSE;
561     struct trap *t;
562
563     /* avoid known traps (i == 0) and boulders, but allow them as a backup */
564     if (reason != DISMOUNT_BYCHOICE || Stunned || Confusion || Fumbling)
565         i = 1;
566     for (; !found && i < 2; ++i) {
567         for (x = u.ux - 1; x <= u.ux + 1; x++)
568             for (y = u.uy - 1; y <= u.uy + 1; y++) {
569                 if (!isok(x, y) || (x == u.ux && y == u.uy))
570                     continue;
571
572                 if (accessible(x, y) && !MON_AT(x, y)) {
573                     distance = distu(x, y);
574                     if (min_distance < 0 || distance < min_distance
575                         || (distance == min_distance && rn2(2))) {
576                         if (i > 0 || (((t = t_at(x, y)) == 0 || !t->tseen)
577                                       && (!sobj_at(BOULDER, x, y)
578                                           || throws_rocks(youmonst.data)))) {
579                             spot->x = x;
580                             spot->y = y;
581                             min_distance = distance;
582                             found = TRUE;
583                         }
584                     }
585                 }
586             }
587     }
588
589     /* If we didn't find a good spot and forceit is on, try enexto(). */
590     if (forceit && min_distance < 0
591         && !enexto(spot, u.ux, u.uy, youmonst.data))
592         return FALSE;
593
594     return found;
595 }
596
597 /* Stop riding the current steed */
598 void
599 dismount_steed(reason)
600 int reason; /* Player was thrown off etc. */
601 {
602     struct monst *mtmp;
603     struct obj *otmp;
604     coord cc;
605 /*JP
606     const char *verb = "fall";
607 */
608     const char *verb = "\97\8e\82¿\82½";
609     boolean repair_leg_damage = (Wounded_legs != 0L);
610     unsigned save_utrap = u.utrap;
611     boolean have_spot = landing_spot(&cc, reason, 0);
612
613     mtmp = u.usteed; /* make a copy of steed pointer */
614     /* Sanity check */
615     if (!mtmp) /* Just return silently */
616         return;
617
618     /* Check the reason for dismounting */
619     otmp = which_armor(mtmp, W_SADDLE);
620     switch (reason) {
621     case DISMOUNT_THROWN:
622 /*JP
623         verb = "are thrown";
624 */
625         verb = "\82Ó\82è\97\8e\82³\82ê\82½";
626     case DISMOUNT_FELL:
627 /*JP
628         You("%s off of %s!", verb, mon_nam(mtmp));
629 */
630         You("%s\82©\82ç%s\81I", mon_nam(mtmp), verb);
631         if (!have_spot)
632             have_spot = landing_spot(&cc, reason, 1);
633 /*JP
634         losehp(Maybe_Half_Phys(rn1(10, 10)), "riding accident", KILLED_BY_AN);
635 */
636         losehp(Maybe_Half_Phys(rn1(10, 10)), "\8bR\8fæ\8e\96\8cÌ\82Å", KILLED_BY_AN);
637         set_wounded_legs(BOTH_SIDES, (int) HWounded_legs + rn1(5, 5));
638         repair_leg_damage = FALSE;
639         break;
640     case DISMOUNT_POLY:
641 /*JP
642         You("can no longer ride %s.", mon_nam(u.usteed));
643 */
644         You("%s\82É\8fæ\82Á\82Ä\82ç\82ê\82È\82¢\81D", mon_nam(u.usteed));
645         if (!have_spot)
646             have_spot = landing_spot(&cc, reason, 1);
647         break;
648     case DISMOUNT_ENGULFED:
649         /* caller displays message */
650         break;
651     case DISMOUNT_BONES:
652         /* hero has just died... */
653         break;
654     case DISMOUNT_GENERIC:
655         /* no messages, just make it so */
656         break;
657     case DISMOUNT_BYCHOICE:
658     default:
659         if (otmp && otmp->cursed) {
660 #if 0 /*JP*/
661             You("can't.  The saddle %s cursed.",
662                 otmp->bknown ? "is" : "seems to be");
663 #else
664             You("\8d~\82è\82ç\82ê\82È\82¢\81D\88Æ\82Í\8eô\82í\82ê\82Ä\82¢\82é%s\81D",
665                 otmp->bknown ? "" : "\82æ\82¤\82¾");
666 #endif
667             otmp->bknown = TRUE;
668             return;
669         }
670         if (!have_spot) {
671 /*JP
672             You("can't. There isn't anywhere for you to stand.");
673 */
674             pline("\82 \82È\82½\82Ì\97§\82Â\8fê\8f\8a\82ª\82È\82¢\82Ì\82Å\8d~\82è\82ç\82ê\82È\82¢\81D");
675             return;
676         }
677         if (!has_mname(mtmp)) {
678 /*JP
679             pline("You've been through the dungeon on %s with no name.",
680 */
681             pline("\82 \82È\82½\82Í\96¼\91O\82Ì\82È\82¢%s\82Æ\8b¤\82É\96À\8b{\93à\82É\82¢\82é\81D",
682                   an(mtmp->data->mname));
683             if (Hallucination)
684 /*JP
685                 pline("It felt good to get out of the rain.");
686 */
687                 pline("\89J\82ª\8d~\82ç\82È\82¢\82Ì\82Æ\82¢\82¤\82Ì\82Í\82¢\82¢\8bC\95ª\82¾\82Á\82½\81D");
688         } else
689 /*JP
690             You("dismount %s.", mon_nam(mtmp));
691 */
692             You("%s\82©\82ç\8d~\82è\82½\81D", mon_nam(mtmp));
693     }
694     /* While riding, Wounded_legs refers to the steed's legs;
695        after dismounting, it reverts to the hero's legs. */
696     if (repair_leg_damage) {
697         /* [TODO: make heal_legs() take a parameter to handle this] */
698         in_steed_dismounting = TRUE;
699         heal_legs();
700         in_steed_dismounting = FALSE;
701     }
702
703     /* Release the steed and saddle */
704     u.usteed = 0;
705     u.ugallop = 0L;
706
707     /* Set player and steed's position.  Try moving the player first
708        unless we're in the midst of creating a bones file. */
709     if (reason == DISMOUNT_BONES) {
710         /* move the steed to an adjacent square */
711         if (enexto(&cc, u.ux, u.uy, mtmp->data))
712             rloc_to(mtmp, cc.x, cc.y);
713         else /* evidently no room nearby; move steed elsewhere */
714             (void) rloc(mtmp, FALSE);
715         return;
716     }
717     if (mtmp->mhp > 0) {
718         place_monster(mtmp, u.ux, u.uy);
719         if (!u.uswallow && !u.ustuck && have_spot) {
720             struct permonst *mdat = mtmp->data;
721
722             /* The steed may drop into water/lava */
723             if (!is_flyer(mdat) && !is_floater(mdat) && !is_clinger(mdat)) {
724                 if (is_pool(u.ux, u.uy)) {
725                     if (!Underwater)
726 /*JP
727                         pline("%s falls into the %s!", Monnam(mtmp),
728 */
729                         pline("%s\82Í%s\82É\97\8e\82¿\82½\81I", Monnam(mtmp),
730                               surface(u.ux, u.uy));
731                     if (!is_swimmer(mdat) && !amphibious(mdat)) {
732                         killed(mtmp);
733                         adjalign(-1);
734                     }
735                 } else if (is_lava(u.ux, u.uy)) {
736 /*JP
737                     pline("%s is pulled into the lava!", Monnam(mtmp));
738 */
739                     pline("%s\82Í\97n\8aâ\82Ì\92\86\82É\82Ð\82Á\82Ï\82ç\82ê\82½\81I", Monnam(mtmp));
740                     if (!likes_lava(mdat)) {
741                         killed(mtmp);
742                         adjalign(-1);
743                     }
744                 }
745             }
746             /* Steed dismounting consists of two steps: being moved to another
747              * square, and descending to the floor.  We have functions to do
748              * each of these activities, but they're normally called
749              * individually and include an attempt to look at or pick up the
750              * objects on the floor:
751              * teleds() --> spoteffects() --> pickup()
752              * float_down() --> pickup()
753              * We use this kludge to make sure there is only one such attempt.
754              *
755              * Clearly this is not the best way to do it.  A full fix would
756              * involve having these functions not call pickup() at all,
757              * instead
758              * calling them first and calling pickup() afterwards.  But it
759              * would take a lot of work to keep this change from having any
760              * unforeseen side effects (for instance, you would no longer be
761              * able to walk onto a square with a hole, and autopickup before
762              * falling into the hole).
763              */
764             /* [ALI] No need to move the player if the steed died. */
765             if (mtmp->mhp > 0) {
766                 /* Keep steed here, move the player to cc;
767                  * teleds() clears u.utrap
768                  */
769                 in_steed_dismounting = TRUE;
770                 teleds(cc.x, cc.y, TRUE);
771                 in_steed_dismounting = FALSE;
772
773                 /* Put your steed in your trap */
774                 if (save_utrap)
775                     (void) mintrap(mtmp);
776             }
777             /* Couldn't... try placing the steed */
778         } else if (enexto(&cc, u.ux, u.uy, mtmp->data)) {
779             /* Keep player here, move the steed to cc */
780             rloc_to(mtmp, cc.x, cc.y);
781             /* Player stays put */
782             /* Otherwise, kill the steed */
783         } else {
784             killed(mtmp);
785             adjalign(-1);
786         }
787     }
788
789     /* Return the player to the floor */
790     if (reason != DISMOUNT_ENGULFED) {
791         in_steed_dismounting = TRUE;
792         (void) float_down(0L, W_SADDLE);
793         in_steed_dismounting = FALSE;
794         context.botl = 1;
795         (void) encumber_msg();
796         vision_full_recalc = 1;
797     } else
798         context.botl = 1;
799     /* polearms behave differently when not mounted */
800     if (uwep && is_pole(uwep))
801         unweapon = TRUE;
802     return;
803 }
804
805 /* when attempting to saddle or mount a sleeping steed, try to wake it up
806    (for the saddling case, it won't be u.usteed yet) */
807 STATIC_OVL void
808 maybewakesteed(steed)
809 struct monst *steed;
810 {
811     int frozen = (int) steed->mfrozen;
812     boolean wasimmobile = steed->msleeping || !steed->mcanmove;
813
814     steed->msleeping = 0;
815     if (frozen) {
816         frozen = (frozen + 1) / 2; /* half */
817         /* might break out of timed sleep or paralysis */
818         if (!rn2(frozen)) {
819             steed->mfrozen = 0;
820             steed->mcanmove = 1;
821         } else {
822             /* didn't awake, but remaining duration is halved */
823             steed->mfrozen = frozen;
824         }
825     }
826     if (wasimmobile && !steed->msleeping && steed->mcanmove)
827         pline("%s wakes up.", Monnam(steed));
828     /* regardless of waking, terminate any meal in progress */
829     finish_meating(steed);
830 }
831
832 /* decide whether hero's steed is able to move;
833    doesn't check for holding traps--those affect the hero directly */
834 boolean
835 stucksteed(checkfeeding)
836 boolean checkfeeding;
837 {
838     struct monst *steed = u.usteed;
839
840     if (steed) {
841         /* check whether steed can move */
842         if (steed->msleeping || !steed->mcanmove) {
843             pline("%s won't move!", upstart(y_monnam(steed)));
844             return TRUE;
845         }
846         /* optionally check whether steed is in the midst of a meal */
847         if (checkfeeding && steed->meating) {
848             pline("%s is still eating.", upstart(y_monnam(steed)));
849             return TRUE;
850         }
851     }
852     return FALSE;
853 }
854
855 void
856 place_monster(mon, x, y)
857 struct monst *mon;
858 int x, y;
859 {
860     if (mon == u.usteed
861         /* special case is for convoluted vault guard handling */
862         || (DEADMONSTER(mon) && !(mon->isgd && x == 0 && y == 0))) {
863         impossible("placing %s onto map?",
864                    (mon == u.usteed) ? "steed" : "defunct monster");
865         return;
866     }
867     mon->mx = x, mon->my = y;
868     level.monsters[x][y] = mon;
869 }
870
871 /*steed.c*/