|
|
1.1 ! root 1: /* ! 2: * Functions to implement the various sticks one might find ! 3: * while wandering around the dungeon. ! 4: * ! 5: * @(#)sticks.c 3.14 (Berkeley) 6/15/81 ! 6: */ ! 7: ! 8: #include <curses.h> ! 9: #include <ctype.h> ! 10: #include "rogue.h" ! 11: ! 12: fix_stick(cur) ! 13: register struct object *cur; ! 14: { ! 15: if (strcmp(ws_type[cur->o_which], "staff") == 0) ! 16: cur->o_damage = "2d3"; ! 17: else ! 18: cur->o_damage = "1d1"; ! 19: cur->o_hurldmg = "1d1"; ! 20: ! 21: cur->o_charges = 3 + rnd(5); ! 22: switch (cur->o_which) ! 23: { ! 24: when WS_HIT: ! 25: cur->o_hplus = 3; ! 26: cur->o_dplus = 3; ! 27: cur->o_damage = "1d8"; ! 28: when WS_LIGHT: ! 29: cur->o_charges = 10 + rnd(10); ! 30: } ! 31: } ! 32: ! 33: do_zap(gotdir) ! 34: bool gotdir; ! 35: { ! 36: register struct linked_list *item; ! 37: register struct object *obj; ! 38: register struct room *rp; ! 39: register struct thing *tp; ! 40: register int y, x; ! 41: ! 42: if ((item = get_item("zap with", STICK)) == NULL) ! 43: return; ! 44: obj = (struct object *) ldata(item); ! 45: if (obj->o_type != STICK) ! 46: { ! 47: msg("You can't zap with that!"); ! 48: after = FALSE; ! 49: return; ! 50: } ! 51: if (obj->o_charges == 0) ! 52: { ! 53: msg("Nothing happens."); ! 54: return; ! 55: } ! 56: if (!gotdir) ! 57: do { ! 58: delta.y = rnd(3) - 1; ! 59: delta.x = rnd(3) - 1; ! 60: } while (delta.y == 0 && delta.x == 0); ! 61: switch (obj->o_which) ! 62: { ! 63: when WS_LIGHT: ! 64: /* ! 65: * Reddy Kilowat wand. Light up the room ! 66: */ ! 67: ws_know[WS_LIGHT] = TRUE; ! 68: if ((rp = roomin(&hero)) == NULL) ! 69: msg("The corridor glows and then fades"); ! 70: else ! 71: { ! 72: addmsg("The room is lit"); ! 73: if (!terse) ! 74: addmsg(" by a shimmering blue light."); ! 75: endmsg(); ! 76: rp->r_flags &= ~ISDARK; ! 77: /* ! 78: * Light the room and put the player back up ! 79: */ ! 80: light(&hero); ! 81: mvwaddch(cw, hero.y, hero.x, PLAYER); ! 82: } ! 83: when WS_DRAIN: ! 84: /* ! 85: * Take away 1/2 of hero's hit points, then take it away ! 86: * evenly from the monsters in the room (or next to hero ! 87: * if he is in a passage) ! 88: */ ! 89: if (pstats.s_hpt < 2) ! 90: { ! 91: msg("You are too weak to use it."); ! 92: return; ! 93: } ! 94: else if ((rp = roomin(&hero)) == NULL) ! 95: drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1); ! 96: else ! 97: drain(rp->r_pos.y, rp->r_pos.y+rp->r_max.y, ! 98: rp->r_pos.x, rp->r_pos.x+rp->r_max.x); ! 99: when WS_POLYMORPH: ! 100: case WS_TELAWAY: ! 101: case WS_TELTO: ! 102: case WS_CANCEL: ! 103: { ! 104: register char monster, oldch; ! 105: register int rm; ! 106: ! 107: y = hero.y; ! 108: x = hero.x; ! 109: while (step_ok(winat(y, x))) ! 110: { ! 111: y += delta.y; ! 112: x += delta.x; ! 113: } ! 114: if (isupper(monster = mvwinch(mw, y, x))) ! 115: { ! 116: register char omonst = monster; ! 117: ! 118: if (monster == 'F') ! 119: player.t_flags &= ~ISHELD; ! 120: item = find_mons(y, x); ! 121: tp = (struct thing *) ldata(item); ! 122: if (obj->o_which == WS_POLYMORPH) ! 123: { ! 124: detach(mlist, item); ! 125: oldch = tp->t_oldch; ! 126: delta.y = y; ! 127: delta.x = x; ! 128: new_monster(item, monster = rnd(26) + 'A', &delta); ! 129: if (!(tp->t_flags & ISRUN)) ! 130: runto(&delta, &hero); ! 131: if (isupper(mvwinch(cw, y, x))) ! 132: mvwaddch(cw, y, x, monster); ! 133: tp->t_oldch = oldch; ! 134: ws_know[WS_POLYMORPH] |= (monster != omonst); ! 135: } ! 136: else if (obj->o_which == WS_CANCEL) ! 137: { ! 138: tp->t_flags |= ISCANC; ! 139: tp->t_flags &= ~ISINVIS; ! 140: } ! 141: else ! 142: { ! 143: if (obj->o_which == WS_TELAWAY) ! 144: { ! 145: do ! 146: { ! 147: rm = rnd_room(); ! 148: rnd_pos(&rooms[rm], &tp->t_pos); ! 149: } until(winat(tp->t_pos.y, tp->t_pos.x) == FLOOR); ! 150: } ! 151: else ! 152: { ! 153: tp->t_pos.y = hero.y + delta.y; ! 154: tp->t_pos.x = hero.x + delta.x; ! 155: } ! 156: if (isupper(mvwinch(cw, y, x))) ! 157: mvwaddch(cw, y, x, tp->t_oldch); ! 158: tp->t_dest = &hero; ! 159: tp->t_flags |= ISRUN; ! 160: mvwaddch(mw, y, x, ' '); ! 161: mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, monster); ! 162: if (tp->t_pos.y != y || tp->t_pos.x != x) ! 163: tp->t_oldch = mvwinch(cw, tp->t_pos.y, tp->t_pos.x); ! 164: } ! 165: } ! 166: } ! 167: when WS_MISSILE: ! 168: { ! 169: static struct object bolt = ! 170: { ! 171: '*' , {0, 0}, "", 0, 0, "1d4" , 0, 0, 100, 1 ! 172: }; ! 173: ! 174: do_motion(&bolt, delta.y, delta.x); ! 175: if (isupper(mvwinch(mw, bolt.o_pos.y, bolt.o_pos.x)) ! 176: && !save_throw(VS_MAGIC, ldata(find_mons(unc(bolt.o_pos))))) ! 177: hit_monster(unc(bolt.o_pos), &bolt); ! 178: else if (terse) ! 179: msg("Missle vanishes"); ! 180: else ! 181: msg("The missle vanishes with a puff of smoke"); ! 182: ws_know[WS_MISSILE] = TRUE; ! 183: } ! 184: when WS_HIT: ! 185: { ! 186: register char ch; ! 187: ! 188: delta.y += hero.y; ! 189: delta.x += hero.x; ! 190: ch = winat(delta.y, delta.x); ! 191: if (isupper(ch)) ! 192: { ! 193: if (rnd(20) == 0) ! 194: { ! 195: obj->o_damage = "3d8"; ! 196: obj->o_dplus = 9; ! 197: } ! 198: else ! 199: { ! 200: obj->o_damage = "1d8"; ! 201: obj->o_dplus = 3; ! 202: } ! 203: fight(&delta, ch, obj, FALSE); ! 204: } ! 205: } ! 206: when WS_HASTE_M: ! 207: case WS_SLOW_M: ! 208: y = hero.y; ! 209: x = hero.x; ! 210: while (step_ok(winat(y, x))) ! 211: { ! 212: y += delta.y; ! 213: x += delta.x; ! 214: } ! 215: if (isupper(mvwinch(mw, y, x))) ! 216: { ! 217: item = find_mons(y, x); ! 218: tp = (struct thing *) ldata(item); ! 219: if (obj->o_which == WS_HASTE_M) ! 220: { ! 221: if (on(*tp, ISSLOW)) ! 222: tp->t_flags &= ~ISSLOW; ! 223: else ! 224: tp->t_flags |= ISHASTE; ! 225: } ! 226: else ! 227: { ! 228: if (on(*tp, ISHASTE)) ! 229: tp->t_flags &= ~ISHASTE; ! 230: else ! 231: tp->t_flags |= ISSLOW; ! 232: tp->t_turn = TRUE; ! 233: } ! 234: delta.y = y; ! 235: delta.x = x; ! 236: runto(&delta, &hero); ! 237: } ! 238: when WS_ELECT: ! 239: case WS_FIRE: ! 240: case WS_COLD: ! 241: { ! 242: register char dirch, ch, *name; ! 243: register bool bounced, used; ! 244: coord pos; ! 245: coord spotpos[BOLT_LENGTH]; ! 246: static struct object bolt = ! 247: { ! 248: '*' , {0, 0}, "", 0, 0, "6d6" , 0, 0, 100, 0 ! 249: }; ! 250: ! 251: ! 252: switch (delta.y + delta.x) ! 253: { ! 254: when 0: dirch = '/'; ! 255: when 1: case -1: dirch = (delta.y == 0 ? '-' : '|'); ! 256: when 2: case -2: dirch = '\\'; ! 257: } ! 258: pos = hero; ! 259: bounced = FALSE; ! 260: used = FALSE; ! 261: if (obj->o_which == WS_ELECT) ! 262: name = "bolt"; ! 263: else if (obj->o_which == WS_FIRE) ! 264: name = "flame"; ! 265: else ! 266: name = "ice"; ! 267: for (y = 0; y < BOLT_LENGTH && !used; y++) ! 268: { ! 269: ch = winat(pos.y, pos.x); ! 270: spotpos[y] = pos; ! 271: switch (ch) ! 272: { ! 273: case DOOR: ! 274: case SECRETDOOR: ! 275: case '|': ! 276: case '-': ! 277: case ' ': ! 278: bounced = TRUE; ! 279: delta.y = -delta.y; ! 280: delta.x = -delta.x; ! 281: y--; ! 282: msg("The bolt bounces"); ! 283: break; ! 284: default: ! 285: if (!bounced && isupper(ch)) ! 286: { ! 287: if (!save_throw(VS_MAGIC, ldata(find_mons(unc(pos))))) ! 288: { ! 289: bolt.o_pos = pos; ! 290: hit_monster(unc(pos), &bolt); ! 291: used = TRUE; ! 292: } ! 293: else if (ch != 'M' || show(pos.y, pos.x) == 'M') ! 294: { ! 295: if (terse) ! 296: msg("%s misses", name); ! 297: else ! 298: msg("The %s whizzes past the %s", name, monsters[ch-'A'].m_name); ! 299: runto(&pos, &hero); ! 300: } ! 301: } ! 302: else if (bounced && pos.y == hero.y && pos.x == hero.x) ! 303: { ! 304: bounced = FALSE; ! 305: if (!save(VS_MAGIC)) ! 306: { ! 307: if (terse) ! 308: msg("The %s hits", name); ! 309: else ! 310: msg("You are hit by the %s", name); ! 311: if ((pstats.s_hpt -= roll(6, 6)) <= 0) ! 312: death('b'); ! 313: used = TRUE; ! 314: } ! 315: else ! 316: msg("The %s whizzes by you", name); ! 317: } ! 318: mvwaddch(cw, pos.y, pos.x, dirch); ! 319: draw(cw); ! 320: } ! 321: pos.y += delta.y; ! 322: pos.x += delta.x; ! 323: } ! 324: for (x = 0; x < y; x++) ! 325: mvwaddch(cw, spotpos[x].y, spotpos[x].x, show(spotpos[x].y, spotpos[x].x)); ! 326: ws_know[obj->o_which] = TRUE; ! 327: } ! 328: otherwise: ! 329: msg("What a bizarre schtick!"); ! 330: } ! 331: obj->o_charges--; ! 332: } ! 333: ! 334: /* ! 335: * drain: ! 336: * Do drain hit points from player shtick ! 337: */ ! 338: ! 339: drain(ymin, ymax, xmin, xmax) ! 340: int ymin, ymax, xmin, xmax; ! 341: { ! 342: register int i, j, count; ! 343: register struct thing *ick; ! 344: register struct linked_list *item; ! 345: ! 346: /* ! 347: * First count how many things we need to spread the hit points among ! 348: */ ! 349: count = 0; ! 350: for (i = ymin; i <= ymax; i++) ! 351: for (j = xmin; j <= xmax; j++) ! 352: if (isupper(mvwinch(mw, i, j))) ! 353: count++; ! 354: if (count == 0) ! 355: { ! 356: msg("You have a tingling feeling"); ! 357: return; ! 358: } ! 359: count = pstats.s_hpt / count; ! 360: pstats.s_hpt /= 2; ! 361: /* ! 362: * Now zot all of the monsters ! 363: */ ! 364: for (i = ymin; i <= ymax; i++) ! 365: for (j = xmin; j <= xmax; j++) ! 366: if (isupper(mvwinch(mw, i, j)) && ! 367: ((item = find_mons(i, j)) != NULL)) ! 368: { ! 369: ick = (struct thing *) ldata(item); ! 370: if ((ick->t_stats.s_hpt -= count) < 1) ! 371: killed(item, cansee(i, j) && !on(*ick, ISINVIS)); ! 372: } ! 373: } ! 374: ! 375: /* ! 376: * charge a wand for wizards. ! 377: */ ! 378: char * ! 379: charge_str(obj) ! 380: register struct object *obj; ! 381: { ! 382: static char buf[20]; ! 383: ! 384: if (!(obj->o_flags & ISKNOW)) ! 385: buf[0] = '\0'; ! 386: else if (terse) ! 387: sprintf(buf, " [%d]", obj->o_charges); ! 388: else ! 389: sprintf(buf, " [%d charges]", obj->o_charges); ! 390: return buf; ! 391: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.