/* * Functions to implement the various sticks one might find * while wandering around the dungeon. * * @(#)sticks.c 3.14 (Berkeley) 6/15/81 * * Rogue: Exploring the Dungeons of Doom * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman * All rights reserved. * * See the file LICENSE.TXT for full copyright and licensing information. */ #include "curses.h" #include #include #include "rogue.h" void fix_stick(struct object *cur) { if (strcmp(ws_type[cur->o_which], "staff") == 0) strcpy(cur->o_damage,"2d3"); else strcpy(cur->o_damage,"1d1"); strcpy(cur->o_hurldmg,"1d1"); cur->o_charges = 3 + rnd(5); switch (cur->o_which) { case WS_HIT: cur->o_hplus = 3; cur->o_dplus = 3; strcpy(cur->o_damage,"1d8"); when WS_LIGHT: cur->o_charges = 10 + rnd(10); } } void do_zap(int gotdir) { struct linked_list *item; struct object *obj; struct room *rp; struct thing *tp; int y, x; if ((item = get_item("zap with", STICK)) == NULL) return; obj = (struct object *) ldata(item); if (obj->o_type != STICK) { msg("You can't zap with that!"); after = FALSE; return; } if (obj->o_charges == 0) { msg("Nothing happens."); return; } if (!gotdir) do { delta.y = rnd(3) - 1; delta.x = rnd(3) - 1; } while (delta.y == 0 && delta.x == 0); switch (obj->o_which) { case WS_LIGHT: /* * Reddy Kilowat wand. Light up the room */ ws_know[WS_LIGHT] = TRUE; if ((rp = roomin(&hero)) == NULL) msg("The corridor glows and then fades"); else { addmsg("The room is lit"); if (!terse) addmsg(" by a shimmering blue light."); endmsg(); rp->r_flags &= ~ISDARK; /* * Light the room and put the player back up */ light(&hero); mvwaddch(cw, hero.y, hero.x, PLAYER); } when WS_DRAIN: /* * Take away 1/2 of hero's hit points, then take it away * evenly from the monsters in the room (or next to hero * if he is in a passage) */ if (pstats.s_hpt < 2) { msg("You are too weak to use it."); return; } else if ((rp = roomin(&hero)) == NULL) drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1); else drain(rp->r_pos.y, rp->r_pos.y+rp->r_max.y, rp->r_pos.x, rp->r_pos.x+rp->r_max.x); when WS_POLYMORPH: case WS_TELAWAY: case WS_TELTO: case WS_CANCEL: { int monster; int oldch; int rm; y = hero.y; x = hero.x; while (step_ok(winat(y, x))) { y += delta.y; x += delta.x; } if (isupper(monster = mvwinch(mw, y, x))) { int omonst = monster; if (monster == 'F') player.t_flags &= ~ISHELD; item = find_mons(y, x); tp = (struct thing *) ldata(item); if (obj->o_which == WS_POLYMORPH) { detach(mlist, item); oldch = tp->t_oldch; delta.y = y; delta.x = x; new_monster(item, monster = rnd(26) + 'A', &delta); if (!(tp->t_flags & ISRUN)) runto(&delta, &hero); if (isupper(mvwinch(cw, y, x))) mvwaddch(cw, y, x, monster); tp->t_oldch = oldch; ws_know[WS_POLYMORPH] |= (monster != omonst); } else if (obj->o_which == WS_CANCEL) { tp->t_flags |= ISCANC; tp->t_flags &= ~ISINVIS; } else { if (obj->o_which == WS_TELAWAY) { do { rm = rnd_room(); rnd_pos(&rooms[rm], &tp->t_pos); } until(winat(tp->t_pos.y, tp->t_pos.x) == FLOOR); } else { tp->t_pos.y = hero.y + delta.y; tp->t_pos.x = hero.x + delta.x; } if (isupper(mvwinch(cw, y, x))) mvwaddch(cw, y, x, tp->t_oldch); tp->t_dest = &hero; tp->t_flags |= ISRUN; mvwaddch(mw, y, x, ' '); mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, monster); if (tp->t_pos.y != y || tp->t_pos.x != x) tp->t_oldch = mvwinch(cw, tp->t_pos.y, tp->t_pos.x); } } } when WS_MISSILE: { static struct object bolt = { '*' , {0, 0}, 0, "", "1d4" , 0, 0, 100, 1, 0, 0, 0 }; do_motion(&bolt, delta.y, delta.x); if (isupper(mvwinch(mw, bolt.o_pos.y, bolt.o_pos.x)) && !save_throw(VS_MAGIC, THINGPTR(find_mons(unc(bolt.o_pos))))) hit_monster(unc(bolt.o_pos), &bolt); else if (terse) msg("Missile vanishes"); else msg("The missile vanishes with a puff of smoke"); ws_know[WS_MISSILE] = TRUE; } when WS_HIT: { int ch; delta.y += hero.y; delta.x += hero.x; ch = winat(delta.y, delta.x); if (isupper(ch)) { if (rnd(20) == 0) { strcpy(obj->o_damage,"3d8"); obj->o_dplus = 9; } else { strcpy(obj->o_damage,"1d8"); obj->o_dplus = 3; } fight(&delta, ch, obj, FALSE); } } when WS_HASTE_M: case WS_SLOW_M: y = hero.y; x = hero.x; while (step_ok(winat(y, x))) { y += delta.y; x += delta.x; } if (isupper(mvwinch(mw, y, x))) { item = find_mons(y, x); tp = (struct thing *) ldata(item); if (obj->o_which == WS_HASTE_M) { if (on(*tp, ISSLOW)) tp->t_flags &= ~ISSLOW; else tp->t_flags |= ISHASTE; } else { if (on(*tp, ISHASTE)) tp->t_flags &= ~ISHASTE; else tp->t_flags |= ISSLOW; tp->t_turn = TRUE; } delta.y = y; delta.x = x; runto(&delta, &hero); } when WS_ELECT: case WS_FIRE: case WS_COLD: { int dirch; char *name; int ch; int bounced, used; coord pos; coord spotpos[BOLT_LENGTH]; static struct object bolt = { '*' , {0, 0}, 0, "", "6d6" , 0, 0, 100, 0, 0, 0 ,0 }; switch (delta.y + delta.x) { case 0: dirch = '/'; when 1: case -1: dirch = (delta.y == 0 ? '-' : '|'); when 2: case -2: dirch = '\\'; } pos = hero; bounced = FALSE; used = FALSE; if (obj->o_which == WS_ELECT) name = "bolt"; else if (obj->o_which == WS_FIRE) name = "flame"; else name = "ice"; for (y = 0; y < BOLT_LENGTH && !used; y++) { ch = winat(pos.y, pos.x); spotpos[y] = pos; switch (ch) { case DOOR: case SECRETDOOR: case '|': case '-': case ' ': bounced = TRUE; delta.y = -delta.y; delta.x = -delta.x; y--; msg("The bolt bounces"); break; default: if (!bounced && isupper(ch)) { if (!save_throw(VS_MAGIC, THINGPTR(find_mons(unc(pos))))) { bolt.o_pos = pos; hit_monster(unc(pos), &bolt); used = TRUE; } else if (ch != 'M' || show(pos.y, pos.x) == 'M') { if (terse) msg("%s misses", name); else msg("The %s whizzes past the %s", name, monsters[ch-'A'].m_name); runto(&pos, &hero); } } else if (bounced && pos.y == hero.y && pos.x == hero.x) { bounced = FALSE; if (!save(VS_MAGIC)) { if (terse) msg("The %s hits", name); else msg("You are hit by the %s", name); if ((pstats.s_hpt -= roll(6, 6)) <= 0) death('b'); used = TRUE; } else msg("The %s whizzes by you", name); } mvwaddch(cw, pos.y, pos.x, dirch); draw(cw); } pos.y += delta.y; pos.x += delta.x; } for (x = 0; x < y; x++) mvwaddch(cw, spotpos[x].y, spotpos[x].x, show(spotpos[x].y, spotpos[x].x)); ws_know[obj->o_which] = TRUE; } when WS_NOP: otherwise: msg("What a bizarre schtick!"); } obj->o_charges--; } /* * drain: * Do drain hit points from player shtick */ void drain(int ymin, int ymax, int xmin, int xmax) { int i, j, cnt; struct thing *ick; struct linked_list *item; /* * First count how many things we need to spread the hit points among */ cnt = 0; for (i = ymin; i <= ymax; i++) for (j = xmin; j <= xmax; j++) if (isupper(mvwinch(mw, i, j))) cnt++; if (cnt == 0) { msg("You have a tingling feeling"); return; } cnt = pstats.s_hpt / cnt; pstats.s_hpt /= 2; /* * Now zot all of the monsters */ for (i = ymin; i <= ymax; i++) for (j = xmin; j <= xmax; j++) if (isupper(mvwinch(mw, i, j)) && ((item = find_mons(i, j)) != NULL)) { ick = (struct thing *) ldata(item); if ((ick->t_stats.s_hpt -= cnt) < 1) killed(item, cansee(i, j) && !on(*ick, ISINVIS)); } } /* * charge a wand for wizards. */ char * charge_str(struct object *obj) { static char buf[20]; if (!(obj->o_flags & ISKNOW)) buf[0] = '\0'; else if (terse) sprintf(buf, " [%d]", obj->o_charges); else sprintf(buf, " [%d charges]", obj->o_charges); return buf; }