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); |
