/* * Functions for dealing with problems brought about by weapons * * @(#)weapons.c 4.14 (Berkeley) 4/6/82 * * Rogue: Exploring the Dungeons of Doom * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman * All rights reserved. * * See the file LICENSE.TXT for full copyright and licensing information. */ #include #include #include #include "rogue.h" #define NONE 100 static struct init_weps { char *iw_dam; /* Damage when wielded */ char *iw_hrl; /* Damage when thrown */ char iw_launch; /* Launching weapon */ int iw_flags; /* Miscellaneous flags */ } init_dam[MAXWEAPONS] = { { "2d4", "1d3", NONE, 0 }, /* Mace */ { "3d4", "1d2", NONE, 0 }, /* Long sword */ { "1d1", "1d1", NONE, 0 }, /* Bow */ { "1d1", "2d3", BOW, ISMANY|ISMISL },/* Arrow */ { "1d6", "1d4", NONE, ISMISL }, /* Dagger */ { "4d4", "1d2", NONE, 0 }, /* 2h sword */ { "1d1", "1d3", NONE, ISMANY|ISMISL },/* Dart */ { "1d1", "1d1", NONE, 0 }, /* Crossbow */ { "1d2", "2d5", CROSSBOW, ISMANY|ISMISL },/* Crossbow bolt */ { "2d3", "1d6", NONE, ISMISL } /* Spear */ }; /* * missile: * Fire a missile in a given direction */ void missile(int ydelta, int xdelta) { register THING *obj, *nitem; /* * Get which thing we are hurling */ if ((obj = get_item("throw", WEAPON)) == NULL) return; if (!dropcheck(obj) || is_current(obj)) return; /* * Get rid of the thing. If it is a non-multiple item object, or * if it is the last thing, just drop it. Otherwise, create a new * item with a count of one. */ if (obj->o_count < 2) { detach(pack, obj); inpack--; } else { obj->o_count--; if (obj->o_group == 0) inpack--; nitem = new_item(); *nitem = *obj; nitem->o_count = 1; obj = nitem; } do_motion(obj, ydelta, xdelta); /* * AHA! Here it has hit something. If it is a wall or a door, * or if it misses (combat) the monster, put it on the floor */ if (moat(obj->o_pos.y, obj->o_pos.x) == NULL || !hit_monster(unc(obj->o_pos), obj)) fall(obj, TRUE); } /* * do_motion: * Do the actual motion on the screen done by an object traveling * across the room */ void do_motion(THING *obj, int ydelta, int xdelta) { /* * Come fly with us ... */ obj->o_pos = hero; for (;;) { register int ch; /* * Erase the old one */ if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos))) mvaddch(obj->o_pos.y, obj->o_pos.x, chat(obj->o_pos.y, obj->o_pos.x)); /* * Get the new position */ obj->o_pos.y += ydelta; obj->o_pos.x += xdelta; if (step_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR) { /* * It hasn't hit anything yet, so display it * If it alright. */ if (cansee(unc(obj->o_pos))) { mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type); refresh(); } continue; } break; } } /* * fall: * Drop an item someplace around here. */ void fall(THING *obj, bool pr) { static coord fpos; register int index; if (fallpos(&obj->o_pos, &fpos, TRUE)) { index = INDEX(fpos.y, fpos.x); _level[index] = obj->o_type; obj->o_pos = fpos; if (cansee(fpos.y, fpos.x)) { mvaddch(fpos.y, fpos.x, obj->o_type); if (_monst[index] != NULL) _monst[index]->t_oldch = obj->o_type; } attach(lvl_obj, obj); return; } if (pr) msg("the %s vanishes as it hits the ground", /* BUGFIX: Identification trick */ (obj->o_type==WEAPON) ? w_names[obj->o_which] : inv_name(obj,TRUE)); discard(obj); } /* * init_weapon: * Set up the initial goodies for a weapon */ void init_weapon(THING *weap, char type) { register struct init_weps *iwp; iwp = &init_dam[type]; strncpy(weap->o_damage, iwp->iw_dam, 8); strncpy(weap->o_hurldmg, iwp->iw_hrl, 8); weap->o_launch = iwp->iw_launch; weap->o_flags = iwp->iw_flags; if (weap->o_flags & ISMANY) { weap->o_count = rnd(8) + 8; weap->o_group = group++; } else weap->o_count = 1; } /* * hit_monster: * Does the missile hit the monster? */ bool hit_monster(int y, int x, THING *obj) { static coord mp; mp.y = y; mp.x = x; return fight(&mp, moat(y, x)->t_type, obj, TRUE); } /* * num: * Figure out the plus number for armor/weapons */ char * num(int n1, int n2, char type) { static char numbuf[10]; sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1); if (type == WEAPON) sprintf(&numbuf[strlen(numbuf)], ",%s%d", n2 < 0 ? "" : "+", n2); return numbuf; } /* * wield: * Pull out a certain weapon */ void wield(void) { register THING *obj, *oweapon; register char *sp; oweapon = cur_weapon; if (!dropcheck(cur_weapon)) { cur_weapon = oweapon; return; } cur_weapon = oweapon; if ((obj = get_item("wield", WEAPON)) == NULL) { bad: after = FALSE; return; } if (obj->o_type == ARMOR) { msg("you can't wield armor"); goto bad; } if (is_current(obj)) goto bad; sp = inv_name(obj, TRUE); cur_weapon = obj; if (!terse) addmsg("you are now "); msg("wielding %s (%c)", sp, pack_char(obj)); } /* * fallpos: * Pick a random position around the give (y, x) coordinates */ bool fallpos(coord *pos, coord *newpos, bool pass) { register int y, x, cnt, ch; cnt = 0; for (y = pos->y - 1; y <= pos->y + 1; y++) for (x = pos->x - 1; x <= pos->x + 1; x++) { /* * check to make certain the spot is empty, if it is, * put the object there, set it in the level list * and re-draw the room if he can see it */ if (y == hero.y && x == hero.x) continue; if (((ch = chat(y, x)) == FLOOR || (pass && ch == PASSAGE)) && rnd(++cnt) == 0) { newpos->y = y; newpos->x = x; } } return (cnt != 0); }