Annotation of early-roguelike/rogue5/sticks.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Functions to implement the various sticks one might find
! 3: * while wandering around the dungeon.
! 4: *
! 5: * @(#)sticks.c 4.39 (Berkeley) 02/05/99
! 6: *
! 7: * Rogue: Exploring the Dungeons of Doom
! 8: * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
! 9: * All rights reserved.
! 10: *
! 11: * See the file LICENSE.TXT for full copyright and licensing information.
! 12: */
! 13:
! 14: #include <curses.h>
! 15: #include <string.h>
! 16: #include <ctype.h>
! 17: #include "rogue.h"
! 18:
! 19: /*
! 20: * fix_stick:
! 21: * Set up a new stick
! 22: */
! 23:
! 24: void
! 25: fix_stick(THING *cur)
! 26: {
! 27: if (strcmp(ws_type[cur->o_which], "staff") == 0)
! 28: strncpy(cur->o_damage,"2x3",sizeof(cur->o_damage));
! 29: else
! 30: strncpy(cur->o_damage,"1x1",sizeof(cur->o_damage));
! 31: strncpy(cur->o_hurldmg,"1x1",sizeof(cur->o_hurldmg));
! 32:
! 33: switch (cur->o_which)
! 34: {
! 35: case WS_LIGHT:
! 36: cur->o_charges = rnd(10) + 10;
! 37: otherwise:
! 38: cur->o_charges = rnd(5) + 3;
! 39: }
! 40: }
! 41:
! 42: /*
! 43: * do_zap:
! 44: * Perform a zap with a wand
! 45: */
! 46:
! 47: void
! 48: do_zap(void)
! 49: {
! 50: THING *obj, *tp;
! 51: int y, x;
! 52: char *name;
! 53: int monster, oldch;
! 54: THING bolt;
! 55:
! 56: if ((obj = get_item("zap with", STICK)) == NULL)
! 57: return;
! 58: if (obj->o_type != STICK)
! 59: {
! 60: after = FALSE;
! 61: msg("you can't zap with that!");
! 62: return;
! 63: }
! 64: if (obj->o_charges == 0)
! 65: {
! 66: msg("nothing happens");
! 67: return;
! 68: }
! 69: switch (obj->o_which)
! 70: {
! 71: case WS_LIGHT:
! 72: /*
! 73: * Reddy Kilowat wand. Light up the room
! 74: */
! 75: ws_info[WS_LIGHT].oi_know = TRUE;
! 76: if (proom->r_flags & ISGONE)
! 77: msg("the corridor glows and then fades");
! 78: else
! 79: {
! 80: proom->r_flags &= ~ISDARK;
! 81: /*
! 82: * Light the room and put the player back up
! 83: */
! 84: enter_room(&hero);
! 85: addmsg("the room is lit");
! 86: if (!terse)
! 87: addmsg(" by a shimmering %s light", pick_color("blue"));
! 88: endmsg();
! 89: }
! 90: when WS_DRAIN:
! 91: /*
! 92: * take away 1/2 of hero's hit points, then take it away
! 93: * evenly from the monsters in the room (or next to hero
! 94: * if he is in a passage)
! 95: */
! 96: if (pstats.s_hpt < 2)
! 97: {
! 98: msg("you are too weak to use it");
! 99: return;
! 100: }
! 101: else
! 102: drain();
! 103: when WS_INVIS:
! 104: case WS_POLYMORPH:
! 105: case WS_TELAWAY:
! 106: case WS_TELTO:
! 107: case WS_CANCEL:
! 108: y = hero.y;
! 109: x = hero.x;
! 110: while (step_ok(winat(y, x)))
! 111: {
! 112: y += delta.y;
! 113: x += delta.x;
! 114: }
! 115: if ((tp = moat(y, x)) != NULL)
! 116: {
! 117: monster = tp->t_type;
! 118: if (monster == 'F')
! 119: player.t_flags &= ~ISHELD;
! 120: switch (obj->o_which) {
! 121: case WS_INVIS:
! 122: tp->t_flags |= ISINVIS;
! 123: if (cansee(y, x))
! 124: mvaddch(y, x, tp->t_oldch);
! 125: break;
! 126: case WS_POLYMORPH:
! 127: {
! 128: THING *pp;
! 129:
! 130: pp = tp->t_pack;
! 131: detach(mlist, tp);
! 132: if (see_monst(tp))
! 133: mvaddch(y, x, chat(y, x));
! 134: oldch = tp->t_oldch;
! 135: delta.y = y;
! 136: delta.x = x;
! 137: new_monster(tp, monster = rnd(26) + 'A', &delta);
! 138: if (see_monst(tp))
! 139: mvaddch(y, x, monster);
! 140: tp->t_oldch = oldch;
! 141: tp->t_pack = pp;
! 142: ws_info[WS_POLYMORPH].oi_know |= see_monst(tp);
! 143: break;
! 144: }
! 145: case WS_CANCEL:
! 146: tp->t_flags |= ISCANC;
! 147: tp->t_flags &= ~(ISINVIS|CANHUH);
! 148: tp->t_disguise = tp->t_type;
! 149: if (see_monst(tp))
! 150: mvaddch(y, x, tp->t_disguise);
! 151: break;
! 152: case WS_TELAWAY:
! 153: case WS_TELTO:
! 154: {
! 155: coord new_pos;
! 156:
! 157: if (obj->o_which == WS_TELAWAY)
! 158: {
! 159: do
! 160: {
! 161: find_floor(NULL, &new_pos, FALSE, TRUE);
! 162: } while (ce(new_pos, hero));
! 163: }
! 164: else
! 165: {
! 166: new_pos.y = hero.y + delta.y;
! 167: new_pos.x = hero.x + delta.x;
! 168: }
! 169: tp->t_dest = &hero;
! 170: tp->t_flags |= ISRUN;
! 171: relocate(tp, &new_pos);
! 172: }
! 173: }
! 174: }
! 175: when WS_MISSILE:
! 176: ws_info[WS_MISSILE].oi_know = TRUE;
! 177: bolt.o_type = '*';
! 178: strncpy(bolt.o_hurldmg,"1x4",sizeof(bolt.o_hurldmg));
! 179: bolt.o_hplus = 100;
! 180: bolt.o_dplus = 1;
! 181: bolt.o_flags = ISMISL;
! 182: if (cur_weapon != NULL)
! 183: bolt.o_launch = cur_weapon->o_which;
! 184: do_motion(&bolt, delta.y, delta.x);
! 185: if ((tp = moat(bolt.o_pos.y, bolt.o_pos.x)) != NULL
! 186: && !save_throw(VS_MAGIC, tp))
! 187: hit_monster(unc(bolt.o_pos), &bolt);
! 188: else if (terse)
! 189: msg("missle vanishes");
! 190: else
! 191: msg("the missle vanishes with a puff of smoke");
! 192: when WS_HASTE_M:
! 193: case WS_SLOW_M:
! 194: y = hero.y;
! 195: x = hero.x;
! 196: while (step_ok(winat(y, x)))
! 197: {
! 198: y += delta.y;
! 199: x += delta.x;
! 200: }
! 201: if ((tp = moat(y, x)) != NULL)
! 202: {
! 203: if (obj->o_which == WS_HASTE_M)
! 204: {
! 205: if (on(*tp, ISSLOW))
! 206: tp->t_flags &= ~ISSLOW;
! 207: else
! 208: tp->t_flags |= ISHASTE;
! 209: }
! 210: else
! 211: {
! 212: if (on(*tp, ISHASTE))
! 213: tp->t_flags &= ~ISHASTE;
! 214: else
! 215: tp->t_flags |= ISSLOW;
! 216: tp->t_turn = TRUE;
! 217: }
! 218: delta.y = y;
! 219: delta.x = x;
! 220: runto(&delta);
! 221: }
! 222: when WS_ELECT:
! 223: case WS_FIRE:
! 224: case WS_COLD:
! 225: if (obj->o_which == WS_ELECT)
! 226: name = "bolt";
! 227: else if (obj->o_which == WS_FIRE)
! 228: name = "flame";
! 229: else
! 230: name = "ice";
! 231: fire_bolt(&hero, &delta, name);
! 232: ws_info[obj->o_which].oi_know = TRUE;
! 233: when WS_NOP:
! 234: break;
! 235: #ifdef MASTER
! 236: otherwise:
! 237: msg("what a bizarre schtick!");
! 238: #endif
! 239: }
! 240: obj->o_charges--;
! 241: }
! 242:
! 243: /*
! 244: * drain:
! 245: * Do drain hit points from player shtick
! 246: */
! 247:
! 248: void
! 249: drain(void)
! 250: {
! 251: THING *mp;
! 252: struct room *corp;
! 253: THING **dp;
! 254: int cnt;
! 255: int inpass;
! 256: THING *drainee[40];
! 257:
! 258: /*
! 259: * First cnt how many things we need to spread the hit points among
! 260: */
! 261: cnt = 0;
! 262: if (chat(hero.y, hero.x) == DOOR)
! 263: corp = &passages[flat(hero.y, hero.x) & F_PNUM];
! 264: else
! 265: corp = NULL;
! 266: inpass = (proom->r_flags & ISGONE);
! 267: dp = drainee;
! 268: for (mp = mlist; mp != NULL; mp = next(mp))
! 269: if (mp->t_room == proom || mp->t_room == corp ||
! 270: (inpass && chat(mp->t_pos.y, mp->t_pos.x) == DOOR &&
! 271: &passages[flat(mp->t_pos.y, mp->t_pos.x) & F_PNUM] == proom))
! 272: *dp++ = mp;
! 273: if ((cnt = (int)(dp - drainee)) == 0)
! 274: {
! 275: msg("you have a tingling feeling");
! 276: return;
! 277: }
! 278: *dp = NULL;
! 279: pstats.s_hpt /= 2;
! 280: cnt = pstats.s_hpt / cnt;
! 281: /*
! 282: * Now zot all of the monsters
! 283: */
! 284: for (dp = drainee; *dp; dp++)
! 285: {
! 286: mp = *dp;
! 287: if ((mp->t_stats.s_hpt -= cnt) <= 0)
! 288: killed(mp, see_monst(mp));
! 289: else
! 290: runto(&mp->t_pos);
! 291: }
! 292: }
! 293:
! 294: /*
! 295: * fire_bolt:
! 296: * Fire a bolt in a given direction from a specific starting place
! 297: */
! 298:
! 299: void
! 300: fire_bolt(const coord *start, coord *dir, const char *name)
! 301: {
! 302: coord *c1, *c2;
! 303: THING *tp;
! 304: int dirch = 0, ch;
! 305: int hit_hero, used, changed;
! 306: coord pos;
! 307: coord spotpos[BOLT_LENGTH];
! 308: THING bolt;
! 309:
! 310: bolt.o_type = WEAPON;
! 311: bolt.o_which = FLAME;
! 312: strncpy(bolt.o_hurldmg,"6x6",sizeof(bolt.o_hurldmg));
! 313: strncpy(bolt.o_damage,"0x0",sizeof(bolt.o_damage));
! 314: bolt.o_launch = -1;
! 315: bolt.o_hplus = 100;
! 316: bolt.o_dplus = 0;
! 317: weap_info[FLAME].oi_name = name;
! 318: switch (dir->y + dir->x)
! 319: {
! 320: case 0: dirch = '/';
! 321: when 1: case -1: dirch = (dir->y == 0 ? '-' : '|');
! 322: when 2: case -2: dirch = '\\';
! 323: }
! 324: pos = *start;
! 325: hit_hero = (start != &hero);
! 326: used = FALSE;
! 327: changed = FALSE;
! 328: for (c1 = spotpos; c1 <= &spotpos[BOLT_LENGTH-1] && !used; c1++)
! 329: {
! 330: pos.y += dir->y;
! 331: pos.x += dir->x;
! 332: *c1 = pos;
! 333: ch = winat(pos.y, pos.x);
! 334: switch (ch)
! 335: {
! 336: case DOOR:
! 337: /*
! 338: * this code is necessary if the hero is on a door
! 339: * and he fires at the wall the door is in, it would
! 340: * otherwise loop infinitely
! 341: */
! 342: if (ce(hero, pos))
! 343: goto def;
! 344: /* FALLTHROUGH */
! 345: case '|':
! 346: case '-':
! 347: case ' ':
! 348: if (!changed)
! 349: hit_hero = !hit_hero;
! 350: changed = FALSE;
! 351: dir->y = -dir->y;
! 352: dir->x = -dir->x;
! 353: c1--;
! 354: msg("the %s bounces", name);
! 355: break;
! 356: default:
! 357: def:
! 358: if (!hit_hero && (tp = moat(pos.y, pos.x)) != NULL)
! 359: {
! 360: hit_hero = TRUE;
! 361: changed = !changed;
! 362: tp->t_oldch = chat(pos.y, pos.x);
! 363: if (!save_throw(VS_MAGIC, tp))
! 364: {
! 365: bolt.o_pos = pos;
! 366: used = TRUE;
! 367: if (tp->t_type == 'D' && strcmp(name, "flame") == 0)
! 368: {
! 369: addmsg("the flame bounces");
! 370: if (!terse)
! 371: addmsg(" off the dragon");
! 372: endmsg();
! 373: }
! 374: else
! 375: hit_monster(unc(pos), &bolt);
! 376: }
! 377: else if (ch != 'M' || tp->t_disguise == 'M')
! 378: {
! 379: if (start == &hero)
! 380: runto(&pos);
! 381: if (terse)
! 382: msg("%s misses", name);
! 383: else
! 384: msg("the %s whizzes past %s", name, set_mname(tp));
! 385: }
! 386: }
! 387: else if (hit_hero && ce(pos, hero))
! 388: {
! 389: hit_hero = FALSE;
! 390: changed = !changed;
! 391: if (!save(VS_MAGIC))
! 392: {
! 393: if ((pstats.s_hpt -= roll(6, 6)) <= 0)
! 394: {
! 395: if (start == &hero)
! 396: death('b');
! 397: else
! 398: death(moat(start->y, start->x)->t_type);
! 399: }
! 400: used = TRUE;
! 401: if (terse)
! 402: msg("the %s hits", name);
! 403: else
! 404: msg("you are hit by the %s", name);
! 405: }
! 406: else
! 407: msg("the %s whizzes by you", name);
! 408: }
! 409: mvaddch(pos.y, pos.x, dirch);
! 410: refresh();
! 411: }
! 412: }
! 413: for (c2 = spotpos; c2 < c1; c2++)
! 414: mvaddch(c2->y, c2->x, chat(c2->y, c2->x));
! 415: }
! 416:
! 417: /*
! 418: * charge_str:
! 419: * Return an appropriate string for a wand charge
! 420: */
! 421: const char *
! 422: charge_str(const THING *obj)
! 423: {
! 424: static char buf[20];
! 425:
! 426: if (!(obj->o_flags & ISKNOW))
! 427: buf[0] = '\0';
! 428: else if (terse)
! 429: sprintf(buf, " [%d]", obj->o_charges);
! 430: else
! 431: sprintf(buf, " [%d charges]", obj->o_charges);
! 432: return buf;
! 433: }
CVSweb