diff rogue5/scrolls.c @ 33:f502bf60e6e4

Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author elwin
date Mon, 24 May 2010 20:10:59 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue5/scrolls.c	Mon May 24 20:10:59 2010 +0000
@@ -0,0 +1,330 @@
+/*
+ * Read a scroll and let it happen
+ *
+ * @(#)scrolls.c	4.44 (Berkeley) 02/05/99
+ *
+ * Rogue: Exploring the Dungeons of Doom
+ * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include <curses.h>
+#include <ctype.h>
+#include "rogue.h"
+
+/*
+ * read_scroll:
+ *	Read a scroll from the pack and do the appropriate thing
+ */
+
+void
+read_scroll(void)
+{
+    THING *obj;
+    PLACE *pp;
+    int y, x;
+    int ch;
+    int i;
+    int discardit = FALSE;
+    struct room *cur_room;
+    THING *orig_obj;
+    coord mp;
+
+    obj = get_item("read", SCROLL);
+    if (obj == NULL)
+	return;
+    if (obj->o_type != SCROLL)
+    {
+	if (!terse)
+	    msg("there is nothing on it to read");
+	else
+	    msg("nothing to read");
+	return;
+    }
+    /*
+     * Calculate the effect it has on the poor guy.
+     */
+    if (obj == cur_weapon)
+	cur_weapon = NULL;
+    /*
+     * Get rid of the thing
+     */
+    discardit = (obj->o_count == 1);
+    leave_pack(obj, FALSE, FALSE);
+    orig_obj = obj;
+
+    switch (obj->o_which)
+    {
+	case S_CONFUSE:
+	    /*
+	     * Scroll of monster confusion.  Give him that power.
+	     */
+	    player.t_flags |= CANHUH;
+	    msg("your hands begin to glow %s", pick_color("red"));
+	when S_ARMOR:
+	    if (cur_armor != NULL)
+	    {
+		cur_armor->o_arm--;
+		cur_armor->o_flags &= ~ISCURSED;
+		msg("your armor glows %s for a moment", pick_color("silver"));
+	    }
+	when S_HOLD:
+	    /*
+	     * Hold monster scroll.  Stop all monsters within two spaces
+	     * from chasing after the hero.
+	     */
+
+	    ch = 0;
+	    for (x = hero.x - 2; x <= hero.x + 2; x++)
+		if (x >= 0 && x < NUMCOLS)
+		    for (y = hero.y - 2; y <= hero.y + 2; y++)
+			if (y >= 0 && y <= NUMLINES - 1)
+			    if ((obj = moat(y, x)) != NULL && on(*obj, ISRUN))
+			    {
+				obj->t_flags &= ~ISRUN;
+				obj->t_flags |= ISHELD;
+				ch++;
+			    }
+	    if (ch)
+	    {
+		addmsg("the monster");
+		if (ch > 1)
+		    addmsg("s around you");
+		addmsg(" freeze");
+		if (ch == 1)
+		    addmsg("s");
+		endmsg();
+		scr_info[S_HOLD].oi_know = TRUE;
+	    }
+	    else
+		msg("you feel a strange sense of loss");
+	when S_SLEEP:
+	    /*
+	     * Scroll which makes you fall asleep
+	     */
+	    scr_info[S_SLEEP].oi_know = TRUE;
+	    no_command += rnd(SLEEPTIME) + 4;
+	    player.t_flags &= ~ISRUN;
+	    msg("you fall asleep");
+	when S_CREATE:
+	    /*
+	     * Create a monster:
+	     * First look in a circle around him, next try his room
+	     * otherwise give up
+	     */
+	    i = 0;
+	    for (y = hero.y - 1; y <= hero.y + 1; y++)
+		for (x = hero.x - 1; x <= hero.x + 1; x++)
+		    /*
+		     * Don't put a monster in top of the player.
+		     */
+		    if (y == hero.y && x == hero.x)
+			continue;
+		    /*
+		     * Or anything else nasty
+		     * Also avoid a xeroc which is disguised as scroll
+		     */
+		    else if (moat(y, x) == NULL && step_ok(ch = winat(y, x)))
+		    {
+			if (ch == SCROLL
+			    && find_obj(y, x)->o_which == S_SCARE)
+				continue;
+			else if (rnd(++i) == 0)
+			{
+			    mp.y = y;
+			    mp.x = x;
+			}
+		    }
+	    if (i == 0)
+		msg("you hear a faint cry of anguish in the distance");
+	    else
+	    {
+		obj = new_item();
+		new_monster(obj, randmonster(FALSE), &mp);
+	    }
+	when S_ID_POTION:
+	case S_ID_SCROLL:
+	case S_ID_WEAPON:
+	case S_ID_ARMOR:
+	case S_ID_R_OR_S:
+	{
+	    int id_type[S_ID_R_OR_S + 1] =
+		{ 0, 0, 0, 0, 0, POTION, SCROLL, WEAPON, ARMOR, R_OR_S };
+	    /*
+	     * Identify, let him figure something out
+	     */
+	    scr_info[obj->o_which].oi_know = TRUE;
+	    msg("this scroll is an %s scroll", scr_info[obj->o_which].oi_name);
+	    whatis(TRUE, id_type[obj->o_which]);
+	}
+	when S_MAP:
+	    /*
+	     * Scroll of magic mapping.
+	     */
+	    scr_info[S_MAP].oi_know = TRUE;
+	    msg("oh, now this scroll has a map on it");
+	    /*
+	     * take all the things we want to keep hidden out of the window
+	     */
+	    for (y = 1; y < NUMLINES - 1; y++)
+		for (x = 0; x < NUMCOLS; x++)
+		{
+		    pp = INDEX(y, x);
+		    switch (ch = pp->p_ch)
+		    {
+			case DOOR:
+			case STAIRS:
+			    break;
+
+			case '-':
+			case '|':
+			    if (!(pp->p_flags & F_REAL))
+			    {
+				ch = pp->p_ch = DOOR;
+				pp->p_flags |= F_REAL;
+			    }
+			    break;
+
+			case ' ':
+			    if (pp->p_flags & F_REAL)
+				goto def;
+			    pp->p_flags |= F_REAL;
+			    ch = pp->p_ch = PASSAGE;
+			    /* FALLTHROUGH */
+
+			case PASSAGE:
+pass:
+			    if (!(pp->p_flags & F_REAL))
+				pp->p_ch = PASSAGE;
+			    pp->p_flags |= (F_SEEN|F_REAL);
+			    ch = PASSAGE;
+			    break;
+
+			case FLOOR:
+			    if (pp->p_flags & F_REAL)
+				ch = ' ';
+			    else
+			    {
+				ch = TRAP;
+				pp->p_ch = TRAP;
+				pp->p_flags |= (F_SEEN|F_REAL);
+			    }
+			    break;
+
+			default:
+def:
+			    if (pp->p_flags & F_PASS)
+				goto pass;
+			    ch = ' ';
+			    break;
+		    }
+		    if (ch != ' ')
+		    {
+			if ((obj = pp->p_monst) != NULL)
+			    obj->t_oldch = ch;
+			if (obj == NULL || !on(player, SEEMONST))
+			    mvaddch(y, x, ch);
+		    }
+		}
+	when S_FDET:
+	    /*
+	     * Potion of gold detection
+	     */
+	    ch = FALSE;
+	    wclear(hw);
+	    for (obj = lvl_obj; obj != NULL; obj = next(obj))
+		if (obj->o_type == FOOD)
+		{
+		    ch = TRUE;
+		    wmove(hw, obj->o_pos.y, obj->o_pos.x);
+		    waddch(hw, FOOD);
+		}
+	    if (ch)
+	    {
+		scr_info[S_FDET].oi_know = TRUE;
+		show_win("Your nose tingles and you smell food.--More--");
+	    }
+	    else
+		msg("your nose tingles");
+	when S_TELEP:
+	    /*
+	     * Scroll of teleportation:
+	     * Make him dissapear and reappear
+	     */
+	    {
+		cur_room = proom;
+		teleport();
+		if (cur_room != proom)
+		    scr_info[S_TELEP].oi_know = TRUE;
+	    }
+	when S_ENCH:
+	    if (cur_weapon == NULL || cur_weapon->o_type != WEAPON)
+		msg("you feel a strange sense of loss");
+	    else
+	    {
+		cur_weapon->o_flags &= ~ISCURSED;
+		if (rnd(2) == 0)
+		    cur_weapon->o_hplus++;
+		else
+		    cur_weapon->o_dplus++;
+		msg("your %s glows %s for a moment",
+		    weap_info[cur_weapon->o_which].oi_name, pick_color("blue"));
+	    }
+	when S_SCARE:
+	    /*
+	     * Reading it is a mistake and produces laughter at her
+	     * poor boo boo.
+	     */
+	    msg("you hear maniacal laughter in the distance");
+	when S_REMOVE:
+	    uncurse(cur_armor);
+	    uncurse(cur_weapon);
+	    uncurse(cur_ring[LEFT]);
+	    uncurse(cur_ring[RIGHT]);
+	    msg(choose_str("you feel in touch with the Universal Onenes",
+			   "you feel as if somebody is watching over you"));
+	when S_AGGR:
+	    /*
+	     * This scroll aggravates all the monsters on the current
+	     * level and sets them running towards the hero
+	     */
+	    aggravate();
+	    msg("you hear a high pitched humming noise");
+	when S_PROTECT:
+	    if (cur_armor != NULL)
+	    {
+		cur_armor->o_flags |= ISPROT;
+		msg("your armor is covered by a shimmering %s shield",
+		    pick_color("gold"));
+	    }
+	    else
+		msg("you feel a strange sense of loss");
+#ifdef MASTER
+	otherwise:
+	    msg("what a puzzling scroll!");
+	    return;
+#endif
+    }
+    obj = orig_obj;
+    look(TRUE);	/* put the result of the scroll on the screen */
+    status();
+
+    call_it(&scr_info[obj->o_which]);
+
+    if (discardit)
+	discard(obj);
+}
+
+/*
+ * uncurse:
+ *	Uncurse an item
+ */
+
+void
+uncurse(THING *obj)
+{
+    if (obj != NULL)
+	obj->o_flags &= ~ISCURSED;
+}