Example #1
0
/*
 * Open the drawbridge located at x,y
 */
void open_drawbridge(int x, int y)
{
	struct rm *loc1, *loc2;
	struct trap *t;
	int x2, y2;

	loc1 = &level->locations[x][y];
	if (loc1->typ != DRAWBRIDGE_UP) return;
	x2 = x; y2 = y;
	get_wall_for_db(&x2,&y2);
	if (cansee(x,y) || cansee(x2,y2))
		pline("You see a drawbridge %s down!",
		    (distu(x2,y2) < distu(x,y)) ? "going" : "coming");
	loc1->typ = DRAWBRIDGE_DOWN;
	loc2 = &level->locations[x2][y2];
	loc2->typ = DOOR;
	loc2->doormask = D_NODOOR;
	set_entity(x, y, &(occupants[0]));
	set_entity(x2, y2, &(occupants[1]));
	do_entity(&(occupants[0]));		/* do set_entity after first */
	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tails */
	do_entity(&(occupants[1]));
	revive_nasty(x,y,NULL);
	delallobj(x, y);
	if ((t = t_at(level, x, y)) != 0) deltrap(level, t);
	if ((t = t_at(level, x2, y2)) != 0) deltrap(level, t);
	newsym(x, y);
	newsym(x2, y2);
	unblock_point(x2,y2);	/* vision */
	if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE;
}
Example #2
0
/*
 * Close the drawbridge located at x,y.
 * Returns TRUE if the drawbridge was closed, FALSE otherwise.
 */
boolean close_drawbridge(int x, int y)
{
	struct rm *loc1, *loc2;
	struct monst *m;
	struct trap *t;
	int x2, y2;

	loc1 = &level->locations[x][y];
	if (loc1->typ != DRAWBRIDGE_DOWN) return FALSE;
	/* A huge monster will block the drawbridge. */
	if ((m = m_at(level, x, y)) && hugemonst(m->data)) {
	    pline("%s blocks the drawbridge with %s weight!",
		  canseemon(level, m) ? Amonnam(m) : "Something",
		  canseemon(level, m) ? mhis(level, m) : "its");
	    return FALSE;
	}
	if (rn2(5) == 0) {
	    pline("The mechanism seems to have something stuck in it and won't close.");
	    return FALSE;
	}
	x2 = x; y2 = y;
	get_wall_for_db(&x2,&y2);
	if (cansee(x,y) || cansee(x2,y2))
		pline("You see a drawbridge %s up!",
		    (((u.ux == x || u.uy == y) && !Underwater) ||
		     distu(x2,y2) < distu(x,y)) ? "coming" : "going");
	loc1->typ = DRAWBRIDGE_UP;
	loc2 = &level->locations[x2][y2];
	loc2->typ = DBWALL;
	switch (loc1->drawbridgemask & DB_DIR) {
		case DB_NORTH:
		case DB_SOUTH:
			loc2->horizontal = TRUE;
			break;
		case DB_WEST:
		case DB_EAST:
			loc2->horizontal = FALSE;
			break;
	}
	loc2->wall_info = W_NONDIGGABLE;
	set_entity(x, y, &(occupants[0]));
	set_entity(x2, y2, &(occupants[1]));
	do_entity(&(occupants[0]));		/* Do set_entity after first */
	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tail */
	do_entity(&(occupants[1]));
	if (OBJ_AT(x, y) && flags.soundok)
	    You_hear("smashing and crushing.");
	revive_nasty(x,y,NULL);
	revive_nasty(x2,y2,NULL);
	delallobj(x, y);
	delallobj(x2, y2);
	if ((t = t_at(level, x, y)) != 0) deltrap(level, t);
	if ((t = t_at(level, x2, y2)) != 0) deltrap(level, t);
	newsym(x, y);
	newsym(x2, y2);
	block_point(x2,y2);	/* vision */
	return TRUE;
}
Example #3
0
/*
 * Close the drawbridge located at x,y
 */
void
close_drawbridge(int x, int y)
{
    struct rm *loc1, *loc2;
    struct trap *t;
    int x2, y2;

    loc1 = &level->locations[x][y];
    if (loc1->typ != DRAWBRIDGE_DOWN)
        return;
    x2 = x;
    y2 = y;
    get_wall_for_db(&x2, &y2);
    if (cansee(x, y) || cansee(x2, y2))
        pline("You see a drawbridge %s up!",
              (((u.ux == x || u.uy == y) && !Underwater) ||
               distu(x2, y2) < distu(x, y)) ? "coming" : "going");
    else if (canhear())
        pline("You hear chains rattling and gears turning.");
    loc1->typ = DRAWBRIDGE_UP;
    loc2 = &level->locations[x2][y2];
    loc2->typ = DBWALL;
    switch (loc1->drawbridgemask & DB_DIR) {
    case DB_NORTH:
    case DB_SOUTH:
        loc2->horizontal = TRUE;
        break;
    case DB_WEST:
    case DB_EAST:
        loc2->horizontal = FALSE;
        break;
    }
    loc2->wall_info = W_NONDIGGABLE;
    set_entity(x, y, &(occupants[0]));
    set_entity(x2, y2, &(occupants[1]));
    do_entity(&(occupants[0])); /* Do set_entity after first */
    set_entity(x2, y2, &(occupants[1]));        /* do_entity for worm tail */
    do_entity(&(occupants[1]));
    if (OBJ_AT(x, y))
        You_hear("smashing and crushing.");
    revive_nasty(x, y, NULL);
    revive_nasty(x2, y2, NULL);
    delallobj(x, y);
    delallobj(x2, y2);
    if ((t = t_at(level, x, y)) != 0)
        deltrap(level, t);
    if ((t = t_at(level, x2, y2)) != 0)
        deltrap(level, t);
    del_engr_at(level, x, y);
    del_engr_at(level, x2, y2);
    newsym(x, y);
    newsym(x2, y2);
    block_point(x2, y2);        /* vision */
}
Example #4
0
/*
 * Expell the player to the stairs on the parent of the quest dungeon.
 *
 * This assumes that the hero is currently _in_ the quest dungeon and that
 * there is a single branch to and from it.
 */
static void
expulsion(boolean seal)
{
    branch *br;
    d_level *dest;
    struct trap *t;
    int portal_flag;

    br = dungeon_branch("The Quest");
    dest = (br->end1.dnum == u.uz.dnum) ? &br->end2 : &br->end1;
    portal_flag = u.uevent.qexpelled ? 0 :      /* returned via artifact? */
        !seal ? 1 : -1;
    schedule_goto(dest, FALSE, FALSE, portal_flag, NULL, NULL);
    if (seal) { /* remove the portal to the quest - sealing it off */
        int reexpelled = u.uevent.qexpelled;

        u.uevent.qexpelled = 1;
        historic_event(FALSE, FALSE, "were expelled from the quest.");
        /* Delete the near portal now; the far (main dungeon side) portal will
           be deleted as part of arrival on that level. If monster movement is
           in progress, any who haven't moved yet will now miss out on a chance 
           to wander through it... */
        for (t = level->lev_traps; t; t = t->ntrap)
            if (t->ttyp == MAGIC_PORTAL)
                break;
        if (t)
            deltrap(level, t);  /* (display might be briefly out of sync) */
        else if (!reexpelled)
            impossible("quest portal already gone?");
    }
}
Example #5
0
int dosearch(void)
{
    xchar x, y;
    struct trap *trap;
    struct monst *mtmp;

    if (u.uswallow)
	pline("What are you looking for? The exit?");
    else
	for (x = u.ux - 1; x < u.ux + 2; x++)
	    for (y = u.uy - 1; y < u.uy + 2; y++)
		if (x != u.ux || y != u.uy) {
		    if (levl[x][y].typ == SDOOR) {
			if (rn2(7))
			    continue;
			levl[x][y].typ = DOOR;
			levl[x][y].seen = 0;	// force prl
			prl(x, y);
			nomul(0);
		    } else if (levl[x][y].typ == SCORR) {
			if (rn2(7))
			    continue;
			levl[x][y].typ = CORR;
			levl[x][y].seen = 0;	// force prl
			prl(x, y);
			nomul(0);
		    } else {
			// Be careful not to find anything in an SCORR or SDOOR
			if ((mtmp = m_at(x, y)) != NULL) {
			    if (mtmp->mimic) {
				seemimic(mtmp);
				pline("You find a mimic.");
				return 1;
			    }
			}
			for (trap = ftrap; trap; trap = trap->ntrap) {
			    if (trap->tx == x && trap->ty == y && !trap->tseen && !rn2(8)) {
				nomul(0);
				pline("You find a%s.", traps[trap->ttyp]);
				if (trap->ttyp == PIERC) {
				    deltrap(trap);
				    (void) makemon(PM_PIERCER, x, y);
				    return 1;
				}
				trap->tseen = 1;
				if (!vism_at(x, y))
				    atl(x, y, '^');
			    }
			}
		    }
		}
    return 1;
}
Example #6
0
// ok, the SDOOR/SCORR part works.  however, none of the rest is tested
// (traps, mimics, swallowed, etc)
void do_search() // was dosearch
{
  Int8 x,y;
  trap_t *trap;
  monst_t *mtmp;
  UChar floor_type, tmp_type;

  if (you.uswallow) {
    message("What are you looking for? The exit?");
    return;
  }
  for (x = you.ux - 1 ; x <= you.ux + 1 ; x++)
    for (y = you.uy - 1 ; y <= you.uy + 1 ; y++) {
      if (x == you.ux && y == you.uy) continue;
      floor_type = get_cell_type(floor_info[x][y]);
      if (floor_type == SDOOR || floor_type == SCORR) {
	if (rund(7)) continue;
	tmp_type = (floor_type == SDOOR) ? DOOR : CORR;
	set_cell_type(floor_info[x][y], tmp_type);
	floor_info[x][y] &= ~SEEN_CELL;	/* force prl */
	prl(x,y);
	nomul(0);
      } else {
	/* Be careful not to find anything in an SCORR or SDOOR */
	mtmp = mon_at(x,y);
	if (mtmp && (mtmp->bitflags & M_IS_MIMIC)) {
	  see_mimic(mtmp);
	  message("You find a mimic.");
	  return;
	}
	for (trap = ftrap ; trap ; trap = trap->ntrap)
	  if (trap->tx == x && trap->ty == y &&
	      !(get_trap_seen(trap->trap_info)) && !rund(8)) {
	    nomul(0);
	    tmp_type = get_trap_type(trap->trap_info);
	    StrPrintF(ScratchBuffer, "You find a%s.", traps[tmp_type]);
	    message(ScratchBuffer);
	    if (tmp_type == PIERC) {
	      deltrap(trap);
	      makemon(PM_PIERCER, x, y);
	      return;
	    }
	    trap->trap_info |= SEEN_TRAP;
	    if (!vism_at(x,y))
	      print(x, y, '^');
	  }
      }
    }
}
Example #7
0
void tele_trap(struct trap *trap)
{
	if (In_endgame(&u.uz) || Antimagic) {
		if (Antimagic)
			shieldeff(u.ux, u.uy);
		pline("You feel a wrenching sensation.");
	} else if (!next_to_u()) {
		pline("You shudder for a moment.");
	} else if (trap->once) {
		deltrap(trap);
		newsym(u.ux,u.uy);	/* get rid of trap symbol */
		vault_tele();
	} else
		tele();
}
Example #8
0
Short findit()   /* returns number of things found */
{
  Short num;
  UChar zx,zy;
  trap_t *ttmp;
  monst_t *mtmp;
  UChar lx,hx,ly,hy;

  if (you.uswallow) return false;
  for (lx = you.ux;
       (num = get_cell_type(floor_info[lx-1][you.uy])) && num != CORR; lx--) ;
  for (hx = you.ux;
       (num = get_cell_type(floor_info[hx+1][you.uy])) && num != CORR; hx++) ;
  for (ly = you.uy;
       (num = get_cell_type(floor_info[you.ux][ly-1])) && num != CORR; ly--) ;
  for (hy = you.uy;
       (num = get_cell_type(floor_info[you.ux][hy+1])) && num != CORR; hy++) ;
  num = 0;
  for (zy = ly; zy <= hy; zy++) {
    for (zx = lx; zx <= hx; zx++) {
      if (get_cell_type(floor_info[zx][zy]) == SDOOR) {
	set_cell_type(floor_info[zx][zy], DOOR);
	print(zx, zy, DOOR_SYM);
	num++;
      } else if (get_cell_type(floor_info[zx][zy]) == SCORR) {
	set_cell_type(floor_info[zx][zy], CORR);
	print(zx, zy, CORR_SYM);
	num++;
      } else if ((ttmp = trap_at(zx, zy))) {
	if (get_trap_type(ttmp->trap_info) == PIERC) {
	  makemon(PM_PIERCER, zx, zy);
	  num++;
	  deltrap(ttmp);
	} else if (!get_trap_seen(ttmp->trap_info)) {
	  ttmp->trap_info |= SEEN_TRAP;
	  if (!vism_at(zx, zy))
	    print(zx,zy,'^');
	  num++;
	}
      } else if ((mtmp = mon_at(zx,zy)) && (mtmp->bitflags & M_IS_MIMIC)) {
	see_mimic(mtmp);
	num++;
      }
    }
  }
  return num;
}
Example #9
0
int findit(void)
{			       // returns number of things found
    int num;
    xchar zx, zy;
    struct trap *ttmp;
    struct monst *mtmp;
    xchar lx, hx, ly, hy;

    if (u.uswallow)
	return 0;
    for (lx = u.ux; (num = levl[lx - 1][u.uy].typ) && num != CORR; lx--);
    for (hx = u.ux; (num = levl[hx + 1][u.uy].typ) && num != CORR; hx++);
    for (ly = u.uy; (num = levl[u.ux][ly - 1].typ) && num != CORR; ly--);
    for (hy = u.uy; (num = levl[u.ux][hy + 1].typ) && num != CORR; hy++);
    num = 0;
    for (zy = ly; zy <= hy; zy++)
	for (zx = lx; zx <= hx; zx++) {
	    if (levl[zx][zy].typ == SDOOR) {
		levl[zx][zy].typ = DOOR;
		atl(zx, zy, '+');
		num++;
	    } else if (levl[zx][zy].typ == SCORR) {
		levl[zx][zy].typ = CORR;
		atl(zx, zy, CORR_SYM);
		num++;
	    } else if ((ttmp = t_at(zx, zy)) != NULL) {
		if (ttmp->ttyp == PIERC) {
		    (void) makemon(PM_PIERCER, zx, zy);
		    num++;
		    deltrap(ttmp);
		} else if (!ttmp->tseen) {
		    ttmp->tseen = 1;
		    if (!vism_at(zx, zy))
			atl(zx, zy, '^');
		    num++;
		}
	    } else if ((mtmp = m_at(zx, zy)) != NULL)
		if (mtmp->mimic) {
		    seemimic(mtmp);
		    num++;
		}
	}
    return num;
}
Example #10
0
void level_tele_trap(struct trap *trap)
{
	pline("You %s onto a level teleport trap!",
		      Levitation ? (const char *)"float" :
				  locomotion(youmonst.data, "step"));
	if (Antimagic) {
	    shieldeff(u.ux, u.uy);
	}
	if (Antimagic || In_endgame(&u.uz)) {
	    pline("You feel a wrenching sensation.");
	    return;
	}
	if (!Blind)
	    pline("You are momentarily blinded by a flash of light.");
	else
	    pline("You are momentarily disoriented.");
	deltrap(trap);
	newsym(u.ux,u.uy);	/* get rid of trap symbol */
	level_tele();
}
Example #11
0
void do_trap(trap_t *trap) // was dotrap
{
  Short ttype = get_trap_type(trap->trap_info);

  nomul(0);
  if (get_trap_seen(trap->trap_info) && !rund(5) && ttype != PIT) {
    StrPrintF(ScratchBuffer, "You escape a%s.", traps[ttype]);
    message(ScratchBuffer);
  } else {
    trap->trap_info |= SEEN_TRAP;
    switch(ttype) {
    case SLP_GAS_TRAP:
      message("A cloud of gas puts you to sleep!");
      nomul(-rnd(25));
      break;
    case BEAR_TRAP:
      if (Levitation) {
	message("You float over a bear trap.");
	break;
      }
      you.utrap = 4 + rund(4);
      you.utraptype = TT_BEARTRAP;
      message("A bear trap closes on your foot!");
      break;
    case PIERC:
      deltrap(trap);
      if (makemon(PM_PIERCER, you.ux, you.uy)) {
	message("A piercer suddenly drops from the ceiling!");
	if (uarmh)
	  message("Its blow glances off your helmet.");
	else
	  thing_hit_you(3, dice(4,6), "falling piercer");
      }
      break;
    case ARROW_TRAP:
      message("An arrow shoots out at you!");
      if (!thing_hit_you(8, rnd(6), "arrow")){
	mksobj_at(ARROW, you.ux, you.uy);
	fobj->quantity = 1;
      }
      break;
    case TRAPDOOR:
      if (!xdnstair) {
	message("A trap door in the ceiling opens and a rock falls on your head!");
	if (uarmh) message("Fortunately, you are wearing a helmet!");
	losehp((uarmh ? 2 : dice(2,10)), "falling rock");
	mksobj_at(ROCK, you.ux, you.uy);
	fobj->quantity = 1;
	stackobj(fobj);
	if (Invisible) newsym(you.ux, you.uy);
      } else {
	Short newlevel = dlevel + 1;
	while (!rund(4) && newlevel < 29)
	  newlevel++;
	message("A trap door opens up under you!");
	if (Levitation || you.ustuck) {
	  message("For some reason you don't fall in.");
	  break;
	}

	goto_level(newlevel, false);
      }
      break;
    case DART_TRAP:
      message("A little dart shoots out at you!");
      if (thing_hit_you(7, rnd(3), "little dart")) {
	if (!rund(6))
	  poisoned("dart", "poison dart");
      } else {
	mksobj_at(DART, you.ux, you.uy);
	fobj->quantity = 1;
      }
      break;
    case TELEP_TRAP:
      map_mode_teleport = TELE_TRAP;
      if (get_trap_once(trap->trap_info)) {
	deltrap(trap);
	newsym(you.ux,you.uy);
	vtele();
      } else {
	newsym(you.ux,you.uy);
	tele();
      }
      break;
    case PIT:
      if (Levitation) {
	message("A pit opens up under you!");
	message("You don't fall in!");
	break;
      }
      message("You fall into a pit!");
      you.utrap = rund(6) + 2;
      you.utraptype = TT_PIT;
      losehp(rnd(6),"fall into a pit");
      selftouch("Falling, you");
      break;
    default:
      StrPrintF(ScratchBuffer, "BUG: You hit a trap with info=%u",
		trap->trap_info);
      message(ScratchBuffer);
    }
  }
}
Example #12
0
static boolean
clear_fcorr(struct monst *grd, boolean forceshow)
{
    int fcx, fcy, fcbeg, oldtyp;
    struct monst *mtmp;
    boolean showmsg = FALSE;

    if (!on_level(&(EGD(grd)->gdlevel), &u.uz))
        return TRUE;

    while ((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) {
        fcx = EGD(grd)->fakecorr[fcbeg].fx;
        fcy = EGD(grd)->fakecorr[fcbeg].fy;
        if ((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) &&
            EGD(grd)->gddone)
            forceshow = TRUE;
        if ((u.ux == fcx && u.uy == fcy && grd->mhp > 0)
            || (!forceshow && couldsee(fcx, fcy)))
            return FALSE;

        if ((Punished && !carried(uball)
             && uball->ox == fcx && uball->oy == fcy)) {
            unplacebc();
            placebc();
        }

        if ((mtmp = m_at(level, fcx, fcy)) != 0) {
            if (mtmp->isgd)
                return FALSE;
            else if (!in_fcorridor(grd, u.ux, u.uy)) {
                if (mtmp->mtame)
                    yelp(mtmp);
                rloc(mtmp, FALSE);
            }
        }
        oldtyp = level->locations[fcx][fcy].typ;
        level->locations[fcx][fcy].typ = EGD(grd)->fakecorr[fcbeg].ftyp;
        if (!ACCESSIBLE(level->locations[fcx][fcy].typ) && ACCESSIBLE(oldtyp)) {
            struct trap *t = t_at(level, fcx, fcy);

            if (couldsee(fcx, fcy))
                showmsg = TRUE;
            if (t)
                deltrap(level, t);
            level->locations[fcx][fcy].lit = FALSE;
            block_point(fcx, fcy);
        }
        map_location(fcx, fcy, 1, FALSE);      /* bypass vision */
        EGD(grd)->fcbeg++;
    }
    if (grd->mhp <= 0) {
        if (showmsg) {
            if (!Blind)
                pline("The corridor disappears.");
            else
                pline("You feel claustrophobic.");
        }
        if (IS_ROCK(level->locations[u.ux][u.uy].typ))
            pline("You are encased in rock.");
    }
    return TRUE;
}
Example #13
0
/* returns number of scattered objects */
long
scatter(int sx, int sy, /* location of objects to scatter */
        int blastforce, /* force behind the scattering */
        unsigned int scflags, struct obj *obj)
{   /* only scatter this obj */
    struct obj *otmp;
    struct level *lev = obj ? obj->olev : level;
    int tmp;
    int farthest = 0;
    uchar typ;
    long qtmp;
    boolean used_up;
    boolean individual_object = obj ? TRUE : FALSE;
    struct monst *mtmp;
    struct scatter_chain *stmp, *stmp2 = 0;
    struct scatter_chain *schain = NULL;
    long total = 0L;
    boolean visible = (lev == level && cansee(sx, sy));

    while ((otmp = individual_object ? obj : lev->objects[sx][sy]) != 0) {
        if (otmp->quan > 1L) {
            qtmp = otmp->quan - 1;
            if (qtmp > LARGEST_INT)
                qtmp = LARGEST_INT;
            qtmp = (long)rnd((int)qtmp);
            otmp = splitobj(otmp, qtmp);
        } else {
            obj = NULL; /* all used */
        }
        obj_extract_self(otmp);
        used_up = FALSE;

        /* 9 in 10 chance of fracturing boulders or statues */
        if ((scflags & MAY_FRACTURE)
                && ((otmp->otyp == BOULDER) || (otmp->otyp == STATUE))
                && rn2(10)) {
            if (otmp->otyp == BOULDER) {
                if (visible)
                    pline("%s apart.", Tobjnam(otmp, "break"));
                fracture_rock(otmp);
                place_object(otmp, lev, sx, sy);
                if ((otmp = sobj_at(BOULDER, lev, sx, sy)) != 0) {
                    /* another boulder here, restack it to the top */
                    obj_extract_self(otmp);
                    place_object(otmp, lev, sx, sy);
                }
            } else {
                struct trap *trap;

                if ((trap = t_at(lev, sx, sy)) && trap->ttyp == STATUE_TRAP)
                    deltrap(lev, trap);
                if (visible)
                    pline("%s.", Tobjnam(otmp, "crumble"));
                break_statue(otmp);
                place_object(otmp, lev, sx, sy); /* put fragments on floor */
            }
            used_up = TRUE;

            /* 1 in 10 chance of destruction of obj; glass, egg destruction */
        } else if ((scflags & MAY_DESTROY) &&
                   (!rn2(10) || (objects[otmp->otyp].oc_material == GLASS ||
                                 otmp->otyp == EGG))) {
            if (breaks(otmp, (xchar) sx, (xchar) sy))
                used_up = TRUE;
        }

        if (!used_up) {
            stmp = malloc(sizeof (struct scatter_chain));
            stmp->next = NULL;
            stmp->obj = otmp;
            stmp->ox = sx;
            stmp->oy = sy;
            tmp = rn2(8);       /* get the direction */
            stmp->dx = xdir[tmp];
            stmp->dy = ydir[tmp];
            tmp = blastforce - (otmp->owt / 40);
            if (tmp < 1)
                tmp = 1;
            stmp->range = rnd(tmp);     /* anywhere up to that determ. by wt */
            if (farthest < stmp->range)
                farthest = stmp->range;
            stmp->stopped = FALSE;
            if (!schain)
                schain = stmp;
            else
                stmp2->next = stmp;
            stmp2 = stmp;
        }
    }

    while (farthest-- > 0) {
        for (stmp = schain; stmp; stmp = stmp->next) {
            if ((stmp->range-- > 0) && (!stmp->stopped)) {
                bhitpos.x = stmp->ox + stmp->dx;
                bhitpos.y = stmp->oy + stmp->dy;
                typ = lev->locations[bhitpos.x][bhitpos.y].typ;
                if (!isok(bhitpos.x, bhitpos.y)) {
                    bhitpos.x -= stmp->dx;
                    bhitpos.y -= stmp->dy;
                    stmp->stopped = TRUE;
                } else if (!ZAP_POS(typ) ||
                           closed_door(lev, bhitpos.x, bhitpos.y)) {
                    bhitpos.x -= stmp->dx;
                    bhitpos.y -= stmp->dy;
                    stmp->stopped = TRUE;
                } else if ((mtmp = m_at(lev, bhitpos.x, bhitpos.y)) != 0) {
                    if (scflags & MAY_HITMON) {
                        stmp->range--;
                        if (ohitmon(mtmp, stmp->obj, 1, FALSE)) {
                            stmp->obj = NULL;
                            stmp->stopped = TRUE;
                        }
                    }
                } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
                    if (scflags & MAY_HITYOU) {
                        int hitvalu, hitu;

                        action_interrupted();

                        hitvalu = 8 + stmp->obj->spe;
                        if (bigmonst(youmonst.data))
                            hitvalu++;
                        hitu =
                            thitu(hitvalu, dmgval(stmp->obj, &youmonst),
                                  stmp->obj, NULL);
                        if (hitu)
                            stmp->range -= 3;
                    }
                } else {
                    if (scflags & VIS_EFFECTS) {
                        /* tmpsym_at(bhitpos.x, bhitpos.y); */
                        /* delay_output(); */
                    }
                }
                stmp->ox = bhitpos.x;
                stmp->oy = bhitpos.y;
            }
        }
    }
    for (stmp = schain; stmp; stmp = stmp2) {
        int x, y;

        stmp2 = stmp->next;
        x = stmp->ox;
        y = stmp->oy;
        if (stmp->obj) {
            if (x != sx || y != sy)
                total += stmp->obj->quan;
            place_object(stmp->obj, lev, x, y);
            stackobj(stmp->obj);
        }
        free(stmp);
        if (lev == level)
            newsym(x, y);
    }

    return total;
}
Example #14
0
/*
 * Let's destroy the drawbridge located at x,y
 */
void
destroy_drawbridge(int x, int y)
{
    struct rm *loc1, *loc2;
    struct trap *t;
    int x2, y2;
    boolean e_inview;
    struct entity *etmp1 = &(occupants[0]), *etmp2 = &(occupants[1]);

    loc1 = &level->locations[x][y];
    if (!IS_DRAWBRIDGE(loc1->typ))
        return;
    x2 = x;
    y2 = y;
    get_wall_for_db(&x2, &y2);
    loc2 = &level->locations[x2][y2];
    if ((loc1->drawbridgemask & DB_UNDER) == DB_MOAT ||
        (loc1->drawbridgemask & DB_UNDER) == DB_LAVA) {
        struct obj *otmp;
        boolean lava = (loc1->drawbridgemask & DB_UNDER) == DB_LAVA;

        if (loc1->typ == DRAWBRIDGE_UP) {
            if (cansee(x2, y2))
                pline(msgc_consequence,
                      "The portcullis of the drawbridge falls into the %s!",
                      lava ? "lava" : waterbody_name(x2, y2));
            else
                You_hear(msgc_levelsound, "a loud *SPLASH*!");
        } else {
            if (cansee(x, y))
                pline(msgc_consequence,
                      "The drawbridge collapses into the %s!",
                      lava ? "lava" : waterbody_name(x, y));
            else
                You_hear(msgc_levelsound, "a loud *SPLASH*!");
        }
        loc1->typ = lava ? LAVAPOOL : MOAT;
        loc1->drawbridgemask = 0;
        if ((otmp = sobj_at(BOULDER, level, x, y)) != 0) {
            obj_extract_self(otmp);
            flooreffects(otmp, x, y, "fall");
        }
    } else {
        if (cansee(x, y))
            pline(msgc_consequence, "The drawbridge disintegrates!");
        else
            You_hear(msgc_levelsound, "a loud *CRASH*!");
        loc1->typ = ((loc1->drawbridgemask & DB_ICE) ? ICE : ROOM);
        loc1->icedpool = ((loc1->drawbridgemask & DB_ICE) ? ICED_MOAT : 0);
    }
    wake_nearto(x, y, 500);
    loc2->typ = DOOR;
    loc2->doormask = D_NODOOR;
    if ((t = t_at(level, x, y)) != 0)
        deltrap(level, t);
    if ((t = t_at(level, x2, y2)) != 0)
        deltrap(level, t);
    newsym(x, y);
    newsym(x2, y2);
    if (!does_block(level, x2, y2))
        unblock_point(x2, y2);  /* vision */
    if (Is_stronghold(&u.uz))
        u.uevent.uopened_dbridge = TRUE;

    set_entity(x2, y2, etmp2);  /* currently only automissers can be here */
    if (etmp2->edata) {
        enum msg_channel hit_msgc;
        if (is_u(etmp2))
            hit_msgc = msgc_fatal_predone;
        else if (etmp2->emon->mtame && canspotmon(etmp2->emon))
            hit_msgc = msgc_petfatal;
        else
            hit_msgc = msgc_monneutral;
        
        e_inview = e_canseemon(etmp2);
        if (!automiss(etmp2)) {
            if (e_inview)
                pline(hit_msgc, "%s blown apart by flying debris.",
                      E_phrase(etmp2, "are"));
            e_died(etmp2, e_inview ? 3 : 2, CRUSHING,
                   killer_msg(CRUSHING, "an exploding drawbridge"));
        }       /* nothing which is vulnerable can survive this */
    }
    set_entity(x, y, etmp1);
    if (etmp1->edata) {
        enum msg_channel hit_msgc;
        if (is_u(etmp1))
            hit_msgc = msgc_fatal_predone;
        else if (etmp1->emon->mtame && canspotmon(etmp1->emon))
            hit_msgc = msgc_petfatal;
        else
            hit_msgc = msgc_monneutral;
        
        e_inview = e_canseemon(etmp1);
        if (!e_missed(etmp1, TRUE)) {
            if (e_inview) {
                if (!is_u(etmp1) && Hallucination)
                    pline(hit_msgc, "%s into some heavy metal!",
                          E_phrase(etmp1, "get"));
                else
                    pline(hit_msgc, "%s hit by a huge chunk of metal!",
                          E_phrase(etmp1, "are"));
            } else {
                if (!is_u(etmp1) && !is_pool(level, x, y))
                    You_hear(msgc_levelsound, "a crushing sound.");
            }
            e_died(etmp1, e_inview ? 3 : 2, CRUSHING,
                   killer_msg(CRUSHING, "a collapsing drawbridge"));
            /* if (loc1->typ == MOAT) do_entity(etmp1); */
        }
        if (is_u(etmp1))
            spoteffects(FALSE);
        else if (!DEADMONSTER(etmp1->emon))
            minliquid(etmp1->emon);
    }
}
Example #15
0
int dospinweb(void)
{
	struct trap *ttmp = t_at(level, u.ux, u.uy);

	if (Levitation || Is_airlevel(&u.uz)
	    || Underwater || Is_waterlevel(&u.uz)) {
		pline("You must be on the ground to spin a web.");
		return 0;
	}
	if (u.uswallow) {
		pline("You release web fluid inside %s.", mon_nam(u.ustuck));
		if (is_animal(u.ustuck->data)) {
			expels(u.ustuck, u.ustuck->data, TRUE);
			return 0;
		}
		if (is_whirly(u.ustuck->data)) {
			int i;

			for (i = 0; i < NATTK; i++)
				if (u.ustuck->data->mattk[i].aatyp == AT_ENGL)
					break;
			if (i == NATTK)
			       impossible("Swallower has no engulfing attack?");
			else {
				char sweep[30];

				sweep[0] = '\0';
				switch(u.ustuck->data->mattk[i].adtyp) {
					case AD_FIRE:
						strcpy(sweep, "ignites and ");
						break;
					case AD_ELEC:
						strcpy(sweep, "fries and ");
						break;
					case AD_COLD:
						strcpy(sweep,
						      "freezes, shatters and ");
						break;
				}
				pline("The web %sis swept away!", sweep);
			}
			return 0;
		}		     /* default: a nasty jelly-like creature */
		pline("The web dissolves into %s.", mon_nam(u.ustuck));
		return 0;
	}
	if (u.utrap) {
		pline("You cannot spin webs while stuck in a trap.");
		return 0;
	}
	exercise(A_DEX, TRUE);
	if (ttmp) switch (ttmp->ttyp) {
		case PIT:
		case SPIKED_PIT: pline("You spin a web, covering up the pit.");
			deltrap(ttmp);
			bury_objs(u.ux, u.uy);
			newsym(u.ux, u.uy);
			return 1;
		case SQKY_BOARD: pline("The squeaky board is muffled.");
			deltrap(ttmp);
			newsym(u.ux, u.uy);
			return 1;
		case TELEP_TRAP:
		case LEVEL_TELEP:
		case MAGIC_PORTAL:
                case VIBRATING_SQUARE:
			pline("Your webbing vanishes!");
			return 0;
		case WEB: pline("You make the web thicker.");
			return 1;
		case HOLE:
		case TRAPDOOR:
			pline("You web over the %s.",
			    (ttmp->ttyp == TRAPDOOR) ? "trap door" : "hole");
			deltrap(ttmp);
			newsym(u.ux, u.uy);
			return 1;
		case ROLLING_BOULDER_TRAP:
			pline("You spin a web, jamming the trigger.");
			deltrap(ttmp);
			newsym(u.ux, u.uy);
			return 1;
		case ARROW_TRAP:
		case DART_TRAP:
		case BEAR_TRAP:
		case ROCKTRAP:
		case FIRE_TRAP:
		case LANDMINE:
		case SLP_GAS_TRAP:
		case RUST_TRAP:
		case MAGIC_TRAP:
		case ANTI_MAGIC:
		case POLY_TRAP:
			pline("You have triggered a trap!");
			dotrap(ttmp, 0);
			return 1;
		default:
			impossible("Webbing over trap type %d?", ttmp->ttyp);
			return 0;
		}
	else if (On_stairs(u.ux, u.uy)) {
	    /* cop out: don't let them hide the stairs */
	    pline("Your web fails to impede access to the %s.",
		 (level->locations[u.ux][u.uy].typ == STAIRS) ? "stairs" : "ladder");
	    return 1;
		 
	}
	ttmp = maketrap(level, u.ux, u.uy, WEB);
	if (ttmp) {
		ttmp->tseen = 1;
		ttmp->madeby_u = 1;
	}
	newsym(u.ux, u.uy);
	return 1;
}
/* TODO: Perhaps work out some way to let controlled teleport in on a
   CMD_ARG_POS, but there are too many codeflow possibilities involved to make
   that easy. For now, if dotele turns into the spell, we copy the argument on
   to the spell-handling function (which currently ignores it), but the other
   possible codepaths just lose it. */
int
dotele(const struct nh_cmd_arg *arg)
{
    struct trap *trap;

    trap = t_at(level, u.ux, u.uy);
    if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP))
        trap = 0;

    if (trap) {
        if (trap->once) {
            pline("This is a vault teleport, usable once only.");
            if (yn("Jump in?") == 'n')
                trap = 0;
            else {
                deltrap(level, trap);
                newsym(u.ux, u.uy);
            }
        }
        if (trap)
            pline("You %s onto the teleportation trap.",
                  locomotion(youmonst.data, "jump"));
    }
    if (!trap) {
        boolean castit = FALSE;
        int sp_no = 0, energy = 0;

        if (!supernatural_ability_available(SPID_RLOC)) {
            /* Try to use teleport away spell. */
            if (objects[SPE_TELEPORT_AWAY].oc_name_known && !Confusion)
                for (sp_no = 0; sp_no < MAXSPELL; sp_no++)
                    if (spl_book[sp_no].sp_id == SPE_TELEPORT_AWAY) {
                        castit = TRUE;
                        break;
                    }
            if (!castit) {
                if (!Teleportation)
                    pline("You don't know that spell.");
                else
                    pline("You are not able to teleport at will.");
                return 0;
            }
        }

        if (u.uhunger <= 100 || ACURR(A_STR) < 6) {
            pline("You lack the strength %s.",
                  castit ? "for a teleport spell" : "to teleport");
            return 1;
        }

        energy = objects[SPE_TELEPORT_AWAY].oc_level * 7 / 2 - 2;
        if (u.uen <= energy) {
            pline("You lack the energy %s.",
                  castit ? "for a teleport spell" : "to teleport");
            return 1;
        }

        if (check_capacity("Your concentration falters from carrying so much."))
            return 1;

        if (castit) {
            exercise(A_WIS, TRUE);
            if (spelleffects(sp_no, TRUE, arg))
                return 1;
            else
                return 0;
        } else
            u.uen -= energy;
    }

    if (trap && trap->once) {
        if (next_to_u())
            vault_tele();
        else
            pline("You shudder for a moment.");
    } else if (!tele_impl(FALSE, TRUE))
        return 0;

    next_to_u();

    if (!trap)
        morehungry(100);
    return 1;
}
Example #17
0
/*
 * Let's destroy the drawbridge located at x,y
 */
void destroy_drawbridge(int x, int y)
{
	struct rm *loc1, *loc2;
	struct trap *t;
	int x2, y2;
	int db_u;
	boolean e_inview;
	struct entity *etmp1 = &(occupants[0]), *etmp2 = &(occupants[1]);

	loc1 = &level->locations[x][y];
	if (!IS_DRAWBRIDGE(loc1->typ))
		return;
	x2 = x; y2 = y;
	get_wall_for_db(&x2,&y2);
	loc2 = &level->locations[x2][y2];
	db_u = (loc1->drawbridgemask & DB_UNDER);
	if (db_u == DB_MOAT || db_u == DB_LAVA || db_u == DB_BOG) {
		struct obj *otmp;
		int where = (db_u == DB_LAVA) ? 0 :
			    (db_u == DB_MOAT) ? 1 : 2;
		static char *wstr[3] = { "lava", "moat", "swamp" };
		if (loc1->typ == DRAWBRIDGE_UP) {
			if (cansee(x2,y2))
			    pline("The portcullis of the drawbridge falls into the %s!",
				  wstr[where]);
			else if (flags.soundok)
				You_hear("a loud *SPLASH*!");
		} else {
			if (cansee(x,y))
			    pline("The drawbridge collapses into the %s!",
				  wstr[where]);
			else if (flags.soundok)
				You_hear("a loud *SPLASH*!");
		}
		loc1->typ = (where == 0) ? LAVAPOOL :
			    (where == 1) ? MOAT : BOG;
		loc1->drawbridgemask = 0;
		if ((otmp = sobj_at(BOULDER, level, x,y)) != 0) {
		    obj_extract_self(otmp);
		    flooreffects(otmp,x,y,"fall");
		}
	} else {
		if (cansee(x,y))
			pline("The drawbridge disintegrates!");
		else
			You_hear("a loud *CRASH*!");
		loc1->typ =
			((loc1->drawbridgemask & DB_ICE) ? ICE : ROOM);
		loc1->icedpool =
			((loc1->drawbridgemask & DB_ICE) ? ICED_MOAT : 0);
	}
	wake_nearto(x, y, 500);
	loc2->typ = DOOR;
	loc2->doormask = D_NODOOR;
	if ((t = t_at(level, x, y)) != 0) deltrap(level, t);
	if ((t = t_at(level, x2, y2)) != 0) deltrap(level, t);
	newsym(x,y);
	newsym(x2,y2);
	if (!does_block(level, x2, y2, NULL)) unblock_point(x2,y2); /* vision */
	if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE;

	set_entity(x2, y2, etmp2); /* currently only automissers can be here */
	if (etmp2->edata) {
		e_inview = e_canseemon(level, etmp2);
		if (!automiss(etmp2)) {
			if (e_inview)
				pline("%s blown apart by flying debris.",
				      E_phrase(etmp2, "are"));
			killer_format = KILLED_BY_AN;
			killer = "exploding drawbridge";
			e_died(etmp2, e_inview? 3 : 2, CRUSHING); /*no corpse*/
		}	     /* nothing which is vulnerable can survive this */
	}
	set_entity(x, y, etmp1);
	if (etmp1->edata) {
		e_inview = e_canseemon(level, etmp1);
		if (!e_missed(etmp1, TRUE)) {
			if (e_inview) {
			    if (!is_u(etmp1) && Hallucination)
				pline("%s into some heavy metal!",
				      E_phrase(etmp1, "get"));
			    else
				pline("%s hit by a huge chunk of metal!",
				      E_phrase(etmp1, "are"));
			} else {
			    if (flags.soundok && !is_u(etmp1) && !is_pool(level, x,y))
				You_hear("a crushing sound.");
			}
			killer_format = KILLED_BY_AN;
			killer = "collapsing drawbridge";
			e_died(etmp1, e_inview? 3 : 2, CRUSHING); /*no corpse*/
			if (loc1->typ == MOAT) do_entity(etmp1);
		}
	}
}
Example #18
0
static void wallify_vault(struct monst *grd) {
    int x, y, typ;
    int vlt = EGD(grd)->vroom;
    char tmp_viz;
    signed char lox = rooms[vlt].lx - 1, hix = rooms[vlt].hx + 1, loy = rooms[vlt].ly - 1, hiy = rooms[vlt].hy + 1;
    struct monst *mon;
    struct obj *gold;
    struct trap *trap;
    bool fixed = false;
    bool movedgold = false;

    for (x = lox; x <= hix; x++) {
        for (y = loy; y <= hiy; y++) {
            /* if not on the room boundary, skip ahead */
            if (x != lox && x != hix && y != loy && y != hiy)
                continue;

            if (!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
                if ((mon = m_at(x, y)) != 0 && mon != grd) {
                    if (mon->mtame)
                        yelp(mon);
                    (void)rloc(mon, false);
                }
                if ((gold = g_at(x, y)) != 0) {
                    move_gold(gold, EGD(grd)->vroom);
                    movedgold = true;
                }
                if ((trap = t_at(x, y)) != 0)
                    deltrap(trap);
                if (x == lox)
                    typ = (y == loy) ? TLCORNER : (y == hiy) ? BLCORNER : VWALL;
                else if (x == hix)
                    typ = (y == loy) ? TRCORNER : (y == hiy) ? BRCORNER : VWALL;
                else
                    /* not left or right side, must be top or bottom */
                    typ = HWALL;
                levl[x][y].typ = typ;
                levl[x][y].flags = 0;
                /*
                 * hack: player knows walls are restored because of the
                 * message, below, so show this on the screen.
                 */
                tmp_viz = viz_array[y][x];
                viz_array[y][x] = IN_SIGHT | COULD_SEE;
                newsym(x, y);
                viz_array[y][x] = tmp_viz;
                block_point(x, y);
                fixed = true;
            }
        }
    }

    if (movedgold || fixed) {
        if (in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my)) {
            char name[BUFSZ];
            g_monnam(name, BUFSZ, grd);
            pline_The("%s whispers an incantation.", name);
        } else {
            You_hear("a distant chant.");
        }
        if (movedgold)
            pline("A mysterious force moves the gold into the vault.");
        if (fixed)
            pline_The("damaged vault's walls are magically restored!");
    }
}
Example #19
0
/*
 * Let's destroy the drawbridge located at x,y
 */
void
destroy_drawbridge(int x, int y)
{
    struct rm *loc1, *loc2;
    struct trap *t;
    struct obj *chain;
    int x2, y2, i;
    boolean e_inview;
    struct entity *etmp1 = &(occupants[0]), *etmp2 = &(occupants[1]);

    loc1 = &level->locations[x][y];
    if (!IS_DRAWBRIDGE(loc1->typ))
        return;
    x2 = x;
    y2 = y;
    get_wall_for_db(&x2, &y2);
    loc2 = &level->locations[x2][y2];
    if ((loc1->drawbridgemask & DB_UNDER) == DB_MOAT ||
        (loc1->drawbridgemask & DB_UNDER) == DB_LAVA) {
        struct obj *otmp;
        boolean lava = (loc1->drawbridgemask & DB_UNDER) == DB_LAVA;

        if (loc1->typ == DRAWBRIDGE_UP) {
            if (cansee(x2, y2))
                pline("The portcullis of the drawbridge falls into the %s!",
                      lava ? "lava" : waterbody_name(x2, y2));
            else
                You_hear("a loud *SPLASH*!");
        } else {
            if (cansee(x, y))
                pline("The drawbridge collapses into the %s!",
                      lava ? "lava" : waterbody_name(x, y));
            else
                You_hear("a loud *SPLASH*!");
        }
        loc1->typ = lava ? LAVAPOOL : MOAT;
        loc1->drawbridgemask = 0;
        if ((otmp = sobj_at(BOULDER, level, x, y)) != 0) {
            obj_extract_self(otmp);
            flooreffects(otmp, x, y, "fall");
        }
    } else {
        if (cansee(x, y))
            pline("The drawbridge disintegrates!");
        else
            You_hear("a loud *CRASH*!");
        loc1->typ = ((loc1->drawbridgemask & DB_ICE) ? ICE : ROOM);
        loc1->icedpool = ((loc1->drawbridgemask & DB_ICE) ? ICED_MOAT : 0);
    }
    wake_nearto(x, y, 500);
    loc2->typ = DOOR;
    loc2->doormask = D_NODOOR;
    if ((t = t_at(level, x, y)) != 0)
        deltrap(level, t);
    if ((t = t_at(level, x2, y2)) != 0)
        deltrap(level, t);
    del_engr_at(level, x, y);
    del_engr_at(level, x2, y2);
    for (i = rn2(6); i > 0; --i) {  /* scatter some debris */
        /* doesn't matter if we happen to pick <x,y2> or <x2,y>;
           since drawbridges are never placed diagonally, those
           pairings will always match one of <x,y> or <x2,y2> */
        chain = mksobj_at(IRON_CHAIN, level,
                          rn2(2) ? x : x2, rn2(2) ? y : y2,
                          TRUE, FALSE, rng_main);
        /* a force of 5 here would yield a radius of 2 for
           iron chain; anything less produces a radius of 1 */
        (void) scatter(chain->ox, chain->oy, 1, MAY_HIT, chain);
    }
    newsym(x, y);
    newsym(x2, y2);
    if (!does_block(level, x2, y2))
        unblock_point(x2, y2);  /* vision */
    if (Is_stronghold(&u.uz))
        u.uevent.uopened_dbridge = TRUE;

    set_entity(x2, y2, etmp2);  /* currently only automissers can be here */
    if (etmp2->edata) {
        e_inview = e_canseemon(etmp2);
        if (!automiss(etmp2)) {
            if (e_inview)
                pline("%s blown apart by flying debris.",
                      E_phrase(etmp2, "are"));
            e_died(etmp2, e_inview ? 3 : 2, CRUSHING,
                   killer_msg(CRUSHING, "an exploding drawbridge"));
        }       /* nothing which is vulnerable can survive this */
    }
    set_entity(x, y, etmp1);
    if (etmp1->edata) {
        e_inview = e_canseemon(etmp1);
        if (!e_missed(etmp1, TRUE)) {
            if (e_inview) {
                if (!is_u(etmp1) && Hallucination)
                    pline("%s into some heavy metal!", E_phrase(etmp1, "get"));
                else
                    pline("%s hit by a huge chunk of metal!",
                          E_phrase(etmp1, "are"));
            } else {
                if (!is_u(etmp1) && !is_pool(level, x, y))
                    You_hear("a crushing sound.");
            }
            e_died(etmp1, e_inview ? 3 : 2, CRUSHING,
                   killer_msg(CRUSHING, "a collapsing drawbridge"));
            /* if (loc1->typ == MOAT) do_entity(etmp1); */
        }
        if (is_u(etmp1))
            spoteffects(FALSE);
        else if (!DEADMONSTER(etmp1->emon))
            minliquid(etmp1->emon);
    }
}
Example #20
0
/*
 *  drop_ball()
 *
 *  The punished hero drops or throws her iron ball.  If the hero is
 *  blind, we must reset the order and glyph.  Check for side effects.
 *  This routine expects the ball to be already placed.
 *
 *  Should not be called while swallowed.
 */
void
drop_ball(xchar x, xchar y, schar dx, schar dy)
{
    if (Blind) {
        u.bc_order = bc_order();        /* get the order */
        /* pick up mem_obj */
        u.bglyph = (u.bc_order) ? u.cglyph : level->locations[x][y].mem_obj;
    }

    if (x != u.ux || y != u.uy) {
        struct trap *t;
        const char *pullmsg = "The ball pulls you out of the %s!";

        if (u.utrap && u.utraptype != TT_INFLOOR) {
            switch (u.utraptype) {
            case TT_PIT:
                pline(pullmsg, "pit");
                break;
            case TT_WEB:
                pline(pullmsg, "web");
                pline("The web is destroyed!");
                deltrap(level, t_at(level, u.ux, u.uy));
                break;
            case TT_LAVA:
                pline(pullmsg, "lava");
                break;
            case TT_BEARTRAP:{
                    long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE;

                    pline(pullmsg, "bear trap");
                    set_wounded_legs(side, rn1(1000, 500));

                    if (!u.usteed) {
                        pline("Your %s %s is severely damaged.",
                              (side == LEFT_SIDE) ? "left" : "right",
                              body_part(LEG));
                        losehp(2, killer_msg(DIED, "leg damage from being "
                                             "pulled out of a bear trap"));
                    }
                    break;
                }
            }
            u.utrap = 0;
            fill_pit(level, u.ux, u.uy);
        }

        u.ux0 = u.ux;
        u.uy0 = u.uy;
        if (!Levitation && !MON_AT(level, x, y) && !u.utrap &&
            (is_pool(level, x, y) ||
             ((t = t_at(level, x, y)) &&
              (t->ttyp == PIT || t->ttyp == SPIKED_PIT || t->ttyp == TRAPDOOR ||
               t->ttyp == HOLE)))) {
            u.ux = x;
            u.uy = y;
        } else {
            u.ux = x - dx;
            u.uy = y - dy;
        }

        /* hero has moved, recalculate vision later */
        turnstate.vision_full_recalc = TRUE;

        if (Blind) {
            /* drop glyph under the chain */
            if (u.bc_felt & BC_CHAIN)
                level->locations[uchain->ox][uchain->oy].mem_obj = u.cglyph;
            u.bc_felt = 0;      /* feel nothing */
            /* pick up new glyph */
            u.cglyph =
                (u.bc_order) ? u.bglyph : level->locations[u.ux][u.uy].mem_obj;
        }
        movobj(uchain, u.ux, u.uy);     /* has a newsym */
        if (Blind) {
            u.bc_order = bc_order();
        }
        newsym(u.ux0, u.uy0);   /* clean up old position */
        if (u.ux0 != u.ux || u.uy0 != u.uy) {
            spoteffects(TRUE);
            if (In_sokoban(&u.uz))
                change_luck(-1);        /* Sokoban guilt */
        }
    }
}
Example #21
0
static void
wallify_vault(struct monst *grd)
{
    int x, y, typ;
    int vlt = EGD(grd)->vroom;
    char tmp_viz;
    xchar lox = level->rooms[vlt].lx - 1, hix = level->rooms[vlt].hx + 1, loy =
        level->rooms[vlt].ly - 1, hiy = level->rooms[vlt].hy + 1;
    struct monst *mon;
    struct obj *gold;
    struct trap *trap;
    boolean fixed = FALSE;
    boolean movedgold = FALSE;

    for (x = lox; x <= hix; x++)
        for (y = loy; y <= hiy; y++) {
            /* if not on the room boundary, skip ahead */
            if (x != lox && x != hix && y != loy && y != hiy)
                continue;

            if (!IS_WALL(level->locations[x][y].typ) &&
                !in_fcorridor(grd, x, y)) {
                if ((mon = m_at(level, x, y)) != 0 && mon != grd) {
                    if (mon->mtame)
                        yelp(mon);
                    rloc(mon, FALSE);
                }
                if ((gold = gold_at(level, x, y)) != 0) {
                    move_gold(gold, EGD(grd)->vroom);
                    movedgold = TRUE;
                }
                if ((trap = t_at(level, x, y)) != 0)
                    deltrap(level, trap);
                if (x == lox)
                    typ = (y == loy) ? TLCORNER : (y == hiy) ? BLCORNER : VWALL;
                else if (x == hix)
                    typ = (y == loy) ? TRCORNER : (y == hiy) ? BRCORNER : VWALL;
                else    /* not left or right side, must be top or bottom */
                    typ = HWALL;
                level->locations[x][y].typ = typ;
                level->locations[x][y].doormask = 0;
                /* 
                 * hack: player knows walls are restored because of the
                 * message, below, so show this on the screen.
                 */
                tmp_viz = viz_array[y][x];
                viz_array[y][x] = IN_SIGHT | COULD_SEE;
                newsym(x, y);
                viz_array[y][x] = tmp_viz;
                block_point(x, y);
                fixed = TRUE;
            }
        }

    if (movedgold || fixed) {
        if (mon_visible(grd))
            pline("%s whispers an incantation.", Monnam(grd));
        else
            You_hear("a %s chant.", in_fcorridor(grd, grd->mx, grd->my)
                     ? "nearby" : "distant");
        if (movedgold)
            pline("A mysterious force moves the gold into the vault.");
        if (fixed)
            pline("The damaged vault's walls are magically restored!");
    }
}