OSDN Git Service

add translation
[jnethack/source.git] / src / steed.c
1 /* NetHack 3.6  steed.c $NHDT-Date: 1545441042 2018/12/22 01:10:42 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.62 $ */
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 = 0L;
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                              || M_AP_TYPE(mtmp) == M_AP_FURNITURE
305                              || M_AP_TYPE(mtmp) == 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 (mtmp->data == &mons[PM_LONG_WORM]
313         && (u.ux + u.dx != mtmp->mx || u.uy + u.dy != mtmp->my)) {
314         /* 3.6.2:  test_move(below) is used to check for trying to mount
315            diagonally into or out of a doorway or through a tight squeeze;
316            attempting to mount a tail segment when hero was not adjacent
317            to worm's head could trigger an impossible() in worm_cross()
318            called from test_move(), so handle not-on-head before that */
319 /*JP
320         You("couldn't ride %s, let alone its tail.", a_monnam(mtmp));
321 */
322         You("%s\82É\82Í\8fæ\82ê\82È\82¢\81C\82à\82¿\82ë\82ñ\90K\94ö\82É\82à\8fæ\82ê\82È\82¢\81D", a_monnam(mtmp));
323         return FALSE;
324     }
325     if (u.uswallow || u.ustuck || u.utrap || Punished
326         || !test_move(u.ux, u.uy, mtmp->mx - u.ux, mtmp->my - u.uy,
327                       TEST_MOVE)) {
328         if (Punished || !(u.uswallow || u.ustuck || u.utrap))
329 /*JP
330             You("are unable to swing your %s over.", body_part(LEG));
331 */
332             You("\88Æ\82ð\82Ü\82½\82®\82±\82Æ\82ª\82Å\82«\82È\82¢\81D");
333         else
334 /*JP
335             You("are stuck here for now.");
336 */
337             You("\82Í\82Ü\82Á\82Ä\82¢\82é\82Ì\82Å\8fo\97\88\82È\82¢\81D");
338         return (FALSE);
339     }
340
341     /* Is this a valid monster? */
342     otmp = which_armor(mtmp, W_SADDLE);
343     if (!otmp) {
344 /*JP
345         pline("%s is not saddled.", Monnam(mtmp));
346 */
347         pline("%s\82É\82Í\88Æ\82ª\8eæ\82è\82Â\82¯\82ç\82ê\82Ä\82¢\82È\82¢\81D", Monnam(mtmp));
348         return (FALSE);
349     }
350     ptr = mtmp->data;
351     if (touch_petrifies(ptr) && !Stone_resistance) {
352         char kbuf[BUFSZ];
353
354 /*JP
355         You("touch %s.", mon_nam(mtmp));
356 */
357         You("%s\82É\90G\82ê\82½\81D", mon_nam(mtmp));
358 /*JP
359         Sprintf(kbuf, "attempting to ride %s", an(mtmp->data->mname));
360 */
361         Sprintf(kbuf, "%s\82É\8fæ\82ë\82¤\82Æ\82µ\82Ä", a_monnam(mtmp));
362         instapetrify(kbuf);
363     }
364     if (!mtmp->mtame || mtmp->isminion) {
365 /*JP
366         pline("I think %s would mind.", mon_nam(mtmp));
367 */
368         pline("%s\82Í\8c\99\82ª\82Á\82Ä\82¢\82é\82æ\82¤\82¾\81D", mon_nam(mtmp));
369         return (FALSE);
370     }
371     if (mtmp->mtrapped) {
372         struct trap *t = t_at(mtmp->mx, mtmp->my);
373
374 #if 0 /*JP*/
375         You_cant("mount %s while %s's trapped in %s.", mon_nam(mtmp),
376                  mhe(mtmp), an(defsyms[trap_to_defsym(t->ttyp)].explanation));
377 #else
378         You("%s\82É\95ß\82Ü\82Á\82Ä\82¢\82é%s\82É\82Í\8fæ\82ê\82È\82¢\81D",
379             defsyms[trap_to_defsym(t->ttyp)].explanation, mon_nam(mtmp));
380 #endif
381         return (FALSE);
382     }
383
384     if (!force && !Role_if(PM_KNIGHT) && !(--mtmp->mtame)) {
385         /* no longer tame */
386         newsym(mtmp->mx, mtmp->my);
387 #if 0 /*JP*/
388         pline("%s resists%s!", Monnam(mtmp),
389               mtmp->mleashed ? " and its leash comes off" : "");
390 #else
391         pline("%s\82Í\8b\91\94Û%s\81I", Monnam(mtmp),
392               mtmp->mleashed ? "\82µ\82Ä\81C\95R\82ð\82Í\82¸\82µ\82½" : "\82µ\82½");
393 #endif
394         if (mtmp->mleashed)
395             m_unleash(mtmp, FALSE);
396         return (FALSE);
397     }
398     if (!force && Underwater && !is_swimmer(ptr)) {
399 #if 0 /*JP*/
400         You_cant("ride that creature while under %s.",
401                  hliquid("water"));
402 #else /*\82Æ\82è\82 \82¦\82¸\90\85\82¾\82¯*/
403         You("\90\85\92\86\82Å\8fæ\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
404 #endif
405         return (FALSE);
406     }
407     if (!can_saddle(mtmp) || !can_ride(mtmp)) {
408 /*JP
409         You_cant("ride such a creature.");
410 */
411         You("\82»\82Ì\90\82«\95¨\82É\8fæ\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
412         return FALSE;
413     }
414
415     /* Is the player impaired? */
416     if (!force && !is_floater(ptr) && !is_flyer(ptr) && Levitation
417         && !Lev_at_will) {
418 /*JP
419         You("cannot reach %s.", mon_nam(mtmp));
420 */
421         You("%s\82É\93Í\82©\82È\82¢\81D", mon_nam(mtmp));
422         return (FALSE);
423     }
424     if (!force && uarm && is_metallic(uarm) && greatest_erosion(uarm)) {
425 #if 0 /*JP*/
426         Your("%s armor is too stiff to be able to mount %s.",
427              uarm->oeroded ? "rusty" : "corroded", mon_nam(mtmp));
428 #else
429         Your("%s\8aZ\82Í\83M\83V\83M\83V\82¢\82Á\82Ä\82¨\82è%s\82É\8fæ\82ê\82È\82¢\81D",
430              uarm->oeroded ? "\8eK\82Ñ\82½" : "\95\85\90H\82µ\82½", mon_nam(mtmp));
431 #endif
432         return (FALSE);
433     }
434     if (!force
435         && (Confusion || Fumbling || Glib || Wounded_legs || otmp->cursed
436             || (u.ulevel + mtmp->mtame < rnd(MAXULEV / 2 + 5)))) {
437         if (Levitation) {
438 /*JP
439             pline("%s slips away from you.", Monnam(mtmp));
440 */
441             pline("%s\82Í\82 \82È\82½\82©\82ç\82Í\82È\82ê\82Ä\82¢\82Á\82½\81D", Monnam(mtmp));
442             return FALSE;
443         }
444 /*JP
445         You("slip while trying to get on %s.", mon_nam(mtmp));
446 */
447         You("%s\82É\8fæ\82ë\82¤\82Æ\82µ\82Ä\82·\82×\82Á\82½\81D", mon_nam(mtmp));
448
449 /*JP
450         Sprintf(buf, "slipped while mounting %s",
451 */
452         Sprintf(buf, "%s\82É\8fæ\82ë\82¤\82Æ\82µ\82Ä\82·\82×\82è\97\8e\82¿\82Ä",
453                 /* "a saddled mumak" or "a saddled pony called Dobbin" */
454                 x_monnam(mtmp, ARTICLE_A, (char *) 0,
455                          SUPPRESS_IT | SUPPRESS_INVISIBLE
456                              | SUPPRESS_HALLUCINATION,
457                          TRUE));
458 #if 0 /*JP*/
459         losehp(Maybe_Half_Phys(rn1(5, 10)), buf, NO_KILLER_PREFIX);
460 #else
461         losehp(Maybe_Half_Phys(rn1(5, 10)), buf, KILLED_BY);
462 #endif
463         return (FALSE);
464     }
465
466     /* Success */
467     maybewakesteed(mtmp);
468     if (!force) {
469         if (Levitation && !is_floater(ptr) && !is_flyer(ptr))
470             /* Must have Lev_at_will at this point */
471 /*JP
472             pline("%s magically floats up!", Monnam(mtmp));
473 */
474             pline("%s\82Í\96\82\96@\82Ì\97Í\82Å\95\82\82¢\82½\81I", Monnam(mtmp));
475 /*JP
476         You("mount %s.", mon_nam(mtmp));
477 */
478         You("%s\82É\8fæ\82Á\82½\81D", mon_nam(mtmp));
479         if (Flying)
480 /*JP
481             You("and %s take flight together.", mon_nam(mtmp));
482 */
483             You("\82Æ%s\82Í\88ê\8f\8f\82É\8bó\82ð\94ò\82ñ\82¾\81D", mon_nam(mtmp));
484     }
485     /* setuwep handles polearms differently when you're mounted */
486     if (uwep && is_pole(uwep))
487         unweapon = FALSE;
488     u.usteed = mtmp;
489     remove_monster(mtmp->mx, mtmp->my);
490     teleds(mtmp->mx, mtmp->my, TRUE);
491     context.botl = TRUE;
492     return TRUE;
493 }
494
495 /* You and your steed have moved */
496 void
497 exercise_steed()
498 {
499     if (!u.usteed)
500         return;
501
502     /* It takes many turns of riding to exercise skill */
503     if (++u.urideturns >= 100) {
504         u.urideturns = 0;
505         use_skill(P_RIDING, 1);
506     }
507     return;
508 }
509
510 /* The player kicks or whips the steed */
511 void
512 kick_steed()
513 {
514 #if 0 /*JP*/
515     char He[4];
516 #else
517     /* role.c Gender.he \82Ì\92l\82ª\83R\83s\81[\82³\82ê\82é */
518     char He[16];
519 #endif
520     if (!u.usteed)
521         return;
522
523     /* [ALI] Various effects of kicking sleeping/paralyzed steeds */
524     if (u.usteed->msleeping || !u.usteed->mcanmove) {
525         /* We assume a message has just been output of the form
526          * "You kick <steed>."
527          */
528         Strcpy(He, mhe(u.usteed));
529         *He = highc(*He);
530         if ((u.usteed->mcanmove || u.usteed->mfrozen) && !rn2(2)) {
531             if (u.usteed->mcanmove)
532                 u.usteed->msleeping = 0;
533             else if (u.usteed->mfrozen > 2)
534                 u.usteed->mfrozen -= 2;
535             else {
536                 u.usteed->mfrozen = 0;
537                 u.usteed->mcanmove = 1;
538             }
539             if (u.usteed->msleeping || !u.usteed->mcanmove)
540 #if 0 /*JP*/
541                 pline("%s stirs.", He);
542 #else
543                 pline("%s\82Í\90g\82\82ë\82¬\82µ\82½\81D", He);
544 #endif
545             else
546 #if 0 /*JP*/
547                 pline("%s rouses %sself!", He, mhim(u.usteed));
548 #else
549                 pline("%s\82Í\95±\8bN\82µ\82½\81I", He);
550 #endif
551         } else
552 #if 0 /*JP*/
553             pline("%s does not respond.", He);
554 #else
555             pline("%s\82Í\94½\89\9e\82µ\82È\82¢\81D", He);
556 #endif
557         return;
558     }
559
560     /* Make the steed less tame and check if it resists */
561     if (u.usteed->mtame)
562         u.usteed->mtame--;
563     if (!u.usteed->mtame && u.usteed->mleashed)
564         m_unleash(u.usteed, TRUE);
565     if (!u.usteed->mtame
566         || (u.ulevel + u.usteed->mtame < rnd(MAXULEV / 2 + 5))) {
567         newsym(u.usteed->mx, u.usteed->my);
568         dismount_steed(DISMOUNT_THROWN);
569         return;
570     }
571
572 /*JP
573     pline("%s gallops!", Monnam(u.usteed));
574 */
575     pline("%s\82Í\91¬\91«\82É\82È\82Á\82½\81I", Monnam(u.usteed));
576     u.ugallop += rn1(20, 30);
577     return;
578 }
579
580 /*
581  * Try to find a dismount point adjacent to the steed's location.
582  * If all else fails, try enexto().  Use enexto() as a last resort because
583  * enexto() chooses its point randomly, possibly even outside the
584  * room's walls, which is not what we want.
585  * Adapted from mail daemon code.
586  */
587 STATIC_OVL boolean
588 landing_spot(spot, reason, forceit)
589 coord *spot; /* landing position (we fill it in) */
590 int reason;
591 int forceit;
592 {
593     int i = 0, x, y, distance, min_distance = -1;
594     boolean found = FALSE;
595     struct trap *t;
596
597     /* avoid known traps (i == 0) and boulders, but allow them as a backup */
598     if (reason != DISMOUNT_BYCHOICE || Stunned || Confusion || Fumbling)
599         i = 1;
600     for (; !found && i < 2; ++i) {
601         for (x = u.ux - 1; x <= u.ux + 1; x++)
602             for (y = u.uy - 1; y <= u.uy + 1; y++) {
603                 if (!isok(x, y) || (x == u.ux && y == u.uy))
604                     continue;
605
606                 if (accessible(x, y) && !MON_AT(x, y)) {
607                     distance = distu(x, y);
608                     if (min_distance < 0 || distance < min_distance
609                         || (distance == min_distance && rn2(2))) {
610                         if (i > 0 || (((t = t_at(x, y)) == 0 || !t->tseen)
611                                       && (!sobj_at(BOULDER, x, y)
612                                           || throws_rocks(youmonst.data)))) {
613                             spot->x = x;
614                             spot->y = y;
615                             min_distance = distance;
616                             found = TRUE;
617                         }
618                     }
619                 }
620             }
621     }
622
623     /* If we didn't find a good spot and forceit is on, try enexto(). */
624     if (forceit && min_distance < 0
625         && !enexto(spot, u.ux, u.uy, youmonst.data))
626         return FALSE;
627
628     return found;
629 }
630
631 /* Stop riding the current steed */
632 void
633 dismount_steed(reason)
634 int reason; /* Player was thrown off etc. */
635 {
636     struct monst *mtmp;
637     struct obj *otmp;
638     coord cc, steedcc;
639 /*JP
640     const char *verb = "fall";
641 */
642     const char *verb = "\97\8e\82¿\82½";
643     boolean repair_leg_damage = (Wounded_legs != 0L);
644     unsigned save_utrap = u.utrap;
645     boolean have_spot = landing_spot(&cc, reason, 0);
646
647     mtmp = u.usteed; /* make a copy of steed pointer */
648     /* Sanity check */
649     if (!mtmp) /* Just return silently */
650         return;
651
652     /* Check the reason for dismounting */
653     otmp = which_armor(mtmp, W_SADDLE);
654     switch (reason) {
655     case DISMOUNT_THROWN:
656 /*JP
657         verb = "are thrown";
658 */
659         verb = "\82Ó\82è\97\8e\82³\82ê\82½";
660         /*FALLTHRU*/
661     case DISMOUNT_FELL:
662 /*JP
663         You("%s off of %s!", verb, mon_nam(mtmp));
664 */
665         You("%s\82©\82ç%s\81I", mon_nam(mtmp), verb);
666         if (!have_spot)
667             have_spot = landing_spot(&cc, reason, 1);
668 /*JP
669         losehp(Maybe_Half_Phys(rn1(10, 10)), "riding accident", KILLED_BY_AN);
670 */
671         losehp(Maybe_Half_Phys(rn1(10, 10)), "\8bR\8fæ\8e\96\8cÌ\82Å", KILLED_BY_AN);
672         set_wounded_legs(BOTH_SIDES, (int) HWounded_legs + rn1(5, 5));
673         repair_leg_damage = FALSE;
674         break;
675     case DISMOUNT_POLY:
676 /*JP
677         You("can no longer ride %s.", mon_nam(u.usteed));
678 */
679         You("%s\82É\8fæ\82Á\82Ä\82ç\82ê\82È\82¢\81D", mon_nam(u.usteed));
680         if (!have_spot)
681             have_spot = landing_spot(&cc, reason, 1);
682         break;
683     case DISMOUNT_ENGULFED:
684         /* caller displays message */
685         break;
686     case DISMOUNT_BONES:
687         /* hero has just died... */
688         break;
689     case DISMOUNT_GENERIC:
690         /* no messages, just make it so */
691         break;
692     case DISMOUNT_BYCHOICE:
693     default:
694         if (otmp && otmp->cursed) {
695 #if 0 /*JP*/
696             You("can't.  The saddle %s cursed.",
697                 otmp->bknown ? "is" : "seems to be");
698 #else
699             You("\8d~\82è\82ç\82ê\82È\82¢\81D\88Æ\82Í\8eô\82í\82ê\82Ä\82¢\82é%s\81D",
700                 otmp->bknown ? "" : "\82æ\82¤\82¾");
701 #endif
702             otmp->bknown = TRUE;
703             return;
704         }
705         if (!have_spot) {
706 /*JP
707             You("can't.  There isn't anywhere for you to stand.");
708 */
709             pline("\82 \82È\82½\82Ì\97§\82Â\8fê\8f\8a\82ª\82È\82¢\82Ì\82Å\8d~\82è\82ç\82ê\82È\82¢\81D");
710             return;
711         }
712         if (!has_mname(mtmp)) {
713 /*JP
714             pline("You've been through the dungeon on %s with no name.",
715 */
716             pline("\82 \82È\82½\82Í\96¼\91O\82Ì\82È\82¢%s\82Æ\8b¤\82É\96À\8b{\93à\82É\82¢\82é\81D",
717                   an(mtmp->data->mname));
718             if (Hallucination)
719 /*JP
720                 pline("It felt good to get out of the rain.");
721 */
722                 pline("\89J\82ª\8d~\82ç\82È\82¢\82Ì\82Æ\82¢\82¤\82Ì\82Í\82¢\82¢\8bC\95ª\82¾\82Á\82½\81D");
723         } else
724 /*JP
725             You("dismount %s.", mon_nam(mtmp));
726 */
727             You("%s\82©\82ç\8d~\82è\82½\81D", mon_nam(mtmp));
728     }
729     /* While riding, Wounded_legs refers to the steed's legs;
730        after dismounting, it reverts to the hero's legs. */
731     if (repair_leg_damage)
732         heal_legs(1);
733
734     /* Release the steed and saddle */
735     u.usteed = 0;
736     u.ugallop = 0L;
737     /*
738      * rloc(), rloc_to(), and monkilled()->mondead()->m_detach() all
739      * expect mtmp to be on the map or else have mtmp->mx be 0, but
740      * setting the latter to 0 here would interfere with dropping
741      * the saddle.  Prior to 3.6.2, being off the map didn't matter.
742      *
743      * place_monster() expects mtmp to be alive and not be u.usteed.
744      *
745      * Unfortunately, <u.ux,u.uy> (former steed's implicit location)
746      * might now be occupied by an engulfer, so we can't just put mtmp
747      * at that spot.  An engulfer's previous spot will be unoccupied
748      * but we don't know where that was and even if we did, it might
749      * be hostile terrain.
750      */
751     steedcc.x = u.ux, steedcc.y = u.uy;
752     if (m_at(u.ux, u.uy)) {
753         /* hero's spot has a monster in it; hero must have been plucked
754            from saddle as engulfer moved into his spot--other dismounts
755            shouldn't run into this situation; find nearest viable spot */
756         if (!enexto(&steedcc, u.ux, u.uy, mtmp->data)
757             /* no spot? must have been engulfed by a lurker-above over
758                water or lava; try requesting a location for a flyer */
759             && !enexto(&steedcc, u.ux, u.uy, &mons[PM_BAT]))
760             /* still no spot; last resort is any spot within bounds */
761             (void) enexto(&steedcc, u.ux, u.uy, &mons[PM_GHOST]);
762     }
763     if (!m_at(steedcc.x, steedcc.y)) {
764         if (mtmp->mhp < 1)
765             mtmp->mhp = 0; /* make sure it isn't negative */
766         mtmp->mhp++; /* force at least one hit point, possibly resurrecting */
767         place_monster(mtmp, steedcc.x, steedcc.y);
768         mtmp->mhp--; /* take the extra hit point away: cancel resurrection */
769     } else {
770         impossible("Dismounting: can't place former steed on map.");
771     }
772
773     if (!DEADMONSTER(mtmp)) {
774         /* if for bones, there's no reason to place the hero;
775            we want to make room for potential ghost, so move steed */
776         if (reason == DISMOUNT_BONES) {
777             /* move the steed to an adjacent square */
778             if (enexto(&cc, u.ux, u.uy, mtmp->data))
779                 rloc_to(mtmp, cc.x, cc.y);
780             else /* evidently no room nearby; move steed elsewhere */
781                 (void) rloc(mtmp, FALSE);
782             return;
783         }
784
785         /* Set hero's and/or steed's positions.  Try moving the hero first. */
786         if (!u.uswallow && !u.ustuck && have_spot) {
787             struct permonst *mdat = mtmp->data;
788
789             /* The steed may drop into water/lava */
790             if (!is_flyer(mdat) && !is_floater(mdat) && !is_clinger(mdat)) {
791                 if (is_pool(u.ux, u.uy)) {
792                     if (!Underwater)
793 /*JP
794                         pline("%s falls into the %s!", Monnam(mtmp),
795 */
796                         pline("%s\82Í%s\82É\97\8e\82¿\82½\81I", Monnam(mtmp),
797                               surface(u.ux, u.uy));
798                     if (!is_swimmer(mdat) && !amphibious(mdat)) {
799                         killed(mtmp);
800                         adjalign(-1);
801                     }
802                 } else if (is_lava(u.ux, u.uy)) {
803 #if 0 /*JP*/
804                     pline("%s is pulled into the %s!", Monnam(mtmp),
805                           hliquid("lava"));
806 #else
807                     pline("%s\82Í%s\82Ì\92\86\82É\82Ð\82Á\82Ï\82ç\82ê\82½\81I", Monnam(mtmp),
808                           hliquid("\97n\8aâ"));
809 #endif
810                     if (!likes_lava(mdat)) {
811                         killed(mtmp);
812                         adjalign(-1);
813                     }
814                 }
815             }
816             /* Steed dismounting consists of two steps: being moved to another
817              * square, and descending to the floor.  We have functions to do
818              * each of these activities, but they're normally called
819              * individually and include an attempt to look at or pick up the
820              * objects on the floor:
821              * teleds() --> spoteffects() --> pickup()
822              * float_down() --> pickup()
823              * We use this kludge to make sure there is only one such attempt.
824              *
825              * Clearly this is not the best way to do it.  A full fix would
826              * involve having these functions not call pickup() at all,
827              * instead
828              * calling them first and calling pickup() afterwards.  But it
829              * would take a lot of work to keep this change from having any
830              * unforeseen side effects (for instance, you would no longer be
831              * able to walk onto a square with a hole, and autopickup before
832              * falling into the hole).
833              */
834             /* [ALI] No need to move the player if the steed died. */
835             if (!DEADMONSTER(mtmp)) {
836                 /* Keep steed here, move the player to cc;
837                  * teleds() clears u.utrap
838                  */
839                 in_steed_dismounting = TRUE;
840                 teleds(cc.x, cc.y, TRUE);
841                 in_steed_dismounting = FALSE;
842
843                 /* Put your steed in your trap */
844                 if (save_utrap)
845                     (void) mintrap(mtmp);
846             }
847
848         /* Couldn't move hero... try moving the steed. */
849         } else if (enexto(&cc, u.ux, u.uy, mtmp->data)) {
850             /* Keep player here, move the steed to cc */
851             rloc_to(mtmp, cc.x, cc.y);
852             /* Player stays put */
853
854         /* Otherwise, kill the steed. */
855         } else {
856             if (reason == DISMOUNT_BYCHOICE) {
857                 /* [un]#ride: hero gets credit/blame for killing steed */
858                 killed(mtmp);
859                 adjalign(-1);
860             } else {
861                 /* other dismount: kill former steed with no penalty;
862                    damage type is just "neither AD_DGST nor -AD_RBRE" */
863                 monkilled(mtmp, "", -AD_PHYS);
864             }
865         }
866     } /* !DEADMONST(mtmp) */
867
868     /* usually return the hero to the surface */
869     if (reason != DISMOUNT_ENGULFED && reason != DISMOUNT_BONES) {
870         in_steed_dismounting = TRUE;
871         (void) float_down(0L, W_SADDLE);
872         in_steed_dismounting = FALSE;
873         context.botl = TRUE;
874         (void) encumber_msg();
875         vision_full_recalc = 1;
876     } else
877         context.botl = TRUE;
878     /* polearms behave differently when not mounted */
879     if (uwep && is_pole(uwep))
880         unweapon = TRUE;
881     return;
882 }
883
884 /* when attempting to saddle or mount a sleeping steed, try to wake it up
885    (for the saddling case, it won't be u.usteed yet) */
886 STATIC_OVL void
887 maybewakesteed(steed)
888 struct monst *steed;
889 {
890     int frozen = (int) steed->mfrozen;
891     boolean wasimmobile = steed->msleeping || !steed->mcanmove;
892
893     steed->msleeping = 0;
894     if (frozen) {
895         frozen = (frozen + 1) / 2; /* half */
896         /* might break out of timed sleep or paralysis */
897         if (!rn2(frozen)) {
898             steed->mfrozen = 0;
899             steed->mcanmove = 1;
900         } else {
901             /* didn't awake, but remaining duration is halved */
902             steed->mfrozen = frozen;
903         }
904     }
905     if (wasimmobile && !steed->msleeping && steed->mcanmove)
906 /*JP
907         pline("%s wakes up.", Monnam(steed));
908 */
909         pline("%s\82Í\8bN\82«\82½\81D", Monnam(steed));
910     /* regardless of waking, terminate any meal in progress */
911     finish_meating(steed);
912 }
913
914 /* decide whether hero's steed is able to move;
915    doesn't check for holding traps--those affect the hero directly */
916 boolean
917 stucksteed(checkfeeding)
918 boolean checkfeeding;
919 {
920     struct monst *steed = u.usteed;
921
922     if (steed) {
923         /* check whether steed can move */
924         if (steed->msleeping || !steed->mcanmove) {
925 /*JP
926             pline("%s won't move!", upstart(y_monnam(steed)));
927 */
928             pline("%s\82Í\93®\82¯\82È\82¢\81I", y_monnam(steed));
929             return TRUE;
930         }
931         /* optionally check whether steed is in the midst of a meal */
932         if (checkfeeding && steed->meating) {
933 /*JP
934             pline("%s is still eating.", upstart(y_monnam(steed)));
935 */
936             pline("%s\82Í\82Ü\82¾\90H\82×\82Ä\82¢\82é\81D", y_monnam(steed));
937             return TRUE;
938         }
939     }
940     return FALSE;
941 }
942
943 void
944 place_monster(mon, x, y)
945 struct monst *mon;
946 int x, y;
947 {
948     /* normal map bounds are <1..COLNO-1,0..ROWNO-1> but sometimes
949        vault guards (either living or dead) are parked at <0,0> */
950     if (!isok(x, y) && (x != 0 || y != 0 || !mon->isgd)) {
951         impossible("trying to place monster at <%d,%d>", x, y);
952         x = y = 0;
953     }
954     if (mon == u.usteed
955         /* special case is for convoluted vault guard handling */
956         || (DEADMONSTER(mon) && !(mon->isgd && x == 0 && y == 0))) {
957         impossible("placing %s onto map?",
958                    (mon == u.usteed) ? "steed" : "defunct monster");
959         return;
960     }
961     if (level.monsters[x][y])
962         impossible("placing monster over another at <%d,%d>?", x, y);
963     mon->mx = x, mon->my = y;
964     level.monsters[x][y] = mon;
965 }
966
967 /*steed.c*/