OSDN Git Service

version++
[jnethack/source.git] / src / dbridge.c
1 /* NetHack 3.6  dbridge.c       $NHDT-Date: 1449269914 2015/12/04 22:58:34 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.35 $ */
2 /*      Copyright (c) 1989 by Jean-Christophe Collet              */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /*
6  * This file contains the drawbridge manipulation (create, open, close,
7  * destroy).
8  *
9  * Added comprehensive monster-handling, and the "entity" structure to
10  * deal with players as well. - 11/89
11  *
12  * Any traps and/or engravings at either the portcullis or span location
13  * are destroyed whenever the bridge is lowered, raised, or destroyed.
14  * (Engraving handling could be extended to flag whether an engraving on
15  * the DB_UNDER surface is hidden by the lowered bridge, or one on the
16  * bridge itself is hidden because the bridge has been raised, but that
17  * seems like an awful lot of effort for very little gain.)
18  */
19
20 /* JNetHack Copyright */
21 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
22 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
23 /* JNetHack may be freely redistributed.  See license for details. */
24
25 #include "hack.h"
26
27 STATIC_DCL void FDECL(get_wall_for_db, (int *, int *));
28 STATIC_DCL struct entity *FDECL(e_at, (int, int));
29 STATIC_DCL void FDECL(m_to_e, (struct monst *, int, int, struct entity *));
30 STATIC_DCL void FDECL(u_to_e, (struct entity *));
31 STATIC_DCL void FDECL(set_entity, (int, int, struct entity *));
32 STATIC_DCL const char *FDECL(e_nam, (struct entity *));
33 STATIC_DCL const char *FDECL(E_phrase, (struct entity *, const char *));
34 STATIC_DCL boolean FDECL(e_survives_at, (struct entity *, int, int));
35 STATIC_DCL void FDECL(e_died, (struct entity *, int, int));
36 STATIC_DCL boolean FDECL(automiss, (struct entity *));
37 STATIC_DCL boolean FDECL(e_missed, (struct entity *, BOOLEAN_P));
38 STATIC_DCL boolean FDECL(e_jumps, (struct entity *));
39 STATIC_DCL void FDECL(do_entity, (struct entity *));
40
41 boolean
42 is_pool(x, y)
43 int x, y;
44 {
45     schar ltyp;
46
47     if (!isok(x, y))
48         return FALSE;
49     ltyp = levl[x][y].typ;
50     /* The ltyp == MOAT is not redundant with is_moat, because the
51      * Juiblex level does not have moats, although it has MOATs. There
52      * is probably a better way to express this. */
53     if (ltyp == POOL || ltyp == MOAT || ltyp == WATER || is_moat(x, y))
54         return TRUE;
55     return FALSE;
56 }
57
58 boolean
59 is_lava(x, y)
60 int x, y;
61 {
62     schar ltyp;
63
64     if (!isok(x, y))
65         return FALSE;
66     ltyp = levl[x][y].typ;
67     if (ltyp == LAVAPOOL
68         || (ltyp == DRAWBRIDGE_UP
69             && (levl[x][y].drawbridgemask & DB_UNDER) == DB_LAVA))
70         return TRUE;
71     return FALSE;
72 }
73
74 boolean
75 is_pool_or_lava(x, y)
76 int x, y;
77 {
78     if (is_pool(x, y) || is_lava(x, y))
79         return TRUE;
80     else
81         return FALSE;
82 }
83
84 boolean
85 is_ice(x, y)
86 int x, y;
87 {
88     schar ltyp;
89
90     if (!isok(x, y))
91         return FALSE;
92     ltyp = levl[x][y].typ;
93     if (ltyp == ICE || (ltyp == DRAWBRIDGE_UP
94                         && (levl[x][y].drawbridgemask & DB_UNDER) == DB_ICE))
95         return TRUE;
96     return FALSE;
97 }
98
99 boolean
100 is_moat(x, y)
101 int x, y;
102 {
103     schar ltyp;
104
105     if (!isok(x, y))
106         return FALSE;
107     ltyp = levl[x][y].typ;
108     if (!Is_juiblex_level(&u.uz)
109         && (ltyp == MOAT
110             || (ltyp == DRAWBRIDGE_UP
111                 && (levl[x][y].drawbridgemask & DB_UNDER) == DB_MOAT)))
112         return TRUE;
113     return FALSE;
114 }
115
116 schar
117 db_under_typ(mask)
118 int mask;
119 {
120     switch (mask & DB_UNDER) {
121     case DB_ICE:
122         return ICE;
123         break;
124     case DB_LAVA:
125         return LAVAPOOL;
126         break;
127     case DB_MOAT:
128         return MOAT;
129         break;
130     default:
131         return STONE;
132         break;
133     }
134 }
135
136 /*
137  * We want to know whether a wall (or a door) is the portcullis (passageway)
138  * of an eventual drawbridge.
139  *
140  * Return value:  the direction of the drawbridge.
141  */
142
143 int
144 is_drawbridge_wall(x, y)
145 int x, y;
146 {
147     struct rm *lev;
148
149     lev = &levl[x][y];
150     if (lev->typ != DOOR && lev->typ != DBWALL)
151         return -1;
152
153     if (IS_DRAWBRIDGE(levl[x + 1][y].typ)
154         && (levl[x + 1][y].drawbridgemask & DB_DIR) == DB_WEST)
155         return DB_WEST;
156     if (IS_DRAWBRIDGE(levl[x - 1][y].typ)
157         && (levl[x - 1][y].drawbridgemask & DB_DIR) == DB_EAST)
158         return DB_EAST;
159     if (IS_DRAWBRIDGE(levl[x][y - 1].typ)
160         && (levl[x][y - 1].drawbridgemask & DB_DIR) == DB_SOUTH)
161         return DB_SOUTH;
162     if (IS_DRAWBRIDGE(levl[x][y + 1].typ)
163         && (levl[x][y + 1].drawbridgemask & DB_DIR) == DB_NORTH)
164         return DB_NORTH;
165
166     return -1;
167 }
168
169 /*
170  * Use is_db_wall where you want to verify that a
171  * drawbridge "wall" is UP in the location x, y
172  * (instead of UP or DOWN, as with is_drawbridge_wall).
173  */
174 boolean
175 is_db_wall(x, y)
176 int x, y;
177 {
178     return (boolean) (levl[x][y].typ == DBWALL);
179 }
180
181 /*
182  * Return true with x,y pointing to the drawbridge if x,y initially indicate
183  * a drawbridge or drawbridge wall.
184  */
185 boolean
186 find_drawbridge(x, y)
187 int *x, *y;
188 {
189     int dir;
190
191     if (IS_DRAWBRIDGE(levl[*x][*y].typ))
192         return TRUE;
193     dir = is_drawbridge_wall(*x, *y);
194     if (dir >= 0) {
195         switch (dir) {
196         case DB_NORTH:
197             (*y)++;
198             break;
199         case DB_SOUTH:
200             (*y)--;
201             break;
202         case DB_EAST:
203             (*x)--;
204             break;
205         case DB_WEST:
206             (*x)++;
207             break;
208         }
209         return TRUE;
210     }
211     return FALSE;
212 }
213
214 /*
215  * Find the drawbridge wall associated with a drawbridge.
216  */
217 STATIC_OVL void
218 get_wall_for_db(x, y)
219 int *x, *y;
220 {
221     switch (levl[*x][*y].drawbridgemask & DB_DIR) {
222     case DB_NORTH:
223         (*y)--;
224         break;
225     case DB_SOUTH:
226         (*y)++;
227         break;
228     case DB_EAST:
229         (*x)++;
230         break;
231     case DB_WEST:
232         (*x)--;
233         break;
234     }
235 }
236
237 /*
238  * Creation of a drawbridge at pos x,y.
239  *     dir is the direction.
240  *     flag must be put to TRUE if we want the drawbridge to be opened.
241  */
242
243 boolean
244 create_drawbridge(x, y, dir, flag)
245 int x, y, dir;
246 boolean flag;
247 {
248     int x2, y2;
249     boolean horiz;
250     boolean lava = levl[x][y].typ == LAVAPOOL; /* assume initialized map */
251
252     x2 = x;
253     y2 = y;
254     switch (dir) {
255     case DB_NORTH:
256         horiz = TRUE;
257         y2--;
258         break;
259     case DB_SOUTH:
260         horiz = TRUE;
261         y2++;
262         break;
263     case DB_EAST:
264         horiz = FALSE;
265         x2++;
266         break;
267     default:
268         impossible("bad direction in create_drawbridge");
269         /*FALLTHRU*/
270     case DB_WEST:
271         horiz = FALSE;
272         x2--;
273         break;
274     }
275     if (!IS_WALL(levl[x2][y2].typ))
276         return FALSE;
277     if (flag) { /* We want the bridge open */
278         levl[x][y].typ = DRAWBRIDGE_DOWN;
279         levl[x2][y2].typ = DOOR;
280         levl[x2][y2].doormask = D_NODOOR;
281     } else {
282         levl[x][y].typ = DRAWBRIDGE_UP;
283         levl[x2][y2].typ = DBWALL;
284         /* Drawbridges are non-diggable. */
285         levl[x2][y2].wall_info = W_NONDIGGABLE;
286     }
287     levl[x][y].horizontal = !horiz;
288     levl[x2][y2].horizontal = horiz;
289     levl[x][y].drawbridgemask = dir;
290     if (lava)
291         levl[x][y].drawbridgemask |= DB_LAVA;
292     return  TRUE;
293 }
294
295 struct entity {
296     struct monst *emon;     /* youmonst for the player */
297     struct permonst *edata; /* must be non-zero for record to be valid */
298     int ex, ey;
299 };
300
301 #define ENTITIES 2
302
303 static NEARDATA struct entity occupants[ENTITIES];
304
305 STATIC_OVL
306 struct entity *
307 e_at(x, y)
308 int x, y;
309 {
310     int entitycnt;
311
312     for (entitycnt = 0; entitycnt < ENTITIES; entitycnt++)
313         if ((occupants[entitycnt].edata) && (occupants[entitycnt].ex == x)
314             && (occupants[entitycnt].ey == y))
315             break;
316     debugpline1("entitycnt = %d", entitycnt);
317 #ifdef D_DEBUG
318     wait_synch();
319 #endif
320     return (entitycnt == ENTITIES) ? (struct entity *) 0
321                                    : &(occupants[entitycnt]);
322 }
323
324 STATIC_OVL void
325 m_to_e(mtmp, x, y, etmp)
326 struct monst *mtmp;
327 int x, y;
328 struct entity *etmp;
329 {
330     etmp->emon = mtmp;
331     if (mtmp) {
332         etmp->ex = x;
333         etmp->ey = y;
334         if (mtmp->wormno && (x != mtmp->mx || y != mtmp->my))
335             etmp->edata = &mons[PM_LONG_WORM_TAIL];
336         else
337             etmp->edata = mtmp->data;
338     } else
339         etmp->edata = (struct permonst *) 0;
340 }
341
342 STATIC_OVL void
343 u_to_e(etmp)
344 struct entity *etmp;
345 {
346     etmp->emon = &youmonst;
347     etmp->ex = u.ux;
348     etmp->ey = u.uy;
349     etmp->edata = youmonst.data;
350 }
351
352 STATIC_OVL void
353 set_entity(x, y, etmp)
354 int x, y;
355 struct entity *etmp;
356 {
357     if ((x == u.ux) && (y == u.uy))
358         u_to_e(etmp);
359     else if (MON_AT(x, y))
360         m_to_e(m_at(x, y), x, y, etmp);
361     else
362         etmp->edata = (struct permonst *) 0;
363 }
364
365 #define is_u(etmp) (etmp->emon == &youmonst)
366 #define e_canseemon(etmp) \
367     (is_u(etmp) ? (boolean) TRUE : canseemon(etmp->emon))
368
369 /*
370  * e_strg is a utility routine which is not actually in use anywhere, since
371  * the specialized routines below suffice for all current purposes.
372  */
373
374 /* #define e_strg(etmp, func) (is_u(etmp)? (char *)0 : func(etmp->emon)) */
375
376 STATIC_OVL const char *
377 e_nam(etmp)
378 struct entity *etmp;
379 {
380 /*JP
381     return is_u(etmp) ? "you" : mon_nam(etmp->emon);
382 */
383     return is_u(etmp) ? "\82 \82È\82½" : mon_nam(etmp->emon);
384 }
385
386 /*
387  * Generates capitalized entity name, makes 2nd -> 3rd person conversion on
388  * verb, where necessary.
389  */
390
391 STATIC_OVL const char *
392 E_phrase(etmp, verb)
393 struct entity *etmp;
394 const char *verb;
395 {
396     static char wholebuf[80];
397
398 #if 1 /*JP*/
399     Strcpy(wholebuf, is_u(etmp) ? "\82 \82È\82½" : Monnam(etmp->emon));
400     return wholebuf;
401 #else
402     Strcpy(wholebuf, is_u(etmp) ? "You" : Monnam(etmp->emon));
403     if (!verb || !*verb)
404         return wholebuf;
405     Strcat(wholebuf, " ");
406     if (is_u(etmp))
407         Strcat(wholebuf, verb);
408     else
409         Strcat(wholebuf, vtense((char *) 0, verb));
410     return wholebuf;
411 #endif
412 }
413
414 /*
415  * Simple-minded "can it be here?" routine
416  */
417
418 STATIC_OVL boolean
419 e_survives_at(etmp, x, y)
420 struct entity *etmp;
421 int x, y;
422 {
423     if (noncorporeal(etmp->edata))
424         return TRUE;
425     if (is_pool(x, y))
426         return (boolean) ((is_u(etmp) && (Wwalking || Amphibious || Swimming
427                                           || Flying || Levitation))
428                           || is_swimmer(etmp->edata)
429                           || is_flyer(etmp->edata)
430                           || is_floater(etmp->edata));
431     /* must force call to lava_effects in e_died if is_u */
432     if (is_lava(x, y))
433         return (boolean) ((is_u(etmp) && (Levitation || Flying))
434                           || likes_lava(etmp->edata)
435                           || is_flyer(etmp->edata));
436     if (is_db_wall(x, y))
437         return (boolean) (is_u(etmp) ? Passes_walls
438                           : passes_walls(etmp->edata));
439     return TRUE;
440 }
441
442 STATIC_OVL void
443 e_died(etmp, dest, how)
444 struct entity *etmp;
445 int dest, how;
446 {
447     if (is_u(etmp)) {
448         if (how == DROWNING) {
449             killer.name[0] = 0; /* drown() sets its own killer */
450             (void) drown();
451         } else if (how == BURNING) {
452             killer.name[0] = 0; /* lava_effects() sets own killer */
453             (void) lava_effects();
454         } else {
455             coord xy;
456
457             /* use more specific killer if specified */
458             if (!killer.name[0]) {
459                 killer.format = KILLED_BY_AN;
460 /*JP
461                 Strcpy(killer.name, "falling drawbridge");
462 */
463                 Strcpy(killer.name, "\8d~\82è\82Ä\82«\82½\92µ\82Ë\8b´\82Å");
464             }
465             done(how);
466             /* So, you didn't die */
467             if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
468                 if (enexto(&xy, etmp->ex, etmp->ey, etmp->edata)) {
469 #if 0 /*JP*/
470                     pline("A %s force teleports you away...",
471                           Hallucination ? "normal" : "strange");
472 #else
473                     pline("%s\97Í\82ª\82 \82È\82½\82ð\89\93\82­\82É\89^\82ñ\82¾\81D\81D\81D",
474                           Hallucination ? "\95\81\92Ê\82Ì" : "\8aï\96­\82È");
475 #endif
476                     teleds(xy.x, xy.y, FALSE);
477                 }
478                 /* otherwise on top of the drawbridge is the
479                  * only viable spot in the dungeon, so stay there
480                  */
481             }
482         }
483         /* we might have crawled out of the moat to survive */
484         etmp->ex = u.ux, etmp->ey = u.uy;
485     } else {
486         int entitycnt;
487
488         killer.name[0] = 0;
489 /* fake "digested to death" damage-type suppresses corpse */
490 #define mk_message(dest) ((dest & 1) ? "" : (char *) 0)
491 #define mk_corpse(dest) ((dest & 2) ? AD_DGST : AD_PHYS)
492         /* if monsters are moving, one of them caused the destruction */
493         if (context.mon_moving)
494             monkilled(etmp->emon, mk_message(dest), mk_corpse(dest));
495         else /* you caused it */
496             xkilled(etmp->emon, dest);
497         etmp->edata = (struct permonst *) 0;
498
499         /* dead long worm handling */
500         for (entitycnt = 0; entitycnt < ENTITIES; entitycnt++) {
501             if (etmp != &(occupants[entitycnt])
502                 && etmp->emon == occupants[entitycnt].emon)
503                 occupants[entitycnt].edata = (struct permonst *) 0;
504         }
505 #undef mk_message
506 #undef mk_corpse
507     }
508 }
509
510 /*
511  * These are never directly affected by a bridge or portcullis.
512  */
513
514 STATIC_OVL boolean
515 automiss(etmp)
516 struct entity *etmp;
517 {
518     return (boolean) ((is_u(etmp) ? Passes_walls : passes_walls(etmp->edata))
519                       || noncorporeal(etmp->edata));
520 }
521
522 /*
523  * Does falling drawbridge or portcullis miss etmp?
524  */
525
526 STATIC_OVL boolean
527 e_missed(etmp, chunks)
528 struct entity *etmp;
529 boolean chunks;
530 {
531     int misses;
532
533     if (chunks) {
534         debugpline0("Do chunks miss?");
535     }
536     if (automiss(etmp))
537         return TRUE;
538
539     if (is_flyer(etmp->edata)
540         && (is_u(etmp) ? !Unaware
541                        : (etmp->emon->mcanmove && !etmp->emon->msleeping)))
542         /* flying requires mobility */
543         misses = 5; /* out of 8 */
544     else if (is_floater(etmp->edata)
545              || (is_u(etmp) && Levitation)) /* doesn't require mobility */
546         misses = 3;
547     else if (chunks && is_pool(etmp->ex, etmp->ey))
548         misses = 2; /* sitting ducks */
549     else
550         misses = 0;
551
552     if (is_db_wall(etmp->ex, etmp->ey))
553         misses -= 3; /* less airspace */
554
555     debugpline1("Miss chance = %d (out of 8)", misses);
556
557     return (misses >= rnd(8)) ? TRUE : FALSE;
558 }
559
560 /*
561  * Can etmp jump from death?
562  */
563
564 STATIC_OVL boolean
565 e_jumps(etmp)
566 struct entity *etmp;
567 {
568     int tmp = 4; /* out of 10 */
569
570     if (is_u(etmp) ? (Unaware || Fumbling)
571                    : (!etmp->emon->mcanmove || etmp->emon->msleeping
572                       || !etmp->edata->mmove || etmp->emon->wormno))
573         return FALSE;
574
575     if (is_u(etmp) ? Confusion : etmp->emon->mconf)
576         tmp -= 2;
577
578     if (is_u(etmp) ? Stunned : etmp->emon->mstun)
579         tmp -= 3;
580
581     if (is_db_wall(etmp->ex, etmp->ey))
582         tmp -= 2; /* less room to maneuver */
583
584     debugpline2("%s to jump (%d chances in 10)", E_phrase(etmp, "try"), tmp);
585     return (tmp >= rnd(10)) ? TRUE : FALSE;
586 }
587
588 STATIC_OVL void
589 do_entity(etmp)
590 struct entity *etmp;
591 {
592     int newx, newy, at_portcullis, oldx, oldy;
593     boolean must_jump = FALSE, relocates = FALSE, e_inview;
594     struct rm *crm;
595
596     if (!etmp->edata)
597         return;
598
599     e_inview = e_canseemon(etmp);
600     oldx = etmp->ex;
601     oldy = etmp->ey;
602     at_portcullis = is_db_wall(oldx, oldy);
603     crm = &levl[oldx][oldy];
604
605     if (automiss(etmp) && e_survives_at(etmp, oldx, oldy)) {
606         if (e_inview && (at_portcullis || IS_DRAWBRIDGE(crm->typ)))
607 #if 0 /*JP*/
608             pline_The("%s passes through %s!",
609                       at_portcullis ? "portcullis" : "drawbridge",
610                       e_nam(etmp));
611 #else
612             pline_The("%s\82Í%s\82ð\92Ê\82è\94²\82¯\82½\81I",
613                       at_portcullis ? "\97\8e\82µ\8ai\8eq" : "\92µ\82Ë\8b´",
614                       e_nam(etmp));
615 #endif
616         if (is_u(etmp))
617             spoteffects(FALSE);
618         return;
619     }
620     if (e_missed(etmp, FALSE)) {
621         if (at_portcullis) {
622 /*JP
623             pline_The("portcullis misses %s!", e_nam(etmp));
624 */
625             pline("\97\8e\82µ\8ai\8eq\82Í%s\82É\96½\92\86\82µ\82È\82©\82Á\82½\81I", e_nam(etmp));
626         } else {
627             debugpline1("The drawbridge misses %s!", e_nam(etmp));
628         }
629         if (e_survives_at(etmp, oldx, oldy)) {
630             return;
631         } else {
632             debugpline0("Mon can't survive here");
633             if (at_portcullis)
634                 must_jump = TRUE;
635             else
636                 relocates = TRUE; /* just ride drawbridge in */
637         }
638     } else {
639         if (crm->typ == DRAWBRIDGE_DOWN) {
640 /*JP
641             pline("%s crushed underneath the drawbridge.",
642 */
643             pline("%s\82Í\92µ\82Ë\8b´\82Ì\89º\95~\82É\82È\82Á\82½\81D",
644                   E_phrase(etmp, "are"));             /* no jump */
645             e_died(etmp, e_inview ? 3 : 2, CRUSHING); /* no corpse */
646             return;       /* Note: Beyond this point, we know we're  */
647         }                 /* not at an opened drawbridge, since all  */
648         must_jump = TRUE; /* *missable* creatures survive on the     */
649     }                     /* square, and all the unmissed ones die.  */
650     if (must_jump) {
651         if (at_portcullis) {
652             if (e_jumps(etmp)) {
653                 relocates = TRUE;
654                 debugpline0("Jump succeeds!");
655             } else {
656                 if (e_inview)
657 /*JP
658                     pline("%s crushed by the falling portcullis!",
659 */
660                     pline("%s\82Í\97\8e\82¿\82Ä\82«\82½\97\8e\82µ\8ai\8eq\82É\92×\82³\82ê\82½\81I",
661                           E_phrase(etmp, "are"));
662                 else if (!Deaf)
663 /*JP
664                     You_hear("a crushing sound.");
665 */
666                     You_hear("\89½\82©\82ª\92×\82ê\82é\89¹\82ð\95·\82¢\82½\81D");
667                 e_died(etmp, e_inview ? 3 : 2, CRUSHING);
668                 /* no corpse */
669                 return;
670             }
671         } else { /* tries to jump off bridge to original square */
672             relocates = !e_jumps(etmp);
673             debugpline1("Jump %s!", (relocates) ? "fails" : "succeeds");
674         }
675     }
676
677     /*
678      * Here's where we try to do relocation.  Assumes that etmp is not
679      * arriving
680      * at the portcullis square while the drawbridge is falling, since this
681      * square
682      * would be inaccessible (i.e. etmp started on drawbridge square) or
683      * unnecessary (i.e. etmp started here) in such a situation.
684      */
685     debugpline0("Doing relocation.");
686     newx = oldx;
687     newy = oldy;
688     (void) find_drawbridge(&newx, &newy);
689     if ((newx == oldx) && (newy == oldy))
690         get_wall_for_db(&newx, &newy);
691     debugpline0("Checking new square for occupancy.");
692     if (relocates && (e_at(newx, newy))) {
693         /*
694          * Standoff problem:  one or both entities must die, and/or both
695          * switch
696          * places.  Avoid infinite recursion by checking first whether the
697          * other
698          * entity is staying put.  Clean up if we happen to move/die in
699          * recursion.
700          */
701         struct entity *other;
702
703         other = e_at(newx, newy);
704         debugpline1("New square is occupied by %s", e_nam(other));
705         if (e_survives_at(other, newx, newy) && automiss(other)) {
706             relocates = FALSE; /* "other" won't budge */
707             debugpline1("%s suicide.", E_phrase(etmp, "commit"));
708         } else {
709             debugpline1("Handling %s", e_nam(other));
710             while ((e_at(newx, newy) != 0) && (e_at(newx, newy) != etmp))
711                 do_entity(other);
712             debugpline1("Checking existence of %s", e_nam(etmp));
713 #ifdef D_DEBUG
714             wait_synch();
715 #endif
716             if (e_at(oldx, oldy) != etmp) {
717                 debugpline1("%s moved or died in recursion somewhere",
718                             E_phrase(etmp, "have"));
719 #ifdef D_DEBUG
720                 wait_synch();
721 #endif
722                 return;
723             }
724         }
725     }
726     if (relocates && !e_at(newx, newy)) { /* if e_at() entity = worm tail */
727         debugpline1("Moving %s", e_nam(etmp));
728         if (!is_u(etmp)) {
729             remove_monster(etmp->ex, etmp->ey);
730             place_monster(etmp->emon, newx, newy);
731             update_monster_region(etmp->emon);
732         } else {
733             u.ux = newx;
734             u.uy = newy;
735         }
736         etmp->ex = newx;
737         etmp->ey = newy;
738         e_inview = e_canseemon(etmp);
739     }
740     debugpline1("Final disposition of %s", e_nam(etmp));
741 #ifdef D_DEBUG
742     wait_synch();
743 #endif
744     if (is_db_wall(etmp->ex, etmp->ey)) {
745         debugpline1("%s in portcullis chamber", E_phrase(etmp, "are"));
746 #ifdef D_DEBUG
747         wait_synch();
748 #endif
749         if (e_inview) {
750             if (is_u(etmp)) {
751 /*JP
752                 You("tumble towards the closed portcullis!");
753 */
754                 You("\95Â\82Ü\82è\82©\82¯\82Ì\97\8e\82µ\8ai\8eq\82ð\82±\82ë\82Ô\82æ\82¤\82É\82·\82è\82Ê\82¯\82½\81I");
755                 if (automiss(etmp))
756 /*JP
757                     You("pass through it!");
758 */
759                     You("\92Ê\82è\82Ê\82¯\82½\81I");
760                 else
761 /*JP
762                     pline_The("drawbridge closes in...");
763 */
764                     pline_The("\92µ\82Ë\8b´\82Í\95Â\82\82½\81D\81D\81D");
765             } else
766 /*JP
767                 pline("%s behind the drawbridge.",
768 */
769                 pline("%s\82Í\92µ\82Ë\8b´\82Ì\97 \82É\88Ú\93®\82µ\82½\81D",
770                       E_phrase(etmp, "disappear"));
771         }
772         if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
773             killer.format = KILLED_BY_AN;
774 /*JP
775             Strcpy(killer.name, "closing drawbridge");
776 */
777             Strcpy(killer.name, "\95Â\82\82Ä\82¢\82­\92µ\82Ë\8b´\82É\8b·\82Ü\82ê\82Ä");
778             e_died(etmp, 0, CRUSHING); /* no message */
779             return;
780         }
781         debugpline1("%s in here", E_phrase(etmp, "survive"));
782     } else {
783         debugpline1("%s on drawbridge square", E_phrase(etmp, "are"));
784         if (is_pool(etmp->ex, etmp->ey) && !e_inview)
785             if (!Deaf)
786 /*JP
787                 You_hear("a splash.");
788 */
789                 You_hear("\83p\83V\83\83\83p\83V\83\83\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
790         if (e_survives_at(etmp, etmp->ex, etmp->ey)) {
791             if (e_inview && !is_flyer(etmp->edata)
792                 && !is_floater(etmp->edata))
793 /*JP
794                 pline("%s from the bridge.", E_phrase(etmp, "fall"));
795 */
796                 pline("%s\82Í\8b´\82©\82ç\97\8e\82¿\82½\81D", E_phrase(etmp, "fall"));
797             return;
798         }
799         debugpline1("%s cannot survive on the drawbridge square",
800                     E_phrase(etmp, NULL));
801         if (is_pool(etmp->ex, etmp->ey) || is_lava(etmp->ex, etmp->ey))
802             if (e_inview && !is_u(etmp)) {
803                 /* drown() will supply msgs if nec. */
804                 boolean lava = is_lava(etmp->ex, etmp->ey);
805
806                 if (Hallucination)
807 #if 0 /*JP*/
808                     pline("%s the %s and disappears.",
809                           E_phrase(etmp, "drink"), lava ? "lava" : "moat");
810 #else
811                     pline("%s\82Í%s\82ð\88ù\82Ý\81C\8fÁ\82¦\82½\81D",
812                           E_phrase(etmp, "drink"), lava ? "\97n\8aâ" : "\96x");
813 #endif
814                 else
815 #if 0 /*JP*/
816                     pline("%s into the %s.", E_phrase(etmp, "fall"),
817                           lava ? "lava" : "moat");
818 #else
819                     pline("%s\82Í%s\82Ì\92\86\82É\97\8e\82¿\82½\81D", E_phrase(etmp, "fall"),
820                           lava ? "\97n\8aâ" : "\96x");
821 #endif
822             }
823 #if 0 /*JP:T*/
824         killer.format = NO_KILLER_PREFIX;
825         Strcpy(killer.name, "fell from a drawbridge");
826 #else
827         killer.format = KILLED_BY;
828         Strcpy(killer.name, "\92µ\82Ë\8b´\82©\82ç\97\8e\82¿\82Ä");
829 #endif
830         e_died(etmp, e_inview ? 3 : 2, /* CRUSHING is arbitrary */
831                (is_pool(etmp->ex, etmp->ey))
832                    ? DROWNING
833                    : (is_lava(etmp->ex, etmp->ey)) ? BURNING
834                                                    : CRUSHING); /*no corpse*/
835         return;
836     }
837 }
838
839 /*
840  * Close the drawbridge located at x,y
841  */
842
843 void
844 close_drawbridge(x, y)
845 int x, y;
846 {
847     register struct rm *lev1, *lev2;
848     struct trap *t;
849     int x2, y2;
850
851     lev1 = &levl[x][y];
852     if (lev1->typ != DRAWBRIDGE_DOWN)
853         return;
854     x2 = x;
855     y2 = y;
856     get_wall_for_db(&x2, &y2);
857     if (cansee(x, y) || cansee(x2, y2))
858 #if 0 /*JP*/
859         You_see("a drawbridge %s up!",
860                 (((u.ux == x || u.uy == y) && !Underwater)
861                  || distu(x2, y2) < distu(x, y))
862                     ? "coming"
863                     : "going");
864 #else
865         pline("\92µ\82Ë\8b´\82ª\8fã\82ª\82Á\82Ä\82¢\82­\82Ì\82ª\8c©\82¦\82½\81I");
866 #endif
867     else /* "5 gears turn" for castle drawbridge tune */
868 /*JP
869         You_hear("chains rattling and gears turning.");
870 */
871         You_hear("\8e\95\8eÔ\82ª\89ñ\82è\83`\83F\81[\83\93\82ª\83K\83\89\83K\83\89\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
872     lev1->typ = DRAWBRIDGE_UP;
873     lev2 = &levl[x2][y2];
874     lev2->typ = DBWALL;
875     switch (lev1->drawbridgemask & DB_DIR) {
876     case DB_NORTH:
877     case DB_SOUTH:
878         lev2->horizontal = TRUE;
879         break;
880     case DB_WEST:
881     case DB_EAST:
882         lev2->horizontal = FALSE;
883         break;
884     }
885     lev2->wall_info = W_NONDIGGABLE;
886     set_entity(x, y, &(occupants[0]));
887     set_entity(x2, y2, &(occupants[1]));
888     do_entity(&(occupants[0]));          /* Do set_entity after first */
889     set_entity(x2, y2, &(occupants[1])); /* do_entity for worm tail */
890     do_entity(&(occupants[1]));
891     if (OBJ_AT(x, y) && !Deaf)
892 /*JP
893         You_hear("smashing and crushing.");
894 */
895         You_hear("\83K\83V\83\83\83\93\81C\83K\83\89\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
896     (void) revive_nasty(x, y, (char *) 0);
897     (void) revive_nasty(x2, y2, (char *) 0);
898     delallobj(x, y);
899     delallobj(x2, y2);
900     if ((t = t_at(x, y)) != 0)
901         deltrap(t);
902     if ((t = t_at(x2, y2)) != 0)
903         deltrap(t);
904     del_engr_at(x, y);
905     del_engr_at(x2, y2);
906     newsym(x, y);
907     newsym(x2, y2);
908     block_point(x2, y2); /* vision */
909 }
910
911 /*
912  * Open the drawbridge located at x,y
913  */
914
915 void
916 open_drawbridge(x, y)
917 int x, y;
918 {
919     register struct rm *lev1, *lev2;
920     struct trap *t;
921     int x2, y2;
922
923     lev1 = &levl[x][y];
924     if (lev1->typ != DRAWBRIDGE_UP)
925         return;
926     x2 = x;
927     y2 = y;
928     get_wall_for_db(&x2, &y2);
929     if (cansee(x, y) || cansee(x2, y2))
930 #if 0 /*JP*/
931         You_see("a drawbridge %s down!",
932                 (distu(x2, y2) < distu(x, y)) ? "going" : "coming");
933 #else
934         pline("\92µ\82Ë\8b´\82ª\89º\82ª\82é\82Ì\82ª\8c©\82¦\82½\81I");
935 #endif
936     else /* "5 gears turn" for castle drawbridge tune */
937 /*JP
938         You_hear("gears turning and chains rattling.");
939 */
940         You_hear("\8e\95\8eÔ\82ª\89ñ\82è\83`\83F\81[\83\93\82ª\83K\83\89\83K\83\89\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
941     lev1->typ = DRAWBRIDGE_DOWN;
942     lev2 = &levl[x2][y2];
943     lev2->typ = DOOR;
944     lev2->doormask = D_NODOOR;
945     set_entity(x, y, &(occupants[0]));
946     set_entity(x2, y2, &(occupants[1]));
947     do_entity(&(occupants[0]));          /* do set_entity after first */
948     set_entity(x2, y2, &(occupants[1])); /* do_entity for worm tails */
949     do_entity(&(occupants[1]));
950     (void) revive_nasty(x, y, (char *) 0);
951     delallobj(x, y);
952     if ((t = t_at(x, y)) != 0)
953         deltrap(t);
954     if ((t = t_at(x2, y2)) != 0)
955         deltrap(t);
956     del_engr_at(x, y);
957     del_engr_at(x2, y2);
958     newsym(x, y);
959     newsym(x2, y2);
960     unblock_point(x2, y2); /* vision */
961     if (Is_stronghold(&u.uz))
962         u.uevent.uopened_dbridge = TRUE;
963 }
964
965 /*
966  * Let's destroy the drawbridge located at x,y
967  */
968
969 void
970 destroy_drawbridge(x, y)
971 int x, y;
972 {
973     register struct rm *lev1, *lev2;
974     struct trap *t;
975     struct obj *otmp;
976     int x2, y2, i;
977     boolean e_inview;
978     struct entity *etmp1 = &(occupants[0]), *etmp2 = &(occupants[1]);
979
980     lev1 = &levl[x][y];
981     if (!IS_DRAWBRIDGE(lev1->typ))
982         return;
983     x2 = x;
984     y2 = y;
985     get_wall_for_db(&x2, &y2);
986     lev2 = &levl[x2][y2];
987     if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT
988         || (lev1->drawbridgemask & DB_UNDER) == DB_LAVA) {
989         struct obj *otmp2;
990         boolean lava = (lev1->drawbridgemask & DB_UNDER) == DB_LAVA;
991         if (lev1->typ == DRAWBRIDGE_UP) {
992             if (cansee(x2, y2))
993 #if 0 /*JP*/
994                 pline_The("portcullis of the drawbridge falls into the %s!",
995                           lava ? "lava" : "moat");
996 #else
997                 pline("\92µ\82Ë\8b´\82Ì\97\8e\82µ\8ai\8eq\82ª%s\82É\97\8e\82¿\82½\81I",
998                           lava ? "\97n\8aâ" : "\96x");
999 #endif
1000             else if (!Deaf)
1001 /*JP
1002                 You_hear("a loud *SPLASH*!");
1003 */
1004                 You_hear("\91å\82«\82È\83o\83b\83V\83\83\81[\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81I");
1005         } else {
1006             if (cansee(x, y))
1007 #if 0 /*JP*/
1008                 pline_The("drawbridge collapses into the %s!",
1009                           lava ? "lava" : "moat");
1010 #else
1011                 pline("\92µ\82Ë\8b´\82Í%s\82É\82­\82¸\82ê\97\8e\82¿\82½\81I",
1012                           lava ? "\97n\8aâ" : "\96x");
1013 #endif
1014             else if (!Deaf)
1015 /*JP
1016                 You_hear("a loud *SPLASH*!");
1017 */
1018                 You_hear("\91å\82«\82È\83o\83b\83V\83\83\81[\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81I");
1019         }
1020         lev1->typ = lava ? LAVAPOOL : MOAT;
1021         lev1->drawbridgemask = 0;
1022         if ((otmp2 = sobj_at(BOULDER, x, y)) != 0) {
1023             obj_extract_self(otmp2);
1024 /*JP
1025             (void) flooreffects(otmp2, x, y, "fall");
1026 */
1027             (void) flooreffects(otmp2, x, y, "\97\8e\82¿\82é");
1028         }
1029     } else {
1030         if (cansee(x, y))
1031 /*JP
1032             pline_The("drawbridge disintegrates!");
1033 */
1034             pline("\92µ\82Ë\8b´\82Í\82±\82È\82²\82È\82É\82È\82Á\82½\81I");
1035         else
1036 /*JP
1037             You_hear("a loud *CRASH*!");
1038 */
1039             You_hear("\91å\82«\82È\83K\83V\83\83\81[\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81I");
1040         lev1->typ = ((lev1->drawbridgemask & DB_ICE) ? ICE : ROOM);
1041         lev1->icedpool = ((lev1->drawbridgemask & DB_ICE) ? ICED_MOAT : 0);
1042     }
1043     wake_nearto(x, y, 500);
1044     lev2->typ = DOOR;
1045     lev2->doormask = D_NODOOR;
1046     if ((t = t_at(x, y)) != 0)
1047         deltrap(t);
1048     if ((t = t_at(x2, y2)) != 0)
1049         deltrap(t);
1050     del_engr_at(x, y);
1051     del_engr_at(x2, y2);
1052     for (i = rn2(6); i > 0; --i) { /* scatter some debris */
1053         /* doesn't matter if we happen to pick <x,y2> or <x2,y>;
1054            since drawbridges are never placed diagonally, those
1055            pairings will always match one of <x,y> or <x2,y2> */
1056         otmp = mksobj_at(IRON_CHAIN, rn2(2) ? x : x2, rn2(2) ? y : y2, TRUE,
1057                          FALSE);
1058         /* a force of 5 here would yield a radius of 2 for
1059            iron chain; anything less produces a radius of 1 */
1060         (void) scatter(otmp->ox, otmp->oy, 1, MAY_HIT, otmp);
1061     }
1062     newsym(x, y);
1063     newsym(x2, y2);
1064     if (!does_block(x2, y2, lev2))
1065         unblock_point(x2, y2); /* vision */
1066     if (Is_stronghold(&u.uz))
1067         u.uevent.uopened_dbridge = TRUE;
1068
1069     set_entity(x2, y2, etmp2); /* currently only automissers can be here */
1070     if (etmp2->edata) {
1071         e_inview = e_canseemon(etmp2);
1072         if (!automiss(etmp2)) {
1073             if (e_inview)
1074 /*JP
1075                 pline("%s blown apart by flying debris.",
1076 */
1077                 pline("%s\82Í\94ò\82Ñ\8eU\82Á\82½\8a¢âI\82Ì\94j\95Ð\82ð\97\81\82Ñ\82½\81D",
1078                       E_phrase(etmp2, "are"));
1079             killer.format = KILLED_BY_AN;
1080 /*JP
1081             Strcpy(killer.name, "exploding drawbridge");
1082 */
1083             Strcpy(killer.name, "\92µ\82Ë\8b´\82Ì\94\9a\94­\82Å");
1084             e_died(etmp2, e_inview ? 3 : 2, CRUSHING); /*no corpse*/
1085         } /* nothing which is vulnerable can survive this */
1086     }
1087     set_entity(x, y, etmp1);
1088     if (etmp1->edata) {
1089         e_inview = e_canseemon(etmp1);
1090         if (e_missed(etmp1, TRUE)) {
1091             debugpline1("%s spared!", E_phrase(etmp1, "are"));
1092             /* if there is water or lava here, fall in now */
1093             if (is_u(etmp1))
1094                 spoteffects(FALSE);
1095             else
1096                 (void) minliquid(etmp1->emon);
1097         } else {
1098             if (e_inview) {
1099                 if (!is_u(etmp1) && Hallucination)
1100 /*JP
1101                     pline("%s into some heavy metal!",
1102 */
1103                     pline("%s\82Í\8fd\8bà\91®\82É\96\84\82à\82ê\82½\81I",
1104                           E_phrase(etmp1, "get"));
1105                 else
1106 /*JP
1107                     pline("%s hit by a huge chunk of metal!",
1108 */
1109                     pline("\91å\82«\82È\93S\82Ì\89ò\82ª%s\82É\96½\92\86\82µ\82½\81I",
1110                           E_phrase(etmp1, "are"));
1111             } else {
1112                 if (!Deaf && !is_u(etmp1) && !is_pool(x, y)) {
1113 /*JP
1114                     You_hear("a crushing sound.");
1115 */
1116                     You_hear("\83K\83\89\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
1117                 } else {
1118                     debugpline1("%s from shrapnel", E_phrase(etmp1, "die"));
1119                 }
1120             }
1121             killer.format = KILLED_BY_AN;
1122 /*JP
1123             Strcpy(killer.name, "collapsing drawbridge");
1124 */
1125             Strcpy(killer.name, "\83o\83\89\83o\83\89\82É\82È\82Á\82½\92µ\82Ë\8b´\82Å");
1126             e_died(etmp1, e_inview ? 3 : 2, CRUSHING); /*no corpse*/
1127             if (levl[etmp1->ex][etmp1->ey].typ == MOAT)
1128                 do_entity(etmp1);
1129         }
1130     }
1131 }
1132
1133 /*dbridge.c*/