comparison urogue/scrolls.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children e52a8a7ad4c5
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 scrolls.c - Functions for dealing with scrolls
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <ctype.h>
22 #include "rogue.h"
23
24 /*
25 read_scroll - read a scroll (or effect a scroll-like spell)
26 reader: who does it
27 which: which S_SCROLL (-1 means ask from pack)
28 flags: ISBLESSED, ISCURSED
29 */
30
31 void
32 read_scroll(struct thing *reader, int which, int flags)
33 {
34 struct object *obj;
35 struct linked_list *item, *nitem;
36 int i, j, charm_power;
37 char ch, nch;
38 int blessed = flags & ISBLESSED;
39 int cursed = flags & ISCURSED;
40 int is_scroll = (which < 0 ? TRUE : FALSE);
41 char buf[2 * LINELEN];
42
43 if (reader != &player)
44 {
45 monread(reader, which, flags);
46 return;
47 }
48
49 if (is_scroll) /* A regular scroll */
50 {
51 if ((item = get_item("read", SCROLL)) == NULL)
52 return;
53
54 obj = OBJPTR(item);
55
56 if (obj->o_type != SCROLL)
57 {
58 msg("It says 'Made in Yugoslavia'!");
59 return;
60 }
61
62 if (on(player, ISBLIND))
63 {
64 msg("You can't see to read anything.");
65 return;
66 }
67
68 /* Calculate its effect */
69
70 cursed = obj->o_flags & ISCURSED;
71 blessed = obj->o_flags & ISBLESSED;
72 flags = obj->o_flags;
73 which = obj->o_which;
74
75 /* remove it from the pack */
76
77 rem_pack(obj);
78 discard(item);
79 updpack();
80 }
81
82 switch (which)
83 {
84 case S_CONFUSE: /* Touch causes monster confusion. */
85 if (cursed)
86 quaff(reader, P_CLEAR, ISCURSED);
87 else
88 {
89 msg("Your hands begin to glow red.");
90 turn_on(player, CANHUH);
91 /* if blessed... */
92 }
93 break;
94
95 case S_CURING: /* A cure disease spell */
96 if (on(player, HASINFEST) || on(player, HASDISEASE))
97 {
98 if (!cursed && on(player, HASDISEASE))
99 {
100 extinguish_fuse(FUSE_CURE_DISEASE);
101 cure_disease(NULL);
102 }
103
104 if (on(player, HASINFEST))
105 {
106 msg("You begin to feel yourself improving again.");
107 turn_off(player, HASINFEST);
108 infest_dam = 0;
109 }
110
111 if (is_scroll)
112 know_items[TYP_SCROLL][S_CURING] = TRUE;
113 }
114 else
115 nothing_message(flags);
116 break;
117
118 case S_LIGHT:
119 if (blue_light(flags) && is_scroll)
120 know_items[TYP_SCROLL][S_LIGHT] = TRUE;
121 break;
122
123 case S_HOLD:
124 if (cursed)
125 {
126 /*
127 * This scroll aggravates all the monsters on the
128 * current level and sets them running towards the
129 * hero
130 */
131 aggravate();
132 hearmsg("You hear a high pitched humming noise.");
133 }
134 else if (blessed) /* Hold all monsters on level */
135 {
136 if (mlist == NULL)
137 nothing_message(flags);
138 else
139 {
140 struct linked_list *mon;
141 struct thing *th;
142
143 for (mon = mlist; mon != NULL; mon = next(mon))
144 {
145 th = THINGPTR(mon);
146 turn_off(*th, ISRUN);
147 turn_on(*th, ISHELD);
148 }
149 msg("A sudden peace comes over the dungeon.");
150 }
151 }
152 else
153 {
154 /*
155 * Hold monster scroll. Stop all monsters within two
156 * spaces from chasing after the hero.
157 */
158 int x, y;
159 struct linked_list *mon;
160 int gotone = FALSE;
161
162 for (x = hero.x - 2; x <= hero.x + 2; x++)
163 {
164 for (y = hero.y - 2; y <= hero.y + 2; y++)
165 {
166 if (y > 0 && x > 0 && isalpha(mvwinch(mw, y, x)))
167 {
168 if ((mon = find_mons(y, x)) != NULL)
169 {
170 struct thing *th;
171
172 gotone = TRUE;
173 th = THINGPTR(mon);
174 turn_off(*th, ISRUN);
175 turn_on(*th, ISHELD);
176 }
177 }
178 }
179 }
180
181 if (gotone)
182 msg("A sudden peace surrounds you.");
183 else
184 nothing_message(flags);
185 }
186 break;
187
188 case S_SLEEP:
189
190 /* if cursed, you fall asleep */
191
192 if (cursed)
193 {
194 if (is_wearing(R_ALERT))
195 msg("You feel drowsy for a moment.");
196 else
197 {
198 msg("You fall asleep.");
199 no_command += 4 + rnd(SLEEPTIME);
200 }
201 }
202 else
203 {
204 /*
205 * sleep monster scroll. puts all monsters within 2
206 * spaces asleep
207 */
208 int x, y;
209 struct linked_list *mon;
210 int gotone = FALSE;
211
212 for (x = hero.x - 2; x <= hero.x + 2; x++)
213 {
214 for (y = hero.y - 2; y <= hero.y + 2; y++)
215 {
216 if (y > 0 && x > 0 && isalpha(mvwinch(mw, y, x)))
217 {
218 if ((mon = find_mons(y, x)) != NULL)
219 {
220 struct thing *th;
221 th = THINGPTR(mon);
222
223 if (on(*th, ISUNDEAD))
224 continue;
225
226 gotone = TRUE;
227 th->t_no_move += SLEEPTIME;
228 }
229 }
230 }
231 }
232
233 if (gotone)
234 msg("The monster(s) around you seem to have fallen asleep.");
235 else
236 nothing_message(flags);
237 }
238 break;
239
240 case S_CREATE:
241 {
242 /*
243 * Create a monster. First look in a circle around
244 * him, next try his room otherwise give up
245 */
246
247 struct thing *tp;
248 struct linked_list *ip;
249
250 if (blessed)
251 summon_monster((short) 0, NOFAMILIAR, MESSAGE);
252 else if (cursed)
253 {
254 i = rnd(4) + 3;
255 for (j = 0; j < i; j++)
256 {
257 if ((ip = creat_mons(&player, (short) 0, MESSAGE)) != NULL)
258 {
259 tp = THINGPTR(ip);
260 turn_off(*tp, ISFRIENDLY);
261 }
262 }
263 }
264 else if ((ip = creat_mons(&player, (short) 0, MESSAGE)) != NULL)
265 {
266 tp = THINGPTR(ip);
267 turn_off(*tp, ISFRIENDLY);
268 }
269 }
270 break;
271
272 case S_IDENTIFY:
273 if (cursed)
274 msg("You identify this scroll as an identify scroll");
275 else if (blessed) /* identify everything in the pack */
276 {
277 msg("You feel more Knowledgeable!");
278 idenpack();
279 }
280 else
281 {
282 /* Identify, let the rogue figure something out */
283
284 if (is_scroll && know_items[TYP_SCROLL][S_IDENTIFY] != TRUE)
285 {
286 msg("This scroll is an identify scroll.");
287 know_items[TYP_SCROLL][S_IDENTIFY] = TRUE;
288 }
289 whatis(NULL);
290 }
291 break;
292
293 case S_MAP:
294
295 /* Scroll of magic mapping. */
296
297 if (cursed)
298 {
299 msg("Your mind goes blank for a moment.");
300 wclear(cw);
301 light(&hero);
302 status(TRUE);
303 break;
304 }
305
306 if (is_scroll && know_items[TYP_SCROLL][S_MAP] != TRUE)
307 {
308 msg("Oh! This scroll has a map on it!!");
309 know_items[TYP_SCROLL][S_MAP] = TRUE;
310 }
311
312 if (blessed)
313 turn_on(player, BLESSMAP);
314
315 overwrite(stdscr, hw);
316
317 /* Take all the things we want to keep hidden out of the window */
318
319 for (i = 0; i < LINES; i++)
320 for (j = 0; j < COLS; j++)
321 {
322 switch (nch = ch = CCHAR(mvwinch(hw, i, j)))
323 {
324 case SECRETDOOR:
325 nch = DOOR;
326 mvaddch(i, j, nch);
327 break;
328
329 case '-':
330 case '|':
331 case DOOR:
332 case PASSAGE:
333 case ' ':
334 case STAIRS:
335 if (mvwinch(mw, i, j) != ' ')
336 {
337 struct thing *it;
338 struct linked_list *lit;
339
340 lit = find_mons(i, j);
341
342 if (lit) {
343 it = THINGPTR(lit);
344
345 if (it && it->t_oldch == ' ')
346 it->t_oldch = nch;
347 }
348 }
349 break;
350
351 default:
352 if (!blessed || !isatrap(ch))
353 nch = ' ';
354 else
355 {
356 struct trap *tp;
357 struct room *rp;
358
359 tp = trap_at(i, j);
360 rp = roomin(hero);
361
362 if (tp->tr_type == FIRETRAP && rp != NULL)
363 {
364 rp->r_flags &= ~ISDARK;
365 light(&hero);