1 /* NetHack 3.6 dbridge.c $NHDT-Date: 1503355815 2017/08/21 22:50:15 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.39 $ */
2 /* Copyright (c) 1989 by Jean-Christophe Collet */
3 /* NetHack may be freely redistributed. See license for details. */
6 * This file contains the drawbridge manipulation (create, open, close,
9 * Added comprehensive monster-handling, and the "entity" structure to
10 * deal with players as well. - 11/89
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.)
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. */
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 *));
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))
66 ltyp = levl[x][y].typ;
68 || (ltyp == DRAWBRIDGE_UP
69 && (levl[x][y].drawbridgemask & DB_UNDER) == DB_LAVA))
78 if (is_pool(x, y) || is_lava(x, y))
92 ltyp = levl[x][y].typ;
93 if (ltyp == ICE || (ltyp == DRAWBRIDGE_UP
94 && (levl[x][y].drawbridgemask & DB_UNDER) == DB_ICE))
107 ltyp = levl[x][y].typ;
108 if (!Is_juiblex_level(&u.uz)
110 || (ltyp == DRAWBRIDGE_UP
111 && (levl[x][y].drawbridgemask & DB_UNDER) == DB_MOAT)))
120 switch (mask & DB_UNDER) {
133 * We want to know whether a wall (or a door) is the portcullis (passageway)
134 * of an eventual drawbridge.
136 * Return value: the direction of the drawbridge.
140 is_drawbridge_wall(x, y)
146 if (lev->typ != DOOR && lev->typ != DBWALL)
149 if (IS_DRAWBRIDGE(levl[x + 1][y].typ)
150 && (levl[x + 1][y].drawbridgemask & DB_DIR) == DB_WEST)
152 if (IS_DRAWBRIDGE(levl[x - 1][y].typ)
153 && (levl[x - 1][y].drawbridgemask & DB_DIR) == DB_EAST)
155 if (IS_DRAWBRIDGE(levl[x][y - 1].typ)
156 && (levl[x][y - 1].drawbridgemask & DB_DIR) == DB_SOUTH)
158 if (IS_DRAWBRIDGE(levl[x][y + 1].typ)
159 && (levl[x][y + 1].drawbridgemask & DB_DIR) == DB_NORTH)
166 * Use is_db_wall where you want to verify that a
167 * drawbridge "wall" is UP in the location x, y
168 * (instead of UP or DOWN, as with is_drawbridge_wall).
174 return (boolean) (levl[x][y].typ == DBWALL);
178 * Return true with x,y pointing to the drawbridge if x,y initially indicate
179 * a drawbridge or drawbridge wall.
182 find_drawbridge(x, y)
187 if (IS_DRAWBRIDGE(levl[*x][*y].typ))
189 dir = is_drawbridge_wall(*x, *y);
211 * Find the drawbridge wall associated with a drawbridge.
214 get_wall_for_db(x, y)
217 switch (levl[*x][*y].drawbridgemask & DB_DIR) {
234 * Creation of a drawbridge at pos x,y.
235 * dir is the direction.
236 * flag must be put to TRUE if we want the drawbridge to be opened.
239 create_drawbridge(x, y, dir, flag)
245 boolean lava = levl[x][y].typ == LAVAPOOL; /* assume initialized map */
263 impossible("bad direction in create_drawbridge");
270 if (!IS_WALL(levl[x2][y2].typ))
272 if (flag) { /* We want the bridge open */
273 levl[x][y].typ = DRAWBRIDGE_DOWN;
274 levl[x2][y2].typ = DOOR;
275 levl[x2][y2].doormask = D_NODOOR;
277 levl[x][y].typ = DRAWBRIDGE_UP;
278 levl[x2][y2].typ = DBWALL;
279 /* Drawbridges are non-diggable. */
280 levl[x2][y2].wall_info = W_NONDIGGABLE;
282 levl[x][y].horizontal = !horiz;
283 levl[x2][y2].horizontal = horiz;
284 levl[x][y].drawbridgemask = dir;
286 levl[x][y].drawbridgemask |= DB_LAVA;
291 struct monst *emon; /* youmonst for the player */
292 struct permonst *edata; /* must be non-zero for record to be valid */
298 static NEARDATA struct entity occupants[ENTITIES];
307 for (entitycnt = 0; entitycnt < ENTITIES; entitycnt++)
308 if ((occupants[entitycnt].edata) && (occupants[entitycnt].ex == x)
309 && (occupants[entitycnt].ey == y))
311 debugpline1("entitycnt = %d", entitycnt);
315 return (entitycnt == ENTITIES) ? (struct entity *) 0
316 : &(occupants[entitycnt]);
320 m_to_e(mtmp, x, y, etmp)
329 if (mtmp->wormno && (x != mtmp->mx || y != mtmp->my))
330 etmp->edata = &mons[PM_LONG_WORM_TAIL];
332 etmp->edata = mtmp->data;
334 etmp->edata = (struct permonst *) 0;
341 etmp->emon = &youmonst;
344 etmp->edata = youmonst.data;
348 set_entity(x, y, etmp)
352 if ((x == u.ux) && (y == u.uy))
354 else if (MON_AT(x, y))
355 m_to_e(m_at(x, y), x, y, etmp);
357 etmp->edata = (struct permonst *) 0;
360 #define is_u(etmp) (etmp->emon == &youmonst)
361 #define e_canseemon(etmp) \
362 (is_u(etmp) ? (boolean) TRUE : canseemon(etmp->emon))
365 * e_strg is a utility routine which is not actually in use anywhere, since
366 * the specialized routines below suffice for all current purposes.
369 /* #define e_strg(etmp, func) (is_u(etmp)? (char *)0 : func(etmp->emon)) */
371 STATIC_OVL const char *
376 return is_u(etmp) ? "you" : mon_nam(etmp->emon);
378 return is_u(etmp) ? "
\82 \82È
\82½" : mon_nam(etmp->emon);
382 * Generates capitalized entity name, makes 2nd -> 3rd person conversion on
383 * verb, where necessary.
385 STATIC_OVL const char *
390 static char wholebuf[80];
393 Strcpy(wholebuf, is_u(etmp) ? "
\82 \82È
\82½" : Monnam(etmp->emon));
396 Strcpy(wholebuf, is_u(etmp) ? "You" : Monnam(etmp->emon));
399 Strcat(wholebuf, " ");
401 Strcat(wholebuf, verb);
403 Strcat(wholebuf, vtense((char *) 0, verb));
409 * Simple-minded "can it be here?" routine
412 e_survives_at(etmp, x, y)
416 if (noncorporeal(etmp->edata))
419 return (boolean) ((is_u(etmp) && (Wwalking || Amphibious || Swimming
420 || Flying || Levitation))
421 || is_swimmer(etmp->edata)
422 || is_flyer(etmp->edata)
423 || is_floater(etmp->edata));
424 /* must force call to lava_effects in e_died if is_u */
426 return (boolean) ((is_u(etmp) && (Levitation || Flying))
427 || likes_lava(etmp->edata)
428 || is_flyer(etmp->edata));
429 if (is_db_wall(x, y))
430 return (boolean) (is_u(etmp) ? Passes_walls
431 : passes_walls(etmp->edata));
436 e_died(etmp, xkill_flags, how)
438 int xkill_flags, how;
441 if (how == DROWNING) {
442 killer.name[0] = 0; /* drown() sets its own killer */
444 } else if (how == BURNING) {
445 killer.name[0] = 0; /* lava_effects() sets own killer */
446 (void) lava_effects();
450 /* use more specific killer if specified */
451 if (!killer.name[0]) {
452 killer.format = KILLED_BY_AN;
454 Strcpy(killer.name, "falling drawbridge");
456 Strcpy(killer.name, "
\8d~
\82è
\82Ä
\82«
\82½
\92µ
\82Ë
\8b´
\82Å");
459 /* So, you didn't die */
460 if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
461 if (enexto(&xy, etmp->ex, etmp->ey, etmp->edata)) {
463 pline("A %s force teleports you away...",
464 Hallucination ? "normal" : "strange");
466 pline("%s
\97Í
\82ª
\82 \82È
\82½
\82ð
\89\93\82
\82É
\89^
\82ñ
\82¾
\81D
\81D
\81D",
467 Hallucination ? "
\95\81\92Ê
\82Ì" : "
\8aï
\96
\82È");
469 teleds(xy.x, xy.y, FALSE);
471 /* otherwise on top of the drawbridge is the
472 * only viable spot in the dungeon, so stay there
476 /* we might have crawled out of the moat to survive */
477 etmp->ex = u.ux, etmp->ey = u.uy;
482 /* fake "digested to death" damage-type suppresses corpse */
483 #define mk_message(dest) (((dest & XKILL_NOMSG) != 0) ? (char *) 0 : "")
484 #define mk_corpse(dest) (((dest & XKILL_NOCORPSE) != 0) ? AD_DGST : AD_PHYS)
485 /* if monsters are moving, one of them caused the destruction */
486 if (context.mon_moving)
487 monkilled(etmp->emon,
488 mk_message(xkill_flags), mk_corpse(xkill_flags));
489 else /* you caused it */
490 xkilled(etmp->emon, xkill_flags);
491 etmp->edata = (struct permonst *) 0;
493 /* dead long worm handling */
494 for (entitycnt = 0; entitycnt < ENTITIES; entitycnt++) {
495 if (etmp != &(occupants[entitycnt])
496 && etmp->emon == occupants[entitycnt].emon)
497 occupants[entitycnt].edata = (struct permonst *) 0;
505 * These are never directly affected by a bridge or portcullis.
511 return (boolean) ((is_u(etmp) ? Passes_walls : passes_walls(etmp->edata))
512 || noncorporeal(etmp->edata));
516 * Does falling drawbridge or portcullis miss etmp?
519 e_missed(etmp, chunks)
526 debugpline0("Do chunks miss?");
531 if (is_flyer(etmp->edata)
532 && (is_u(etmp) ? !Unaware
533 : (etmp->emon->mcanmove && !etmp->emon->msleeping)))
534 /* flying requires mobility */
535 misses = 5; /* out of 8 */
536 else if (is_floater(etmp->edata)
537 || (is_u(etmp) && Levitation)) /* doesn't require mobility */
539 else if (chunks && is_pool(etmp->ex, etmp->ey))
540 misses = 2; /* sitting ducks */
544 if (is_db_wall(etmp->ex, etmp->ey))
545 misses -= 3; /* less airspace */
547 debugpline1("Miss chance = %d (out of 8)", misses);
549 return (misses >= rnd(8)) ? TRUE : FALSE;
553 * Can etmp jump from death?
559 int tmp = 4; /* out of 10 */
561 if (is_u(etmp) ? (Unaware || Fumbling)
562 : (!etmp->emon->mcanmove || etmp->emon->msleeping
563 || !etmp->edata->mmove || etmp->emon->wormno))
566 if (is_u(etmp) ? Confusion : etmp->emon->mconf)
569 if (is_u(etmp) ? Stunned : etmp->emon->mstun)
572 if (is_db_wall(etmp->ex, etmp->ey))
573 tmp -= 2; /* less room to maneuver */
575 debugpline2("%s to jump (%d chances in 10)", E_phrase(etmp, "try"), tmp);
576 return (tmp >= rnd(10)) ? TRUE : FALSE;
583 int newx, newy, at_portcullis, oldx, oldy;
584 boolean must_jump = FALSE, relocates = FALSE, e_inview;
590 e_inview = e_canseemon(etmp);
593 at_portcullis = is_db_wall(oldx, oldy);
594 crm = &levl[oldx][oldy];
596 if (automiss(etmp) && e_survives_at(etmp, oldx, oldy)) {
597 if (e_inview && (at_portcullis || IS_DRAWBRIDGE(crm->typ)))
599 pline_The("%s passes through %s!",
600 at_portcullis ? "portcullis" : "drawbridge",
603 pline_The("%s
\82Í%s
\82ð
\92Ê
\82è
\94²
\82¯
\82½
\81I",
604 at_portcullis ? "
\97\8e\82µ
\8ai
\8eq" : "
\92µ
\82Ë
\8b´",
611 if (e_missed(etmp, FALSE)) {
614 pline_The("portcullis misses %s!", e_nam(etmp));
616 pline("
\97\8e\82µ
\8ai
\8eq
\82Í%s
\82É
\96½
\92\86\82µ
\82È
\82©
\82Á
\82½
\81I", e_nam(etmp));
618 debugpline1("The drawbridge misses %s!", e_nam(etmp));
620 if (e_survives_at(etmp, oldx, oldy)) {
623 debugpline0("Mon can't survive here");
627 relocates = TRUE; /* just ride drawbridge in */
630 if (crm->typ == DRAWBRIDGE_DOWN) {
632 killer.format = NO_KILLER_PREFIX;
634 "crushed to death underneath a drawbridge");
637 pline("%s crushed underneath the drawbridge.",
639 pline("%s
\82Í
\92µ
\82Ë
\8b´
\82Ì
\89º
\95~
\82É
\82È
\82Á
\82½
\81D",
640 E_phrase(etmp, "are")); /* no jump */
642 XKILL_NOCORPSE | (e_inview ? XKILL_GIVEMSG : XKILL_NOMSG),
643 CRUSHING); /* no corpse */
644 return; /* Note: Beyond this point, we know we're */
645 } /* not at an opened drawbridge, since all */
646 must_jump = TRUE; /* *missable* creatures survive on the */
647 } /* square, and all the unmissed ones die. */
652 debugpline0("Jump succeeds!");
656 pline("%s crushed by the falling portcullis!",
658 pline("%s
\82Í
\97\8e\82¿
\82Ä
\82«
\82½
\97\8e\82µ
\8ai
\8eq
\82É
\92×
\82³
\82ê
\82½
\81I",
659 E_phrase(etmp, "are"));
662 You_hear("a crushing sound.");
664 You_hear("
\89½
\82©
\82ª
\92×
\82ê
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D");
666 XKILL_NOCORPSE | (e_inview ? XKILL_GIVEMSG
672 } else { /* tries to jump off bridge to original square */
673 relocates = !e_jumps(etmp);
674 debugpline1("Jump %s!", (relocates) ? "fails" : "succeeds");
679 * Here's where we try to do relocation. Assumes that etmp is not
680 * arriving at the portcullis square while the drawbridge is
681 * falling, since this square would be inaccessible (i.e. etmp
682 * started on drawbridge square) or unnecessary (i.e. etmp started
683 * here) in such a situation.
685 debugpline0("Doing relocation.");
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))) {
694 * Standoff problem: one or both entities must die, and/or
695 * both switch places. Avoid infinite recursion by checking
696 * first whether the other entity is staying put. Clean up if
697 * we happen to move/die in recursion.
699 struct entity *other;
701 other = e_at(newx, newy);
702 debugpline1("New square is occupied by %s", e_nam(other));
703 if (e_survives_at(other, newx, newy) && automiss(other)) {
704 relocates = FALSE; /* "other" won't budge */
705 debugpline1("%s suicide.", E_phrase(etmp, "commit"));
707 debugpline1("Handling %s", e_nam(other));
708 while ((e_at(newx, newy) != 0) && (e_at(newx, newy) != etmp))
710 debugpline1("Checking existence of %s", e_nam(etmp));
714 if (e_at(oldx, oldy) != etmp) {
715 debugpline1("%s moved or died in recursion somewhere",
716 E_phrase(etmp, "have"));
724 if (relocates && !e_at(newx, newy)) { /* if e_at() entity = worm tail */
725 debugpline1("Moving %s", e_nam(etmp));
727 remove_monster(etmp->ex, etmp->ey);
728 place_monster(etmp->emon, newx, newy);
729 update_monster_region(etmp->emon);
736 e_inview = e_canseemon(etmp);
738 debugpline1("Final disposition of %s", e_nam(etmp));
742 if (is_db_wall(etmp->ex, etmp->ey)) {
743 debugpline1("%s in portcullis chamber", E_phrase(etmp, "are"));
750 You("tumble towards the closed portcullis!");
752 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 You("pass through it!");
757 You("
\92Ê
\82è
\82Ê
\82¯
\82½
\81I");
760 pline_The("drawbridge closes in...");
762 pline_The("
\92µ
\82Ë
\8b´
\82Í
\95Â
\82¶
\82½
\81D
\81D
\81D");
765 pline("%s behind the drawbridge.",
767 pline("%s
\82Í
\92µ
\82Ë
\8b´
\82Ì
\97 \82É
\88Ú
\93®
\82µ
\82½
\81D",
768 E_phrase(etmp, "disappear"));
770 if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
771 killer.format = KILLED_BY_AN;
773 Strcpy(killer.name, "closing drawbridge");
775 Strcpy(killer.name, "
\95Â
\82¶
\82Ä
\82¢
\82
\92µ
\82Ë
\8b´
\82É
\8b·
\82Ü
\82ê
\82Ä");
776 e_died(etmp, XKILL_NOMSG, CRUSHING);
779 debugpline1("%s in here", E_phrase(etmp, "survive"));
781 debugpline1("%s on drawbridge square", E_phrase(etmp, "are"));
782 if (is_pool(etmp->ex, etmp->ey) && !e_inview)
785 You_hear("a splash.");
787 You_hear("
\83p
\83V
\83\83\83p
\83V
\83\83\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
788 if (e_survives_at(etmp, etmp->ex, etmp->ey)) {
789 if (e_inview && !is_flyer(etmp->edata)
790 && !is_floater(etmp->edata))
792 pline("%s from the bridge.", E_phrase(etmp, "fall"));
794 pline("%s
\82Í
\8b´
\82©
\82ç
\97\8e\82¿
\82½
\81D", E_phrase(etmp, "fall"));
797 debugpline1("%s cannot survive on the drawbridge square",
798 E_phrase(etmp, NULL));
799 if (is_pool(etmp->ex, etmp->ey) || is_lava(etmp->ex, etmp->ey))
800 if (e_inview && !is_u(etmp)) {
801 /* drown() will supply msgs if nec. */
802 boolean lava = is_lava(etmp->ex, etmp->ey);
806 pline("%s the %s and disappears.",
807 E_phrase(etmp, "drink"), lava ? "lava" : "moat");
809 pline("%s
\82Í%s
\82ð
\88ù
\82Ý
\81C
\8fÁ
\82¦
\82½
\81D",
810 E_phrase(etmp, "drink"), lava ? "
\97n
\8aâ" : "
\96x");
814 pline("%s into the %s.", E_phrase(etmp, "fall"),
815 lava ? hliquid("lava") : "moat");
817 pline("%s
\82Í%s
\82Ì
\92\86\82É
\97\8e\82¿
\82½
\81D", E_phrase(etmp, "fall"),
818 lava ? hliquid("
\97n
\8aâ") : "
\96x");
822 killer.format = NO_KILLER_PREFIX;
823 Strcpy(killer.name, "fell from a drawbridge");
825 killer.format = KILLED_BY;
826 Strcpy(killer.name, "
\92µ
\82Ë
\8b´
\82©
\82ç
\97\8e\82¿
\82Ä");
828 e_died(etmp, /* CRUSHING is arbitrary */
829 XKILL_NOCORPSE | (e_inview ? XKILL_GIVEMSG : XKILL_NOMSG),
830 is_pool(etmp->ex, etmp->ey) ? DROWNING
831 : is_lava(etmp->ex, etmp->ey) ? BURNING
832 : CRUSHING); /*no corpse*/
837 /* clear stale reason for death before returning */
838 #define nokiller() (killer.name[0] = '\0', killer.format = 0)
841 * Close the drawbridge located at x,y
844 close_drawbridge(x, y)
847 register struct rm *lev1, *lev2;
852 if (lev1->typ != DRAWBRIDGE_DOWN)
856 get_wall_for_db(&x2, &y2);
857 if (cansee(x, y) || cansee(x2, y2))
859 You_see("a drawbridge %s up!",
860 (((u.ux == x || u.uy == y) && !Underwater)
861 || distu(x2, y2) < distu(x, y))
865 pline("
\92µ
\82Ë
\8b´
\82ª
\8fã
\82ª
\82Á
\82Ä
\82¢
\82
\82Ì
\82ª
\8c©
\82¦
\82½
\81I");
867 else /* "5 gears turn" for castle drawbridge tune */
869 You_hear("chains rattling and gears turning.");
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];
875 switch (lev1->drawbridgemask & DB_DIR) {
878 lev2->horizontal = TRUE;
882 lev2->horizontal = FALSE;
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)
893 You_hear("smashing and crushing.");
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);
900 if ((t = t_at(x, y)) != 0)
902 if ((t = t_at(x2, y2)) != 0)
908 block_point(x2, y2); /* vision */
913 * Open the drawbridge located at x,y
916 open_drawbridge(x, y)
919 register struct rm *lev1, *lev2;
924 if (lev1->typ != DRAWBRIDGE_UP)
928 get_wall_for_db(&x2, &y2);
929 if (cansee(x, y) || cansee(x2, y2))
931 You_see("a drawbridge %s down!",
932 (distu(x2, y2) < distu(x, y)) ? "going" : "coming");
934 pline("
\92µ
\82Ë
\8b´
\82ª
\89º
\82ª
\82é
\82Ì
\82ª
\8c©
\82¦
\82½
\81I");
936 else /* "5 gears turn" for castle drawbridge tune */
938 You_hear("gears turning and chains rattling.");
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];
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);
952 if ((t = t_at(x, y)) != 0)
954 if ((t = t_at(x2, y2)) != 0)
960 unblock_point(x2, y2); /* vision */
961 if (Is_stronghold(&u.uz))
962 u.uevent.uopened_dbridge = TRUE;
967 * Let's destroy the drawbridge located at x,y
970 destroy_drawbridge(x, y)
973 register struct rm *lev1, *lev2;
978 struct entity *etmp1 = &(occupants[0]), *etmp2 = &(occupants[1]);
981 if (!IS_DRAWBRIDGE(lev1->typ))
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) {
990 boolean lava = (lev1->drawbridgemask & DB_UNDER) == DB_LAVA;
992 if (lev1->typ == DRAWBRIDGE_UP) {
995 pline_The("portcullis of the drawbridge falls into the %s!",
996 lava ? hliquid("lava") : "moat");
998 pline("
\92µ
\82Ë
\8b´
\82Ì
\97\8e\82µ
\8ai
\8eq
\82ª%s
\82É
\97\8e\82¿
\82½
\81I",
999 lava ? hliquid("
\97n
\8aâ") : "
\96x");
1003 You_hear("a loud *SPLASH*!");
1005 You_hear("
\91å
\82«
\82È
\83o
\83b
\83V
\83\83\81[
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I");
1009 pline_The("drawbridge collapses into the %s!",
1010 lava ? hliquid("lava") : "moat");
1012 pline("
\92µ
\82Ë
\8b´
\82Í%s
\82É
\82
\82¸
\82ê
\97\8e\82¿
\82½
\81I",
1013 lava ? hliquid("
\97n
\8aâ") : "
\96x");
1017 You_hear("a loud *SPLASH*!");
1019 You_hear("
\91å
\82«
\82È
\83o
\83b
\83V
\83\83\81[
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I");
1021 lev1->typ = lava ? LAVAPOOL : MOAT;
1022 lev1->drawbridgemask = 0;
1023 if ((otmp2 = sobj_at(BOULDER, x, y)) != 0) {
1024 obj_extract_self(otmp2);
1026 (void) flooreffects(otmp2, x, y, "fall");
1028 (void) flooreffects(otmp2, x, y, "
\97\8e\82¿
\82é");
1033 pline_The("drawbridge disintegrates!");
1035 pline("
\92µ
\82Ë
\8b´
\82Í
\82±
\82È
\82²
\82È
\82É
\82È
\82Á
\82½
\81I");
1038 You_hear("a loud *CRASH*!");
1040 You_hear("
\91å
\82«
\82È
\83K
\83V
\83\83\81[
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I");
1041 lev1->typ = ((lev1->drawbridgemask & DB_ICE) ? ICE : ROOM);
1042 lev1->icedpool = ((lev1->drawbridgemask & DB_ICE) ? ICED_MOAT : 0);
1044 wake_nearto(x, y, 500);
1046 lev2->doormask = D_NODOOR;
1047 if ((t = t_at(x, y)) != 0)
1049 if ((t = t_at(x2, y2)) != 0)
1052 del_engr_at(x2, y2);
1053 for (i = rn2(6); i > 0; --i) { /* scatter some debris */
1054 /* doesn't matter if we happen to pick <x,y2> or <x2,y>;
1055 since drawbridges are never placed diagonally, those
1056 pairings will always match one of <x,y> or <x2,y2> */
1057 otmp = mksobj_at(IRON_CHAIN, rn2(2) ? x : x2, rn2(2) ? y : y2, TRUE,
1059 /* a force of 5 here would yield a radius of 2 for
1060 iron chain; anything less produces a radius of 1 */
1061 (void) scatter(otmp->ox, otmp->oy, 1, MAY_HIT, otmp);
1065 if (!does_block(x2, y2, lev2))
1066 unblock_point(x2, y2); /* vision */
1067 if (Is_stronghold(&u.uz))
1068 u.uevent.uopened_dbridge = TRUE;
1070 set_entity(x2, y2, etmp2); /* currently only automissers can be here */
1072 e_inview = e_canseemon(etmp2);
1073 if (!automiss(etmp2)) {
1076 pline("%s blown apart by flying debris.",
1078 pline("%s
\82Í
\94ò
\82Ñ
\8eU
\82Á
\82½
\8a¢âI
\82Ì
\94j
\95Ð
\82ð
\97\81\82Ñ
\82½
\81D",
1079 E_phrase(etmp2, "are"));
1080 killer.format = KILLED_BY_AN;
1082 Strcpy(killer.name, "exploding drawbridge");
1084 Strcpy(killer.name, "
\92µ
\82Ë
\8b´
\82Ì
\94\9a\94
\82Å");
1086 XKILL_NOCORPSE | (e_inview ? XKILL_GIVEMSG : XKILL_NOMSG),
1087 CRUSHING); /*no corpse*/
1088 } /* nothing which is vulnerable can survive this */
1090 set_entity(x, y, etmp1);
1092 e_inview = e_canseemon(etmp1);
1093 if (e_missed(etmp1, TRUE)) {
1094 debugpline1("%s spared!", E_phrase(etmp1, "are"));
1095 /* if there is water or lava here, fall in now */
1099 (void) minliquid(etmp1->emon);
1102 if (!is_u(etmp1) && Hallucination)
1104 pline("%s into some heavy metal!",
1106 pline("%s
\82Í
\8fd
\8bà
\91®
\82É
\96\84\82à
\82ê
\82½
\81I",
1107 E_phrase(etmp1, "get"));
1110 pline("%s hit by a huge chunk of metal!",
1112 pline("
\91å
\82«
\82È
\93S
\82Ì
\89ò
\82ª%s
\82É
\96½
\92\86\82µ
\82½
\81I",
1113 E_phrase(etmp1, "are"));
1115 if (!Deaf && !is_u(etmp1) && !is_pool(x, y)) {
1117 You_hear("a crushing sound.");
1119 You_hear("
\83K
\83\89\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1121 debugpline1("%s from shrapnel", E_phrase(etmp1, "die"));
1124 killer.format = KILLED_BY_AN;
1126 Strcpy(killer.name, "collapsing drawbridge");
1128 Strcpy(killer.name, "
\83o
\83\89\83o
\83\89\82É
\82È
\82Á
\82½
\92µ
\82Ë
\8b´
\82Å");
1130 XKILL_NOCORPSE | (e_inview ? XKILL_GIVEMSG : XKILL_NOMSG),
1131 CRUSHING); /*no corpse*/
1132 if (levl[etmp1->ex][etmp1->ey].typ == MOAT)