Mercurial > hg > early-roguelike
comparison arogue5/sticks.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 * Functions to implement the various sticks one might find | |
| 3 * while wandering around the dungeon. | |
| 4 * | |
| 5 * Advanced Rogue | |
| 6 * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T | |
| 7 * All rights reserved. | |
| 8 * | |
| 9 * Based on "Rogue: Exploring the Dungeons of Doom" | |
| 10 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
| 11 * All rights reserved. | |
| 12 * | |
| 13 * See the file LICENSE.TXT for full copyright and licensing information. | |
| 14 */ | |
| 15 | |
| 16 #include "curses.h" | |
| 17 #include <ctype.h> | |
| 18 #include "rogue.h" | |
| 19 | |
| 20 | |
| 21 /* | |
| 22 * zap a stick and see what happens | |
| 23 */ | |
| 24 do_zap(gotdir, which, flag) | |
| 25 bool gotdir; | |
| 26 int which; | |
| 27 int flag; | |
| 28 { | |
| 29 register struct linked_list *item; | |
| 30 register struct object *obj = NULL; | |
| 31 register struct thing *tp; | |
| 32 register int y, x; | |
| 33 struct linked_list *nitem; | |
| 34 struct object *nobj; | |
| 35 bool cursed, blessed, is_stick; | |
| 36 | |
| 37 blessed = FALSE; | |
| 38 cursed = FALSE; | |
| 39 is_stick = FALSE; | |
| 40 | |
| 41 if (which == 0) { | |
| 42 if ((item = get_item(pack, "zap with", ZAPPABLE)) == NULL) | |
| 43 return(FALSE); | |
| 44 obj = OBJPTR(item); | |
| 45 | |
| 46 /* Handle relics specially here */ | |
| 47 if (obj->o_type == RELIC) { | |
| 48 switch (obj->o_which) { | |
| 49 case ORCUS_WAND: | |
| 50 msg(nothing); | |
| 51 return(TRUE); | |
| 52 when MING_STAFF: | |
| 53 which = WS_MISSILE; | |
| 54 when ASMO_ROD: | |
| 55 switch (rnd(3)) { | |
| 56 case 0: | |
| 57 which = WS_ELECT; | |
| 58 when 1: | |
| 59 which = WS_COLD; | |
| 60 otherwise: | |
| 61 which = WS_FIRE; | |
| 62 } | |
| 63 } | |
| 64 cursed = FALSE; | |
| 65 blessed = FALSE; | |
| 66 } | |
| 67 else { | |
| 68 which = obj->o_which; | |
| 69 ws_know[which] = TRUE; | |
| 70 cursed = (obj->o_flags & ISCURSED) != 0; | |
| 71 blessed = (obj->o_flags & ISBLESSED) != 0; | |
| 72 is_stick = TRUE; | |
| 73 } | |
| 74 } | |
| 75 else { | |
| 76 cursed = flag & ISCURSED; | |
| 77 blessed = flag & ISBLESSED; | |
| 78 } | |
| 79 switch (which) { /* no direction for these */ | |
| 80 case WS_LIGHT: | |
| 81 case WS_DRAIN: | |
| 82 case WS_CHARGE: | |
| 83 case WS_CURING: | |
| 84 break; | |
| 85 | |
| 86 default: | |
| 87 if (!get_dir()) | |
| 88 return(FALSE); | |
| 89 if (!gotdir) { | |
| 90 do { | |
| 91 delta.y = rnd(3) - 1; | |
| 92 delta.x = rnd(3) - 1; | |
| 93 } while (delta.y == 0 && delta.x == 0); | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 if (is_stick) { | |
| 98 if (obj->o_charges < 1) { | |
| 99 msg(nothing); | |
| 100 return(TRUE); | |
| 101 } | |
| 102 obj->o_charges--; | |
| 103 } | |
| 104 if (which == WS_WONDER) { | |
| 105 switch (rnd(14)) { | |
| 106 case 0: which = WS_ELECT; | |
| 107 when 1: which = WS_FIRE; | |
| 108 when 2: which = WS_COLD; | |
| 109 when 3: which = WS_POLYMORPH; | |
| 110 when 4: which = WS_MISSILE; | |
| 111 when 5: which = WS_SLOW_M; | |
| 112 when 6: which = WS_TELMON; | |
| 113 when 7: which = WS_CANCEL; | |
| 114 when 8: which = WS_CONFMON; | |
| 115 when 9: which = WS_DISINTEGRATE; | |
| 116 when 10: which = WS_PETRIFY; | |
| 117 when 11: which = WS_PARALYZE; | |
| 118 when 12: which = WS_MDEG; | |
| 119 when 13: which = WS_FEAR; | |
| 120 } | |
| 121 if(ws_magic[which].mi_curse>0 && rnd(100)<=ws_magic[which].mi_curse){ | |
| 122 cursed = TRUE; | |
| 123 blessed = FALSE; | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 switch (which) { | |
| 128 case WS_LIGHT: | |
| 129 /* | |
| 130 * Reddy Kilowat wand. Light up the room | |
| 131 */ | |
| 132 blue_light(blessed, cursed); | |
| 133 when WS_DRAIN: | |
| 134 /* | |
| 135 * Take away 1/2 of hero's hit points, then take it away | |
| 136 * evenly from the monsters in the room or next to hero | |
| 137 * if he is in a passage (but leave the monsters alone | |
| 138 * if the stick is cursed) | |
| 139 */ | |
| 140 if (pstats.s_hpt < 2) { | |
| 141 msg("You are too weak to use it."); | |
| 142 return(TRUE); | |
| 143 } | |
| 144 if (cursed) | |
| 145 pstats.s_hpt /= 2; | |
| 146 else | |
| 147 drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1); | |
| 148 when WS_POLYMORPH: | |
| 149 case WS_TELMON: | |
| 150 case WS_CANCEL: | |
| 151 { | |
| 152 register char monster, oldch; | |
| 153 register int rm; | |
| 154 | |
| 155 y = hero.y; | |
| 156 x = hero.x; | |
| 157 while (shoot_ok(winat(y, x))) { | |
| 158 y += delta.y; | |
| 159 x += delta.x; | |
| 160 } | |
| 161 if (isalpha(monster = CCHAR( mvwinch(mw, y, x) ))) { | |
| 162 register struct room *rp; | |
| 163 | |
| 164 item = find_mons(y, x); | |
| 165 tp = THINGPTR(item); | |
| 166 /* if the monster gets the saving throw, leave the case */ | |
| 167 if (save(VS_MAGIC, tp, 0)) { | |
| 168 msg(nothing); | |
| 169 break; | |
| 170 } | |
| 171 | |
| 172 /* Unhold player */ | |
| 173 if (on(*tp, DIDHOLD)) { | |
| 174 turn_off(*tp, DIDHOLD); | |
| 175 if (--hold_count == 0) turn_off(player, ISHELD); | |
| 176 } | |
| 177 /* unsuffocate player */ | |
| 178 if (on(*tp, DIDSUFFOCATE)) { | |
| 179 turn_off(*tp, DIDSUFFOCATE); | |
| 180 extinguish(suffocate); | |
| 181 } | |
| 182 rp = roomin(&tp->t_pos); | |
| 183 /* | |
| 184 * check to see if room should go dark | |
| 185 */ | |
| 186 if (on(*tp, HASFIRE)) { | |
| 187 if (rp != NULL) { | |
| 188 register struct linked_list *fire_item; | |
| 189 | |
| 190 for (fire_item = rp->r_fires; fire_item != NULL; | |
| 191 fire_item = next(fire_item)) { | |
| 192 if (THINGPTR(fire_item) == tp) { | |
| 193 detach(rp->r_fires, fire_item); | |
| 194 destroy_item(fire_item); | |
| 195 if (rp->r_fires == NULL) { | |
| 196 rp->r_flags &= ~HASFIRE; | |
| 197 if(cansee(tp->t_pos.y,tp->t_pos.x)) | |
| 198 light(&hero); | |
| 199 } | |
| 200 break; | |
| 201 } | |
| 202 } | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 if (which == WS_POLYMORPH) { | |
| 207 register struct linked_list *pitem; | |
| 208 | |
| 209 delta.x = x; | |
| 210 delta.y = y; | |
| 211 detach(mlist, item); | |
| 212 oldch = tp->t_oldch; | |
| 213 pitem = tp->t_pack; /* save his pack */ | |
| 214 tp->t_pack = NULL; | |
| 215 new_monster(item,rnd(NUMMONST-NUMUNIQUE-1)+1,&delta,FALSE); | |
| 216 if (tp->t_pack != NULL) | |
| 217 o_free_list (tp->t_pack); | |
| 218 tp->t_pack = pitem; | |
| 219 monster = tp->t_type; | |
| 220 if (isalpha(mvwinch(cw, y, x))) | |
| 221 mvwaddch(cw, y, x, monster); | |
| 222 tp->t_oldch = oldch; | |
| 223 /* | |
| 224 * should the room light up? | |
| 225 */ | |
| 226 if (on(*tp, HASFIRE)) { | |
| 227 if (rp) { | |
| 228 register struct linked_list *fire_item; | |
| 229 | |
| 230 fire_item = creat_item(); | |
| 231 ldata(fire_item) = (char *) tp; | |
| 232 attach(rp->r_fires, fire_item); | |
| 233 rp->r_flags |= HASFIRE; | |
| 234 if (cansee(tp->t_pos.y,tp->t_pos.x) && | |
| 235 next(rp->r_fires) == NULL) light(&hero); | |
| 236 } | |
| 237 } | |
| 238 msg(terse ? "A new %s!" : "You have created a new %s!", | |
| 239 monsters[tp->t_index].m_name); | |
| 240 } | |
| 241 else if (which == WS_CANCEL) { | |
| 242 tp->t_flags[0] &= CANC0MASK; | |
| 243 tp->t_flags[1] &= CANC1MASK; | |
| 244 tp->t_flags[2] &= CANC2MASK; | |
| 245 tp->t_flags[3] &= CANC3MASK; | |
| 246 tp->t_flags[4] &= CANC4MASK; | |
| 247 tp->t_flags[4] &= CANC5MASK; | |
| 248 } | |
| 249 else { /* A teleport stick */ | |
| 250 if (cursed) { /* Teleport monster to player */ | |
| 251 if ((y == (hero.y + delta.y)) && | |
| 252 (x == (hero.x + delta.x))) | |
| 253 msg(nothing); | |
| 254 else { | |
| 255 tp->t_pos.y = hero.y + delta.y; | |
| 256 tp->t_pos.x = hero.x + delta.x; | |
| 257 } | |
| 258 } | |
| 259 else if (blessed) { /* Get rid of monster */ | |
| 260 killed(item, FALSE, TRUE); | |
| 261 return(TRUE); | |
| 262 } | |
| 263 else { | |
| 264 register int i=0; | |
| 265 | |
| 266 do { /* Move monster to another room */ | |
| 267 rm = rnd_room(); | |
| 268 rnd_pos(&rooms[rm], &tp->t_pos); | |
| 269 }until(winat(tp->t_pos.y,tp->t_pos.x)==FLOOR ||i++>500); | |
| 270 rp = &rooms[rm]; | |
| 271 } | |
| 272 | |
| 273 /* Now move the monster */ | |
| 274 if (isalpha(mvwinch(cw, y, x))) | |
| 275 mvwaddch(cw, y, x, tp->t_oldch); | |
| 276 turn_off(*tp, ISDISGUISE); | |
| 277 mvwaddch(mw, y, x, ' '); | |
| 278 mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, monster); | |
| 279 if (tp->t_pos.y != y || tp->t_pos.x != x) | |
| 280 tp->t_oldch = CCHAR( mvwinch(cw, tp->t_pos.y, tp->t_pos.x) ); | |
| 281 /* | |
| 282 * check to see if room that creature appears in should | |
| 283 * light up | |
| 284 */ | |
| 285 if (on(*tp, HASFIRE)) { | |
| 286 register struct linked_list *fire_item; | |
| 287 | |
| 288 fire_item = creat_item(); | |
| 289 ldata(fire_item) = (char *) tp; | |
| 290 attach(rp->r_fires, fire_item); | |
| 291 rp->r_flags |= HASFIRE; | |
| 292 if(cansee(tp->t_pos.y, tp->t_pos.x) && | |
| 293 next(rp->r_fires) == NULL) | |
| 294 light(&hero); | |
| 295 } | |
| 296 } | |
| 297 runto(tp, &hero); | |
| 298 } | |
| 299 } | |
| 300 when WS_MISSILE: | |
| 301 { | |
| 302 static struct object bolt = | |
| 303 { | |
| 304 MISSILE , {0, 0}, "", 0, "", "1d4 " , NULL, 0, WS_MISSILE, 50, 1 | |
| 305 }; | |
| 306 | |
| 307 sprintf(bolt.o_hurldmg, "%dd4", pstats.s_lvl); | |
| 308 do_motion(&bolt, delta.y, delta.x, &player); | |
| 309 if (!hit_monster(unc(bolt.o_pos), &bolt, &player)) | |
| 310 msg("The missile vanishes with a puff of smoke"); | |
| 311 } | |
| 312 when WS_HIT: | |
| 313 { | |
| 314 register char ch; | |
| 315 struct object strike; /* don't want to change sticks attributes */ | |
| 316 | |
| 317 delta.y += hero.y; | |
| 318 delta.x += hero.x; | |
| 319 ch = CCHAR( winat(delta.y, delta.x) ); | |
| 320 if (isalpha(ch)) | |
| 321 { | |
| 322 strike = *obj; | |
| 323 strike.o_hplus = 6; | |
| 324 if (EQUAL(ws_type[which], "staff")) | |
| 325 strcpy(strike.o_damage,"3d8"); | |
| 326 else | |
| 327 strcpy(strike.o_damage,"2d8"); | |
| 328 fight(&delta, &strike, FALSE); | |
| 329 } | |
| 330 } | |
| 331 case WS_SLOW_M: | |
| 332 y = hero.y; | |
| 333 x = hero.x; | |
| 334 while (shoot_ok(winat(y, x))) { | |
| 335 y += delta.y; | |
| 336 x += delta.x; | |
| 337 } | |
| 338 if (isalpha(mvwinch(mw, y, x))) { | |
| 339 item = find_mons(y, x); | |
| 340 tp = THINGPTR(item); | |
| 341 runto(tp, &hero); | |
| 342 if (on(*tp, ISUNIQUE) && save(VS_MAGIC, tp, 0)) | |
| 343 msg(nothing); | |
| 344 else if (on(*tp, NOSLOW)) | |
| 345 msg(nothing); | |
| 346 else if (cursed) { | |
| 347 if (on(*tp, ISSLOW)) | |
| 348 turn_off(*tp, ISSLOW); | |
| 349 else | |
| 350 turn_on(*tp, ISHASTE); | |
| 351 } | |
| 352 else if (blessed) { | |
| 353 turn_off(*tp, ISRUN); | |
| 354 turn_on(*tp, ISHELD); | |
| 355 return(TRUE); | |
| 356 } | |
| 357 else { | |
| 358 if (on(*tp, ISHASTE)) | |
| 359 turn_off(*tp, ISHASTE); | |
| 360 else | |
| 361 turn_on(*tp, ISSLOW); | |
| 362 tp->t_turn = TRUE; | |
| 363 } | |
| 364 } | |
| 365 when WS_CHARGE: | |
| 366 if (ws_know[WS_CHARGE] != TRUE && is_stick) | |
| 367 msg("This is a wand of charging."); | |
| 368 if ((nitem = get_item(pack, "charge", STICK)) != NULL) { | |
| 369 nobj = OBJPTR(nitem); | |
| 370 if ((++(nobj->o_charges) == 1) && (nobj->o_which == WS_HIT)) | |
| 371 fix_stick(nobj); | |
| 372 if (EQUAL(ws_type[nobj->o_which], "staff")) { | |
| 373 if (nobj->o_charges > 100) | |
| 374 nobj->o_charges = 100; | |
| 375 } | |
| 376 else { | |
