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