Mercurial > hg > early-roguelike
comparison arogue7/scrolls.c @ 125:adfa37e67084
Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
| author | John "Elwin" Edwards |
|---|---|
| date | Fri, 08 May 2015 15:24:40 -0400 |
| parents | |
| children | b786053d2f37 |
comparison
equal
deleted
inserted
replaced
| 124:d10fc4a065ac | 125:adfa37e67084 |
|---|---|
| 1 /* | |
| 2 * scrolls.c - Functions for dealing with scrolls | |
| 3 * | |
| 4 * Advanced Rogue | |
| 5 * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T | |
| 6 * All rights reserved. | |
| 7 * | |
| 8 * Based on "Rogue: Exploring the Dungeons of Doom" | |
| 9 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
| 10 * All rights reserved. | |
| 11 * | |
| 12 * See the file LICENSE.TXT for full copyright and licensing information. | |
| 13 */ | |
| 14 | |
| 15 /* | |
| 16 * Read a scroll and let it happen | |
| 17 * | |
| 18 */ | |
| 19 | |
| 20 #include "curses.h" | |
| 21 #include <ctype.h> | |
| 22 #include "rogue.h" | |
| 23 | |
| 24 /* | |
| 25 * let the hero get rid of some type of monster (but not a UNIQUE!) | |
| 26 */ | |
| 27 genocide() | |
| 28 { | |
| 29 register struct linked_list *ip; | |
| 30 register struct thing *mp; | |
| 31 register struct linked_list *nip; | |
| 32 register int num_monst = NUMMONST-NUMUNIQUE-1, /* cannot genocide uniques */ | |
| 33 pres_monst=1, | |
| 34 num_lines=2*(lines-3); | |
| 35 register int which_monst; | |
| 36 | |
| 37 which_monst = makemonster(FALSE, "Genocide", "wipe out"); | |
| 38 if (which_monst <= 0) { | |
| 39 msg(""); | |
| 40 return; | |
| 41 } | |
| 42 | |
| 43 /* Remove this monster from the present level */ | |
| 44 for (ip = mlist; ip; ip = nip) { | |
| 45 mp = THINGPTR(ip); | |
| 46 nip = next(ip); | |
| 47 if (mp->t_index == which_monst) { | |
| 48 killed(ip, FALSE, FALSE, TRUE); | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 /* Remove from available monsters */ | |
| 53 monsters[which_monst].m_normal = FALSE; | |
| 54 monsters[which_monst].m_wander = FALSE; | |
| 55 mpos = 0; | |
| 56 msg("You have wiped out the %s.", monsters[which_monst].m_name); | |
| 57 } | |
| 58 | |
| 59 read_scroll(which, flag, is_scroll) | |
| 60 register int which; | |
| 61 int flag; | |
| 62 bool is_scroll; | |
| 63 { | |
| 64 register struct object *obj, *nobj; | |
| 65 register struct linked_list *item, *nitem; | |
| 66 register int i,j; | |
| 67 register char ch, nch; | |
| 68 bool cursed, blessed; | |
| 69 | |
| 70 blessed = FALSE; | |
| 71 cursed = FALSE; | |
| 72 item = NULL; | |
| 73 | |
| 74 if (which < 0) { | |
| 75 if (on(player, ISBLIND)) { | |
| 76 msg("You can't see to read anything"); | |
| 77 return; | |
| 78 } | |
| 79 if (on(player, ISINWALL)) { | |
| 80 msg("You can't see the scroll while inside rock!"); | |
| 81 return; | |
| 82 } | |
| 83 | |
| 84 /* This is a scroll or book. */ | |
| 85 if (player.t_action != C_READ) { | |
| 86 int units; | |
| 87 | |
| 88 item = get_item(pack, "read", READABLE, FALSE, FALSE); | |
| 89 | |
| 90 /* | |
| 91 * Make certain that it is somethings that we want to read | |
| 92 */ | |
| 93 if (item == NULL) | |
| 94 return; | |
| 95 | |
| 96 /* How long does it take to read? */ | |
| 97 units = usage_time(item); | |
| 98 if (units < 0) return; | |
| 99 | |
| 100 player.t_using = item; /* Remember what it is */ | |
| 101 player.t_no_move = units * movement(&player); | |
| 102 if ((OBJPTR(item))->o_type == SCROLL) player.t_action = C_READ; | |
| 103 else player.t_action = C_USE; | |
| 104 return; | |
| 105 } | |
| 106 | |
| 107 /* We have waited our time, let's quaff the potion */ | |
| 108 item = player.t_using; | |
| 109 player.t_using = NULL; | |
| 110 player.t_action = A_NIL; | |
| 111 | |
| 112 obj = OBJPTR(item); | |
| 113 /* remove it from the pack */ | |
| 114 inpack--; | |
| 115 detach(pack, item); | |
| 116 | |
| 117 msg("As you read the scroll, it vanishes."); | |
| 118 cursed = (obj->o_flags & ISCURSED) != 0; | |
| 119 blessed = (obj->o_flags & ISBLESSED) != 0; | |
| 120 | |
| 121 which = obj->o_which; | |
| 122 } | |
| 123 else { | |
| 124 cursed = flag & ISCURSED; | |
| 125 blessed = flag & ISBLESSED; | |
| 126 } | |
| 127 | |
| 128 | |
| 129 switch (which) { | |
| 130 case S_CONFUSE: | |
| 131 /* | |
| 132 * Scroll of monster confusion. Give him that power. | |
| 133 */ | |
| 134 msg("Your hands begin to glow red"); | |
| 135 turn_on(player, CANHUH); | |
| 136 when S_CURING: | |
| 137 /* | |
| 138 * A cure disease spell | |
| 139 */ | |
| 140 if (on(player, HASINFEST) || | |
| 141 on(player, HASDISEASE)|| | |
| 142 on(player, DOROT)) { | |
| 143 if (on(player, HASDISEASE)) { | |
| 144 extinguish(cure_disease); | |
| 145 cure_disease(); | |
| 146 } | |
| 147 if (on(player, HASINFEST)) { | |
| 148 msg(terse ? "You feel yourself improving." | |
| 149 : "You begin to feel yourself improving again."); | |
| 150 turn_off(player, HASINFEST); | |
| 151 infest_dam = 0; | |
| 152 } | |
| 153 if (on(player, DOROT)) { | |
| 154 msg("You feel your skin returning to normal."); | |
| 155 turn_off(player, DOROT); | |
| 156 } | |
| 157 } | |
| 158 else { | |
| 159 msg(nothing); | |
| 160 break; | |
| 161 } | |
| 162 if (is_scroll) s_know[S_CURING] = TRUE; | |
| 163 when S_LIGHT: | |
| 164 if (blue_light(blessed, cursed) && is_scroll) | |
| 165 s_know[S_LIGHT] = TRUE; | |
| 166 when S_HOLD: | |
| 167 if (cursed) { | |
| 168 /* | |
| 169 * This scroll aggravates all the monsters on the current | |
| 170 * level and sets them running towards the hero | |
| 171 */ | |
| 172 aggravate(TRUE, TRUE); | |
| 173 msg("You hear a high pitched humming noise."); | |
| 174 } | |
| 175 else if (blessed) { /* Hold all monsters on level */ | |
| 176 if (mlist == NULL) msg(nothing); | |
| 177 else { | |
| 178 register struct linked_list *mon; | |
| 179 register struct thing *th; | |
| 180 | |
| 181 for (mon = mlist; mon != NULL; mon = next(mon)) { | |
| 182 th = THINGPTR(mon); | |
| 183 turn_off(*th, ISRUN); | |
| 184 turn_on(*th, ISHELD); | |
| 185 } | |
| 186 msg("A sudden peace comes over the dungeon."); | |
| 187 } | |
| 188 } | |
| 189 else { | |
| 190 /* | |
| 191 * Hold monster scroll. Stop all monsters within two spaces | |
| 192 * from chasing after the hero. | |
| 193 */ | |
| 194 register int x,y; | |
| 195 register struct linked_list *mon; | |
| 196 bool gotone=FALSE; | |
| 197 | |
| 198 for (x = hero.x-2; x <= hero.x+2; x++) { | |
| 199 for (y = hero.y-2; y <= hero.y+2; y++) { | |
| 200 if (y < 1 || x < 0 || y > lines - 3 || x > cols - 1) | |
| 201 continue; | |
| 202 if (isalpha(mvwinch(mw, y, x))) { | |
| 203 if ((mon = find_mons(y, x)) != NULL) { | |
| 204 register struct thing *th; | |
| 205 | |
| 206 gotone = TRUE; | |
| 207 th = THINGPTR(mon); | |
| 208 turn_off(*th, ISRUN); | |
| 209 turn_on(*th, ISHELD); | |
| 210 } | |
| 211 } | |
| 212 } | |
| 213 } | |
| 214 if (gotone) msg("A sudden peace surrounds you."); | |
| 215 else msg(nothing); | |
| 216 } | |
| 217 when S_SLEEP: | |
| 218 /* | |
| 219 * if cursed, you fall asleep | |
| 220 */ | |
| 221 if (is_scroll) s_know[S_SLEEP] = TRUE; | |
| 222 if (cursed) { | |
| 223 if (ISWEARING(R_ALERT)) | |
| 224 msg("You feel drowsy for a moment."); | |
| 225 else { | |
| 226 msg("You fall asleep."); | |
| 227 player.t_no_move += movement(&player)*(4 + rnd(SLEEPTIME)); | |
| 228 player.t_action = A_FREEZE; | |
| 229 } | |
| 230 } | |
| 231 else { | |
| 232 /* | |
| 233 * sleep monster scroll. | |
| 234 * puts all monsters within 2 spaces asleep | |
| 235 */ | |
| 236 register int x,y; | |
| 237 register struct linked_list *mon; | |
| 238 bool gotone=FALSE; | |
| 239 | |
| 240 for (x = hero.x-2; x <= hero.x+2; x++) { | |
| 241 for (y = hero.y-2; y <= hero.y+2; y++) { | |
| 242 if (y < 1 || x < 0 || y > lines - 3 || x > cols - 1) | |
| 243 continue; | |
| 244 if (isalpha(mvwinch(mw, y, x))) { | |
| 245 if ((mon = find_mons(y, x)) != NULL) { | |
| 246 register struct thing *th; | |
| 247 | |
| 248 th = THINGPTR(mon); | |
| 249 if (on(*th, ISUNDEAD)) | |
| 250 continue; | |
| 251 th->t_no_move += movement(th)*(SLEEPTIME+4); | |
| 252 th->t_action = A_FREEZE; | |
| 253 gotone = TRUE; | |
| 254 } | |
| 255 } | |
| 256 } | |
| 257 } | |
| 258 if (gotone) | |
| 259 msg("The monster(s) around you seem to have fallen asleep"); | |
| 260 else | |
| 261 msg(nothing); | |
| 262 } | |
| 263 when S_CREATE: | |
| 264 /* | |
| 265 * Create a monster | |
| 266 * First look in a circle around him, next try his room | |
| 267 * otherwise give up | |
| 268 */ | |
| 269 creat_mons(&player, (short) 0, TRUE); | |
| 270 light(&hero); | |
| 271 when S_IDENT: | |
| 272 /* | |
| 273 * if its blessed then identify everything in the pack | |
| 274 */ | |
| 275 if (blessed) { | |
| 276 msg("You feel more Knowledgeable!"); | |
| 277 idenpack(); | |
| 278 } | |
| 279 else { | |
| 280 /* | |
| 281 * Identify, let the rogue figure something out | |
| 282 */ | |
| 283 if (is_scroll && s_know[S_IDENT] != TRUE) { | |
| 284 msg("This scroll is an identify scroll"); | |
| 285 } | |
| 286 whatis(NULL); | |
| 287 } | |
| 288 if (is_scroll) s_know[S_IDENT] = TRUE; | |
| 289 when S_MAP: | |
| 290 /* | |
| 291 * Scroll of magic mapping. | |
| 292 */ | |
| 293 if (is_scroll && s_know[S_MAP] != TRUE) { | |
| 294 msg("Oh, now this scroll has a map on it."); | |
| 295 s_know[S_MAP] = TRUE; | |
| 296 } | |
| 297 overwrite(stdscr, hw); | |
| 298 /* | |
| 299 * Take all the things we want to keep hidden out of the window | |
| 300 */ | |
| 301 for (i = 1; i < lines-2; i++) | |
| 302 for (j = 0; j < cols; j++) | |
| 303 { | |
| 304 switch (nch = ch = CCHAR( mvwinch(hw, i, j) )) | |
| 305 { | |
| 306 case SECRETDOOR: | |
| 307 nch = secretdoor (i, j); | |
| 308 break; | |
| 309 case '-': | |
| 310 case '|': | |
| 311 case DOOR: | |
| 312 case PASSAGE: | |
| 313 case ' ': | |
| 314 case STAIRS: | |
| 315 if (mvwinch(mw, i, j) != ' ') | |
| 316 { | |
| 317 register struct thing *it; | |
| 318 | |
| 319 it = THINGPTR(find_mons(i, j)); | |
| 320 if (it && it->t_oldch == ' ') | |
| 321 it->t_oldch = nch; | |
| 322 } | |
| 323 break; | |
| 324 default: | |
| 325 nch = ' '; | |
| 326 } | |
| 327 if (nch != ch) | |
| 328 waddch(hw, nch); | |
| 329 } | |
| 330 /* | |
| 331 * Copy in what he has discovered | |
| 332 */ | |
| 333 overlay(cw, hw); | |
| 334 /* | |
| 335 * And set up for display | |
| 336 */ | |
| 337 overwrite(hw, cw); | |
| 338 when S_GFIND: | |
| 339 /* | |
| 340 * Scroll of gold detection | |
| 341 */ | |
| 342 { | |
| 343 int gtotal = 0; | |
| 344 | |
| 345 wclear(hw); | |
| 346 for (nitem = lvl_obj; nitem != NULL; nitem = next(nitem)) { | |
| 347 nobj = OBJPTR(nitem); | |
| 348 if (nobj->o_type == GOLD) { | |
| 349 gtotal += nobj->o_count; | |
| 350 mvwaddch(hw, nobj->o_pos.y, nobj->o_pos.x, GOLD); | |
| 351 } | |
| 352 } | |
| 353 for (nitem = mlist; nitem != NULL; nitem = next(nitem)) { | |
| 354 register struct linked_list *gitem; | |
| 355 register struct thing *th; | |
| 356 | |
| 357 th = THINGPTR(nitem); | |
| 358 if (on(*th, NODETECT)) continue; | |
| 359 for(gitem = th->t_pack; gitem != NULL; gitem = next(gitem)){ | |
| 360 nobj = OBJPTR(gitem); | |
| 361 if (nobj->o_type == GOLD) { | |
| 362 gtotal += nobj->o_count; | |
| 363 mvwaddch(hw, th->t_pos.y, th->t_pos.x, GOLD); | |
| 364 } | |
| 365 } | |
| 366 } | |
| 367 if (gtotal) { | |
| 368 if (is_scroll) s_know[S_GFIND] = TRUE; | |
| 369 msg("You begin to feel greedy and you sense gold."); | |
| 370 waddstr(msgw, morestr); | |
| 371 clearok(msgw, FALSE); | |
| 372 draw(msgw); | |
| 373 overlay(hw, cw); | |
| 374 draw(cw); | |
| 375 wait_for(' '); | |
| 376 msg(""); | |
| 377 break; | |
| 378 } | |
