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. */
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) {
137 * We want to know whether a wall (or a door) is the portcullis (passageway)
138 * of an eventual drawbridge.
140 * Return value: the direction of the drawbridge.
144 is_drawbridge_wall(x, y)
150 if (lev->typ != DOOR && lev->typ != DBWALL)
153 if (IS_DRAWBRIDGE(levl[x + 1][y].typ)
154 && (levl[x + 1][y].drawbridgemask & DB_DIR) == DB_WEST)
156 if (IS_DRAWBRIDGE(levl[x - 1][y].typ)
157 && (levl[x - 1][y].drawbridgemask & DB_DIR) == DB_EAST)
159 if (IS_DRAWBRIDGE(levl[x][y - 1].typ)
160 && (levl[x][y - 1].drawbridgemask & DB_DIR) == DB_SOUTH)
162 if (IS_DRAWBRIDGE(levl[x][y + 1].typ)
163 && (levl[x][y + 1].drawbridgemask & DB_DIR) == DB_NORTH)
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).
178 return (boolean) (levl[x][y].typ == DBWALL);
182 * Return true with x,y pointing to the drawbridge if x,y initially indicate
183 * a drawbridge or drawbridge wall.
186 find_drawbridge(x, y)
191 if (IS_DRAWBRIDGE(levl[*x][*y].typ))
193 dir = is_drawbridge_wall(*x, *y);
215 * Find the drawbridge wall associated with a drawbridge.
218 get_wall_for_db(x, y)
221 switch (levl[*x][*y].drawbridgemask & DB_DIR) {
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.
244 create_drawbridge(x, y, dir, flag)
250 boolean lava = levl[x][y].typ == LAVAPOOL; /* assume initialized map */
268 impossible("bad direction in create_drawbridge");
275 if (!IS_WALL(levl[x2][y2].typ))
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;
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;
287 levl[x][y].horizontal = !horiz;
288 levl[x2][y2].horizontal = horiz;
289 levl[x][y].drawbridgemask = dir;
291 levl[x][y].drawbridgemask |= DB_LAVA;
296 struct monst *emon; /* youmonst for the player */
297 struct permonst *edata; /* must be non-zero for record to be valid */
303 static NEARDATA struct entity occupants[ENTITIES];
312 for (entitycnt = 0; entitycnt < ENTITIES; entitycnt++)
313 if ((occupants[entitycnt].edata) && (occupants[entitycnt].ex == x)
314 && (occupants[entitycnt].ey == y))
316 debugpline1("entitycnt = %d", entitycnt);
320 return (entitycnt == ENTITIES) ? (struct entity *) 0
321 : &(occupants[entitycnt]);
325 m_to_e(mtmp, x, y, etmp)
334 if (mtmp->wormno && (x != mtmp->mx || y != mtmp->my))
335 etmp->edata = &mons[PM_LONG_WORM_TAIL];
337 etmp->edata = mtmp->data;
339 etmp->edata = (struct permonst *) 0;
346 etmp->emon = &youmonst;
349 etmp->edata = youmonst.data;
353 set_entity(x, y, etmp)
357 if ((x == u.ux) && (y == u.uy))
359 else if (MON_AT(x, y))
360 m_to_e(m_at(x, y), x, y, etmp);
362 etmp->edata = (struct permonst *) 0;
365 #define is_u(etmp) (etmp->emon == &youmonst)
366 #define e_canseemon(etmp) \
367 (is_u(etmp) ? (boolean) TRUE : canseemon(etmp->emon))
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.
374 /* #define e_strg(etmp, func) (is_u(etmp)? (char *)0 : func(etmp->emon)) */
376 STATIC_OVL const char *
381 return is_u(etmp) ? "you" : mon_nam(etmp->emon);
383 return is_u(etmp) ? "
\82 \82È
\82½" : mon_nam(etmp->emon);
387 * Generates capitalized entity name, makes 2nd -> 3rd person conversion on
388 * verb, where necessary.
391 STATIC_OVL const char *
396 static char wholebuf[80];
399 Strcpy(wholebuf, is_u(etmp) ? "
\82 \82È
\82½" : Monnam(etmp->emon));
402 Strcpy(wholebuf, is_u(etmp) ? "You" : Monnam(etmp->emon));
405 Strcat(wholebuf, " ");
407 Strcat(wholebuf, verb);
409 Strcat(wholebuf, vtense((char *) 0, verb));
415 * Simple-minded "can it be here?" routine
419 e_survives_at(etmp, x, y)
423 if (noncorporeal(etmp->edata))
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 */
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));
443 e_died(etmp, dest, how)
448 if (how == DROWNING) {
449 killer.name[0] = 0; /* drown() sets its own killer */
451 } else if (how == BURNING) {
452 killer.name[0] = 0; /* lava_effects() sets own killer */
453 (void) lava_effects();
457 /* use more specific killer if specified */
458 if (!killer.name[0]) {
459 killer.format = KILLED_BY_AN;
461 Strcpy(killer.name, "falling drawbridge");
463 Strcpy(killer.name, "
\8d~
\82è
\82Ä
\82«
\82½
\92µ
\82Ë
\8b´
\82Å");
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)) {
470 pline("A %s force teleports you away...",
471 Hallucination ? "normal" : "strange");
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È");
476 teleds(xy.x, xy.y, FALSE);
478 /* otherwise on top of the drawbridge is the
479 * only viable spot in the dungeon, so stay there
483 /* we might have crawled out of the moat to survive */
484 etmp->ex = u.ux, etmp->ey = u.uy;
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;
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;
511 * These are never directly affected by a bridge or portcullis.
518 return (boolean) ((is_u(etmp) ? Passes_walls : passes_walls(etmp->edata))
519 || noncorporeal(etmp->edata));
523 * Does falling drawbridge or portcullis miss etmp?
527 e_missed(etmp, chunks)
534 debugpline0("Do chunks miss?");
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 */
547 else if (chunks && is_pool(etmp->ex, etmp->ey))
548 misses = 2; /* sitting ducks */
552 if (is_db_wall(etmp->ex, etmp->ey))
553 misses -= 3; /* less airspace */
555 debugpline1("Miss chance = %d (out of 8)", misses);
557 return (misses >= rnd(8)) ? TRUE : FALSE;
561 * Can etmp jump from death?
568 int tmp = 4; /* out of 10 */
570 if (is_u(etmp) ? (Unaware || Fumbling)
571 : (!etmp->emon->mcanmove || etmp->emon->msleeping
572 || !etmp->edata->mmove || etmp->emon->wormno))
575 if (is_u(etmp) ? Confusion : etmp->emon->mconf)
578 if (is_u(etmp) ? Stunned : etmp->emon->mstun)
581 if (is_db_wall(etmp->ex, etmp->ey))
582 tmp -= 2; /* less room to maneuver */
584 debugpline2("%s to jump (%d chances in 10)", E_phrase(etmp, "try"), tmp);
585 return (tmp >= rnd(10)) ? TRUE : FALSE;
592 int newx, newy, at_portcullis, oldx, oldy;
593 boolean must_jump = FALSE, relocates = FALSE, e_inview;
599 e_inview = e_canseemon(etmp);
602 at_portcullis = is_db_wall(oldx, oldy);
603 crm = &levl[oldx][oldy];
605 if (automiss(etmp) && e_survives_at(etmp, oldx, oldy)) {
606 if (e_inview && (at_portcullis || IS_DRAWBRIDGE(crm->typ)))
608 pline_The("%s passes through %s!",
609 at_portcullis ? "portcullis" : "drawbridge",
612 pline_The("%s
\82Í%s
\82ð
\92Ê
\82è
\94²
\82¯
\82½
\81I",
613 at_portcullis ? "
\97\8e\82µ
\8ai
\8eq" : "
\92µ
\82Ë
\8b´",
620 if (e_missed(etmp, FALSE)) {
623 pline_The("portcullis misses %s!", e_nam(etmp));
625 pline("
\97\8e\82µ
\8ai
\8eq
\82Í%s
\82É
\96½
\92\86\82µ
\82È
\82©
\82Á
\82½
\81I", e_nam(etmp));
627 debugpline1("The drawbridge misses %s!", e_nam(etmp));
629 if (e_survives_at(etmp, oldx, oldy)) {
632 debugpline0("Mon can't survive here");
636 relocates = TRUE; /* just ride drawbridge in */
639 if (crm->typ == DRAWBRIDGE_DOWN) {
641 pline("%s crushed underneath the drawbridge.",
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. */
654 debugpline0("Jump succeeds!");
658 pline("%s crushed by the falling portcullis!",
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"));
664 You_hear("a crushing sound.");
666 You_hear("
\89½
\82©
\82ª
\92×
\82ê
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D");
667 e_died(etmp, e_inview ? 3 : 2, CRUSHING);
671 } else { /* tries to jump off bridge to original square */
672 relocates = !e_jumps(etmp);
673 debugpline1("Jump %s!", (relocates) ? "fails" : "succeeds");
678 * Here's where we try to do relocation. Assumes that etmp is not
680 * at the portcullis square while the drawbridge is falling, since this
682 * would be inaccessible (i.e. etmp started on drawbridge square) or
683 * unnecessary (i.e. etmp started 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 both
696 * places. Avoid infinite recursion by checking first whether the
698 * entity is staying put. Clean up if we happen to move/die in
701 struct entity *other;
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"));
709 debugpline1("Handling %s", e_nam(other));
710 while ((e_at(newx, newy) != 0) && (e_at(newx, newy) != etmp))
712 debugpline1("Checking existence of %s", e_nam(etmp));
716 if (e_at(oldx, oldy) != etmp) {
717 debugpline1("%s moved or died in recursion somewhere",
718 E_phrase(etmp, "have"));
726 if (relocates && !e_at(newx, newy)) { /* if e_at() entity = worm tail */
727 debugpline1("Moving %s", e_nam(etmp));
729 remove_monster(etmp->ex, etmp->ey);
730 place_monster(etmp->emon, newx, newy);
731 update_monster_region(etmp->emon);
738 e_inview = e_canseemon(etmp);
740 debugpline1("Final disposition of %s", e_nam(etmp));
744 if (is_db_wall(etmp->ex, etmp->ey)) {
745 debugpline1("%s in portcullis chamber", E_phrase(etmp, "are"));
752 You("tumble towards the closed portcullis!");
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");
757 You("pass through it!");
759 You("
\92Ê
\82è
\82Ê
\82¯
\82½
\81I");
762 pline_The("drawbridge closes in...");
764 pline_The("
\92µ
\82Ë
\8b´
\82Í
\95Â
\82¶
\82½
\81D
\81D
\81D");
767 pline("%s behind the drawbridge.",
769 pline("%s
\82Í
\92µ
\82Ë
\8b´
\82Ì
\97 \82É
\88Ú
\93®
\82µ
\82½
\81D",
770 E_phrase(etmp, "disappear"));
772 if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
773 killer.format = KILLED_BY_AN;
775 Strcpy(killer.name, "closing drawbridge");
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 */
781 debugpline1("%s in here", E_phrase(etmp, "survive"));
783 debugpline1("%s on drawbridge square", E_phrase(etmp, "are"));
784 if (is_pool(etmp->ex, etmp->ey) && !e_inview)
787 You_hear("a splash.");
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))
794 pline("%s from the bridge.", E_phrase(etmp, "fall"));
796 pline("%s
\82Í
\8b´
\82©
\82ç
\97\8e\82¿
\82½
\81D", E_phrase(etmp, "fall"));
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);
808 pline("%s the %s and disappears.",
809 E_phrase(etmp, "drink"), lava ? "lava" : "moat");
811 pline("%s
\82Í%s
\82ð
\88ù
\82Ý
\81C
\8fÁ
\82¦
\82½
\81D",
812 E_phrase(etmp, "drink"), lava ? "
\97n
\8aâ" : "
\96x");
816 pline("%s into the %s.", E_phrase(etmp, "fall"),
817 lava ? "lava" : "moat");
819 pline("%s
\82Í%s
\82Ì
\92\86\82É
\97\8e\82¿
\82½
\81D", E_phrase(etmp, "fall"),
820 lava ? "
\97n
\8aâ" : "
\96x");
824 killer.format = NO_KILLER_PREFIX;
825 Strcpy(killer.name, "fell from a drawbridge");
827 killer.format = KILLED_BY;
828 Strcpy(killer.name, "
\92µ
\82Ë
\8b´
\82©
\82ç
\97\8e\82¿
\82Ä");
830 e_died(etmp, e_inview ? 3 : 2, /* CRUSHING is arbitrary */
831 (is_pool(etmp->ex, etmp->ey))
833 : (is_lava(etmp->ex, etmp->ey)) ? BURNING
834 : CRUSHING); /*no corpse*/
840 * 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 */
912 * 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;
966 * 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;
991 if (lev1->typ == DRAWBRIDGE_UP) {
994 pline_The("portcullis of the drawbridge falls into the %s!",
995 lava ? "lava" : "moat");
997 pline("
\92µ
\82Ë
\8b´
\82Ì
\97\8e\82µ
\8ai
\8eq
\82ª%s
\82É
\97\8e\82¿
\82½
\81I",
998 lava ? "
\97n
\8aâ" : "
\96x");
1002 You_hear("a loud *SPLASH*!");
1004 You_hear("
\91å
\82«
\82È
\83o
\83b
\83V
\83\83\81[
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I");
1008 pline_The("drawbridge collapses into the %s!",
1009 lava ? "lava" : "moat");
1011 pline("
\92µ
\82Ë
\8b´
\82Í%s
\82É
\82
\82¸
\82ê
\97\8e\82¿
\82½
\81I",
1012 lava ? "
\97n
\8aâ" : "
\96x");
1016 You_hear("a loud *SPLASH*!");
1018 You_hear("
\91å
\82«
\82È
\83o
\83b
\83V
\83\83\81[
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I");
1020 lev1->typ = lava ? LAVAPOOL : MOAT;
1021 lev1->drawbridgemask = 0;
1022 if ((otmp2 = sobj_at(BOULDER, x, y)) != 0) {
1023 obj_extract_self(otmp2);
1025 (void) flooreffects(otmp2, x, y, "fall");
1027 (void) flooreffects(otmp2, x, y, "
\97\8e\82¿
\82é");
1032 pline_The("drawbridge disintegrates!");
1034 pline("
\92µ
\82Ë
\8b´
\82Í
\82±
\82È
\82²
\82È
\82É
\82È
\82Á
\82½
\81I");
1037 You_hear("a loud *CRASH*!");
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);
1043 wake_nearto(x, y, 500);
1045 lev2->doormask = D_NODOOR;
1046 if ((t = t_at(x, y)) != 0)
1048 if ((t = t_at(x2, y2)) != 0)
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,
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);
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;
1069 set_entity(x2, y2, etmp2); /* currently only automissers can be here */
1071 e_inview = e_canseemon(etmp2);
1072 if (!automiss(etmp2)) {
1075 pline("%s blown apart by flying debris.",
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;
1081 Strcpy(killer.name, "exploding drawbridge");
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 */
1087 set_entity(x, y, etmp1);
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 */
1096 (void) minliquid(etmp1->emon);
1099 if (!is_u(etmp1) && Hallucination)
1101 pline("%s into some heavy metal!",
1103 pline("%s
\82Í
\8fd
\8bà
\91®
\82É
\96\84\82à
\82ê
\82½
\81I",
1104 E_phrase(etmp1, "get"));
1107 pline("%s hit by a huge chunk of metal!",
1109 pline("
\91å
\82«
\82È
\93S
\82Ì
\89ò
\82ª%s
\82É
\96½
\92\86\82µ
\82½
\81I",
1110 E_phrase(etmp1, "are"));
1112 if (!Deaf && !is_u(etmp1) && !is_pool(x, y)) {
1114 You_hear("a crushing sound.");
1116 You_hear("
\83K
\83\89\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1118 debugpline1("%s from shrapnel", E_phrase(etmp1, "die"));
1121 killer.format = KILLED_BY_AN;
1123 Strcpy(killer.name, "collapsing drawbridge");
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)