Annotation of early-roguelike/rogue4/weapons.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Functions for dealing with problems brought about by weapons
! 3: *
! 4: * @(#)weapons.c 4.14 (Berkeley) 4/6/82
! 5: *
! 6: * Rogue: Exploring the Dungeons of Doom
! 7: * Copyright (C) 1980, 1981, 1982 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: static struct init_weps {
! 21: char *iw_dam; /* Damage when wielded */
! 22: char *iw_hrl; /* Damage when thrown */
! 23: char iw_launch; /* Launching weapon */
! 24: int iw_flags; /* Miscellaneous flags */
! 25: } init_dam[MAXWEAPONS] = {
! 26: { "2d4", "1d3", NONE, 0 }, /* Mace */
! 27: { "3d4", "1d2", NONE, 0 }, /* Long sword */
! 28: { "1d1", "1d1", NONE, 0 }, /* Bow */
! 29: { "1d1", "2d3", BOW, ISMANY|ISMISL },/* Arrow */
! 30: { "1d6", "1d4", NONE, ISMISL }, /* Dagger */
! 31: { "4d4", "1d2", NONE, 0 }, /* 2h sword */
! 32: { "1d1", "1d3", NONE, ISMANY|ISMISL },/* Dart */
! 33: { "1d1", "1d1", NONE, 0 }, /* Crossbow */
! 34: { "1d2", "2d5", CROSSBOW, ISMANY|ISMISL },/* Crossbow bolt */
! 35: { "2d3", "1d6", NONE, ISMISL } /* Spear */
! 36: };
! 37:
! 38: /*
! 39: * missile:
! 40: * Fire a missile in a given direction
! 41: */
! 42: void
! 43: missile(int ydelta, int xdelta)
! 44: {
! 45: register THING *obj, *nitem;
! 46:
! 47: /*
! 48: * Get which thing we are hurling
! 49: */
! 50: if ((obj = get_item("throw", WEAPON)) == NULL)
! 51: return;
! 52: if (!dropcheck(obj) || is_current(obj))
! 53: return;
! 54: /*
! 55: * Get rid of the thing. If it is a non-multiple item object, or
! 56: * if it is the last thing, just drop it. Otherwise, create a new
! 57: * item with a count of one.
! 58: */
! 59: if (obj->o_count < 2)
! 60: {
! 61: detach(pack, obj);
! 62: inpack--;
! 63: }
! 64: else
! 65: {
! 66: obj->o_count--;
! 67: if (obj->o_group == 0)
! 68: inpack--;
! 69: nitem = new_item();
! 70: *nitem = *obj;
! 71: nitem->o_count = 1;
! 72: obj = nitem;
! 73: }
! 74: do_motion(obj, ydelta, xdelta);
! 75: /*
! 76: * AHA! Here it has hit something. If it is a wall or a door,
! 77: * or if it misses (combat) the monster, put it on the floor
! 78: */
! 79: if (moat(obj->o_pos.y, obj->o_pos.x) == NULL
! 80: || !hit_monster(unc(obj->o_pos), obj))
! 81: fall(obj, TRUE);
! 82: }
! 83:
! 84: /*
! 85: * do_motion:
! 86: * Do the actual motion on the screen done by an object traveling
! 87: * across the room
! 88: */
! 89: void
! 90: do_motion(THING *obj, int ydelta, int xdelta)
! 91: {
! 92: /*
! 93: * Come fly with us ...
! 94: */
! 95: obj->o_pos = hero;
! 96: for (;;)
! 97: {
! 98: register int ch;
! 99:
! 100: /*
! 101: * Erase the old one
! 102: */
! 103: if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)))
! 104: mvaddch(obj->o_pos.y, obj->o_pos.x, chat(obj->o_pos.y, obj->o_pos.x));
! 105: /*
! 106: * Get the new position
! 107: */
! 108: obj->o_pos.y += ydelta;
! 109: obj->o_pos.x += xdelta;
! 110: if (step_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR)
! 111: {
! 112: /*
! 113: * It hasn't hit anything yet, so display it
! 114: * If it alright.
! 115: */
! 116: if (cansee(unc(obj->o_pos)))
! 117: {
! 118: mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type);
! 119: refresh();
! 120: }
! 121: continue;
! 122: }
! 123: break;
! 124: }
! 125: }
! 126:
! 127: /*
! 128: * fall:
! 129: * Drop an item someplace around here.
! 130: */
! 131: void
! 132: fall(THING *obj, bool pr)
! 133: {
! 134: static coord fpos;
! 135: register int index;
! 136:
! 137: if (fallpos(&obj->o_pos, &fpos, TRUE))
! 138: {
! 139: index = INDEX(fpos.y, fpos.x);
! 140: _level[index] = obj->o_type;
! 141: obj->o_pos = fpos;
! 142: if (cansee(fpos.y, fpos.x))
! 143: {
! 144: mvaddch(fpos.y, fpos.x, obj->o_type);
! 145: if (_monst[index] != NULL)
! 146: _monst[index]->t_oldch = obj->o_type;
! 147: }
! 148: attach(lvl_obj, obj);
! 149: return;
! 150: }
! 151:
! 152: if (pr)
! 153: msg("the %s vanishes as it hits the ground",
! 154: /* BUGFIX: Identification trick */
! 155: (obj->o_type==WEAPON) ? w_names[obj->o_which] : inv_name(obj,TRUE));
! 156:
! 157: discard(obj);
! 158: }
! 159:
! 160: /*
! 161: * init_weapon:
! 162: * Set up the initial goodies for a weapon
! 163: */
! 164: void
! 165: init_weapon(THING *weap, char type)
! 166: {
! 167: register struct init_weps *iwp;
! 168:
! 169: iwp = &init_dam[type];
! 170: strncpy(weap->o_damage, iwp->iw_dam, 8);
! 171: strncpy(weap->o_hurldmg, iwp->iw_hrl, 8);
! 172: weap->o_launch = iwp->iw_launch;
! 173: weap->o_flags = iwp->iw_flags;
! 174: if (weap->o_flags & ISMANY)
! 175: {
! 176: weap->o_count = rnd(8) + 8;
! 177: weap->o_group = group++;
! 178: }
! 179: else
! 180: weap->o_count = 1;
! 181: }
! 182:
! 183: /*
! 184: * hit_monster:
! 185: * Does the missile hit the monster?
! 186: */
! 187: bool
! 188: hit_monster(int y, int x, THING *obj)
! 189: {
! 190: static coord mp;
! 191:
! 192: mp.y = y;
! 193: mp.x = x;
! 194: return fight(&mp, moat(y, x)->t_type, obj, TRUE);
! 195: }
! 196:
! 197: /*
! 198: * num:
! 199: * Figure out the plus number for armor/weapons
! 200: */
! 201: char *
! 202: num(int n1, int n2, char type)
! 203: {
! 204: static char numbuf[10];
! 205:
! 206: sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1);
! 207: if (type == WEAPON)
! 208: sprintf(&numbuf[strlen(numbuf)], ",%s%d", n2 < 0 ? "" : "+", n2);
! 209: return numbuf;
! 210: }
! 211:
! 212: /*
! 213: * wield:
! 214: * Pull out a certain weapon
! 215: */
! 216: void
! 217: wield(void)
! 218: {
! 219: register THING *obj, *oweapon;
! 220: register char *sp;
! 221:
! 222: oweapon = cur_weapon;
! 223: if (!dropcheck(cur_weapon))
! 224: {
! 225: cur_weapon = oweapon;
! 226: return;
! 227: }
! 228: cur_weapon = oweapon;
! 229: if ((obj = get_item("wield", WEAPON)) == NULL)
! 230: {
! 231: bad:
! 232: after = FALSE;
! 233: return;
! 234: }
! 235:
! 236: if (obj->o_type == ARMOR)
! 237: {
! 238: msg("you can't wield armor");
! 239: goto bad;
! 240: }
! 241: if (is_current(obj))
! 242: goto bad;
! 243:
! 244: sp = inv_name(obj, TRUE);
! 245: cur_weapon = obj;
! 246: if (!terse)
! 247: addmsg("you are now ");
! 248: msg("wielding %s (%c)", sp, pack_char(obj));
! 249: }
! 250:
! 251: /*
! 252: * fallpos:
! 253: * Pick a random position around the give (y, x) coordinates
! 254: */
! 255: bool
! 256: fallpos(coord *pos, coord *newpos, bool pass)
! 257: {
! 258: register int y, x, cnt, ch;
! 259:
! 260: cnt = 0;
! 261: for (y = pos->y - 1; y <= pos->y + 1; y++)
! 262: for (x = pos->x - 1; x <= pos->x + 1; x++)
! 263: {
! 264: /*
! 265: * check to make certain the spot is empty, if it is,
! 266: * put the object there, set it in the level list
! 267: * and re-draw the room if he can see it
! 268: */
! 269: if (y == hero.y && x == hero.x)
! 270: continue;
! 271: if (((ch = chat(y, x)) == FLOOR || (pass && ch == PASSAGE))
! 272: && rnd(++cnt) == 0)
! 273: {
! 274: newpos->y = y;
! 275: newpos->x = x;
! 276: }
! 277: }
! 278: return (cnt != 0);
! 279: }
CVSweb