diff rogue3/scrolls.c @ 0:527e2150eaf0

Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author edwarj4
date Tue, 13 Oct 2009 13:33:34 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/scrolls.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,317 @@
+
+/*
+ * Read a scroll and let it happen
+ *
+ * @(#)scrolls.c	3.5 (Berkeley) 6/15/81
+ *
+ * Rogue: Exploring the Dungeons of Doom
+ * Copyright (C) 1980, 1981 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 <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include "rogue.h"
+
+void
+read_scroll()
+{
+    struct object *obj;
+    struct linked_list *item;
+    struct room *rp;
+    int i,j;
+    int ch, nch;
+    struct linked_list *titem;
+    char buf[80];
+
+    item = get_item("read", SCROLL);
+    if (item == NULL)
+	return;
+    obj = (struct object *) ldata(item);
+    if (obj->o_type != SCROLL)
+    {
+	if (!terse)
+	    msg("There is nothing on it to read");
+	else
+	    msg("Nothing to read");
+	return;
+    }
+    msg("As you read the scroll, it vanishes.");
+    /*
+     * Calculate the effect it has on the poor guy.
+     */
+    if (obj == cur_weapon)
+	cur_weapon = NULL;
+    switch(obj->o_which)
+    {
+	case S_CONFUSE:
+	    /*
+	     * Scroll of monster confusion.  Give him that power.
+	     */
+	    msg("Your hands begin to glow red");
+	    player.t_flags |= CANHUH;
+	when S_LIGHT:
+	    s_know[S_LIGHT] = TRUE;
+	    if ((rp = roomin(&hero)) == NULL)
+		msg("The corridor glows and then fades");
+	    else
+	    {
+		addmsg("The room is lit");
+		if (!terse)
+		    addmsg(" by a shimmering blue light.");
+		endmsg();
+		rp->r_flags &= ~ISDARK;
+		/*
+		 * Light the room and put the player back up
+		 */
+		light(&hero);
+		mvwaddch(cw, hero.y, hero.x, PLAYER);
+	    }
+	when S_ARMOR:
+	    if (cur_armor != NULL)
+	    {
+		msg("Your armor glows faintly for a moment");
+		cur_armor->o_ac--;
+		cur_armor->o_flags &= ~ISCURSED;
+	    }
+	when S_HOLD:
+	    /*
+	     * Hold monster scroll.  Stop all monsters within two spaces
+	     * from chasing after the hero.
+	     */
+	    {
+		int x,y;
+		struct linked_list *mon;
+
+		for (x = hero.x-2; x <= hero.x+2; x++)
+		    for (y = hero.y-2; y <= hero.y+2; y++)
+			if (y > 0 && x > 0 && isupper(mvwinch(mw, y, x)))
+			    if ((mon = find_mons(y, x)) != NULL)
+			    {
+				struct thing *th;
+
+				th = (struct thing *) ldata(mon);
+				th->t_flags &= ~ISRUN;
+				th->t_flags |= ISHELD;
+			    }
+	    }
+	when S_SLEEP:
+	    /*
+	     * Scroll which makes you fall asleep
+	     */
+	    s_know[S_SLEEP] = TRUE;
+	    msg("You fall asleep.");
+	    no_command += 4 + rnd(SLEEPTIME);
+	when S_CREATE:
+	    /*
+	     * Create a monster
+	     * First look in a circle around him, next try his room
+	     * otherwise give up
+	     */
+	    {
+		int x, y;
+		int appear = 0;
+		coord mp;
+
+		/*
+		 * Search for an open place
+		 */
+		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
+			 */
+			if (step_ok(winat(y, x)))
+			{
+			    if (rnd(++appear) == 0)
+			    {
+				mp.y = y;
+				mp.x = x;
+			    }
+			}
+		    }
+		if (appear)
+		{
+		    titem = new_item(sizeof (struct thing));
+		    new_monster(titem, randmonster(FALSE), &mp);
+		}
+		else
+		    msg("You hear a faint cry of anguish in the distance.");
+	    }
+	when S_IDENT:
+	    /*
+	     * Identify, let the rogue figure something out
+	     */
+	    msg("This scroll is an identify scroll");
+	    s_know[S_IDENT] = TRUE;
+	    whatis();
+	when S_MAP:
+	    /*
+	     * Scroll of magic mapping.
+	     */
+	    s_know[S_MAP] = TRUE;
+	    msg("Oh, now this scroll has a map on it.");
+	    overwrite(stdscr, hw);
+	    /*
+	     * Take all the things we want to keep hidden out of the window
+	     */
+	    for (i = 0; i < LINES; 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;
+
+				it = (struct thing *) ldata(find_mons(i, j));
+				if ((it != NULL) && (it->t_oldch == ' '))
+				    it->t_oldch = nch;
+			    }
+			    break;
+			default:
+			    nch = ' ';
+		    }
+		    if (nch != ch)
+			waddch(hw, nch);
+		}
+	    /*
+	     * Copy in what he has discovered
+	     */
+	    overlay(cw, hw);
+	    /*
+	     * And set up for display
+	     */
+	    overwrite(hw, cw);
+	when S_GFIND:
+	    /*
+	     * Potion of gold detection
+	     */
+	    {
+		int gtotal = 0;
+
+		wclear(hw);
+		for (i = 0; i < MAXROOMS; i++)
+		{
+		    gtotal += rooms[i].r_goldval;
+		    if (rooms[i].r_goldval != 0 &&
+			mvwinch(stdscr, rooms[i].r_gold.y, rooms[i].r_gold.x)
+			== GOLD)
+			mvwaddch(hw,rooms[i].r_gold.y,rooms[i].r_gold.x,GOLD);
+		}
+		if (gtotal)
+		{
+		    s_know[S_GFIND] = TRUE;
+		    show_win(hw,
+			"You begin to feel greedy and you sense gold.--More--");
+		}
+		else msg("You begin to feel a pull downward");
+	    }
+	when S_TELEP:
+	    /*
+	     * Scroll of teleportation:
+	     * Make him dissapear and reappear
+	     */
+	    {
+		int rm;
+		struct room *cur_room;
+
+		cur_room = roomin(&hero);
+		rm = teleport();
+		if (cur_room != &rooms[rm])
+		    s_know[S_TELEP] = TRUE;
+	    }
+	when S_ENCH:
+	    if (cur_weapon == NULL)
+		msg("You feel a strange sense of loss.");
+	    else
+	    {
+		cur_weapon->o_flags &= ~ISCURSED;
+		if (rnd(100) > 50)
+		    cur_weapon->o_hplus++;
+		else
+		    cur_weapon->o_dplus++;
+		msg("Your %s glows blue for a moment.", w_names[cur_weapon->o_which]);
+	    }
+	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 (cur_armor != NULL)
+		cur_armor->o_flags &= ~ISCURSED;
+	    if (cur_weapon != NULL)
+		cur_weapon->o_flags &= ~ISCURSED;
+	    if (cur_ring[LEFT] != NULL)
+		cur_ring[LEFT]->o_flags &= ~ISCURSED;
+	    if (cur_ring[RIGHT] != NULL)
+		cur_ring[RIGHT]->o_flags &= ~ISCURSED;
+	    msg("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_NOP:
+	    msg("This scroll seems to be blank.");
+	when S_GENOCIDE:
+	    msg("You have been granted the boon of genocide");
+	    genocide();
+	    s_know[S_GENOCIDE] = TRUE;
+	otherwise:
+	    msg("What a puzzling scroll!");
+	    return;
+    }
+    look(TRUE);	/* put the result of the scroll on the screen */
+    status();
+    if (s_know[obj->o_which] && s_guess[obj->o_which])
+    {
+	free(s_guess[obj->o_which]);
+	s_guess[obj->o_which] = NULL;
+    }
+    else if (!s_know[obj->o_which] && askme && s_guess[obj->o_which] == NULL)
+    {
+	msg(terse ? "Call it: " : "What do you want to call it? ");
+	if (get_str(buf, cw) == NORM)
+	{
+	    s_guess[obj->o_which] = malloc((unsigned int) strlen(buf) + 1);
+	    if (s_guess[obj->o_which] != NULL)
+		strcpy(s_guess[obj->o_which], buf);
+	}
+    }
+    /*
+     * Get rid of the thing
+     */
+    inpack--;
+    if (obj->o_count > 1)
+	obj->o_count--;
+    else
+    {
+	detach(pack, item);
+        discard(item);
+    }
+}