rogue

Ken Arnold's Rogue
git clone https://git.woozle.org/neale/rogue.git

Neale Pickett  ·  2011-10-13

data.c

  1/*
  2 * Read a scroll and let it happen
  3 *
  4 * @(#)data.c	4.44 (Berkeley) 02/05/99
  5 */
  6
  7#include <curses.h>
  8#include <ctype.h>
  9#include "netprot.h"
 10
 11/*
 12 * read_scroll:
 13 *	Read a scroll from the pack and do the appropriate thing
 14 */
 15void
 16read_scroll(void)
 17{
 18    THING *obj;
 19    PLACE *pp;
 20    int y, x;
 21    char ch;
 22    int i;
 23    bool discardit = FALSE;
 24    struct room *cur_room;
 25    THING *orig_obj;
 26    static coord mp;
 27
 28    obj = get_item("read", SCROLL);
 29    if (obj == NULL)
 30	return;
 31    if (obj->o_type != SCROLL)
 32    {
 33	if (!Terse)
 34	    msg("there is nothing on it to read");
 35	else
 36	    msg("nothing to read");
 37	return;
 38    }
 39    /*
 40     * Calculate the effect it has on the poor guy.
 41     */
 42    if (obj == Cur_weapon)
 43	Cur_weapon = NULL;
 44    /*
 45     * Get rid of the thing
 46     */
 47    discardit = (obj->o_count == 1);
 48    leave_pack(obj, FALSE, FALSE);
 49    orig_obj = obj;
 50
 51    switch (obj->o_which)
 52    {
 53	when S_CONFUSE:
 54	    /*
 55	     * Scroll of monster confusion.  Give him that power.
 56	     */
 57	    Player.t_flags |= CANHUH;
 58	    msg("your hands begin to glow %s", pick_color("red"));
 59	when S_ARMOR:
 60	    if (Cur_armor != NULL)
 61	    {
 62		Cur_armor->o_arm--;
 63		Cur_armor->o_flags &= ~ISCURSED;
 64		msg("your armor glows %s for a moment", pick_color("silver"));
 65	    }
 66	when S_HOLD:
 67	    /*
 68	     * Hold monster scroll.  Stop all monsters within two spaces
 69	     * from chasing after the hero.
 70	     */
 71
 72	    ch = 0;
 73	    for (x = Hero.x - 2; x <= Hero.x + 2; x++)
 74		if (x >= 0 && x < NUMCOLS)
 75		    for (y = Hero.y - 2; y <= Hero.y + 2; y++)
 76			if (y >= 0 && y <= NUMLINES - 1)
 77			    if ((obj = moat(y, x)) != NULL && on(*obj, ISRUN))
 78			    {
 79				obj->t_flags &= ~ISRUN;
 80				obj->t_flags |= ISHELD;
 81				ch++;
 82			    }
 83	    if (ch)
 84	    {
 85		addmsg("the monster");
 86		if (ch > 1)
 87		    addmsg("s around you");
 88		addmsg(" freeze");
 89		if (ch == 1)
 90		    addmsg("s");
 91		endmsg();
 92		Scr_info[S_HOLD].oi_know = TRUE;
 93	    }
 94	    else
 95		msg("you feel a strange sense of loss");
 96	when S_SLEEP:
 97	    /*
 98	     * Scroll which makes you fall asleep
 99	     */
100	    Scr_info[S_SLEEP].oi_know = TRUE;
101	    No_command += rnd(SLEEPTIME) + 4;
102	    Player.t_flags &= ~ISRUN;
103	    msg("you fall asleep");
104	when S_CREATE:
105	    /*
106	     * Create a monster:
107	     * First look in a circle around him, next try his room
108	     * otherwise give up
109	     */
110	    i = 0;
111	    for (y = Hero.y - 1; y <= Hero.y + 1; y++)
112		for (x = Hero.x - 1; x <= Hero.x + 1; x++)
113		    /*
114		     * Don't put a monster in top of the player.
115		     */
116		    if (y == Hero.y && x == Hero.x)
117			continue;
118		    /*
119		     * Or anything else nasty
120		     */
121		    else if (step_ok(ch = winat(y, x)))
122			if (ch == SCROLL
123			    && find_obj(y, x)->o_which == S_SCARE)
124				continue;
125			else if (rnd(++i) == 0)
126			{
127			    mp.y = y;
128			    mp.x = x;
129			}
130	    if (i == 0)
131		msg("you hear a faint cry of anguish in the distance");
132	    else
133	    {
134		obj = new_item();
135		new_monster(obj, randmonster(FALSE), &mp);
136	    }
137	when S_ID_POTION:
138	case S_ID_SCROLL:
139	case S_ID_WEAPON:
140	case S_ID_ARMOR:
141	case S_ID_R_OR_S:
142	{
143	    static char id_type[S_ID_R_OR_S + 1] =
144		{ 0, 0, 0, 0, 0, POTION, SCROLL, WEAPON, ARMOR, R_OR_S };
145	    /*
146	     * Identify, let him figure something out
147	     */
148	    Scr_info[obj->o_which].oi_know = TRUE;
149	    msg("this scroll is an %s scroll", Scr_info[obj->o_which].oi_name);
150	    whatis(TRUE, id_type[obj->o_which]);
151	}
152	when S_MAP:
153	    /*
154	     * Scroll of magic mapping.
155	     */
156	    Scr_info[S_MAP].oi_know = TRUE;
157	    msg("oh, now this scroll has a map on it");
158	    /*
159	     * Take all the things we want to keep hidden out of the window
160	     */
161	    for (y = 1; y < NUMLINES - 1; y++)
162		for (x = 0; x < NUMCOLS; x++)
163		{
164		    pp = INDEX(y, x);
165		    switch (ch = pp->p_ch)
166		    {
167			case DOOR:
168			case STAIRS:
169			    break;
170
171			case '-':
172			case '|':
173			    if (!(pp->p_flags & F_REAL))
174			    {
175				ch = pp->p_ch = DOOR;
176				pp->p_flags |= F_REAL;
177			    }
178			    break;
179
180			case ' ':
181			    if (pp->p_flags & F_REAL)
182				goto def;
183			    pp->p_flags |= F_REAL;
184			    ch = pp->p_ch = PASSAGE;
185			    /* FALLTHROUGH */
186
187			case PASSAGE:
188pass:
189			    if (!(pp->p_flags & F_REAL))
190				pp->p_ch = PASSAGE;
191			    pp->p_flags |= (F_SEEN|F_REAL);
192			    ch = PASSAGE;
193			    break;
194
195			case FLOOR:
196			    if (pp->p_flags & F_REAL)
197				ch = ' ';
198			    else
199			    {
200				ch = TRAP;
201				pp->p_ch = TRAP;
202				pp->p_flags |= (F_SEEN|F_REAL);
203			    }
204			    break;
205
206			default:
207def:
208			    if (pp->p_flags & F_PASS)
209				goto pass;
210			    ch = ' ';
211			    break;
212		    }
213		    if (ch != ' ')
214		    {
215			if ((obj = pp->p_monst) != NULL)
216			    obj->t_oldch = ch;
217			if (obj == NULL || !on(Player, SEEMONST))
218			    mvaddch(y, x, ch);
219		    }
220		}
221	when S_FDET:
222	    /*
223	     * Potion of gold detection
224	     */
225	    ch = FALSE;
226	    wclear(Hw);
227	    for (obj = Lvl_obj; obj != NULL; obj = next(obj))
228		if (obj->o_type == FOOD)
229		{
230		    ch = TRUE;
231		    wmove(Hw, obj->o_pos.y, obj->o_pos.x);
232		    waddch(Hw, FOOD);
233		}
234	    if (ch)
235	    {
236		Scr_info[S_FDET].oi_know = TRUE;
237		show_win("Your nose tingles and you smell food.--More--");
238	    }
239	    else
240		msg("your nose tingles");
241	when S_TELEP:
242	    /*
243	     * Scroll of teleportation:
244	     * Make him dissapear and reappear
245	     */
246	    {
247		cur_room = Proom;
248		teleport();
249		if (cur_room != Proom)
250		    Scr_info[S_TELEP].oi_know = TRUE;
251	    }
252	when S_ENCH:
253	    if (Cur_weapon == NULL || Cur_weapon->o_type != WEAPON)
254		msg("you feel a strange sense of loss");
255	    else
256	    {
257		Cur_weapon->o_flags &= ~ISCURSED;
258		if (rnd(2) == 0)
259		    Cur_weapon->o_hplus++;
260		else
261		    Cur_weapon->o_dplus++;
262		msg("your %s glows %s for a moment",
263		    Weap_info[Cur_weapon->o_which].oi_name, pick_color("blue"));
264	    }
265	when S_SCARE:
266	    /*
267	     * Reading it is a mistake and produces laughter at her
268	     * poor boo boo.
269	     */
270	    msg("you hear maniacal laughter in the distance");
271	when S_REMOVE:
272	    uncurse(Cur_armor);
273	    uncurse(Cur_weapon);
274	    uncurse(Cur_ring[LEFT]);
275	    uncurse(Cur_ring[RIGHT]);
276	    msg(choose_str("you feel in touch with the Universal Onenes",
277			   "you feel as if somebody is watching over you"));
278	when S_AGGR:
279	    /*
280	     * This scroll aggravates all the monsters on the current
281	     * level and sets them running towards the hero
282	     */
283	    aggravate();
284	    msg("you hear a high pitched humming noise");
285	when S_PROTECT:
286	    if (Cur_armor != NULL)
287	    {
288		Cur_armor->o_flags |= ISPROT;
289		msg("your armor is covered by a shimmering %s shield",
290		    pick_color("gold"));
291	    }
292	    else
293		msg("you feel a strange sense of loss");
294#ifdef MASTER
295	otherwise:
296	    msg("what a puzzling scroll!");
297	    return;
298#endif
299    }
300    obj = orig_obj;
301    look(TRUE);	/* put the result of the scroll on the screen */
302    status();
303
304    call_it(&Scr_info[obj->o_which]);
305
306    if (discardit)
307	discard(obj);
308}
309
310/*
311 * uncurse:
312 *	Uncurse an item
313 */
314void
315uncurse(THING *obj)
316{
317    if (obj != NULL)
318	obj->o_flags &= ~ISCURSED;
319}