Mercurial > hg > early-roguelike
comparison xrogue/sticks.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 sticks.c - Functions to implement the various sticks one might find | |
| 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 * zap a stick and see what happens | |
| 25 */ | |
| 26 | |
| 27 do_zap(zapper, obj, direction, which, flags) | |
| 28 struct thing *zapper; | |
| 29 struct object *obj; | |
| 30 coord *direction; | |
| 31 int which; | |
| 32 int flags; | |
| 33 { | |
| 34 register struct linked_list *item = NULL; | |
| 35 register struct thing *tp; | |
| 36 register int y = 0, x = 0, bonus; | |
| 37 struct linked_list *nitem; | |
| 38 struct object *nobj; | |
| 39 bool cursed, blessed, is_player = FALSE; | |
| 40 char *mname = NULL; | |
| 41 | |
| 42 cursed = flags & ISCURSED; | |
| 43 blessed = flags & ISBLESSED; | |
| 44 | |
| 45 if (obj && obj->o_type != RELIC) { /* all relics are chargeless */ | |
| 46 if (obj->o_charges < 1) { | |
| 47 msg(nothing); | |
| 48 return; | |
| 49 } | |
| 50 obj->o_charges--; | |
| 51 } | |
| 52 if (which == WS_WONDER) { | |
| 53 switch (rnd(19)) { | |
| 54 case 0: which = WS_ELECT; | |
| 55 when 1: which = WS_FIRE; | |
| 56 when 2: which = WS_COLD; | |
| 57 when 3: which = WS_POLYMORPH; | |
| 58 when 4: which = WS_MISSILE; | |
| 59 when 5: which = WS_SLOW_M; | |
| 60 when 6: which = WS_TELMON; | |
| 61 when 7: which = WS_CANCEL; | |
| 62 when 8: which = WS_CONFMON; | |
| 63 when 9: which = WS_DISINTEGRATE; | |
| 64 when 10: which = WS_PETRIFY; | |
| 65 when 11: which = WS_PARALYZE; | |
| 66 when 12: which = WS_MDEG; | |
| 67 when 13: which = WS_FEAR; | |
| 68 when 14: which = WS_CURING; | |
| 69 when 15: which = WS_LIGHT; | |
| 70 when 16: which = WS_HIT; | |
| 71 when 17: which = WS_DRAIN; | |
| 72 when 18: which = WS_CHARGE; | |
| 73 } | |
| 74 if(ws_magic[which].mi_curse>0 && rnd(100)<=ws_magic[which].mi_curse){ | |
| 75 cursed = TRUE; | |
| 76 blessed = FALSE; | |
| 77 } | |
| 78 } | |
| 79 | |
| 80 tp = NULL; | |
| 81 switch (which) { | |
| 82 case WS_POLYMORPH: | |
| 83 case WS_SLOW_M: | |
| 84 case WS_TELMON: | |
| 85 case WS_CANCEL: | |
| 86 case WS_CONFMON: | |
| 87 case WS_DISINTEGRATE: | |
| 88 case WS_PETRIFY: | |
| 89 case WS_PARALYZE: | |
| 90 case WS_MDEG: | |
| 91 case WS_FEAR: | |
| 92 y = zapper->t_pos.y; | |
| 93 x = zapper->t_pos.x; | |
| 94 | |
| 95 do { | |
| 96 y += direction->y; | |
| 97 x += direction->x; | |
| 98 } | |
| 99 while (shoot_ok(winat(y, x)) && !(y == hero.y && x == hero.x)); | |
| 100 | |
| 101 if (y == hero.y && x == hero.x) | |
| 102 is_player = TRUE; | |
| 103 else if (isalpha(mvwinch(mw, y, x))) { | |
| 104 item = find_mons(y, x); | |
| 105 tp = THINGPTR(item); | |
| 106 runto(tp, &hero); | |
| 107 turn_off(*tp, CANSURPRISE); | |
| 108 mname = monster_name(tp); | |
| 109 is_player = FALSE; | |
| 110 | |
| 111 /* The monster may not like being shot at */ | |
| 112 if ((zapper == &player) && | |
| 113 on(*tp, ISCHARMED) && | |
| 114 save(VS_MAGIC, tp, 0)) { | |
| 115 msg("The eyes of %s turn clear.", prname(mname, FALSE)); | |
| 116 turn_off(*tp, ISCHARMED); | |
| 117 mname = monster_name(tp); | |
| 118 } | |
| 119 } | |
| 120 else { | |
| 121 /* | |
| 122 * if monster misses player because the player dodged then lessen | |
| 123 * the chances he will use the wand again since the player appears | |
| 124 * to be rather dextrous | |
| 125 */ | |
| 126 if (zapper != &player) | |
| 127 zapper->t_wand = zapper->t_wand * 3 / 5; | |
| 128 } | |
| 129 } | |
| 130 switch (which) { | |
| 131 case WS_LIGHT: | |
| 132 /* | |
| 133 * Reddy Kilowat wand. Light up the room | |
| 134 */ | |
| 135 blue_light(blessed, cursed); | |
| 136 when WS_DRAIN: | |
| 137 /* | |
| 138 * Take away 1/2 of hero's hit points, then take it away | |
| 139 * evenly from the monsters in the room or next to hero | |
| 140 * if he is in a passage (but leave the monsters alone | |
| 141 * if the stick is cursed) | |
| 142 */ | |
| 143 if (pstats.s_hpt < 2) { | |
| 144 msg("You are too weak to use it."); | |
| 145 } | |
| 146 else if (cursed) | |
| 147 pstats.s_hpt /= 2; | |
| 148 if (pstats.s_hpt <= 0) { | |
| 149 pstats.s_hpt = -1; | |
| 150 msg("You drain your own life away. --More--"); | |
| 151 death(D_STRENGTH); | |
| 152 } | |
| 153 else | |
| 154 drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1); | |
| 155 | |
| 156 when WS_POLYMORPH: | |
| 157 { | |
| 158 register char oldch; | |
| 159 register struct room *rp; | |
| 160 register struct linked_list *pitem; | |
| 161 coord delta; | |
| 162 | |
| 163 if (tp == NULL) | |
| 164 break; | |
| 165 if (save(VS_MAGIC, tp, 0)) { | |
| 166 msg(nothing); | |
| 167 break; | |
| 168 } | |
| 169 rp = roomin(&tp->t_pos); | |
| 170 check_residue(tp); | |
| 171 delta.x = x; | |
| 172 delta.y = y; | |
| 173 detach(mlist, item); | |
| 174 oldch = tp->t_oldch; | |
| 175 pitem = tp->t_pack; /* save his pack */ | |
| 176 tp->t_pack = NULL; | |
| 177 | |
| 178 if (levtype == OUTSIDE) | |
| 179 new_monster(item,rnd(NUMDINOS)+NUMMONST-NUMDINOS,&delta,FALSE); | |
| 180 else | |
| 181 new_monster(item,rnd(NUMMONST-NUMUNIQUE-NUMDINOS-1)+1,&delta,FALSE); | |
| 182 | |
| 183 if (tp->t_pack != NULL) | |
| 184 o_free_list (tp->t_pack); | |
| 185 tp->t_pack = pitem; | |
| 186 if (isalpha(mvwinch(cw, y, x))) | |
| 187 mvwaddch(cw, y, x, tp->t_type); | |
| 188 tp->t_oldch = oldch; | |
| 189 /* | |
| 190 * should the room light up? | |
| 191 */ | |
| 192 if (on(*tp, HASFIRE)) { | |
| 193 if (rp) { | |
| 194 register struct linked_list *fire_item; | |
| 195 | |
| 196 fire_item = creat_item(); | |
| 197 ldata(fire_item) = (char *) tp; | |
| 198 attach(rp->r_fires, fire_item); | |
| 199 rp->r_flags |= HASFIRE; | |
| 200 if (cansee(tp->t_pos.y,tp->t_pos.x) && | |
| 201 next(rp->r_fires) == NULL) light(&hero); | |
| 202 } | |
| 203 } | |
| 204 runto(tp, &hero); | |
| 205 msg(terse ? "A new %s!" | |
| 206 : "You have created a new %s!", | |
| 207 monster_name(tp)); | |
| 208 } | |
| 209 | |
| 210 when WS_PETRIFY: | |
| 211 if (tp == NULL) | |
| 212 break; | |
| 213 if (save(VS_MAGIC, tp, 0)) { | |
| 214 msg(nothing); | |
| 215 break; | |
| 216 } | |
| 217 check_residue(tp); | |
| 218 turn_on(*tp, ISSTONE); | |
| 219 turn_on(*tp, NOSTONE); | |
| 220 turn_off(*tp, ISRUN); | |
| 221 turn_off(*tp, ISINVIS); | |
| 222 turn_off(*tp, CANSURPRISE); | |
| 223 turn_off(*tp, ISDISGUISE); | |
| 224 tp->t_action = A_NIL; | |
| 225 tp->t_no_move = 0; | |
| 226 msg("%s is turned to stone!",prname(mname, TRUE)); | |
| 227 | |
| 228 when WS_TELMON: | |
| 229 { | |
| 230 register int rm; | |
| 231 register struct room *rp; | |
| 232 | |
| 233 if (tp == NULL) | |
| 234 break; | |
| 235 if (save(VS_MAGIC, tp, 0)) { | |
| 236 msg(nothing); | |
| 237 break; | |
| 238 } | |
| 239 rp = NULL; | |
| 240 check_residue(tp); | |
| 241 tp->t_action = A_FREEZE; /* creature is disoriented */ | |
| 242 tp->t_no_move = 2; | |
| 243 if (cursed) { /* Teleport monster to player */ | |
| 244 if ((y == (hero.y + direction->y)) && | |
| 245 (x == (hero.x + direction->x))) | |
| 246 msg(nothing); | |
| 247 else { | |
| 248 tp->t_pos.y = hero.y + direction->y; | |
| 249 tp->t_pos.x = hero.x + direction->x; | |
| 250 } | |
| 251 } | |
| 252 else if (blessed) { /* Get rid of monster */ | |
| 253 killed(item, FALSE, TRUE, TRUE); | |
| 254 return; | |
| 255 } | |
| 256 else { | |
| 257 register int i=0; | |
| 258 | |
| 259 do { /* Move monster to another room */ | |
| 260 rm = rnd_room(); | |
| 261 rnd_pos(&rooms[rm], &tp->t_pos); | |
| 262 }until(winat(tp->t_pos.y,tp->t_pos.x)==FLOOR ||i++>500); | |
| 263 rp = &rooms[rm]; | |
| 264 } | |
| 265 | |
| 266 /* Now move the monster */ | |
| 267 if (isalpha(mvwinch(cw, y, x))) | |
| 268 mvwaddch(cw, y, x, tp->t_oldch); | |
| 269 mvwaddch(mw, y, x, ' '); | |
| 270 mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type); | |
| 271 if (tp->t_pos.y != y || tp->t_pos.x != x) | |
| 272 tp->t_oldch = mvwinch(cw, tp->t_pos.y, tp->t_pos.x); | |
| 273 /* | |
| 274 * check to see if room that creature appears in should | |
| 275 * light up | |
| 276 */ | |
| 277 if (on(*tp, HASFIRE)) { | |
| 278 if (rp) { | |
| 279 register struct linked_list *fire_item; | |
| 280 | |
| 281 fire_item = creat_item(); | |
| 282 ldata(fire_item) = (char *) tp; | |
| 283 attach(rp->r_fires, fire_item); | |
| 284 rp->r_flags |= HASFIRE; | |
| 285 if(cansee(tp->t_pos.y, tp->t_pos.x) && | |
| 286 next(rp->r_fires) == NULL) | |
| 287 light(&hero); | |
| 288 } | |
| 289 } | |
| 290 } | |
| 291 when WS_CANCEL: | |
| 292 if (tp == NULL) | |
| 293 break; | |
| 294 if (save(VS_MAGIC, tp, 0)) { | |
| 295 msg(nothing); | |
| 296 break; | |
| 297 } | |
| 298 check_residue(tp); | |
| 299 tp->t_flags[0] &= CANC0MASK; | |
| 300 tp->t_flags[1] &= CANC1MASK; | |
| 301 tp->t_flags[2] &= CANC2MASK; | |
| 302 tp->t_flags[3] &= CANC3MASK; | |
| 303 tp->t_flags[4] &= CANC4MASK; | |
| 304 tp->t_flags[5] &= CANC5MASK; | |
| 305 tp->t_flags[6] &= CANC6MASK; | |
| 306 tp->t_flags[7] &= CANC7MASK; | |
| 307 tp->t_flags[8] &= CANC8MASK; | |
| 308 tp->t_flags[9] &= CANC9MASK; | |
| 309 tp->t_flags[10] &= CANCAMASK; | |
| 310 tp->t_flags[11] &= CANCBMASK; | |
| 311 tp->t_flags[12] &= CANCCMASK; | |
| 312 tp->t_flags[13] &= CANCDMASK; | |
| 313 tp->t_flags[14] &= CANCEMASK; | |
| 314 tp->t_flags[15] &= CANCFMASK; | |
| 315 | |
| 316 when WS_MISSILE: | |
| 317 { | |
| 318 int dice; | |
| 319 static struct object bolt = | |
| 320 { | |
| 321 MISSILE , {0, 0}, 0, "", "1d4 " , NULL, 0, WS_MISSILE, 50, 1 | |
| 322 }; | |
| 323 | |
| 324 if (!obj) | |
| 325 dice = zapper->t_stats.s_lvl; | |
| 326 if (obj->o_type == RELIC) | |
| 327 dice = 15; | |
| 328 else if (EQUAL(ws_type[which], "staff")) | |
| 329 dice = 10; | |
| 330 else | |
| 331 dice = 6; | |
| 332 sprintf(bolt.o_hurldmg, "%dd4", dice); | |
| 333 do_motion(&bolt, direction->y, direction->x, zapper); | |
| 334 if (!hit_monster(unc(bolt.o_pos), &bolt, zapper)) | |
| 335 msg("The missile vanishes with a puff of smoke"); | |
| 336 } | |
| 337 when WS_HIT: | |
| 338 { | |
| 339 register unsigned char ch; | |
| 340 struct object strike; /* don't want to change sticks attributes */ | |
| 341 | |
| 342 direction->y += hero.y; | |
| 343 direction->x += hero.x; | |
| 344 ch = winat(direction->y, direction->x); | |
| 345 if (isalpha(ch)) | |
| 346 { | |
| 347 strike = *obj; | |
| 348 strike.o_hplus = 7; | |
| 349 if (EQUAL(ws_type[which], "staff")) | |
| 350 strcpy(strike.o_damage,"3d8"); | |
| 351 else | |
| 352 strcpy(strike.o_damage,"2d8"); | |
| 353 fight(direction, &strike, FALSE); | |
| 354 } | |
| 355 } | |
| 356 when WS_SLOW_M: | |
| 357 if (is_player) { | |
| 358 |
