Пример #1
0
/* find obj on one of the lists */
obj_t * bp_to_obj(bill_t *bp)
{
  obj_t *obj;
  monst_t *mtmp;
  UShort id = bp->bo_id;

  if (bp->useup)
    obj = o_on(id, billobjs);
  else if (!(obj = o_on(id, invent)) &&
	   !(obj = o_on(id, fobj)) &&
	   !(obj = o_on(id, fcobj))) {
    for (mtmp = fmon ; mtmp ; mtmp = mtmp->nmon)
      if ((obj = o_on(id, mtmp->minvent)))
	break;
    for (mtmp = fallen_down ; mtmp ; mtmp = mtmp->nmon)
      if ((obj = o_on(id, mtmp->minvent)))
	break;
  }
  return obj;
}
Пример #2
0
/* find obj on one of the lists */
static struct obj *
bp_to_obj(struct bill_x *bp)
{
	struct obj *obj;
	struct monst *mtmp;
	unsigned id = bp->bo_id;

	if (bp->useup)
		obj = o_on(id, billobjs);
	else if (!(obj = o_on(id, invent)) &&
		 !(obj = o_on(id, fobj)) &&
		 !(obj = o_on(id, fcobj))) {
		for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
			if ((obj = o_on(id, mtmp->minvent)) != NULL)
				break;
		for (mtmp = fallen_down; mtmp; mtmp = mtmp->nmon)
			if ((obj = o_on(id, mtmp->minvent)) != NULL)
				break;
	}
	return (obj);
}
Пример #3
0
/*
 * quaff:
 *	Let the hero drink a potion
 */
int quaff()
{
	struct object *obj;
	struct linked_list *item, *titem;
	struct thing *th;
	int wh;
	char buf[LINLEN];
	bool bless, curse;

	/*
	 * Make certain that it is somethings that we want to drink
	 */
	if ((item = get_item("quaff", POTION)) == NULL)
		return 0;
	obj = OBJPTR(item);
	if (obj->o_type != POTION) {
		msg("That's undrinkable!");
		after = FALSE;
		return 0;
	}
	wh = obj->o_which;
	bless = o_on(obj, ISBLESS);
	curse = o_on(obj, ISCURSED);
	del_pack(item);		/* get rid of it */

	/*
	 * Calculate the effect it has on the poor guy.
	 */
	switch(wh) {
	case P_CONFUSE:
		if (!bless) {
			if (pl_on(ISINVINC))
				msg("You remain level-headed.");
			else {
				chg_abil(WIS,-1,TRUE);		/* confuse his mind */
				if (pl_off(ISHUH)) {
					msg("Wait, what's going on here. Huh? What? Who?");
					if (pl_on(ISHUH))
						lengthen(unconfuse,rnd(8)+HUHDURATION);
					else
						fuse(unconfuse,TRUE,rnd(8)+HUHDURATION);
					player.t_flags |= ISHUH;
				}
			}
			p_know[P_CONFUSE] = TRUE;
		}
	when P_POISON:
		if (!bless) {
			if (pl_off(ISINVINC) && !iswearing(R_SUSTSTR) &&
			  !iswearing(R_SUSAB)) {
				chg_abil(CON,-1,TRUE);		
				chg_abil(STR,-(rnd(3)+1),TRUE);
				msg("You feel very sick now.");
			}
			else
				msg("You feel momentarily sick.");
			p_know[P_POISON] = TRUE;
		}
	when P_HEALING:
		if (!curse) {
			heal_self(4, TRUE);
			msg("You begin to feel better.");
			if (!iswearing(R_SLOW))
				notslow(FALSE);
			sight(FALSE);
			p_know[P_HEALING] = TRUE;
		}
	when P_STRENGTH:
		if (!curse) {
			msg("You feel stronger, now.  What bulging muscles!");
			chg_abil(STR,1,TRUE);
			p_know[P_STRENGTH] = TRUE;
		}
	when P_MFIND:
		/*
		 * Potion of monster detection - find all monsters
		 */
		if (mlist != NULL && !curse) {
			dispmons();
			mpos = 0;
			msg("You begin to sense the presence of monsters--More--");
			p_know[P_MFIND] = TRUE;
			wait_for(cw,' ');
			msg("");		/* clear line */
		}
		else
			msg("You have a strange feeling for a moment, then it passes.");
	when P_TFIND:
		/*
		 * Potion of magic detection.  Show the potions and scrolls
		 */
		if (lvl_obj != NULL && !curse) {
			struct linked_list *mobj;
			struct object *tp;
			bool show;

			show = FALSE;
			wclear(hw);
			for (mobj = lvl_obj; mobj != NULL; mobj = next(mobj)) {
				tp = OBJPTR(mobj);
				if (is_magic(tp)) {
					show = TRUE;
					mvwaddch(hw, tp->o_pos.y, tp->o_pos.x, MAGIC);
				}
			}
			for(titem = mlist; titem != NULL; titem = next(titem)) {
				struct linked_list *pitem;

				th = THINGPTR(titem);
				for(pitem=th->t_pack;pitem!=NULL;pitem=next(pitem)) {
					if (is_magic(ldata(pitem))) {
						show = TRUE;
						mvwaddch(hw,th->t_pos.y, th->t_pos.x, MAGIC);
					}
				}
			}
			if (show) {
				msg("You begin to sense the presence of magic.");
				overlay(hw,cw);
				p_know[P_TFIND] = TRUE;
				break;
			}
		}
		msg("You have a strange feeling for a moment, then it passes.");
	when P_PARALYZE:
		if (!bless) {
			if (pl_on(ISINVINC))
				msg("You feel numb for a moment.");
			else {
				msg("You can't move.");
				player.t_nocmd = HOLDTIME;
			}
			p_know[P_PARALYZE] = TRUE;
		}
	when P_SEEINVIS:
		if (!curse) {
			int invlen = roll(40,20);

			msg("This potion tastes like %s juice.", fruit);
			if (pl_off(CANSEE)) {
				player.t_flags |= CANSEE;
				fuse(unsee, TRUE, invlen);
				light(&hero);
			}
			else
				lengthen(unsee, invlen);
			sight(FALSE);
		}
	when P_RAISE:
		if (!curse) {
			msg("You suddenly feel much more skillful.");
			p_know[P_RAISE] = TRUE;
			chg_abil(DEX,1,TRUE);
			chg_abil(WIS,1,TRUE);
			chg_abil(CON,1,TRUE);
			raise_level();
		}
	when P_XHEAL:
		if (!curse) {
			heal_self(8, TRUE);
			if (rnd(100) < 50)
				chg_abil(CON,1,TRUE);
			msg("You begin to feel much better.");
			p_know[P_XHEAL] = TRUE;
			if (!iswearing(R_SLOW))
				notslow(FALSE);
			unconfuse();
			extinguish(unconfuse);
			sight(FALSE);
		}
	when P_HASTE:
		if (!curse) {
			add_haste(TRUE);
			msg("You feel yourself moving much faster.");
			p_know[P_HASTE] = TRUE;
		}
	when P_INVINC:
		if (!curse) {
			int time = rnd(400) + 350;

			msg("You feel invincible.");
			if (player.t_flags & ISINVINC)
				lengthen(notinvinc,time);
			else
				fuse(notinvinc,TRUE,time);
			player.t_flags |= ISINVINC;
			p_know[P_INVINC] = TRUE;
		}
	when P_SMART:
		if (!curse) {
			msg("You feel more perceptive.");
			p_know[P_SMART] = TRUE;
			chg_abil(WIS,1,TRUE);
		}
	when P_RESTORE:
		if (!curse) {
			msg("Hey, this tastes great. You feel warm all over.");
			him->s_re = max_stats.s_re;
			him->s_ef = max_stats.s_re;
			ringabil();				/* add in rings */
			updpack();				/* update weight */
			p_know[P_RESTORE] = TRUE;
			extinguish(rchg_str);	/* kill restore in from ulodyte */
		}
	when P_BLIND:
		if (!bless) {
			if (pl_on(ISINVINC))
				msg("The light dims for a moment.");
			else {
				chg_abil(WIS,-1,TRUE);
				msg("A cloak of darkness falls around you.");
				if (pl_off(ISBLIND)) {
					player.t_flags |= ISBLIND;
					fuse(sight, TRUE, rnd(400) + 450);
					light(&hero);
				}
			}
			p_know[P_BLIND] = TRUE;
		}
	when P_ETH:
		if (!curse) {
			int ethlen = roll(40,20);

			msg("You feel more vaporous.");
			if (pl_on(ISETHER))
				lengthen(noteth,ethlen);
			else
				fuse(noteth,TRUE,ethlen);
			player.t_flags |= ISETHER;
			p_know[P_ETH] = TRUE;
		}
	when P_NOP:
		msg("This potion tastes extremely dull.");
	when P_DEX:
		if (!curse) {
			chg_abil(DEX,1,TRUE);		/* increase dexterity */
			p_know[P_DEX] = TRUE;
			msg("You feel much more agile.");
		}
	when P_REGEN:
		if (!curse) {
			int reglen = rnd(450) + 450;

			if (pl_on(ISREGEN))
				lengthen(notregen, reglen);
			else
				fuse(notregen, TRUE, reglen);
			player.t_flags |= ISREGEN;
			msg("You feel yourself improved.");
			p_know[P_REGEN] = TRUE;
		}
	when P_DECREP:
	case P_SUPHERO: {
		int howmuch = rnd(3) + 1;

		if (wh == P_DECREP) {
			if (!bless) {
				if (iswearing(R_SUSAB) || pl_on(ISINVINC)) {
					msg("You feel momentarily woozy.");
					howmuch = 0;
				}
				else {
					msg("You feel crippled.");
					howmuch = -howmuch;
					if (!iswearing(R_SUSTSTR))
						chg_abil(STR,howmuch,TRUE);
				}
			}
			else
				howmuch = 0;
		}
		else {			/* potion of superhero */
			if (curse)
				howmuch = 0;
			msg("You feel invigorated.");
			chg_abil(STR,howmuch,TRUE);
		}
		chg_abil(CON,howmuch,TRUE);
		chg_abil(DEX,howmuch,TRUE);
		chg_abil(WIS,howmuch,TRUE);		/* change abilities */
		p_know[wh] = TRUE;
	}
	otherwise:
		msg("What an odd tasting potion!");
		return 0;
	}
	nochange = FALSE;
	if (p_know[wh] && p_guess[wh]) {
		free(p_guess[wh]);
		p_guess[wh] = NULL;
	}
	else if(!p_know[wh] && p_guess[wh] == NULL) {
		strcpy(buf, p_colors[wh]);
		msg(callit);
		if (get_str(buf, cw) == NORM) {
			p_guess[wh] = new(strlen(buf) + 1);
			strcpy(p_guess[wh], buf);
		}
Пример #4
0
/*
 * ring_on:
 *	Put on a ring
 */
int ring_on()
{
  struct object *obj;
  struct linked_list *item;
  int ring, wh;
  char buf[LINLEN];
  bool okring;

  if (cur_ring[LEFT] != NULL && cur_ring[RIGHT] != NULL) {
    msg("Already wearing two rings.");
    after = FALSE;
    return 0;
  }
  /*
   * Make certain that it is somethings that we want to wear
   */
  if ((item = get_item("put on", RING)) == NULL)
    return 0;
  obj = OBJPTR(item);
  if (obj->o_type != RING) {
    msg("That won't fit on your finger.");
    return 0;
  }
  /*
   * find out which hand to put it on
   */
  if (is_current(obj))
    return 0;
  if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL) {
    if ((ring = gethand(FALSE)) < 0)
      return 0;
  } else if (cur_ring[LEFT] == NULL)
    ring = LEFT;
  else
    ring = RIGHT;
  cur_ring[ring] = obj;
  wh = obj->o_which;
  /*
   * okring = FALSE when:
   * 1) ring is cursed and benefit = plus
   * 2) ring is blessed and benefit = minus
   */
  okring = !((obj->o_ac > 0 && o_on(obj, ISCURSED)) ||
             (obj->o_ac < 0 && o_on(obj, ISBLESS)));
  /*
   * Calculate the effect it has on the poor guy (if possible).
   */
  if (okring) {
    switch (wh) {
    case R_SPEED:
      if (--obj->o_ac < 0) {
        obj->o_ac = 0;
        setoflg(obj, ISCURSED);
      } else {
        add_haste(FALSE);
        msg("You find yourself moving must faster.");
      }
      when R_GIANT : /* to 24 */
                     him->s_ef.a_str = MAXSTR;
      when R_ADDSTR : chg_abil(STR, obj->o_ac, FROMRING);
      when R_KNOW : chg_abil(WIS, obj->o_ac, FROMRING);
      when R_DEX : chg_abil(DEX, obj->o_ac, FROMRING);
      when R_CONST : chg_abil(CON, obj->o_ac, FROMRING);
      when R_SEEINVIS : player.t_flags |= CANSEE;
      light(&hero);
      mvwaddch(cw, hero.y, hero.x, PLAYER);
      when R_AGGR : aggravate();
      when R_HEAVY : updpack(); /* new pack weight */
      when R_BLIND : r_know[R_BLIND] = TRUE;
      player.t_flags |= ISBLIND;
      look(FALSE);
      when R_SLOW : player.t_flags |= ISSLOW;
      when R_SAPEM : fuse(sapem, TRUE, 150);
      when R_LIGHT:
      {
        struct room *rop;

        r_know[R_LIGHT] = TRUE;
        if ((rop = player.t_room) != NULL) {
          rop->r_flags &= ~ISDARK;
          light(&hero);
          mvwaddch(cw, hero.y, hero.x, PLAYER);
        }
      }
    }
  }
  if (r_know[wh] && r_guess[wh]) {
    free(r_guess[wh]);
    r_guess[wh] = NULL;
  } else if (!r_know[wh] && r_guess[wh] == NULL) {
    mpos = 0;
    strcpy(buf, r_stones[wh]);
    msg(callit);
    if (get_str(buf, cw) == NORM) {
      r_guess[wh] = new (strlen(buf) + 1);
      strcpy(r_guess[wh], buf);
    }
Пример #5
0
/*
 * read_scroll:
 *	Let the hero read a scroll
 */
int read_scroll()
{
	struct object *obj;
	struct linked_list *item;
	int i, j, wh;
	unsigned long ch, nch;
	struct room *rp;
	struct linked_list *titem;
	char buf[LINLEN];
	bool bless, curse;

	if ((item = get_item("read", SCROLL)) == NULL)
		return 0;
	obj = OBJPTR(item);
	if (obj->o_type != SCROLL) {
		msg("Nothing to read.");
		after = FALSE;
		return 0;
	}
	msg("As you read the scroll, it vanishes.");
	wh = obj->o_which;
	bless = o_on(obj, ISBLESS);
	curse = o_on(obj, ISCURSED);
	del_pack(item);		/* Get rid of the thing */

	/*
	 * Calculate the effect it has on the hero
	 */
	switch(wh) {
	case S_KNOWALL:
		if (!curse) {
			idenpack();				/* identify all the pack */
			msg("You feel more knowledgable.");
			chg_abil(WIS,1,TRUE);
			s_know[S_KNOWALL] = TRUE;
		}
	when S_CONFUSE:
		if (!curse) {
			/*
			 * Scroll of monster confusion.  Give him that power.
			 */
			msg("Your hands begin to glow red.");
			player.t_flags |= CANHUH;
			s_know[S_CONFUSE] = TRUE;
		}
	when S_LIGHT:
		rp = player.t_room;
		if (!curse) {
			if (rp == NULL) {
				s_know[S_LIGHT] = TRUE;
				msg("The corridor glows and then fades.");
			}
			else {
				if (rf_on(rp,ISDARK)) {
					s_know[S_LIGHT] = TRUE;
					msg("The room is lit.");
					rp->r_flags &= ~ISDARK;
				}
				light(&hero);
				mvwaddch(cw, hero.y, hero.x, PLAYER);
			}
		}
	when S_ARMOR:
		if (!curse) {
			if (cur_armor != NULL && o_off(cur_armor,ISPROT)) {
				s_know[S_ARMOR] = TRUE;
				msg("Your armor glows faintly for a moment.");
				if (o_on(cur_armor,ISCURSED))
					cur_armor->o_ac = armors[cur_armor->o_which].a_class;
				else
					cur_armor->o_ac--;
				resoflg(cur_armor,ISCURSED);
			}
		}
	when S_HOLD:
		if (!curse) {
			/*
			 * Hold monster scroll.  Stop all monsters within 3 spaces
			 * from chasing after the hero.
			 */
			int x,y;
			struct linked_list *mon;

			for (x = hero.x - 3; x <= hero.x + 3; x++) {
				for (y = hero.y - 3; y <= hero.y + 3; y++) {
					if (y > 0 && x > 0 && isalpha(mvwinch(mw, y, x))) {
						if ((mon = find_mons(y, x)) != NULL) {
							struct thing *th;

							th = THINGPTR(mon);
							th->t_flags &= ~ISRUN;
							th->t_flags |= ISHELD;
							th->t_flags |= ISSTUCK;
						}
					}
				}
			}
		}
	when S_SLEEP:
		/*
		 * Scroll which makes you fall asleep
		 */
		if (!bless) {
			s_know[S_SLEEP] = TRUE;
			msg("You fall asleep.");
			player.t_nocmd += 4 + rnd(SLEEPTIME);
		}
	when S_CREATE:
		if (!bless) {
			if (makemons(mtlev[rnd(levcount)]->m_show))
				s_know[S_CREATE] = TRUE;
			else
				msg("You hear a faint cry of anguish in the distance.");
		}
	when S_IDENT:
		if (!curse) {
			msg("This scroll is an identify scroll");
			s_know[S_IDENT] = TRUE;
			whatis(NULL);
		}
	when S_MAP:
		if (curse)
			break;
		s_know[S_MAP] = TRUE;
		addmsg("Oh, now this scroll has a ");
		if (rnd(100) < 10 || bless) {
			addmsg("very detailed map on it.");
			endmsg();
			displevl();
		}
		else {
			addmsg("map on it.");
			endmsg();
			overwrite(stdscr, hw);
			for (i = 1; i < LINES - 2; i++) {
				for (j = 0; j < COLS; j++) {
					switch (nch = ch = mvwinch(hw, i, j)) {
						case SECRETDOOR:
							nch = DOOR;
							mvaddch(i, j, nch);
						case '-':
						case '|':
						case DOOR:
						case PASSAGE:
						case ' ':
						case STAIRS:
							if (mvwinch(mw, i, j) != ' ') {
								struct thing *it;
								struct linked_list *blah;

								blah = find_mons(i, j);
								if (blah != NULL) {
									it = THINGPTR(blah);
									if (it->t_oldch == ' ')
										it->t_oldch = nch;
								}
							}
							break;
						default:
							nch = ' ';
					}
					if (nch != ch)
						waddch(hw, nch);
				}
			}
			overlay(cw, hw);
			overwrite(hw, cw);
		}
	when S_GFIND:
		if (!curse) {
			int gtotal = 0;
			struct room *rp;

			wclear(hw);
			for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
				gtotal += rp->r_goldval;
				if (rp->r_goldval != 0 &&
				  mvinch(rp->r_gold.y,rp->r_gold.x) == GOLD)
					mvwaddch(hw,rp->r_gold.y,rp->r_gold.x,GOLD);
			}
			if (gtotal) {
				s_know[S_GFIND] = TRUE;
				msg("You begin to feel greedy and sense gold.");
				overlay(hw,cw);
			}
			else
				msg("You begin to feel a pull downward.");
		}
	when S_TELEP:
		if (!curse) {
			int rm;
			struct room *cur_room;

			cur_room = player.t_room;
			rm = teleport(rndspot, &player);
			if (cur_room != &rooms[rm])
				s_know[S_TELEP] = TRUE;
		}
	when S_ENCH:
		if (!curse) {
			if (cur_weapon == NULL || (cur_weapon != NULL &&
			  (o_on(cur_weapon,ISPROT) || cur_weapon->o_type != WEAPON)))
				msg("You feel a strange sense of loss.");
			else {
				s_know[S_ENCH] = TRUE;
				if (o_on(cur_weapon,ISCURSED)) {
					resoflg(cur_weapon,ISCURSED);
					cur_weapon->o_hplus = rnd(2);
					cur_weapon->o_dplus = rnd(2);
				}
				else {		/* weapon was not cursed here */
					if (rnd(100) < 50)
						cur_weapon->o_hplus += 1;
					else
						cur_weapon->o_dplus += 1;
				}
				setoflg(cur_weapon, ISKNOW);
				msg("Your %s glows blue for a moment.",
				  w_magic[cur_weapon->o_which].mi_name);
			}
		}
	when S_SCARE:
		/*
		 * A monster will refuse to step on a scare monster scroll
		 * if it is dropped.  Thus reading it is a mistake and produces
		 * laughter at the poor rogue's boo boo.
		 */
		msg("You hear maniacal laughter in the distance.");
	when S_REMOVE:
		if (!curse) {
			if (cur_armor != NULL && o_off(cur_armor,ISPROT))
				resoflg(cur_armor,ISCURSED);
			if (cur_weapon != NULL && o_off(cur_weapon,ISPROT))
				resoflg(cur_weapon,ISCURSED);
			if (cur_ring[LEFT]!=NULL && o_off(cur_ring[LEFT],ISPROT))
				resoflg(cur_ring[LEFT],ISCURSED);
			if (cur_ring[RIGHT]!=NULL && o_off(cur_ring[RIGHT],ISPROT))
				resoflg(cur_ring[RIGHT],ISCURSED);
			msg("You feel as if somebody is watching over you.");
			s_know[S_REMOVE] = TRUE;
		}
	when S_AGGR:
		if (!bless) {
			if (mlist != NULL) {
				aggravate();
				msg("You hear a high pitched humming noise.");
				s_know[S_AGGR] = TRUE;
			}
		}
	when S_NOP:
		msg("This scroll seems to be blank.");
	when S_GENOCIDE:
		if (!curse) {
			msg("You have been granted the boon of genocide.");
			genocide();
			s_know[S_GENOCIDE] = TRUE;
		}
	when S_DCURSE:
		if (!bless) {
			struct linked_list *ll;
			struct object *lb;

			msg("Your pack shudders.");
			for (ll = pack ; ll != NULL ; ll = next(ll)) {
				lb = OBJPTR(ll);
				if (o_off(lb,ISPROT)) {
					resoflg(lb, ISBLESS);
					setoflg(lb, ISCURSED);
				}
			}
		}
	when S_DLEVEL:
		if (!bless) {
			int much = rnd(9) - 4;

			if (much != 0) {
				level += much;
				if (level < 1)
					level = 1;
				mpos = 0;
				new_level(NORMLEV);		/* change levels */
				msg("You are whisked away to another region.");
				s_know[S_DLEVEL] = TRUE;
			}
		}
	when S_PROTECT:
		if (!curse) {
			struct linked_list *ll;
			struct object *lb;

			msg("You are granted the power of protection.");
			if ((ll = get_item("protect",0)) != NULL) {
				lb = OBJPTR(ll);
				setoflg(lb,ISPROT);
				mpos = 0;
				msg("Protected %s.",inv_name(lb,TRUE));
			}
			s_know[S_PROTECT] = TRUE;
		}
	when S_ALLENCH:
		if (!curse) {
			struct linked_list *ll;
			struct object *lb;
			int howmuch, ac, good;

			msg("You are granted the power of enchantment.");
			good = TRUE;
			if ((ll = get_item("enchant",0)) != NULL) {
				lb = OBJPTR(ll);
				resoflg(lb,ISCURSED);
				resoflg(lb,ISPROT);
				howmuch = rnd(3) + 1;
				switch(lb->o_type) {
					case RING:
						if (lb->o_ac < 0)
							lb->o_ac = 0;
						lb->o_ac += howmuch;
					when ARMOR:
						ac = armors[lb->o_which].a_class;
						if (lb->o_ac > ac)
							lb->o_ac = ac;
						lb->o_ac -= howmuch;
					when STICK:
						lb->o_charges += howmuch + 10;
					when WEAPON:
						if (lb->o_dplus < 0)
							lb->o_dplus = 0;
						if (lb->o_hplus < 0)
							lb->o_hplus = 0;
						lb->o_hplus += howmuch;
						lb->o_dplus += howmuch;
					otherwise:
						msg("You are injured as the scroll flashes & bursts into flames !!!");
						chg_hpt(-roll(6,6),FALSE,K_SCROLL);
						good = FALSE;
				}
				if (good) {
					mpos = 0;
					msg("Enchanted %s.",inv_name(lb,TRUE));
				}
			}
			s_know[S_ALLENCH] = TRUE;
		}
	when S_BLESS:
		if (!curse) {
			struct linked_list *ll;
			struct object *lb;

			msg("Your pack glistens brightly.");
			for (ll = pack ; ll != NULL ; ll = next(ll)) {
				whatis(ll);
				lb = OBJPTR(ll);
				resoflg(lb,ISCURSED);
				setoflg(lb,ISBLESS);
			}
		}
	when S_MAKEIT:
		if (!curse) {
			msg("You have been endowed with the power of creation.");
			s_know[S_MAKEIT] = TRUE;
			create_obj(TRUE);
		}
	when S_BAN: {
		int howdeep;
		char *ptr;

		if (bless) {
			if (level > 6) {
				howdeep = 1 + rnd(5);
				ptr = "elevated to the upper";
			}
			else {
				howdeep = -1;
				bless = FALSE;
			}
		}
		else {
			howdeep = level + 10 + rnd(20) + (curse * 20);
			ptr = "banished to the lower";
		}
		if ((!bless && level < howdeep) || bless) {
			level = howdeep;
			new_level(NORMLEV);
			mpos = 0;
			msg("You are %s regions.", ptr);
			s_know[S_BAN] = TRUE;
		}
	}
	when S_CWAND:
		if (!curse) {
			struct linked_list *ll;
			struct object *lb;
			bool wands = FALSE;

			for (ll = pack ; ll != NULL ; ll = next(ll)) {
				lb = OBJPTR(ll);
				if (lb->o_type == STICK) {
					whatis(ll);
					setoflg(lb, ISKNOW);
					resoflg(lb, ISCURSED);
					lb->o_charges += rnd(11) + 5;
					wands = TRUE;
				}
			}
			if (wands) {
				msg("Your sticks gleam.");
				s_know[wh] = TRUE;
			}
		}
	when S_LOCTRAP: {
		struct trap *trp;

		if (ntraps > 0) {
			for (trp = &traps[0]; trp < &traps[ntraps]; trp++)
				trp->tr_flags |= ISFOUND;
			look(FALSE);
			msg("You now recognize pitfalls.");
			s_know[S_LOCTRAP] = TRUE;
		}
	}
	otherwise:
		msg("What a puzzling scroll!");
		return 0;
	}
Пример #6
0
/*
 * add_pack:
 * Pick up an object and add it to the pack.  If the argument
 * is non-null use it as the linked_list pointer instead of
 * getting it off the ground.
 */
bool add_pack(struct linked_list *item,bool silent)
{
	struct linked_list *ip, *lp;
	struct object *obj, *op;
	bool from_floor;
	char delchar;

	if (player.t_room == NULL)
		delchar = PASSAGE;
	else
		delchar = FLOOR;
	if (item == NULL) {
		from_floor = TRUE;
		if ((item = find_obj(hero.y, hero.x)) == NULL) {
			mpos = 0;
			msg("That object must have been an illusion.");
			mvaddch(hero.y, hero.x, delchar);
			return FALSE;
		}
		/*
		 * Check for scare monster scrolls
		 */
		obj = OBJPTR(item);
		if (obj->o_type == SCROLL && obj->o_which == S_SCARE) {
			if (o_on(obj,ISFOUND)) {
				msg("The scroll turns to dust as you pick it up.");
				detach(lvl_obj, item);
				discard(item);
				mvaddch(hero.y, hero.x, delchar);	
				return FALSE;
			}
		}
	}
	else
		from_floor = FALSE;
	obj = OBJPTR(item);
	/*
	 * See if this guy can carry any more weight
	 */
	if (itemweight(obj) + him->s_pack > him->s_carry) {
		msg("You can't carry that %s.", obj->o_typname);
		return FALSE;
	}
	/*
	 * Check if there is room
	 */
	if (packvol + obj->o_vol > V_PACK) {
		msg("That %s won't fit in your pack.", obj->o_typname);
		return FALSE;
	}
	if (from_floor) {
		detach(lvl_obj, item);
		mvaddch(hero.y, hero.x, delchar);
	}
	item->l_prev = NULL;
	item->l_next = NULL;
	setoflg(obj, ISFOUND);
	/*
	 * start looking thru pack to find the start of items
	 * with the same type.
	 */
	lp = pack;
	for (ip = pack; ip != NULL; ip = next(ip)) {
		op = OBJPTR(ip);
		/*
		 * If we find a matching type then quit.
		 */
		if (op->o_type == obj->o_type)
			break;
		if (next(ip) != NULL)
			lp = next(lp);		/* update "previous" entry */
	}
	/*
	 * If the pack was empty, just stick the item in it.
	 */
	if (pack == NULL) {
		pack = item;
		item->l_prev = NULL;
	}
	/*
	 * If we looked thru the pack, but could not find an
	 * item of the same type, then stick it at the end,
	 * unless it was food, then put it in front.
	 */
	else if (ip == NULL) {
		if (obj->o_type == FOOD) {	/* insert food at front */
			item->l_next = pack;
			pack->l_prev = item;
			pack = item;
			item->l_prev = NULL;
		}
		else {						/* insert other stuff at back */
			lp->l_next = item;
			item->l_prev = lp;
		}
	}
	/*
	 * Here, we found at least one item of the same type.
	 * Look thru these items to see if there is one of the
	 * same group. If so, increment the count and throw the
	 * new item away. If not, stick it at the end of the
	 * items with the same type. Also keep all similar
	 * objects near each other, like all identify scrolls, etc.
	 */
	else {
		struct linked_list **save;

		while (ip != NULL && op->o_type == obj->o_type) {
			if (op->o_group == obj->o_group) {
				if (op->o_flags == obj->o_flags) {
					op->o_count++;
					discard(item);
					item = ip;
					goto picked_up;
				}
				else {
					goto around;
				}
			}
			if (op->o_which == obj->o_which) {
				if (obj->o_type == FOOD)
					ip = next(ip);
				break;
			}
around:
			ip = next(ip);
			if (ip != NULL) {
				op = OBJPTR(ip);
				lp = next(lp);
			}
		}
		/*
		 * If inserting into last of group at end of pack,
		 * just tack on the end.
		 */
		if (ip == NULL) {
			lp->l_next = item;
			item->l_prev = lp;
		}
		/*
		 * Insert into the last of a group of objects
		 * not at the end of the pack.
		 */
		else {
			save = &((ip->l_prev)->l_next);
			item->l_next = ip;
			item->l_prev = ip->l_prev;
			ip->l_prev = item;
			*save = item;
		}
	}
picked_up:
	obj = OBJPTR(item);
	if (!silent)
		msg("%s (%c)",inv_name(obj,FALSE),pack_char(obj));
	if (obj->o_type == AMULET)
		amulet = TRUE;
	updpack();				/* new pack weight & volume */
	return TRUE;
}