Example #1
0
tri_val_t finish_do_drink(obj_t *otmp, Boolean nothing, Boolean unkn)
{
  Boolean go_on = false;
  if (!otmp) return NO_OP; // bug if that happens
  if (nothing) {
    unkn = true;
    message("You have a peculiar feeling for a moment, then it passes.");
  }
  if ((otmp->bitflags & O_IS_DESCKNOWN) &&
      !BITTEST(oc_name_known, otmp->otype)) {
    if (!unkn) {
      BITSET(oc_name_known, otmp->otype);//objects[otmp->otyp].oc_name_known=1;
      more_experienced(0,10);
    } else if (!oc_has_uname(otmp->otype)) {
      // here's what I'll do instead of do_call/docall(otmp) :
      show_all_messages();
      clone_for_call(otmp); // so we don't have to worry about useup!
      FrmPopupForm(EngraveForm);
      go_on = true;
    }
  }
  useup(otmp);
  if (go_on) return GO_ON;
  else       return DONE;
}
Example #2
0
opentin(){
	register int r;

	if(!carried(tin.tin))		/* perhaps it was stolen? */
		return(0);		/* %% probably we should use tinoid */
	if(tin.usedtime++ >= 50) {
		pline("You give up your attempt to open the tin.");
		return(0);
	}
	if(tin.usedtime < tin.reqtime)
		return(1);		/* still busy */

	pline("You succeed in opening the tin.");
	useup(tin.tin);
	r = rn2(2*TTSZ);
	if(r < TTSZ){
	    pline(tintxts[r].txt);
	    lesshungry(tintxts[r].nut);
	    if(r == 1)	/* SALMON */ {
		Glib = rnd(15);
		pline("Eating salmon made your fingers very slippery.");
	    }
	} else {
	    pline("It contains spinach - this makes you feel like Popeye!");
	    lesshungry(600);
	    if(u.ustr < 118)
		u.ustr += rnd( ((u.ustr < 17) ? 19 : 118) - u.ustr);
	    if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
	    flags.botl = 1;
	}
	return(0);
}
Example #3
0
int opentin(void)
{
    if (!carried(tin.tin))     // perhaps it was stolen?
	return 0;	       // %% probably we should use tinoid
    if (tin.usedtime++ >= 50) {
	pline("You give up your attempt to open the tin.");
	return 0;
    }
    if (tin.usedtime < tin.reqtime)
	return 1;	       // still busy

    pline("You succeed in opening the tin.");
    useup(tin.tin);
    unsigned r = rn2(2 * ArraySize(c_tintxts));
    if (r < ArraySize(c_tintxts)) {
	pline(c_tintxts[r].txt);
	lesshungry(c_tintxts[r].nut);
	if (r == 1) {	       // SALMON
	    Glib = rnd(15);
	    pline("Eating salmon made your fingers very slippery.");
	}
    } else {
	pline("It contains spinach - this makes you feel like Popeye!");
	lesshungry(600);
	if (_u.ustr < 118)
	    _u.ustr += rnd(((_u.ustr < 17) ? 19 : 118) - _u.ustr);
	if (_u.ustr > _u.ustrmax)
	    _u.ustrmax = _u.ustr;
	_wflags.botl = 1;
    }
    return 0;
}
Example #4
0
int chwepon(struct obj *otmp, int amount)
{
    const char *color = (amount < 0) ? "black" : "green";
    const char *time;
    if (!uwep || uwep->olet != WEAPON_SYM) {
	strange_feeling(otmp, (amount > 0) ? "Your hands twitch." : "Your hands itch.");
	return 0;
    }
    // there is a (soft) upper limit to uwep->spe
    if (amount > 0 && uwep->spe > 5 && rn2(3)) {
	pline("Your %s violently green for a while and then evaporate%s.", aobjnam(uwep, "glow"), plur(uwep->quan));
	while (uwep)
	    // let all of them disappear
	    // note: uwep->quan = 1 is nogood if unpaid
	    useup(uwep);
	return 1;
    }
    if (!rn2(6))
	amount *= 2;
    time = (amount * amount == 1) ? "moment" : "while";
    pline("Your %s %s for a %s.", aobjnam(uwep, "glow"), color, time);
    uwep->spe += amount;
    if (amount > 0)
	uwep->cursed = 0;
    return 1;
}
Example #5
0
void
strange_feeling(struct obj *obj, char *txt)
{
	if(flags.beginner)
	    pline("You have a strange feeling for a moment, then it passes.");
	else
	    pline(txt);
	if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
		docall(obj);
	useup(obj);
}
Example #6
0
/* (Notes from the original hack)
 * -- rudimentary -- to do this correctly requires much more work
 * -- all sharp weapons get one or more qualities derived from the potions
 * -- texts on scrolls may be (partially) wiped out; do they become blank?
 * --   or does their effect change, like under Confusion?
 * -- all objects may be made invisible by POT_INVISIBILITY
 * -- If the flask is small, can one dip a large object? Does it magically
 * --   become a jug? Etc.
 */
Boolean do_dip(obj_t *potion, obj_t *obj)
{
  message("Interesting...");
  if (obj->otype == ARROW || 
      obj->otype == DART ||
      obj->otype == CROSSBOW_BOLT) {
    if (potion->otype == POT_SICKNESS) {
      useup(potion);
      if (obj->spe < 7) obj->spe++;	/* %% */
    }
  }
  return true;
}
Example #7
0
// also used for scrolls.
Boolean strange_feeling(obj_t *obj, Char *txt)
{
  Boolean engrave = false;
  if (flags.beginner)
    message("You have a strange feeling for a moment, then it passes.");
  else
    message(txt);
  if (!BITTEST(oc_name_known, obj->otype) &&
      !oc_has_uname(obj->otype)) {
    // here's what I'll do instead of do_call/docall(obj) :
    show_all_messages();
    clone_for_call(obj); // so we don't have to worry about useup!
    FrmPopupForm(EngraveForm);
    engrave = true;
  }
  useup(obj);
  return engrave;
}
Example #8
0
/*
 * -- rudimentary -- to do this correctly requires much more work
 * -- all sharp weapons get one or more qualities derived from the potions
 * -- texts on scrolls may be (partially) wiped out; do they become blank?
 * --   or does their effect change, like under Confusion?
 * -- all objects may be made invisible by POT_INVISIBILITY
 * -- If the flask is small, can one dip a large object? Does it magically
 * --   become a jug? Etc.
 */
int
dodip()
{
	struct obj *potion, *obj;

	if(!(obj = getobj("#", "dip")))
		return(0);
	if(!(potion = getobj("!", "dip into")))
		return(0);
	pline("Interesting...");
	if(obj->otyp == ARROW || obj->otyp == DART ||
	   obj->otyp == CROSSBOW_BOLT) {
		if(potion->otyp == POT_SICKNESS) {
			useup(potion);
			if(obj->spe < 7) obj->spe++;	/* %% */
		}
	}
	return(1);
}
Example #9
0
int
chwepon(struct obj *otmp, int amount)
{
	char *color = (amount < 0) ? "black" : "green";
	char *time;

	if(!uwep || uwep->olet != WEAPON_SYM) {
		strange_feeling(otmp,
			(amount > 0) ? "Your hands twitch."
				     : "Your hands itch.");
		return(0);
	}

	if(uwep->otyp == WORM_TOOTH && amount > 0) {
		uwep->otyp = CRYSKNIFE;
		pline("Your weapon seems sharper now.");
		uwep->cursed = 0;
		return(1);
	}

	if(uwep->otyp == CRYSKNIFE && amount < 0) {
		uwep->otyp = WORM_TOOTH;
		pline("Your weapon looks duller now.");
		return(1);
	}

	/* there is a (soft) upper limit to uwep->spe */
	if(amount > 0 && uwep->spe > 5 && rn2(3)) {
	    pline("Your %s violently green for a while and then evaporate%s.",
		aobjnam(uwep, "glow"), plur(uwep->quan));
	    while(uwep)		/* let all of them disappear */
				/* note: uwep->quan = 1 is nogood if unpaid */
		useup(uwep);
	    return(1);
	}
	if(!rn2(6)) amount *= 2;
	time = (amount*amount == 1) ? "moment" : "while";
	pline("Your %s %s for a %s.",
		aobjnam(uwep, "glow"), color, time);
	uwep->spe += amount;
	if(amount > 0) uwep->cursed = 0;
	return(1);
}
Example #10
0
static void
burn_scrolls(void)
{
	struct obj *obj, *obj2;
	int cnt = 0;

	for(obj = invent; obj; obj = obj2) {
		obj2 = obj->nobj;
		if(obj->olet == SCROLL_SYM) {
			cnt++;
			useup(obj);
		}
	}
	if(cnt > 1) {
		pline("Your scrolls catch fire!");
		losehp(cnt, "burning scrolls");
	} else if(cnt) {
		pline("Your scroll catches fire!");
		losehp(1, "burning scroll");
	}
}
Example #11
0
/* study while confused: returns TRUE if the book is destroyed */
static boolean
confused_book(struct obj *spellbook)
{
    boolean gone = FALSE;

    if (!rn2(3) && spellbook->otyp != SPE_BOOK_OF_THE_DEAD) {
        spellbook->in_use = TRUE;       /* in case called from learn */
        pline("Being confused you have difficulties in controlling your "
              "actions.");
        win_pause_output(P_MESSAGE);
        pline("You accidentally tear the spellbook to pieces.");
        if (!objects[spellbook->otyp].oc_name_known &&
            !objects[spellbook->otyp].oc_uname)
            docall(spellbook);
        useup(spellbook);
        gone = TRUE;
    } else {
        pline("You find yourself reading the %s line over and over again.",
              spellbook == u.utracked[tos_book] ? "next" : "first");
    }
    return gone;
}
Example #12
0
int
doread() {
	register struct obj *scroll;
	register boolean confused = (Confusion != 0);

	known = FALSE;
	scroll = getobj(readable, "read");	/* "#-" added by GAN 10/22/86 */
	if(!scroll) return(0);

	/* below added to allow reading of fortune cookies */
	if(scroll->otyp == FORTUNE_COOKIE) {
	    if(flags.verbose)
		You("break up the cookie and throw away the pieces.");
	    outrumor(bcsign(scroll), TRUE);
	    useup(scroll);
	    return(1);
	} else
		if(scroll->olet != SCROLL_SYM
#ifdef SPELLS
		   && scroll->olet != SPBOOK_SYM
#endif
		  ) {
			pline("That is a silly thing to read.");
			return(0);
		}

	if(Blind) {
#ifdef SPELLS
	    if (scroll->olet == SPBOOK_SYM) {
		pline("Being blind, you cannot read the mystic runes.");
		return(0);
	    } else
#endif
	    if (!scroll->dknown) {
		pline("Being blind, you cannot read the formula on the scroll.");
		return(0);
	    }
	}
#ifndef NO_SIGNAL
	scroll->in_use = TRUE;		/* now being read */
#endif
#ifdef SPELLS
	if(scroll->olet == SPBOOK_SYM) {
	    if(confused) {
		You("cannot grasp the meaning of this tome.");
		useup(scroll);
		return(0);
	    } else
		return(study_book(scroll));
	}
#endif
	if(scroll->otyp != SCR_BLANK_PAPER) {
	  if(Blind)
	    pline("As you pronounce the formula on it, the scroll disappears.");
	  else
	    pline("As you read the scroll, it disappears.");
	  if(confused) {
	    if (Hallucination)
		pline("Being so trippy, you screw up...");
	    else
		pline("Being confused, you mispronounce the magic words...");
	  }
	}
	if(!seffects(scroll))  {
		if(!objects[scroll->otyp].oc_name_known) {
		    if(known && !confused) {
			makeknown(scroll->otyp);
			more_experienced(0,10);
		    } else if(!objects[scroll->otyp].oc_uname)
			docall(scroll);
		}
		if(!(scroll->otyp == SCR_BLANK_PAPER) || confused)
			useup(scroll);
#ifndef NO_SIGNAL
		else scroll->in_use = FALSE;
#endif
	}
	return(1);
}
Example #13
0
int doeat(void)
{
    struct obj *otmp;
    int tmp;

    // Is there some food (probably a heavy corpse) here on the ground?
    if (!Levitation)
	for (otmp = _level->objects; otmp; otmp = otmp->nobj) {
	    if (otmp->ox == _u.ux && otmp->oy == _u.uy && otmp->olet == FOOD_SYM) {
		pline("There %s %s here; eat %s? [ny] ", (otmp->quan == 1) ? "is" : "are", doname(otmp), (otmp->quan == 1) ? "it" : "one");
		if (readchar() == 'y') {
		    if (otmp->quan != 1)
			(void) splitobj(otmp, 1);
		    freeobj(otmp);
		    otmp = addinv(otmp);
		    addtobill(otmp);
		    goto gotit;
		}
	    }
	}
    otmp = getobj("%", "eat");
    if (!otmp)
	return 0;
  gotit:
    if (otmp->otyp == TIN) {
	if (uwep) {
	    switch (uwep->otyp) {
		case CAN_OPENER:
		    tmp = 1;
		    break;
		case DAGGER:
		    tmp = 3;
		    break;
		case PICK_AXE:
		case AXE:
		    tmp = 6;
		    break;
		default:
		    goto no_opener;
	    }
	    pline("Using your %s you try to open the tin.", aobjnam(uwep, NULL));
	} else {
	  no_opener:
	    pline("It is not so easy to open this tin.");
	    if (Glib) {
		pline("The tin slips out of your hands.");
		if (otmp->quan > 1) {
		    struct obj *obj;

		    obj = splitobj(otmp, 1);
		    if (otmp == uwep)
			setuwep(obj);
		}
		dropx(otmp);
		return 1;
	    }
	    tmp = 10 + rn2(1 + 500 / ((int) (_u.ulevel + _u.ustr)));
	}
	tin.reqtime = tmp;
	tin.usedtime = 0;
	tin.tin = otmp;
	occupation = opentin;
	occtxt = "opening the tin";
	return 1;
    }
    const struct objclass* ftmp = &c_Objects[otmp->otyp];
    multi = -ftmp->oc_delay;
    if (otmp->otyp >= CORPSE && eatcorpse(otmp))
	goto eatx;
    if (!rn2(7) && otmp->otyp != FORTUNE_COOKIE) {
	pline("Blecch!  Rotten food!");
	if (!rn2(4)) {
	    pline("You feel rather light headed.");
	    Confusion += d(2, 4);
	} else if (!rn2(4) && !Blind) {
	    pline("Everything suddenly goes dark.");
	    Blind = d(2, 10);
	    seeoff(0);
	} else if (!rn2(3)) {
	    if (Blind)
		pline("The world spins and you slap against the floor.");
	    else
		pline("The world spins and goes dark.");
	    nomul(-rnd(10));
	    nomovemsg = "You are conscious again.";
	}
	lesshungry(ftmp->nutrition / 4);
    } else {
	if (_u.uhunger >= 1500) {
	    pline("You choke over your food.");
	    pline("You die...");
	    killer = ftmp->oc_name;
	    done("choked");
	}
	switch (otmp->otyp) {
	    case FOOD_RATION:
		if (_u.uhunger <= 200)
		    pline("That food really hit the spot!");
		else if (_u.uhunger <= 700)
		    pline("That satiated your stomach!");
		else {
		    pline("You're having a hard time getting all that food down.");
		    multi -= 2;
		}
		lesshungry(ftmp->nutrition);
		if (multi < 0)
		    nomovemsg = "You finished your meal.";
		break;
	    case TRIPE_RATION:
		pline("Yak - dog food!");
		more_experienced(1, 0);
		_wflags.botl = 1;
		if (rn2(2)) {
		    pline("You vomit.");
		    morehungry(20);
		    if (Sick) {
			Sick = 0;	// David Neves
			pline("What a relief!");
		    }
		} else
		    lesshungry(ftmp->nutrition);
		break;
	    default:
		if (otmp->otyp >= CORPSE)
		    pline("That %s tasted terrible!", ftmp->oc_name);
		else
		    pline("That %s was delicious!", ftmp->oc_name);
		lesshungry(ftmp->nutrition);
		if (otmp->otyp == DEAD_LIZARD && (Confusion > 2))
		    Confusion = 2;
		else if (otmp->otyp == FORTUNE_COOKIE) {
		    if (Blind) {
			pline("This cookie has a scrap of paper inside!");
			pline("What a pity, that you cannot read it!");
		    } else
			print_rumor();
		} else if (otmp->otyp == LUMP_OF_ROYAL_JELLY) {
		    // This stuff seems to be VERY healthy!
		    if (_u.ustrmax < 118)
			++_u.ustrmax;
		    if (_u.ustr < _u.ustrmax)
			++_u.ustr;
		    _u.uhp += rnd(20);
		    if (_u.uhp > _u.uhpmax) {
			if (!rn2(17))
			    ++_u.uhpmax;
			_u.uhp = _u.uhpmax;
		    }
		    heal_legs();
		}
		break;
	}
    }
  eatx:
    if (multi < 0 && !nomovemsg) {
	static char msgbuf[BUFSZ];
	sprintf(msgbuf, "You finished eating the %s.", ftmp->oc_name);
	nomovemsg = msgbuf;
    }
    useup(otmp);
    return 1;
}
Example #14
0
/* return 1 if action took 1 (or more) moves, 0 if error or aborted */
int doengrave(struct obj *otmp)
{
	boolean dengr = FALSE;	/* TRUE if we wipe out the current engraving */
	boolean doblind = FALSE;/* TRUE if engraving blinds the player */
	boolean doknown = FALSE;/* TRUE if we identify the stylus */
	boolean eow = FALSE;	/* TRUE if we are overwriting oep */
	boolean jello = FALSE;	/* TRUE if we are engraving in slime */
	boolean ptext = TRUE;	/* TRUE if we must prompt for engrave text */
	boolean teleengr =FALSE;/* TRUE if we move the old engraving */
	boolean zapwand = FALSE;/* TRUE if we remove a wand charge */
	xchar type = DUST;	/* Type of engraving made */
	char buf[BUFSZ];	/* Buffer for final/poly engraving text */
	char ebuf[BUFSZ];	/* Buffer for initial engraving text */
	char qbuf[QBUFSZ];	/* Buffer for query text */
	char post_engr_text[BUFSZ]; /* Text displayed after engraving prompt */
	const char *everb;	/* Present tense of engraving type */
	const char *eloc;	/* Where the engraving is (ie dust/floor/...) */
	char *sp;		/* Place holder for space count of engr text */
	int len;		/* # of nonspace chars of new engraving text */
	int maxelen;		/* Max allowable length of engraving text */
	struct engr *oep = engr_at(level, u.ux,u.uy);
				/* The current engraving */
	char *writer;

	multi = 0;		/* moves consumed */
	nomovemsg = NULL;	/* occupation end message */

	buf[0] = (char)0;
	ebuf[0] = (char)0;
	post_engr_text[0] = (char)0;
	maxelen = BUFSZ - 1;
	if (is_demon(youmonst.data) || youmonst.data->mlet == S_VAMPIRE)
	    type = ENGR_BLOOD;

	/* Can the adventurer engrave at all? */

	if (u.uswallow) {
		if (is_animal(u.ustuck->data)) {
			pline("What would you write?  \"Jonah was here\"?");
			return 0;
		} else if (is_whirly(u.ustuck->data)) {
			pline("You can't reach the %s.", surface(u.ux,u.uy));
                        return 0;
		} else
			jello = TRUE;
	} else if (is_lava(level, u.ux, u.uy)) {
		pline("You can't write on the lava!");
		return 0;
	} else if (Underwater) {
		pline("You can't write underwater!");
		return 0;
	} else if (is_pool(level, u.ux,u.uy) || IS_FOUNTAIN(level->locations[u.ux][u.uy].typ)) {
		pline("You can't write on the water!");
		return 0;
	}
	if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)/* in bubble */) {
		pline("You can't write in thin air!");
		return 0;
	}
	if (cantwield(youmonst.data)) {
		pline("You can't even hold anything!");
		return 0;
	}
	if (check_capacity(NULL)) return 0;

	/* One may write with finger, or weapon, or wand, or..., or...
	 * Edited by GAN 10/20/86 so as not to change weapon wielded.
	 */

	if (otmp && !validate_object(otmp, styluses, "write with"))
		return 0;
	else if (!otmp)
		otmp = getobj(styluses, "write with");
	if (!otmp) return 0;		/* otmp == zeroobj if fingers */

	if (otmp == &zeroobj) writer = makeplural(body_part(FINGER));
	else writer = xname(otmp);

	/* There's no reason you should be able to write with a wand
	 * while both your hands are tied up.
	 */
	if (!freehand() && otmp != uwep && !otmp->owornmask) {
		pline("You have no free %s to write with!", body_part(HAND));
		return 0;
	}

	if (jello) {
		pline("You tickle %s with your %s.", mon_nam(u.ustuck), writer);
		pline("Your message dissolves...");
		return 0;
	}
	if (otmp->oclass != WAND_CLASS && !can_reach_floor()) {
		pline("You can't reach the %s!", surface(u.ux,u.uy));
                return 0;
	}
	if (IS_ALTAR(level->locations[u.ux][u.uy].typ)) {
		pline("You make a motion towards the altar with your %s.", writer);
		altar_wrath(u.ux, u.uy);
		return 0;
	}
	if (IS_GRAVE(level->locations[u.ux][u.uy].typ)) {
	    if (otmp == &zeroobj) { /* using only finger */
		pline("You would only make a small smudge on the %s.",
			surface(u.ux, u.uy));
		return 0;
	    } else if (!level->locations[u.ux][u.uy].disturbed) {
		pline("You disturb the undead!");
		level->locations[u.ux][u.uy].disturbed = 1;
		makemon(&mons[PM_GHOUL], level, u.ux, u.uy, NO_MM_FLAGS);
		exercise(A_WIS, FALSE);
		return 1;
	    }
	}

	/* SPFX for items */

	switch (otmp->oclass) {
	    default:
	    case AMULET_CLASS:
	    case CHAIN_CLASS:
	    case POTION_CLASS:
	    case COIN_CLASS:
		break;

	    case RING_CLASS:
		/* "diamond" rings and others should work */
	    case GEM_CLASS:
		/* diamonds & other hard gems should work */
		if (objects[otmp->otyp].oc_tough) {
			type = ENGRAVE;
			break;
		}
		break;

	    case ARMOR_CLASS:
		if (is_boots(otmp)) {
			type = DUST;
			break;
		}
		/* fall through */
	    /* Objects too large to engrave with */
	    case BALL_CLASS:
	    case ROCK_CLASS:
		pline("You can't engrave with such a large object!");
		ptext = FALSE;
		break;

	    /* Objects too silly to engrave with */
	    case FOOD_CLASS:
	    case SCROLL_CLASS:
	    case SPBOOK_CLASS:
		pline("Your %s would get %s.", xname(otmp),
			is_ice(level, u.ux, u.uy) ? "all frosty" : "too dirty");
		ptext = FALSE;
		break;

	    case RANDOM_CLASS:	/* This should mean fingers */
		break;

	    /* The charge is removed from the wand before prompting for
	     * the engraving text, because all kinds of setup decisions
	     * and pre-engraving messages are based upon knowing what type
	     * of engraving the wand is going to do.  Also, the player
	     * will have potentially seen "You wrest .." message, and
	     * therefore will know they are using a charge.
	     */
	    case WAND_CLASS:
		if (zappable(otmp)) {
		    check_unpaid(otmp);
		    zapwand = TRUE;
		    if (Levitation) ptext = FALSE;

		    switch (otmp->otyp) {
		    /* DUST wands */
		    default:
			break;

			/* NODIR wands */
		    case WAN_LIGHT:
		    case WAN_SECRET_DOOR_DETECTION:
		    case WAN_CREATE_MONSTER:
		    case WAN_WISHING:
		    case WAN_ENLIGHTENMENT:
			zapnodir(otmp);
			break;

			/* IMMEDIATE wands */
			/* If wand is "IMMEDIATE", remember to affect the
			 * previous engraving even if turning to dust.
			 */
		    case WAN_STRIKING:
			strcpy(post_engr_text,
			"The wand unsuccessfully fights your attempt to write!"
			);
			break;
		    case WAN_SLOW_MONSTER:
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The bugs on the %s slow down!",
				   surface(u.ux, u.uy));
			}
			break;
		    case WAN_SPEED_MONSTER:
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The bugs on the %s speed up!",
				   surface(u.ux, u.uy));
			}
			break;
		    case WAN_POLYMORPH:
			if (oep)  {
			    if (!Blind) {
				type = (xchar)0;	/* random */
				random_engraving(buf);
			    }
			    dengr = TRUE;
			}
			break;
		    case WAN_NOTHING:
		    case WAN_UNDEAD_TURNING:
		    case WAN_OPENING:
		    case WAN_LOCKING:
		    case WAN_PROBING:
			break;

			/* RAY wands */
		    case WAN_MAGIC_MISSILE:
			ptext = TRUE;
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The %s is riddled by bullet holes!",
				   surface(u.ux, u.uy));
			}
			break;

		    /* can't tell sleep from death - Eric Backus */
		    case WAN_SLEEP:
		    case WAN_DEATH:
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The bugs on the %s stop moving!",
				   surface(u.ux, u.uy));
			}
			break;

		    case WAN_COLD:
			if (!Blind)
			    strcpy(post_engr_text,
				"A few ice cubes drop from the wand.");
			if (!oep || (oep->engr_type != BURN))
			    break;
		    case WAN_CANCELLATION:
		    case WAN_MAKE_INVISIBLE:
			if (oep && oep->engr_type != HEADSTONE) {
			    if (!Blind)
				pline("The engraving on the %s vanishes!",
					surface(u.ux,u.uy));
			    dengr = TRUE;
			}
			break;
		    case WAN_TELEPORTATION:
			if (oep && oep->engr_type != HEADSTONE) {
			    if (!Blind)
				pline("The engraving on the %s vanishes!",
					surface(u.ux,u.uy));
			    teleengr = TRUE;
			}
			break;

		    /* type = ENGRAVE wands */
		    case WAN_DIGGING:
			ptext = TRUE;
			type  = ENGRAVE;
			if (!objects[otmp->otyp].oc_name_known) {
			    if (flags.verbose)
				pline("This %s is a wand of digging!",
				xname(otmp));
			    doknown = TRUE;
			}
			if (!Blind)
			    strcpy(post_engr_text,
				IS_GRAVE(level->locations[u.ux][u.uy].typ) ?
				"Chips fly out from the headstone." :
				is_ice(level, u.ux, u.uy) ?
				"Ice chips fly up from the ice surface!" :
				"Gravel flies up from the floor.");
			else
			    strcpy(post_engr_text, "You hear drilling!");
			break;

		    /* type = BURN wands */
		    case WAN_FIRE:
			ptext = TRUE;
			type  = BURN;
			if (!objects[otmp->otyp].oc_name_known) {
			if (flags.verbose)
			    pline("This %s is a wand of fire!", xname(otmp));
			    doknown = TRUE;
			}
			strcpy(post_engr_text,
				Blind ? "You feel the wand heat up." :
					"Flames fly from the wand.");
			break;
		    case WAN_LIGHTNING:
			ptext = TRUE;
			type  = BURN;
			if (!objects[otmp->otyp].oc_name_known) {
			    if (flags.verbose)
				pline("This %s is a wand of lightning!",
					xname(otmp));
			    doknown = TRUE;
			}
			if (!Blind) {
			    strcpy(post_engr_text,
				    "Lightning arcs from the wand.");
			    doblind = TRUE;
			} else
			    strcpy(post_engr_text, "You hear crackling!");
			break;

		    /* type = MARK wands */
		    /* type = ENGR_BLOOD wands */
		    }
		} else /* end if zappable */
		    if (!can_reach_floor()) {
			pline("You can't reach the %s!", surface(u.ux,u.uy));
			/* If it's a wrestable wand, the player wasted a
			   turn trying. */
			if (wrestable(otmp))
			    return 1;
			else
			    return 0;
		    }
		break;

	    case WEAPON_CLASS:
		if (is_blade(otmp)) {
		    if ((int)otmp->spe > -3)
			type = ENGRAVE;
		    else
			pline("Your %s too dull for engraving.", aobjnam(otmp,"are"));
		}
		break;

	    case TOOL_CLASS:
		if (otmp == ublindf) {
		    pline(
		"That is a bit difficult to engrave with, don't you think?");
		    return 0;
		}
		switch (otmp->otyp)  {
		    case MAGIC_MARKER:
			if (otmp->spe <= 0)
			    pline("Your marker has dried out.");
			else
			    type = MARK;
			break;
		    case TOWEL:
			/* Can't really engrave with a towel */
			ptext = FALSE;
			if (oep)
			    if ((oep->engr_type == DUST ) ||
				(oep->engr_type == ENGR_BLOOD) ||
				(oep->engr_type == MARK )) {
				if (!Blind)
				    pline("You wipe out the message here.");
				else
				    pline("Your %s %s %s.", xname(otmp),
					 otense(otmp, "get"),
					 is_ice(level, u.ux, u.uy) ?
					 "frosty" : "dusty");
				dengr = TRUE;
			    } else
				pline("Your %s can't wipe out this engraving.",
				     xname(otmp));
			else
			    pline("Your %s %s %s.", xname(otmp), otense(otmp, "get"),
				  is_ice(level, u.ux, u.uy) ? "frosty" : "dusty");
			break;
		    default:
			break;
		}
		break;

	    case VENOM_CLASS:
		if (wizard) {
		    pline("Writing a poison pen letter??");
		    break;
		}
	    case ILLOBJ_CLASS:
		impossible("You're engraving with an illegal object!");
		break;
	}

	if (IS_GRAVE(level->locations[u.ux][u.uy].typ)) {
	    if (type == ENGRAVE || type == 0)
		type = HEADSTONE;
	    else {
		/* ensures the "cannot wipe out" case */
		type = DUST;
		dengr = FALSE;
		teleengr = FALSE;
		buf[0] = (char)0;
	    }
	}

	/* End of implement setup */

	/* Identify stylus */
	if (doknown) {
	    makeknown(otmp->otyp);
	    more_experienced(0,10);
	}

	if (teleengr) {
	    rloc_engr(oep);
	    oep = NULL;
	}

	if (dengr) {
	    del_engr(oep, level);
	    oep = NULL;
	}

	/* Something has changed the engraving here */
	if (*buf) {
	    make_engr_at(level, u.ux, u.uy, buf, moves, type);
	    pline("The engraving now reads: \"%s\".", buf);
	    ptext = FALSE;
	}

	if (zapwand && (otmp->spe < 0)) {
	    pline("%s %sturns to dust.",
		  The(xname(otmp)), Blind ? "" : "glows violently, then ");
	    if (!IS_GRAVE(level->locations[u.ux][u.uy].typ))
		pline("You are not going to get anywhere trying to write in the %s with your dust.",
		    is_ice(level, u.ux, u.uy) ? "frost" : "dust");
	    useup(otmp);
	    ptext = FALSE;
	}

	if (!ptext) {		/* Early exit for some implements. */
	    if (otmp->oclass == WAND_CLASS && !can_reach_floor())
		pline("You can't reach the %s!", surface(u.ux,u.uy));
	    return 1;
	}

	/* Special effects should have deleted the current engraving (if
	 * possible) by now.
	 */

	if (oep) {
	    char c = 'n';

	    /* Give player the choice to add to engraving. */

	    if (type == HEADSTONE) {
		/* no choice, only append */
		c = 'y';
	    } else if ( (type == oep->engr_type) && (!Blind ||
		 (oep->engr_type == BURN) || (oep->engr_type == ENGRAVE)) ) {
		c = yn_function("Do you want to add to the current engraving?",
				ynqchars, 'y');
		if (c == 'q') {
		    pline("Never mind.");
		    return 0;
		}
	    }

	    if (c == 'n' || Blind) {

		if ( (oep->engr_type == DUST) || (oep->engr_type == ENGR_BLOOD) ||
		    (oep->engr_type == MARK) ) {
		    if (!Blind) {
			pline("You wipe out the message that was %s here.",
			    ((oep->engr_type == DUST)  ? "written in the dust" :
			    ((oep->engr_type == ENGR_BLOOD) ? "scrawled in blood"   :
							 "written")));
			del_engr(oep, level);
			oep = NULL;
		    } else
		   /* Don't delete engr until after we *know* we're engraving */
			eow = TRUE;
		} else
		    if ( (type == DUST) || (type == MARK) || (type == ENGR_BLOOD) ) {
			pline(
			 "You cannot wipe out the message that is %s the %s here.",
			 oep->engr_type == BURN ?
			   (is_ice(level, u.ux, u.uy) ? "melted into" : "burned into") :
			   "engraved in", surface(u.ux,u.uy));
			return 1;
		    } else
			if ( (type != oep->engr_type) || (c == 'n') ) {
			    if (!Blind || can_reach_floor())
				pline("You will overwrite the current message.");
			    eow = TRUE;
			}
	    }
	}

	eloc = surface(u.ux,u.uy);
	switch(type){
	    default:
		everb = (oep && !eow ? "add to the weird writing on" :
				       "write strangely on");
		break;
	    case DUST:
		everb = (oep && !eow ? "add to the writing in" :
				       "write in");
		eloc = is_ice(level, u.ux, u.uy) ? "frost" : "dust";
		break;
	    case HEADSTONE:
		everb = (oep && !eow ? "add to the epitaph on" :
				       "engrave on");
		break;
	    case ENGRAVE:
		everb = (oep && !eow ? "add to the engraving in" :
				       "engrave in");
		break;
	    case BURN:
		everb = (oep && !eow ?
			( is_ice(level, u.ux,u.uy) ? "add to the text melted into" :
					      "add to the text burned into") :
			( is_ice(level, u.ux,u.uy) ? "melt into" : "burn into"));
		break;
	    case MARK:
		everb = (oep && !eow ? "add to the graffiti on" :
				       "scribble on");
		break;
	    case ENGR_BLOOD:
		everb = (oep && !eow ? "add to the scrawl on" :
				       "scrawl on");
		break;
	}

	/* Tell adventurer what is going on */
	if (otmp != &zeroobj)
	    pline("You %s the %s with %s.", everb, eloc, doname(otmp));
	else
	    pline("You %s the %s with your %s.", everb, eloc,
		makeplural(body_part(FINGER)));

	/* Prompt for engraving! */
	sprintf(qbuf,"What do you want to %s the %s here?", everb, eloc);
	getlin(qbuf, ebuf);

	/* Count the actual # of chars engraved not including spaces */
	len = strlen(ebuf);
	for (sp = ebuf; *sp; sp++) if (isspace(*sp)) len -= 1;

	if (len == 0 || strchr(ebuf, '\033')) {
	    if (zapwand) {
		if (!Blind)
		    pline("%s, then %s.",
			  Tobjnam(otmp, "glow"), otense(otmp, "fade"));
		return 1;
	    } else {
		pline("Never mind.");
                if (otmp && otmp->oclass == WAND_CLASS && wrestable(otmp))
                    return 1; /* disallow zero turn wrest */
                else
                    return 0;
	    }
	}

	/* A single `x' is the traditional signature of an illiterate person */
	if (len != 1 || (!strchr(ebuf, 'x') && !strchr(ebuf, 'X')))
	    u.uconduct.literate++;

	/* Mix up engraving if surface or state of mind is unsound.
	   Note: this won't add or remove any spaces. */
	for (sp = ebuf; *sp; sp++) {
	    if (isspace(*sp)) continue;
	    if (((type == DUST || type == ENGR_BLOOD) && !rn2(25)) ||
		    (Blind && !rn2(11)) || (Confusion && !rn2(7)) ||
		    (Stunned && !rn2(4)) || (Hallucination && !rn2(2)))
		*sp = ' ' + rnd(96 - 2);	/* ASCII '!' thru '~'
						   (excludes ' ' and DEL) */
	}

	/* Previous engraving is overwritten */
	if (eow) {
	    del_engr(oep, level);
	    oep = NULL;
	}

	/* Figure out how long it took to engrave, and if player has
	 * engraved too much.
	 */
	switch(type){
	    default:
		multi = -(len/10);
		if (multi) nomovemsg = "You finish your weird engraving.";
		break;
	    case DUST:
		multi = -(len/10);
		if (multi) nomovemsg = "You finish writing in the dust.";
		break;
	    case HEADSTONE:
	    case ENGRAVE:
		multi = -(len/10);
		if ((otmp->oclass == WEAPON_CLASS) &&
		    ((otmp->otyp != ATHAME) || otmp->cursed)) {
		    multi = -len;
		    maxelen = ((otmp->spe + 3) * 2) + 1;
			/* -2 = 3, -1 = 5, 0 = 7, +1 = 9, +2 = 11
			 * Note: this does not allow a +0 anything (except
			 *	 an athame) to engrave "Elbereth" all at once.
			 *	 However, you could now engrave "Elb", then
			 *	 "ere", then "th".
			 */
		    pline("Your %s dull.", aobjnam(otmp, "get"));
		    if (otmp->unpaid) {
			struct monst *shkp = shop_keeper(level, *u.ushops);
			if (shkp) {
			    pline("You damage it, you pay for it!");
			    bill_dummy_object(otmp);
			}
		    }
		    if (len > maxelen) {
			multi = -maxelen;
			otmp->spe = -3;
		    } else if (len > 1)
			otmp->spe -= len >> 1;
		    else otmp->spe -= 1; /* Prevent infinite engraving */
		} else
Example #15
0
/* Called every turn during chest-forcing. The caller must set
   u.utracked[tos_lock] to the chest in question. */
static int
forcelock(void)
{
    struct monst *shkp;
    boolean costly;

    struct obj *otmp;
    struct obj *box = u.utracked[tos_lock];

    if (!obj_with_u(box))
        return reset_pick();

    if (!uwep_can_force()) /* prints the messages; ensures uwep != NULL */
        return reset_pick();

    if (u.uoccupation_progress[tos_lock]++ >= 50 ||
         nohands(youmonst.data)) {
        pline(msgc_failrandom, "You give up your attempt to force the lock.");
        if (!nohands(youmonst.data))
            exercise(is_blade(uwep) ? A_DEX : A_STR, TRUE);
        return reset_pick();
    }

    if (is_blade(uwep)) {
        if (rn2(1000 - (int)uwep->spe) > (992 - greatest_erosion(uwep) * 10) &&
            !uwep->cursed && !obj_resists(uwep, 0, 99)) {
            /* for a +0 weapon, probability that it survives an unsuccessful
               attempt to force the lock is (.992)^50 = .67 */
            pline(msgc_substitute, "%sour %s broke!",
                  (uwep->quan > 1L) ? "One of y" : "Y", xname(uwep));
            useup(uwep);
            pline_implied(msgc_failcurse,
                          "You can't exactly force that lock now.");
            exercise(A_DEX, TRUE);
            return reset_pick();
        }
    } else      /* blunt */
        wake_nearby(FALSE);  /* due to hammering on the container */

    if (rn2(100) >= objects[uwep->otyp].oc_wldam * 2)
        return 1;       /* still busy */

    pline(msgc_actionok, "You succeed in forcing the lock.");
    box->olocked = 0;
    box->obroken = 1;
    costly = (*u.ushops && costly_spot(youmonst.mx, youmonst.my));
    shkp = costly ? shop_keeper(level, *u.ushops) : 0;
    if (!is_blade(uwep) && !rn2(3)) {
        long loss = 0L;

        pline(msgc_substitute, "In fact, you've totally destroyed %s.",
              the(xname(box)));

        /* Put the contents on ground at the hero's feet. */
        while ((otmp = box->cobj) != 0) {
            obj_extract_self(otmp);
            if (!rn2(3) || otmp->oclass == POTION_CLASS) {
                chest_shatter_msg(otmp);
                if (costly)
                    loss +=
                        stolen_value(otmp, youmonst.mx, youmonst.my,
                                     (boolean) shkp->mpeaceful, TRUE);
                if (otmp->quan == 1L) {
                    obfree(otmp, NULL);
                    continue;
                }
                useup(otmp);
            }
            if (box->otyp == ICE_BOX && otmp->otyp == CORPSE) {
                otmp->age = moves - otmp->age;  /* actual age */
                start_corpse_timeout(otmp);
            }
            place_object(otmp, level, youmonst.mx, youmonst.my);
            stackobj(otmp);
        }

        if (costly)
            loss +=
                stolen_value(box, youmonst.mx, youmonst.my, (boolean) shkp->mpeaceful,
                             TRUE);
        if (loss)
            pline(msgc_unpaid, "You owe %ld %s for objects destroyed.",
                  loss, currency(loss));
        delobj(box);
    } else {
        if (costly) {
            struct obj *cobjbak = box->cobj;

            box->cobj = (struct obj *)0;
            verbalize(msgc_unpaid, "You damage it, you bought it!");
            bill_dummy_object(box);
            box->cobj = cobjbak;
        }
    }
    exercise(is_blade(uwep) ? A_DEX : A_STR, TRUE);

    return reset_pick();
}
Example #16
0
int
dodrink()
{
	struct obj *otmp,*objs;
	struct monst *mtmp;
	int unkn = 0, nothing = 0;

	otmp = getobj("!", "drink");
	if(!otmp) return(0);
	if(!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) {
		ghost_from_bottle();
		goto use_it;
	}
	switch(otmp->otyp){
	case POT_RESTORE_STRENGTH:
		unkn++;
		pline("Wow!  This makes you feel great!");
		if(u.ustr < u.ustrmax) {
			u.ustr = u.ustrmax;
			flags.botl = 1;
		}
		break;
	case POT_BOOZE:
		unkn++;
		pline("Ooph!  This tastes like liquid fire!");
		Confusion += d(3,8);
		/* the whiskey makes us feel better */
		if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
		if(!rn2(4)) {
			pline("You pass out.");
			multi = -rnd(15);
			nomovemsg = "You awake with a headache.";
		}
		break;
	case POT_INVISIBILITY:
		if(Invis || See_invisible)
		  nothing++;
		else {
		  if(!Blind)
		    pline("Gee!  All of a sudden, you can't see yourself.");
		  else
		    pline("You feel rather airy."), unkn++;
		  newsym(u.ux,u.uy);
		}
		Invis += rn1(15,31);
		break;
	case POT_FRUIT_JUICE:
		pline("This tastes like fruit juice.");
		lesshungry(20);
		break;
	case POT_HEALING:
		pline("You begin to feel better.");
		flags.botl = 1;
		u.uhp += rnd(10);
		if(u.uhp > u.uhpmax)
			u.uhp = ++u.uhpmax;
		if(Blind) Blind = 1;	/* see on next move */
		if(Sick) Sick = 0;
		break;
	case POT_PARALYSIS:
		if(Levitation)
			pline("You are motionlessly suspended.");
		else
			pline("Your feet are frozen to the floor!");
		nomul(-(rn1(10,25)));
		break;
	case POT_MONSTER_DETECTION:
		if(!fmon) {
			strange_feeling(otmp, "You feel threatened.");
			return(1);
		} else {
			cls();
			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
				if(mtmp->mx > 0)
				at(mtmp->mx,mtmp->my,mtmp->data->mlet);
			prme();
			pline("You sense the presence of monsters.");
			more();
			docrt();
		}
		break;
	case POT_OBJECT_DETECTION:
		if(!fobj) {
			strange_feeling(otmp, "You feel a pull downward.");
			return(1);
		} else {
		    for(objs = fobj; objs; objs = objs->nobj)
			if(objs->ox != u.ux || objs->oy != u.uy)
				goto outobjmap;
		    pline("You sense the presence of objects close nearby.");
		    break;
		outobjmap:
			cls();
			for(objs = fobj; objs; objs = objs->nobj)
				at(objs->ox,objs->oy,objs->olet);
			prme();
			pline("You sense the presence of objects.");
			more();
			docrt();
		}
		break;
	case POT_SICKNESS:
		pline("Yech! This stuff tastes like poison.");
		if(Poison_resistance)
    pline("(But in fact it was biologically contaminated orange juice.)");
		losestr(rn1(4,3));
		losehp(rnd(10), "contaminated potion");
		break;
	case POT_CONFUSION:
		if(!Confusion)
			pline("Huh, What?  Where am I?");
		else
			nothing++;
		Confusion += rn1(7,16);
		break;
	case POT_GAIN_STRENGTH:
		pline("Wow do you feel strong!");
		if(u.ustr >= 118) break;	/* > 118 is impossible */
		if(u.ustr > 17) u.ustr += rnd(118-u.ustr);
		else u.ustr++;
		if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
		flags.botl = 1;
		break;
	case POT_SPEED:
		if(Wounded_legs) {
			heal_legs();
			unkn++;
			break;
		}
		if(!(Fast & ~INTRINSIC))
			pline("You are suddenly moving much faster.");
		else
			pline("Your legs get new energy."), unkn++;
		Fast += rn1(10,100);
		break;
	case POT_BLINDNESS:
		if(!Blind)
			pline("A cloud of darkness falls upon you.");
		else
			nothing++;
		Blind += rn1(100,250);
		seeoff(0);
		break;
	case POT_GAIN_LEVEL: 
		pluslvl();
		break;
	case POT_EXTRA_HEALING:
		pline("You feel much better.");
		flags.botl = 1;
		u.uhp += d(2,20)+1;
		if(u.uhp > u.uhpmax)
			u.uhp = (u.uhpmax += 2);
		if(Blind) Blind = 1;
		if(Sick) Sick = 0;
		break;
	case POT_LEVITATION:
		if(!Levitation)
			float_up();
		else
			nothing++;
		Levitation += rnd(100);
		u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
		break;
	default:
		impossible("What a funny potion! (%u)", otmp->otyp);
		return(0);
	}
	if(nothing) {
	    unkn++;
	    pline("You have a peculiar feeling for a moment, then it passes.");
	}
	if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
		if(!unkn) {
			objects[otmp->otyp].oc_name_known = 1;
			more_experienced(0,10);
		} else if(!objects[otmp->otyp].oc_uname)
			docall(otmp);
	}
use_it:
	useup(otmp);
	return(1);
}
Example #17
0
// Note: this is a litte different, it will return true
// iff the action is COMPLETE, and false if there was no action OR
// the action is needing to finish up (after leaving SenseForm).
// So if (do_drink) the caller should exit invform _and_ tick,
// otherwise the caller should just exit invform.
// (exiting the invform occurs _before_ calling do_drink..)
// .. Ok, I've modified this again so that it lets the caller distinguish
// between "it worked" and "it worked and I popped up EngraveForm".
tri_val_t do_drink(obj_t *otmp)
{
  obj_t *objs;
  //  monst_t *mtmp;
  Boolean unkn = false, nothing = false, b;
  Short tmp;

  if (!otmp) return NO_OP;
  tmp = oc_descr_offset[otmp->otype];
  if (tmp >= 0 && (0 == StrNCompare("smoky", oc_descrs+tmp, 5)) && !rund(13)) {
    ghost_from_bottle();
    useup(otmp);
    return DONE;
  }
  switch(otmp->otype) {
  case POT_RESTORE_STRENGTH:
    unkn = true;
    message("Wow!  This makes you feel great!");
    if (you.ustr < you.ustrmax) {
      you.ustr = you.ustrmax;
      flags.botl |= BOTL_STR;
    }
    break;
  case POT_BOOZE:
    unkn = true;
    message("Ooph!  This tastes like liquid fire!");
    Confusion += dice(3,8);
    /* the whiskey makes us feel better */
    if (you.uhp < you.uhpmax) losehp(-1, "bottle of whiskey");
    if (!rund(4)) {
      tri_val_t t;
      //      Short coma;
      message("You pass out.");
      multi = -rnd(15);
      spin_multi("You awake with a headache.");
      //      coma = rnd(15); //
      //      do { tick(); } while (--coma > 0);
      //      message("You awake with a headache.");
      // // nomovemsg = "You awake with a headache.";
      t = finish_do_drink(otmp, nothing, unkn); //.... I guess....
      return (t==DONE ? NO_OP : t); // so that we don't take any _more_ turns
    }
    break;
  case POT_INVISIBILITY:
    if (Invis || See_invisible)
      nothing = true;
    else {
      if (!Blind)
	message("Gee!  All of a sudden, you can't see yourself.");
      else {
	message("You feel rather airy.");
	unkn = true;
      }
      newsym(you.ux,you.uy);
    }
    Invis += rund(15)+31;
    break;
  case POT_FRUIT_JUICE:
    message("This tastes like fruit juice.");
    lesshungry(20);
    break;
  case POT_HEALING:
    message("You begin to feel better.");
    you.uhp += rnd(10);
    if (you.uhp > you.uhpmax)
      you.uhp = ++you.uhpmax;
    if (Blind) Blind = 1;	/* you'll see again on the next move */
    if (Sick) Sick = 0;
    flags.botl |= BOTL_HP;
    break;
  case POT_PARALYSIS:
    if (Levitation)
      message("You are motionlessly suspended.");
    else
      message("Your feet are frozen to the floor!");
    nomul(-(rund(10)+25));
    break;
  case POT_MONSTER_DETECTION:
    if (!fmon) {
      b = strange_feeling(otmp, "You feel threatened.");
      return ((b) ? GO_ON : DONE);
    } else {
      sense_what = SENSE_MONSTERS;
      sense_by_what = otmp;
      sense_init_screen();
      FrmPopupForm(SenseForm);
      return GO_ON; // to postpone the tick!
    }
    break;
  case POT_OBJECT_DETECTION:
    if (!fobj) {
      b = strange_feeling(otmp, "You feel a pull downward.");
      return ((b) ? GO_ON : DONE);
    } else {
      for (objs = fobj; objs; objs = objs->nobj)
	if (objs->ox != you.ux || objs->oy != you.uy) {
	  sense_what = SENSE_OBJECTS;
	  sense_by_what = otmp;
	  sense_init_screen();
	  FrmPopupForm(SenseForm);
	  return GO_ON; // to postpone the tick!
	}
      message("You sense the presence of objects close nearby.");
      break;
    }
    break;
  case POT_SICKNESS:
    message("Yech! This stuff tastes like poison.");
    if (Poison_resistance)
      message("(But in fact it was biologically contaminated orange juice.)");
    losestr(rund(4)+3);
    losehp(rnd(10), "contaminated potion");
    flags.botl |= BOTL_STR;
    break;
  case POT_CONFUSION:
    if (!Confusion)
      message("Huh, What?  Where am I?");
    else
      nothing = true;
    Confusion += rund(7)+16;
    break;
  case POT_GAIN_STRENGTH:
    message("Wow do you feel strong!");
    if (you.ustr >= 118) break;	/* > 118 is impossible */
    if (you.ustr > 17) you.ustr += rnd(118-you.ustr);
    else you.ustr++;
    if (you.ustr > you.ustrmax) you.ustrmax = you.ustr;
    flags.botl |= BOTL_STR;
    break;
  case POT_SPEED:
    if (Wounded_legs) {
      heal_legs();
      unkn = true;
      break;
    }
    if (!(Fast & ~INTRINSIC))
      message("You are suddenly moving much faster.");
    else {
      message("Your legs get new energy.");
      unkn = true;
    }
    Fast += rund(10)+100;
    break;
  case POT_BLINDNESS:
    if (!Blind)
      message("A cloud of darkness falls upon you.");
    else
      nothing = true;
    Blind += rund(100)+250;
    seeoff(false);
    break;
  case POT_GAIN_LEVEL: 
    pluslvl();
    break;
  case POT_EXTRA_HEALING:
    message("You feel much better.");
    you.uhp += dice(2,20)+1;
    if (you.uhp > you.uhpmax)
      you.uhp = (you.uhpmax += 2);
    if (Blind) Blind = 1;
    if (Sick) Sick = 0;
    flags.botl |= BOTL_HP;
    break;
  case POT_LEVITATION:
    if (!Levitation)
      float_up();
    else
      nothing = true;
    Levitation += rnd(100);
    //    you.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down; // UNNEEDED,
    // it has been replaced by tweaking timeout.c to call float_down directly!
    break;
  default:
    StrPrintF(ScratchBuffer, "What a funny potion! (%u)", otmp->otype);
    message(ScratchBuffer);
    return NO_OP;
  }
  return finish_do_drink(otmp, nothing, unkn);
}
Example #18
0
int
dowrite(struct obj *pen, const struct nh_cmd_arg *arg)
{
    struct obj *paper;
    const char *namebuf, *nm, *bp;
    struct obj *new_obj;
    int basecost, actualcost;
    int curseval;
    const char *qbuf;
    int first, last, i;
    boolean by_descr = FALSE, by_name = FALSE;
    const char *typeword;

    if (nohands(youmonst.data)) {
        pline(msgc_cancelled, "You need hands to be able to write!");
        return 0;
    } else if (slippery_fingers(&youmonst)) {
        pline(msgc_cancelled1, "%s from your %s.", Tobjnam(pen, "slip"),
              makeplural(body_part(FINGER)));
        unwield_silently(pen);
        dropx(pen);
        return 1;
    }

    /* get paper to write on */
    paper = getargobj(arg, write_on, "write on");
    if (!paper)
        return 0;

    typeword = (paper->oclass == SPBOOK_CLASS) ? "spellbook" : "scroll";
    if (Blind && !paper->dknown) {
        pline(msgc_cancelled1,
              "You don't know if that %s is blank or not!", typeword);
        return 1;
    }
    paper->dknown = 1;
    if (paper->otyp != SCR_BLANK_PAPER && paper->otyp != SPE_BLANK_PAPER) {
        pline(msgc_cancelled1, "That %s is not blank!", typeword);
        exercise(A_WIS, FALSE);
        return 1;
    }

    /* what to write */
    qbuf = msgprintf("What type of %s do you want to write?", typeword);
    namebuf = getarglin(arg, qbuf);
    namebuf = msgmungspaces(namebuf);   /* remove any excess whitespace */
    if (namebuf[0] == '\033' || !namebuf[0])
        return 1;
    nm = namebuf;
    if (!strncmpi(nm, "scroll ", 7))
        nm += 7;
    else if (!strncmpi(nm, "spellbook ", 10))
        nm += 10;
    if (!strncmpi(nm, "of ", 3))
        nm += 3;

    if ((bp = strstri(nm, " armour")) != 0)
        nm = msgcat_many(msgchop(nm, bp-nm), " armor", bp+7, NULL);

    first = bases[(int)paper->oclass];
    last = bases[(int)paper->oclass + 1] - 1;
    for (i = first; i <= last; i++) {
        /* extra shufflable descr not representing a real object */
        if (!OBJ_NAME(objects[i]))
            continue;

        if (!strcmpi(OBJ_NAME(objects[i]), nm))
            goto found;
        if (!strcmpi(OBJ_DESCR(objects[i]), nm)) {
            by_descr = TRUE;
            goto found;
        }
        if (objects[i].oc_uname &&
            !strcmpi(objects[i].oc_uname, nm)) {
            by_name = TRUE;
            goto found;
        }
    }

    pline(msgc_cancelled1, "There is no such %s!", typeword);
    return 1;
found:

    if (i == SCR_BLANK_PAPER || i == SPE_BLANK_PAPER) {
        pline(msgc_cancelled1, "You can't write that!");
        pline(msgc_cancelled1, "It's obscene!");
        return 1;
    } else if (i == SPE_BOOK_OF_THE_DEAD) {
        pline(msgc_cancelled1, "No mere dungeon adventurer could write that.");
        return 1;
    } else if ((by_descr || by_name) && paper->oclass == SPBOOK_CLASS &&
               !objects[i].oc_name_known) {
        /* can't write unknown spellbooks by description */
        pline(msgc_cancelled1,
              "Unfortunately you don't have enough information to go on.");
        return 1;
    }

    /* KMH, conduct */
    break_conduct(conduct_illiterate);

    new_obj = mksobj(level, i, FALSE, FALSE, rng_main);
    new_obj->bknown = (paper->bknown && pen->bknown);

    /* shk imposes a flat rate per use, not based on actual charges used */
    check_unpaid(pen);

    /* see if there's enough ink */
    basecost = cost(new_obj);
    if (pen->spe < basecost / 2) {
        pline(msgc_failcurse, "Your marker is too dry to write that!");
        obfree(new_obj, NULL);
        return 1;
    }

    /* we're really going to write now, so calculate cost

       no custom RNG used: too much influence from player actions */
    actualcost = rn1(basecost / 2, basecost / 2);
    curseval = bcsign(pen) + bcsign(paper);
    exercise(A_WIS, TRUE);
    /* dry out marker */
    if (pen->spe < actualcost) {
        pen->spe = 0;
        pline(msgc_itemloss, "Your marker dries out!");
        /* scrolls disappear, spellbooks don't */
        if (paper->oclass == SPBOOK_CLASS) {
            pline(msgc_failcurse,
                  "The spellbook is left unfinished and your writing fades.");
            update_inventory(); /* pen charges */
        } else {
            pline(msgc_failcurse, "The scroll is now useless and disappears!");
            useup(paper);
        }
        obfree(new_obj, NULL);
        return 1;
    }
    pen->spe -= actualcost;

    /* can't write if we don't know it - unless we're lucky */
    if (!(objects[new_obj->otyp].oc_name_known) &&
        (rnl(Role_if(PM_WIZARD) ? 3 : 15))) {
        pline(msgc_failrandom, "You %s to write that!",
              by_descr ? "fail" : "don't know how");
        /* scrolls disappear, spellbooks don't */
        if (paper->oclass == SPBOOK_CLASS) {
            pline_implied(msgc_failrandom,
                          "You write in your best handwriting:  "
                          "\"My Diary\", but it quickly fades.");
            update_inventory(); /* pen charges */
        } else {
            const char *written;
            if (by_descr) {
                written = OBJ_DESCR(objects[new_obj->otyp]);
                written = eroded_text(written,
                                      (6 + MAXULEV - youmonst.m_lev) / 6, 0);
            } else
                written = msgprintf("%s was here!", u.uplname);
            pline_implied(msgc_failrandom,
                          "You write \"%s\" and the scroll disappears.",
                          written);
            useup(paper);
        }
        obfree(new_obj, NULL);
        return 1;
    }

    /* useup old scroll / spellbook */
    useup(paper);

    /* success */
    if (new_obj->oclass == SPBOOK_CLASS) {
        /* acknowledge the change in the object's description... */
        pline(msgc_actionok, "The spellbook warps strangely, then turns %s.",
              OBJ_DESCR(objects[new_obj->otyp]));
    }
    new_obj->blessed = (curseval > 0);
    new_obj->cursed = (curseval < 0);
    hold_another_object(new_obj, "Oops!  %s out of your grasp!",
                        The(aobjnam(new_obj, "slip")), NULL);
    return 1;
}
Example #19
0
int
doread()
{
	struct obj *scroll;
	boolean confused = (Confusion != 0);
	boolean known = FALSE;

	scroll = getobj("?", "read");
	if(!scroll) return(0);
	if(!scroll->dknown && Blind) {
	    pline("Being blind, you cannot read the formula on the scroll.");
	    return(0);
	}
	if(Blind)
	  pline("As you pronounce the formula on it, the scroll disappears.");
	else
	  pline("As you read the scroll, it disappears.");
	if(confused)
	  pline("Being confused, you mispronounce the magic words ... ");

	switch(scroll->otyp) {
#ifdef MAIL
	case SCR_MAIL:
		readmail(/* scroll */);
		break;
#endif /* MAIL */
	case SCR_ENCHANT_ARMOR:
	    {	struct obj *otmp = some_armor();
		if(!otmp) {
			strange_feeling(scroll,"Your skin glows then fades.");
			return(1);
		}
		if(confused) {
			pline("Your %s glows silver for a moment.",
				objects[otmp->otyp].oc_name);
			otmp->rustfree = 1;
			break;
		}
		if(otmp->spe > 3 && rn2(otmp->spe)) {
	pline("Your %s glows violently green for a while, then evaporates.",
			objects[otmp->otyp].oc_name);
			useup(otmp);
			break;
		}
		pline("Your %s glows green for a moment.",
			objects[otmp->otyp].oc_name);
		otmp->cursed = 0;
		otmp->spe++;
		break;
	    }
	case SCR_DESTROY_ARMOR:
		if(confused) {
			struct obj *otmp = some_armor();
			if(!otmp) {
				strange_feeling(scroll,"Your bones itch.");
				return(1);
			}
			pline("Your %s glows purple for a moment.",
				objects[otmp->otyp].oc_name);
			otmp->rustfree = 0;
			break;
		}
		if(uarm) {
		    pline("Your armor turns to dust and falls to the floor!");
		    useup(uarm);
		} else if(uarmh) {
		    pline("Your helmet turns to dust and is blown away!");
		    useup(uarmh);
		} else if(uarmg) {
			pline("Your gloves vanish!");
			useup(uarmg);
			selftouch("You");
		} else {
			strange_feeling(scroll,"Your skin itches.");
			return(1);
		}
		break;
	case SCR_CONFUSE_MONSTER:
		if(confused) {
			pline("Your hands begin to glow purple.");
			Confusion += rnd(100);
		} else {
			pline("Your hands begin to glow blue.");
			u.umconf = 1;
		}
		break;
	case SCR_SCARE_MONSTER:
	    {	int ct = 0;
		struct monst *mtmp;

		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
			if(cansee(mtmp->mx,mtmp->my)) {
				if(confused)
					mtmp->mflee = mtmp->mfroz =
					mtmp->msleep = 0;
				else
					mtmp->mflee = 1;
				ct++;
			}
		if(!ct) {
		    if(confused)
			pline("You hear sad wailing in the distance.");
		    else
			pline("You hear maniacal laughter in the distance.");
		}
		break;
	    }
	case SCR_BLANK_PAPER:
		if(confused)
		    pline("You see strange patterns on this scroll.");
		else
		    pline("This scroll seems to be blank.");
		break;
	case SCR_REMOVE_CURSE:
	    {	struct obj *obj;
		if(confused)
		  pline("You feel like you need some help.");
		else
		  pline("You feel like someone is helping you.");
		for(obj = invent; obj ; obj = obj->nobj)
			if(obj->owornmask)
				obj->cursed = confused;
		if(Punished && !confused) {
			Punished = 0;
			freeobj(uchain);
			unpobj(uchain);
			free(uchain);
			uball->spe = 0;
			uball->owornmask &= ~W_BALL;
			uchain = uball = (struct obj *) 0;
		}
		break;
	    }
	case SCR_CREATE_MONSTER:
	    {	int cnt = 1;

		if(!rn2(73)) cnt += rnd(4);
		if(confused) cnt += 12;
		while(cnt--)
		    (void) makemon(confused ? PM_ACID_BLOB :
			(struct permonst *) 0, u.ux, u.uy);
		break;
	    }
	case SCR_ENCHANT_WEAPON:
		if(uwep && confused) {
			pline("Your %s glows silver for a moment.",
				objects[uwep->otyp].oc_name);
			uwep->rustfree = 1;
		} else
			if(!chwepon(scroll, 1))		/* tests for !uwep */
				return(1);
		break;
	case SCR_DAMAGE_WEAPON:
		if(uwep && confused) {
			pline("Your %s glows purple for a moment.",
				objects[uwep->otyp].oc_name);
			uwep->rustfree = 0;
		} else
			if(!chwepon(scroll, -1))	/* tests for !uwep */
				return(1);
		break;
	case SCR_TAMING:
	    {	int i,j;
		int bd = confused ? 5 : 1;
		struct monst *mtmp;

		for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
		if ((mtmp = m_at(u.ux+i, u.uy+j)))
			(void) tamedog(mtmp, NULL);
		break;
	    }
	case SCR_GENOCIDE:
	    {	extern char genocided[], fut_geno[];
		char buf[BUFSZ];
		struct monst *mtmp, *mtmp2;

		pline("You have found a scroll of genocide!");
		known = TRUE;
		if(confused)
			*buf = u.usym;
		else do {
	    pline("What monster do you want to genocide (Type the letter)? ");
			getlin(buf);
		} while(strlen(buf) != 1 || !monstersym(*buf));
		if(!strchr(fut_geno, *buf))
			charcat(fut_geno, *buf);
		if(!strchr(genocided, *buf))
			charcat(genocided, *buf);
		else {
			pline("Such monsters do not exist in this world.");
			break;
		}
		for(mtmp = fmon; mtmp; mtmp = mtmp2){
			mtmp2 = mtmp->nmon;
			if(mtmp->data->mlet == *buf)
				mondead(mtmp);
		}
		pline("Wiped out all %c's.", *buf);
		if(*buf == u.usym) {
			killer = "scroll of genocide";
			u.uhp = -1;
		}
		break;
		}
	case SCR_LIGHT:
		if(!Blind) known = TRUE;
		litroom(!confused);
		break;
	case SCR_TELEPORTATION:
		if(confused)
			level_tele();
		else {
#ifdef QUEST
			int oux = u.ux, ouy = u.uy;
			tele();
			if(dist(oux, ouy) > 100) known = TRUE;
#else /* QUEST */
			int uroom = inroom(u.ux, u.uy);
			tele();
			if(uroom != inroom(u.ux, u.uy)) known = TRUE;
#endif /* QUEST */
		}
		break;
	case SCR_GOLD_DETECTION:
	    /* Unfortunately this code has become slightly less elegant,
	       now that gold and traps no longer are of the same type. */
	    if(confused) {
		struct trap *ttmp;

		if(!ftrap) {
			strange_feeling(scroll, "Your toes stop itching.");
			return(1);
		} else {
			for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
				if(ttmp->tx != u.ux || ttmp->ty != u.uy)
					goto outtrapmap;
			/* only under me - no separate display required */
			pline("Your toes itch!");
			break;
		outtrapmap:
			cls();
			for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
				at(ttmp->tx, ttmp->ty, '$');
			prme();
			pline("You feel very greedy!");
		}
	    } else {
		struct gold *gtmp;

		if(!fgold) {
			strange_feeling(scroll, "You feel materially poor.");
			return(1);
		} else {
			known = TRUE;
			for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
				if(gtmp->gx != u.ux || gtmp->gy != u.uy)
					goto outgoldmap;
			/* only under me - no separate display required */
			pline("You notice some gold between your feet.");
			break;
		outgoldmap:
			cls();
			for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
				at(gtmp->gx, gtmp->gy, '$');
			prme();
			pline("You feel very greedy, and sense gold!");
		}
	    }
		/* common sequel */
		more();
		docrt();
		break;
	case SCR_FOOD_DETECTION:
	    {	int ct = 0, ctu = 0;
		struct obj *obj;
		char foodsym = confused ? POTION_SYM : FOOD_SYM;

		for(obj = fobj; obj; obj = obj->nobj)
			if(obj->olet == FOOD_SYM) {
				if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
				else ct++;
			}
		if(!ct && !ctu) {
			strange_feeling(scroll,"Your nose twitches.");
			return(1);
		} else if(!ct) {
			known = TRUE;
			pline("You smell %s close nearby.",
				confused ? "something" : "food");
			
		} else {
			known = TRUE;
			cls();
			for(obj = fobj; obj; obj = obj->nobj)
			    if(obj->olet == foodsym)
				at(obj->ox, obj->oy, FOOD_SYM);
			prme();
			pline("Your nose tingles and you smell %s!",
				confused ? "something" : "food");
			more();
			docrt();
		}
		break;
	    }
	case SCR_IDENTIFY:
		/* known = TRUE; */
		if(confused)
			pline("You identify this as an identify scroll.");
		else
			pline("This is an identify scroll.");
		useup(scroll);
		objects[SCR_IDENTIFY].oc_name_known = 1;
		if(!confused)
		    while(
			!ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
			&& invent
		    );
		return(1);
	case SCR_MAGIC_MAPPING:
	    {	struct rm *lev;
		int num, zx, zy;

		known = TRUE;
		pline("On this scroll %s a map!",
			confused ? "was" : "is");
		for(zy = 0; zy < ROWNO; zy++)
			for(zx = 0; zx < COLNO; zx++) {
				if(confused && rn2(7)) continue;
				lev = &(levl[zx][zy]);
				if((num = lev->typ) == 0)
					continue;
				if(num == SCORR) {
					lev->typ = CORR;
					lev->scrsym = CORR_SYM;
				} else
				if(num == SDOOR) {
					lev->typ = DOOR;
					lev->scrsym = '+';
					/* do sth in doors ? */
				} else if(lev->seen) continue;
#ifndef QUEST
				if(num != ROOM)
#endif /* QUEST */
				{
				  lev->seen = lev->new = 1;
				  if(lev->scrsym == ' ' || !lev->scrsym)
				    newsym(zx,zy);
				  else
				    on_scr(zx,zy);
				}
			}
		break;
	    }
	case SCR_AMNESIA:
	    {	int zx, zy;

		known = TRUE;
		for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
		    if(!confused || rn2(7))
			if(!cansee(zx,zy))
			    levl[zx][zy].seen = 0;
		docrt();
		pline("Thinking of Maud you forget everything else.");
		break;
	    }
	case SCR_FIRE:
	    {	int num;
		struct monst *mtmp;

		known = TRUE;
		if(confused) {
		    pline("The scroll catches fire and you burn your hands.");
		    losehp(1, "scroll of fire");
		} else {
		    pline("The scroll erupts in a tower of flame!");
		    if(Fire_resistance)
			pline("You are uninjured.");
		    else {
			num = rnd(6);
			u.uhpmax -= num;
			losehp(num, "scroll of fire");
		    }
		}
		num = (2*num + 1)/3;
		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
		    if(dist(mtmp->mx,mtmp->my) < 3) {
			mtmp->mhp -= num;
			if(strchr("FY", mtmp->data->mlet))
			    mtmp->mhp -= 3*num;	/* this might well kill 'F's */
			if(mtmp->mhp < 1) {
			    killed(mtmp);
			    break;		/* primitive */
			}
		    }
		}
		break;
	    }
	case SCR_PUNISHMENT:
		known = TRUE;
		if(confused) {
			pline("You feel guilty.");
			break;
		}
		pline("You are being punished for your misbehaviour!");
		if(Punished){
			pline("Your iron ball gets heavier.");
			uball->owt += 15;
			break;
		}
		Punished = INTRINSIC;
		setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
		setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
		uball->spe = 1;		/* special ball (see save) */
		break;
	default:
		impossible("What weird language is this written in? (%u)",
			scroll->otyp);
	}
Example #20
0
static void break_armor(void)
{
    struct obj *otmp;

    if (breakarm(youmonst.data)) {
	if ((otmp = uarm) != 0) {
		if (donning(otmp)) cancel_don();
		pline("You break out of your armor!");
		exercise(A_STR, FALSE);
		Armor_gone();
		useup(otmp);
	}
	if ((otmp = uarmc) != 0) {
	    if (otmp->oartifact) {
		pline("Your %s falls off!", cloak_simple_name(otmp));
		Cloak_off();
		dropx(otmp);
	    } else {
		pline("Your %s tears apart!", cloak_simple_name(otmp));
		Cloak_off();
		useup(otmp);
	    }
	}
	if (uarmu) {
		pline("Your shirt rips to shreds!");
		useup(uarmu);
	}
    } else if (sliparm(youmonst.data)) {
	if (((otmp = uarm) != 0) && (racial_exception(&youmonst, otmp) < 1)) {
		if (donning(otmp)) cancel_don();
		pline("Your armor falls around you!");
		Armor_gone();
		dropx(otmp);
	}
	if ((otmp = uarmc) != 0) {
		if (is_whirly(youmonst.data))
			pline("Your %s falls, unsupported!", cloak_simple_name(otmp));
		else pline("You shrink out of your %s!", cloak_simple_name(otmp));
		Cloak_off();
		dropx(otmp);
	}
	if ((otmp = uarmu) != 0) {
		if (is_whirly(youmonst.data))
			pline("You seep right through your shirt!");
		else pline("You become much too small for your shirt!");
		setworn(NULL, otmp->owornmask & W_ARMU);
		dropx(otmp);
	}
    }
    if (has_horns(youmonst.data)) {
	if ((otmp = uarmh) != 0) {
	    if (is_flimsy(otmp) && !donning(otmp)) {
		char hornbuf[BUFSZ], yourbuf[BUFSZ];

		/* Future possiblities: This could damage/destroy helmet */
		sprintf(hornbuf, "horn%s", plur(num_horns(youmonst.data)));
		pline("Your %s %s through %s %s.", hornbuf, vtense(hornbuf, "pierce"),
		     shk_your(yourbuf, otmp), xname(otmp));
	    } else {
		if (donning(otmp)) cancel_don();
		pline("Your helmet falls to the %s!", surface(u.ux, u.uy));
		Helmet_off();
		dropx(otmp);
	    }
	}
    }
    if (nohands(youmonst.data) || verysmall(youmonst.data)) {
	if ((otmp = uarmg) != 0) {
	    if (donning(otmp)) cancel_don();
	    /* Drop weapon along with gloves */
	    pline("You drop your gloves%s!", uwep ? " and weapon" : "");
	    drop_weapon(0);
	    Gloves_off();
	    dropx(otmp);
	}
	if ((otmp = uarms) != 0) {
	    pline("You can no longer hold your shield!");
	    Shield_off();
	    dropx(otmp);
	}
	if ((otmp = uarmh) != 0) {
	    if (donning(otmp)) cancel_don();
	    pline("Your helmet falls to the %s!", surface(u.ux, u.uy));
	    Helmet_off();
	    dropx(otmp);
	}
    }
    if (nohands(youmonst.data) || verysmall(youmonst.data) ||
		slithy(youmonst.data) || youmonst.data->mlet == S_CENTAUR) {
	if ((otmp = uarmf) != 0) {
	    if (donning(otmp)) cancel_don();
	    if (is_whirly(youmonst.data))
		pline("Your boots fall away!");
	    else pline("Your boots %s off your feet!",
			verysmall(youmonst.data) ? "slide" : "are pushed");
	    Boots_off();
	    dropx(otmp);
	}
    }
}
Example #21
0
int
study_book(struct obj *spellbook, const struct nh_cmd_arg *arg)
{
    int booktype = spellbook->otyp;
    boolean confused = (Confusion != 0);
    boolean too_hard = FALSE;

    if (u.uoccupation_progress[tos_book] && !confused &&
        spellbook == u.utracked[tos_book] &&
        /* handle the sequence: start reading, get interrupted, have book
           become erased somehow, resume reading it */
        booktype != SPE_BLANK_PAPER) {
        if (turnstate.continue_message)
            pline("You continue your efforts to memorize the spell.");
    } else {
        /* Restarting reading the book */

        /* KMH -- Simplified this code */
        if (booktype == SPE_BLANK_PAPER) {
            pline("This spellbook is all blank.");
            makeknown(booktype);
            return 1;
        }
        switch (objects[booktype].oc_level) {
        case 1:
        case 2:
            u.uoccupation_progress[tos_book] = -objects[booktype].oc_delay;
            break;
        case 3:
        case 4:
            u.uoccupation_progress[tos_book] =
                -(objects[booktype].oc_level - 1) * objects[booktype].oc_delay;
            break;
        case 5:
        case 6:
            u.uoccupation_progress[tos_book] =
                -objects[booktype].oc_level * objects[booktype].oc_delay;
            break;
        case 7:
            u.uoccupation_progress[tos_book] = -8 * objects[booktype].oc_delay;
            break;
        default:
            impossible("Unknown spellbook level %d, book %d;",
                       objects[booktype].oc_level, booktype);
            return 0;
        }

        /* Books are often wiser than their readers (Rus.) */
        spellbook->in_use = TRUE;
        if (!spellbook->blessed && spellbook->otyp != SPE_BOOK_OF_THE_DEAD) {
            if (spellbook->cursed) {
                too_hard = TRUE;
            } else {
                /* uncursed - chance to fail */
                int read_ability =
                    ACURR(A_INT) + 4 + u.ulevel / 2 -
                    2 * objects[booktype].oc_level +
                    ((ublindf && ublindf->otyp == LENSES) ? 2 : 0);
                /* only wizards know if a spell is too difficult */
                if (Role_if(PM_WIZARD) && read_ability < 20 && !confused) {
                    const char *qbuf;

                    qbuf = msgprintf("This spellbook is %sdifficult to "
                                     "comprehend. Continue?",
                                     (read_ability < 12 ? "very " : ""));
                    if (yn(qbuf) != 'y') {
                        spellbook->in_use = FALSE;
                        return 1;
                    }
                }
                /* it's up to random luck now */
                if (rnd(20) > read_ability) {
                    too_hard = TRUE;
                }
            }
        }

        if (too_hard) {
            boolean gone = cursed_book(spellbook);

            helpless(-u.uoccupation_progress[tos_book], hr_paralyzed,
                     "frozen by a spellbook", NULL);
            u.uoccupation_progress[tos_book] = 0;
            if (gone || !rn2(3)) {
                if (!gone)
                    pline("The spellbook crumbles to dust!");
                if (!objects[spellbook->otyp].oc_name_known &&
                    !objects[spellbook->otyp].oc_uname)
                    docall(spellbook);
                useup(spellbook);
            } else
                spellbook->in_use = FALSE;
            return 1;
        } else if (confused) {
            if (!confused_book(spellbook)) {
                spellbook->in_use = FALSE;
            }
            helpless(-u.uoccupation_progress[tos_book], hr_busy,
                     "absorbed in a spellbook",
                     "You're finally able to put the book down.");
            u.uoccupation_progress[tos_book] = 0;
            u.utracked[tos_book] = 0;
            return 1;
        }
        spellbook->in_use = FALSE;

        pline("You begin to %s the runes.",
              spellbook->otyp == SPE_BOOK_OF_THE_DEAD ? "recite" : "memorize");
    }

    u.utracked[tos_book] = spellbook;

    one_occupation_turn(learn, "studying", occ_book);

    return 1;
}
Example #22
0
static void
break_armor (void)
{
    struct obj *otmp;

    if (breakarm(youmonst.data)) {
        if ((otmp = uarm) != 0) {
                if (donning(otmp)) cancel_don();
                You("break out of your armor!");
                exercise(A_STR, false);
                (void) Armor_gone();
                useup(otmp);
        }
        if ((otmp = uarmc) != 0) {
            if(otmp->oartifact) {
                Your("%s falls off!", cloak_simple_name(otmp));
                (void) Cloak_off();
                dropx(otmp);
            } else {
                Your("%s tears apart!", cloak_simple_name(otmp));
                (void) Cloak_off();
                useup(otmp);
            }
        }
        if (uarmu) {
                Your("shirt rips to shreds!");
                useup(uarmu);
        }
    } else if (sliparm(youmonst.data)) {
        if (((otmp = uarm) != 0) && (racial_exception(&youmonst, otmp) < 1)) {
                if (donning(otmp)) cancel_don();
                Your("armor falls around you!");
                (void) Armor_gone();
                dropx(otmp);
        }
        if ((otmp = uarmc) != 0) {
                if (is_whirly(youmonst.data))
                        Your("%s falls, unsupported!", cloak_simple_name(otmp));
                else You("shrink out of your %s!", cloak_simple_name(otmp));
                (void) Cloak_off();
                dropx(otmp);
        }
        if ((otmp = uarmu) != 0) {
                if (is_whirly(youmonst.data))
                        You("seep right through your shirt!");
                else You("become much too small for your shirt!");
                setworn((struct obj *)0, otmp->owornmask & W_ARMU);
                dropx(otmp);
        }
    }
    if (has_horns(youmonst.data)) {
        if ((otmp = uarmh) != 0) {
            if (is_flimsy(otmp) && !donning(otmp)) {
                /* Future possiblities: This could damage/destroy helmet */
                message_object(MSG_YOUR_HORNS_PIERCE_O, otmp);
            } else {
                if (donning(otmp)) cancel_don();
                Your("helmet falls to the %s!", surface(u.ux, u.uy));
                (void) Helmet_off();
                dropx(otmp);
            }
        }
    }
    if (nohands(youmonst.data) || verysmall(youmonst.data)) {
        if ((otmp = uarmg) != 0) {
            if (donning(otmp)) cancel_don();
            /* Drop weapon along with gloves */
            You("drop your gloves%s!", uwep ? " and weapon" : "");
            drop_weapon(0);
            (void) Gloves_off();
            dropx(otmp);
        }
        if ((otmp = uarms) != 0) {
            You("can no longer hold your shield!");
            (void) Shield_off();
            dropx(otmp);
        }
        if ((otmp = uarmh) != 0) {
            if (donning(otmp)) cancel_don();
            Your("helmet falls to the %s!", surface(u.ux, u.uy));
            (void) Helmet_off();
            dropx(otmp);
        }
    }
    if (nohands(youmonst.data) || verysmall(youmonst.data) ||
                slithy(youmonst.data) || youmonst.data->mlet == S_CENTAUR) {
        if ((otmp = uarmf) != 0) {
            if (donning(otmp)) cancel_don();
            if (is_whirly(youmonst.data))
                Your("boots fall away!");
            else Your("boots %s off your feet!",
                        verysmall(youmonst.data) ? "slide" : "are pushed");
            (void) Boots_off();
            dropx(otmp);
        }
    }
}