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