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