Mercurial > hg > early-roguelike
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); + } +}