Mercurial > hg > early-roguelike
comparison xrogue/scrolls.c @ 133:e6179860cb76
Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
| author | John "Elwin" Edwards |
|---|---|
| date | Tue, 21 Apr 2015 08:55:20 -0400 |
| parents | |
| children | ce0cf824c192 |
comparison
equal
deleted
inserted
replaced
| 124:d10fc4a065ac | 133:e6179860cb76 |
|---|---|
| 1 /* | |
| 2 scrolls.c - Functions for dealing with scrolls | |
| 3 | |
| 4 XRogue: Expeditions into the Dungeons of Doom | |
| 5 Copyright (C) 1991 Robert Pietkivitch | |
| 6 All rights reserved. | |
| 7 | |
| 8 Based on "Advanced Rogue" | |
| 9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T | |
| 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 <curses.h> | |
| 20 #include <ctype.h> | |
| 21 #include "rogue.h" | |
| 22 | |
| 23 /* | |
| 24 * let the hero get rid of some type of monster | |
| 25 */ | |
| 26 | |
| 27 genocide() | |
| 28 { | |
| 29 register struct linked_list *ip; | |
| 30 register struct thing *mp; | |
| 31 register struct linked_list *nip; | |
| 32 /* cannot genocide any uniques */ | |
| 33 register int num_monst = NUMMONST-NUMUNIQUE-NUMDINOS; | |
| 34 register int which_monst; | |
| 35 | |
| 36 which_monst = makemonster(FALSE, "wipe out"); | |
| 37 if (which_monst <= 0 || which_monst >= num_monst) { | |
| 38 msg(""); | |
| 39 return; | |
| 40 } | |
| 41 | |
| 42 /* Remove this monster from the present level */ | |
| 43 for (ip = mlist; ip; ip = nip) { | |
| 44 mp = THINGPTR(ip); | |
| 45 nip = next(ip); | |
| 46 if (mp->t_index == which_monst) { | |
| 47 killed(ip, FALSE, FALSE, TRUE); | |
| 48 } | |
| 49 } | |
| 50 | |
| 51 /* Remove from available monsters */ | |
| 52 monsters[which_monst].m_normal = FALSE; | |
| 53 monsters[which_monst].m_wander = FALSE; | |
| 54 mpos = 0; | |
| 55 msg("You have wiped out the %s.", monsters[which_monst].m_name); | |
| 56 } | |
| 57 | |
| 58 read_scroll(which, flag, is_scroll) | |
| 59 register int which; | |
| 60 int flag; | |
| 61 bool is_scroll; | |
| 62 { | |
| 63 register struct object *obj = NULL, *nobj; | |
| 64 register struct linked_list *item, *nitem; | |
| 65 register int i,j; | |
| 66 register unsigned char ch, nch; | |
| 67 bool cursed, blessed; | |
| 68 | |
| 69 blessed = FALSE; | |
| 70 cursed = FALSE; | |
| 71 item = NULL; | |
| 72 | |
| 73 if (which < 0) { | |
| 74 if (on(player, ISBLIND)) { | |
| 75 msg("You can't see to read anything!"); | |
| 76 return; | |
| 77 } | |
| 78 if (on(player, ISINWALL)) { | |
| 79 msg("You can't see the scroll while inside rock!"); | |
| 80 return; | |
| 81 } | |
| 82 | |
| 83 /* This is a scroll or book. */ | |
| 84 if (player.t_action != C_READ) { | |
| 85 int units; | |
| 86 | |
| 87 item = get_item(pack, "read", READABLE, FALSE, FALSE); | |
| 88 | |
| 89 /* | |
| 90 * Make certain that it is somethings that we want to read | |
| 91 */ | |
| 92 if (item == NULL) | |
| 93 return; | |
| 94 | |
| 95 /* How long does it take to read? */ | |
| 96 units = usage_time(item); | |
| 97 if (units < 0) return; | |
| 98 | |
| 99 player.t_using = item; /* Remember what it is */ | |
| 100 player.t_no_move = units * movement(&player); | |
| 101 if ((OBJPTR(item))->o_type == SCROLL) player.t_action = C_READ; | |
| 102 else player.t_action = C_USE; | |
| 103 return; | |
| 104 } | |
| 105 | |
| 106 /* We have waited our time, let's quaff the potion */ | |
| 107 item = player.t_using; | |
| 108 player.t_using = NULL; | |
| 109 player.t_action = A_NIL; | |
| 110 | |
| 111 obj = OBJPTR(item); | |
| 112 /* remove it from the pack */ | |
| 113 inpack--; | |
| 114 detach(pack, item); | |
| 115 | |
| 116 msg("As you read the scroll, it vanishes."); | |
| 117 cursed = obj->o_flags & ISCURSED; | |
| 118 blessed = obj->o_flags & ISBLESSED; | |
| 119 | |
| 120 which = obj->o_which; | |
| 121 } | |
| 122 else { | |
| 123 cursed = flag & ISCURSED; | |
| 124 blessed = flag & ISBLESSED; | |
| 125 } | |
| 126 | |
| 127 switch (which) { | |
| 128 case S_CONFUSE: /* Scroll of monster confusion. Give him that power. */ | |
| 129 { | |
| 130 register char *str; | |
| 131 | |
| 132 switch (rnd(5)) { | |
| 133 case 0: | |
| 134 str = "glow red"; | |
| 135 when 1: | |
| 136 str = "vibrate"; | |
| 137 when 2: | |
| 138 str = "glow blue"; | |
| 139 when 3: | |
| 140 str = "radiate green"; | |
| 141 otherwise: | |
| 142 str = "itch with a strange desire"; | |
| 143 } | |
| 144 msg("Your hands begin to %s. ", str); | |
| 145 turn_on(player, CANHUH); | |
| 146 } | |
| 147 when S_CURING: | |
| 148 /* | |
| 149 * A cure disease spell | |
| 150 */ | |
| 151 if (on(player, HASINFEST) || | |
| 152 on(player, HASDISEASE)|| | |
| 153 on(player, DOROT)) { | |
| 154 if (on(player, HASDISEASE)) { | |
| 155 extinguish(cure_disease); | |
| 156 cure_disease(); | |
| 157 } | |
| 158 if (on(player, HASINFEST)) { | |
| 159 msg(terse ? "You feel yourself improving." | |
| 160 : "You begin to feel yourself improving."); | |
| 161 turn_off(player, HASINFEST); | |
| 162 infest_dam = 0; | |
| 163 } | |
| 164 if (on(player, DOROT)) { | |
| 165 msg("You feel your skin returning to normal."); | |
| 166 turn_off(player, DOROT); | |
| 167 } | |
| 168 } | |
| 169 else { | |
| 170 /* msg(nothing); */ | |
| 171 break; | |
| 172 } | |
| 173 if (is_scroll) s_know[S_CURING] = TRUE; | |
| 174 when S_LIGHT: | |
| 175 if (blue_light(blessed, cursed) && is_scroll) | |
| 176 s_know[S_LIGHT] = TRUE; | |
| 177 when S_HOLD: | |
| 178 if (cursed) { | |
| 179 /* | |
| 180 * This scroll aggravates all the monsters on the current | |
| 181 * level and sets them running towards the hero | |
| 182 */ | |
| 183 msg("You hear a high-pitched humming noise."); | |
| 184 /* protect good charactors */ | |
| 185 if (player.t_ctype == C_PALADIN || | |
| 186 player.t_ctype == C_RANGER || player.t_ctype == C_MONK) { | |
| 187 msg("A chill runs up your spine! "); | |
| 188 aggravate(TRUE, FALSE); | |
| 189 } | |
| 190 else { | |
| 191 aggravate(TRUE, TRUE); | |
| 192 } | |
| 193 } | |
| 194 else if (blessed) { /* Hold all monsters on level */ | |
| 195 if (mlist == NULL) msg(nothing); | |
| 196 else { | |
| 197 register struct linked_list *mon; | |
| 198 register struct thing *th; | |
| 199 | |
| 200 for (mon = mlist; mon != NULL; mon = next(mon)) { | |
| 201 th = THINGPTR(mon); | |
| 202 turn_off(*th, ISRUN); | |
| 203 turn_on(*th, ISHELD); | |
| 204 turn_off(*th, ISCHARMED); | |
| 205 } | |
| 206 if (levtype == OUTSIDE) | |
| 207 msg("A sudden peace comes over the land.. "); | |
| 208 else | |
| 209 msg("A sudden peace comes over the dungeon.. "); | |
| 210 } | |
| 211 } | |
| 212 else { | |
| 213 /* | |
| 214 * Hold monster scroll. Stop all monsters within two spaces | |
| 215 * from chasing after the hero. | |
| 216 */ | |
| 217 register int x,y; | |
| 218 register struct linked_list *mon; | |
| 219 bool gotone=FALSE; | |
| 220 | |
| 221 for (x = hero.x-2; x <= hero.x+2; x++) { | |
| 222 for (y = hero.y-2; y <= hero.y+2; y++) { | |
| 223 if (y < 1 || x < 0 || y > lines - 3 || x > cols - 1) | |
| 224 continue; | |
| 225 if (isalpha(mvwinch(mw, y, x))) { | |
| 226 if ((mon = find_mons(y, x)) != NULL) { | |
| 227 register struct thing *th; | |
| 228 | |
| 229 gotone = TRUE; | |
| 230 th = THINGPTR(mon); | |
| 231 turn_off(*th, ISRUN); | |
| 232 turn_on(*th, ISHELD); | |
| 233 turn_off(*th, ISCHARMED); | |
| 234 } | |
| 235 } | |
| 236 } | |
| 237 } | |
| 238 if (gotone) msg("A sudden peace surrounds you."); | |
| 239 else msg(nothing); | |
| 240 } | |
| 241 when S_SLEEP: | |
| 242 /* | |
| 243 * if cursed, you fall asleep | |
| 244 */ | |
| 245 if (is_scroll) s_know[S_SLEEP] = TRUE; | |
| 246 if (cursed) { | |
| 247 if (ISWEARING(R_ALERT)) | |
| 248 msg("You feel drowsy for a moment."); | |
| 249 else { | |
| 250 msg("You fall asleep."); | |
| 251 player.t_no_move += movement(&player)*(4 + rnd(SLEEPTIME)); | |
| 252 player.t_action = A_FREEZE; | |
| 253 } | |
| 254 } | |
| 255 else { | |
| 256 /* | |
| 257 * sleep monster scroll. | |
| 258 * puts all monsters within 2 spaces asleep | |
| 259 */ | |
| 260 register int x,y; | |
| 261 register struct linked_list *mon; | |
| 262 bool gotone=FALSE; | |
| 263 | |
| 264 for (x = hero.x-2; x <= hero.x+2; x++) { | |
| 265 for (y = hero.y-2; y <= hero.y+2; y++) { | |
| 266 if (y < 1 || x < 0 || y > lines - 3 || x > cols - 1) | |
| 267 continue; | |
| 268 if (isalpha(mvwinch(mw, y, x))) { | |
| 269 if ((mon = find_mons(y, x)) != NULL) { | |
| 270 register struct thing *th; | |
| 271 | |
| 272 th = THINGPTR(mon); | |
| 273 if (on(*th, ISUNDEAD)) | |
| 274 continue; | |
| 275 th->t_no_move += movement(th)*(SLEEPTIME+4); | |
| 276 th->t_action = A_FREEZE; | |
| 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((struct linked_list *)NULL); | |
| 311 } | |
| 312 if (is_scroll) s_know[S_IDENT] = TRUE; | |
| 313 when S_MAP: | |
| 314 /* | |
| 315 * Scroll of magic mapping. | |
| 316 */ | |
| 317 if (blessed) { | |
| 318 register int i; | |
| 319 | |
| 320 if (is_scroll && s_know[S_MAP] != TRUE) | |
| 321 s_know[S_MAP] = TRUE; | |
| 322 /* light rooms */ | |
| 323 for (i=0; i<MAXROOMS; i++){ | |
| 324 rooms[i].r_flags &= ~ISDARK; | |
| 325 } | |
| 326 | |
| 327 msg("This scroll has a very detailed map on it! --More--"); | |
| 328 wait_for(' '); | |
| 329 overwrite(stdscr, hw); | |
| 330 overlay(stdscr, cw); /* wizard CTRL(F) */ | |
| 331 overlay(mw, cw); /* wizard CTRL(X) */ | |
| 332 draw(cw); | |
| 333 goto map_jump; /* skip over regular mapping routine */ | |
| 334 } | |
| 335 if (is_scroll && s_know[S_MAP] != TRUE) { | |
| 336 msg("Oh, now this scroll has a map on it."); | |
| 337 s_know[S_MAP] = TRUE; | |
| 338 } | |
| 339 overwrite(stdscr, hw); | |
| 340 /* | |
| 341 * Take all the things we want to keep hidden out of the window | |
| 342 */ | |
| 343 for (i = 1; i < lines-2; i++) | |
| 344 for (j = 0; j < cols; j++) | |
| 345 { | |
| 346 switch (nch = ch = mvwinch(hw, i, j)) | |
| 347 { | |
| 348 case SECRETDOOR: | |
| 349 nch = secretdoor (i, j); | |
| 350 break; | |
| 351 case HORZWALL: | |
| 352 case VERTWALL: | |
| 353 case DOOR: | |
| 354 case PASSAGE: | |
| 355 case ' ': | |
| 356 |
