Annotation of early-roguelike/rogue3/weapons.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Functions for dealing with problems brought about by weapons
! 3: *
! 4: * @(#)weapons.c 3.17 (Berkeley) 6/15/81
! 5: *
! 6: * Rogue: Exploring the Dungeons of Doom
! 7: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 8: * All rights reserved.
! 9: *
! 10: * See the file LICENSE.TXT for full copyright and licensing information.
! 11: */
! 12:
! 13: #include "curses.h"
! 14: #include <ctype.h>
! 15: #include <string.h>
! 16: #include "rogue.h"
! 17:
! 18: #define NONE 100
! 19:
! 20: char *w_names[MAXWEAPONS] = {
! 21: "mace",
! 22: "long sword",
! 23: "short bow",
! 24: "arrow",
! 25: "dagger",
! 26: "rock",
! 27: "two handed sword",
! 28: "sling",
! 29: "dart",
! 30: "crossbow",
! 31: "crossbow bolt",
! 32: "spear",
! 33: };
! 34:
! 35: static struct init_weps {
! 36: char *iw_dam;
! 37: char *iw_hrl;
! 38: int iw_launch;
! 39: int iw_flags;
! 40: } init_dam[MAXWEAPONS] = {
! 41: { "2d4", "1d3", NONE, 0 }, /* Mace */
! 42: { "1d10", "1d2", NONE,0 }, /* Long sword */
! 43: { "1d1", "1d1", NONE, 0 }, /* Bow */
! 44: { "1d1", "1d6", BOW, ISMANY|ISMISL }, /* Arrow */
! 45: { "1d6", "1d4", NONE, ISMISL }, /* Dagger */
! 46: { "1d2", "1d4", SLING,ISMANY|ISMISL }, /* Rock */
! 47: { "3d6", "1d2", NONE, 0 }, /* 2h sword */
! 48: { "0d0", "0d0", NONE, 0 }, /* Sling */
! 49: { "1d1", "1d3", NONE, ISMANY|ISMISL }, /* Dart */
! 50: { "1d1", "1d1", NONE, 0 }, /* Crossbow */
! 51: { "1d2", "1d10", CROSSBOW, ISMANY|ISMISL }, /* Crossbow bolt */
! 52: { "1d8", "1d6", NONE, ISMISL } /* Spear */
! 53: };
! 54:
! 55: /*
! 56: * missile:
! 57: * Fire a missile in a given direction
! 58: */
! 59:
! 60: void
! 61: missile(int ydelta, int xdelta)
! 62: {
! 63: struct object *obj;
! 64: struct linked_list *item, *nitem;
! 65:
! 66: /*
! 67: * Get which thing we are hurling
! 68: */
! 69: if ((item = get_item("throw", WEAPON)) == NULL)
! 70: return;
! 71: obj = (struct object *) ldata(item);
! 72: if (!dropcheck(obj) || is_current(obj))
! 73: return;
! 74: /*
! 75: * Get rid of the thing. If it is a non-multiple item object, or
! 76: * if it is the last thing, just drop it. Otherwise, create a new
! 77: * item with a count of one.
! 78: */
! 79: if (obj->o_count < 2)
! 80: {
! 81: detach(pack, item);
! 82: inpack--;
! 83: }
! 84: else
! 85: {
! 86: obj->o_count--;
! 87: if (obj->o_group == 0)
! 88: inpack--;
! 89: nitem = (struct linked_list *) new_item(sizeof *obj);
! 90: obj = (struct object *) ldata(nitem);
! 91: *obj = *((struct object *) ldata(item));
! 92: obj->o_count = 1;
! 93: item = nitem;
! 94: }
! 95: do_motion(obj, ydelta, xdelta);
! 96: /*
! 97: * AHA! Here it has hit something. If it is a wall or a door,
! 98: * or if it misses (combat) the mosnter, put it on the floor
! 99: */
! 100: if (!isupper(mvwinch(mw, obj->o_pos.y, obj->o_pos.x))
! 101: || !hit_monster(unc(obj->o_pos), obj))
! 102: fall(item, TRUE);
! 103: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 104: }
! 105:
! 106: /*
! 107: * do the actual motion on the screen done by an object traveling
! 108: * across the room
! 109: */
! 110: void
! 111: do_motion(struct object *obj, int ydelta, int xdelta)
! 112: {
! 113: /*
! 114: * Come fly with us ...
! 115: */
! 116: obj->o_pos = hero;
! 117: for (;;)
! 118: {
! 119: int ch;
! 120:
! 121: /*
! 122: * Erase the old one
! 123: */
! 124: if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)) &&
! 125: mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ')
! 126: mvwaddch(cw, obj->o_pos.y, obj->o_pos.x,
! 127: show(obj->o_pos.y, obj->o_pos.x));
! 128: /*
! 129: * Get the new position
! 130: */
! 131: obj->o_pos.y += ydelta;
! 132: obj->o_pos.x += xdelta;
! 133: if (step_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR)
! 134: {
! 135: /*
! 136: * It hasn't hit anything yet, so display it
! 137: * If it alright.
! 138: */
! 139: if (cansee(unc(obj->o_pos)) &&
! 140: mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ')
! 141: {
! 142: mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, obj->o_type);
! 143: draw(cw);
! 144: }
! 145: continue;
! 146: }
! 147: break;
! 148: }
! 149: }
! 150:
! 151: /*
! 152: * fall:
! 153: * Drop an item someplace around here.
! 154: */
! 155:
! 156: void
! 157: fall(struct linked_list *item, int pr)
! 158: {
! 159: struct object *obj;
! 160: struct room *rp;
! 161: static coord fpos;
! 162:
! 163: obj = (struct object *) ldata(item);
! 164: if (fallpos(&obj->o_pos, &fpos, TRUE))
! 165: {
! 166: mvaddch(fpos.y, fpos.x, obj->o_type);
! 167: obj->o_pos = fpos;
! 168: if ((rp = roomin(&hero)) != NULL && !(rp->r_flags & ISDARK))
! 169: {
! 170: light(&hero);
! 171: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 172: }
! 173: attach(lvl_obj, item);
! 174: return;
! 175: }
! 176: if (pr)
! 177: if (obj->o_type == WEAPON) /* BUGFUX: Identification trick */
! 178: msg("Your %s vanishes as it hits the ground.", w_names[obj->o_which]);
! 179: else
! 180: msg("%s vanishes as it hits the ground.", inv_name(obj,TRUE));
! 181: discard(item);
! 182: }
! 183:
! 184: /*
! 185: * init_weapon:
! 186: * Set up the initial goodies for a weapon
! 187: */
! 188:
! 189: void
! 190: init_weapon(struct object *weap, int type)
! 191: {
! 192: struct init_weps *iwp;
! 193:
! 194: iwp = &init_dam[type];
! 195: strcpy(weap->o_damage,iwp->iw_dam);
! 196: strcpy(weap->o_hurldmg,iwp->iw_hrl);
! 197: weap->o_launch = iwp->iw_launch;
! 198: weap->o_flags = iwp->iw_flags;
! 199: if (weap->o_flags & ISMANY)
! 200: {
! 201: weap->o_count = rnd(8) + 8;
! 202: weap->o_group = newgrp();
! 203: }
! 204: else
! 205: weap->o_count = 1;
! 206: }
! 207:
! 208: /*
! 209: * Does the missile hit the monster
! 210: */
! 211:
! 212: int
! 213: hit_monster(int y, int x, struct object *obj)
! 214: {
! 215: static coord mp;
! 216:
! 217: mp.y = y;
! 218: mp.x = x;
! 219: return fight(&mp, winat(y, x), obj, TRUE);
! 220: }
! 221:
! 222: /*
! 223: * num:
! 224: * Figure out the plus number for armor/weapons
! 225: */
! 226:
! 227: char *
! 228: num(int n1, int n2)
! 229: {
! 230: static char numbuf[80];
! 231:
! 232: if (n1 == 0 && n2 == 0)
! 233: return "+0";
! 234: if (n2 == 0)
! 235: sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1);
! 236: else
! 237: sprintf(numbuf, "%s%d,%s%d",
! 238: n1 < 0 ? "" : "+", n1, n2 < 0 ? "" : "+", n2);
! 239: return numbuf;
! 240: }
! 241:
! 242: /*
! 243: * wield:
! 244: * Pull out a certain weapon
! 245: */
! 246:
! 247: void
! 248: wield()
! 249: {
! 250: struct linked_list *item;
! 251: struct object *obj, *oweapon;
! 252:
! 253: oweapon = cur_weapon;
! 254: if (!dropcheck(cur_weapon))
! 255: {
! 256: cur_weapon = oweapon;
! 257: return;
! 258: }
! 259: cur_weapon = oweapon;
! 260: if ((item = get_item("wield", WEAPON)) == NULL)
! 261: {
! 262: bad:
! 263: after = FALSE;
! 264: return;
! 265: }
! 266:
! 267: obj = (struct object *) ldata(item);
! 268: if (obj->o_type == ARMOR)
! 269: {
! 270: msg("You can't wield armor");
! 271: goto bad;
! 272: }
! 273: if (is_current(obj))
! 274: goto bad;
! 275:
! 276: if (terse)
! 277: addmsg("W");
! 278: else
! 279: addmsg("You are now w");
! 280: msg("ielding %s", inv_name(obj, TRUE));
! 281: cur_weapon = obj;
! 282: }
! 283:
! 284: /*
! 285: * pick a random position around the give (y, x) coordinates
! 286: */
! 287: int
! 288: fallpos(coord *pos, coord *newpos, int passages)
! 289: {
! 290: int y, x, cnt, ch;
! 291:
! 292: cnt = 0;
! 293: for (y = pos->y - 1; y <= pos->y + 1; y++)
! 294: for (x = pos->x - 1; x <= pos->x + 1; x++)
! 295: {
! 296: /*
! 297: * check to make certain the spot is empty, if it is,
! 298: * put the object there, set it in the level list
! 299: * and re-draw the room if he can see it
! 300: */
! 301: if (y == hero.y && x == hero.x)
! 302: continue;
! 303: if (((ch = winat(y, x)) == FLOOR || (passages && ch == PASSAGE))
! 304: && rnd(++cnt) == 0)
! 305: {
! 306: newpos->y = y;
! 307: newpos->x = x;
! 308: }
! 309: }
! 310: return (cnt != 0);
! 311: }
CVSweb