Mercurial > hg > early-roguelike
diff srogue/weapons.c @ 36:2128c7dc8a40
Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Thu, 25 Nov 2010 12:21:41 +0000 |
parents | |
children | 94a0d9dd5ce1 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/weapons.c Thu Nov 25 12:21:41 2010 +0000 @@ -0,0 +1,265 @@ +/* + * Functions for dealing with weapons + * + * @(#)weapons.c 9.0 (rdk) 7/17/84 + * + * Super-Rogue + * Copyright (C) 1984 Robert D. Kindelberger + * All rights reserved. + * + * Based on "Rogue: Exploring the Dungeons of Doom" + * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman + * All rights reserved. + * + * See the file LICENSE.TXT for full copyright and licensing information. + */ + +#include <ctype.h> +#include "rogue.h" +#include "rogue.ext" + +/* + * missile: + * Fire a missile in a given direction + */ +missile(ydelta, xdelta) +int ydelta, xdelta; +{ + reg struct object *obj, *nowwield; + reg struct linked_list *item, *nitem; + + /* + * Get which thing we are hurling + */ + nowwield = cur_weapon; /* must save current weap */ + if ((item = get_item("throw", WEAPON)) == NULL) + return; + obj = OBJPTR(item); + if (!dropcheck(obj) || is_current(obj)) + return; + if (obj == nowwield || obj->o_type != WEAPON) { + reg int c; + + msg("Do you want to throw that %s? (y or n)",obj->o_typname); + do { + c = readchar(); + if (isupper(c)) + c = tolower(c); + if (c == ESCAPE || c == 'n') { + msg(""); + cur_weapon = nowwield; + after = FALSE; /* ooops, a mistake */ + return; + } + } while (c != 'y'); /* keep looking for good ans */ + } + /* + * 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, item); + } + else { + obj->o_count--; + obj->o_vol = itemvol(obj); + nitem = new_item(sizeof *obj); + obj = OBJPTR(nitem); + *obj = *(OBJPTR(item)); + obj->o_count = 1; + obj->o_vol = itemvol(obj); + item = nitem; + } + updpack(); /* new pack weight */ + do_motion(obj, ydelta, xdelta); + if (!isalpha(mvwinch(mw, obj->o_pos.y, obj->o_pos.x)) + || !hit_monster(&obj->o_pos, obj)) + fall(item, TRUE); + mvwaddch(cw, hero.y, hero.x, PLAYER); +} + +/* + * do the actual motion on the screen done by an object traveling + * across the room + */ +do_motion(obj, ydelta, xdelta) +struct object *obj; +int ydelta, xdelta; +{ + reg int ch, y, x; + + obj->o_pos = hero; + while (1) { + y = obj->o_pos.y; + x = obj->o_pos.x; + if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)) && + mvwinch(cw, y, x) != ' ') + mvwaddch(cw, y, x, show(y, x)); + /* + * Get the new position + */ + obj->o_pos.y += ydelta; + obj->o_pos.x += xdelta; + y = obj->o_pos.y; + x = obj->o_pos.x; + ch = winat(y, x); + if (step_ok(ch) && ch != DOOR) { + if (cansee(unc(obj->o_pos)) && mvwinch(cw, y, x) != ' ') { + mvwaddch(cw, y, x, obj->o_type); + draw(cw); + } + continue; + } + break; + } +} + +/* + * fall: + * Drop an item someplace around here. + */ + +fall(item, pr) +struct linked_list *item; +bool pr; +{ + reg struct object *obj; + reg struct room *rp; + static struct coord fpos; + + obj = OBJPTR(item); + if (fallpos(&obj->o_pos, &fpos, TRUE)) { + mvaddch(fpos.y, fpos.x, obj->o_type); + obj->o_pos = fpos; + rp = player.t_room; + if (rp != NULL && !rf_on(rp,ISDARK)) { + light(&hero); + mvwaddch(cw, hero.y, hero.x, PLAYER); + } + attach(lvl_obj, item); + return; + } + + if (pr) + if (obj->o_type == WEAPON) /* BUGFIX: Identification trick */ + msg("Your %s vanishes as it hits the ground.", w_magic[obj->o_which].mi_name); + else + msg("%s vanishes as it hits the ground.", inv_name(obj,TRUE)); + + discard(item); +} + +/* + * init_weapon: + * Set up the initial goodies for a weapon + */ + +init_weapon(weap, type) +struct object *weap; +int type; +{ + reg struct init_weps *iwp; + + weap->o_type = WEAPON; + weap->o_which = type; + iwp = &weaps[type]; + strcpy(weap->o_damage,iwp->w_dam); + strcpy(weap->o_hurldmg,iwp->w_hrl); + weap->o_launch = iwp->w_launch; + weap->o_flags = iwp->w_flags; + weap->o_weight = iwp->w_wght; + weap->o_typname = things[TYP_WEAPON].mi_name; + if (o_on(weap,ISMANY)) + weap->o_count = rnd(8) + 8; + else + weap->o_count = 1; + weap->o_group = newgrp(); + weap->o_vol = itemvol(weap); +} + +/* + * hit_monster: + * Does the missile hit the monster + */ +hit_monster(mp, obj) +struct coord *mp; +struct object *obj; +{ + return fight(mp, obj, TRUE); +} + +/* + * num: + * Figure out the plus number for armor/weapons + */ +char * +num(n1, n2) +int n1, n2; +{ + static char numbuf[LINLEN]; + + if (n1 == 0 && n2 == 0) + return "+0"; + if (n2 == 0) + sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1); + else + sprintf(numbuf,"%s%d,%s%d",n1<0 ? "":"+",n1,n2<0 ? "":"+",n2); + return numbuf; +} + +/* + * wield: + * Pull out a certain weapon + */ +wield() +{ + reg struct linked_list *item; + reg struct object *obj, *oweapon; + + oweapon = cur_weapon; + if (!dropcheck(cur_weapon)) { + cur_weapon = oweapon; + return; + } + cur_weapon = oweapon; + if ((item = get_item("wield", WEAPON)) == NULL) + return; + obj = OBJPTR(item); + if (is_current(obj)) { + after = FALSE; + return; + } + msg("Wielding %s", inv_name(obj, TRUE)); + cur_weapon = obj; +} + +/* + * fallpos: + * Pick a random position around the give (y, x) coordinates + */ +fallpos(pos, newpos, passages) +struct coord *pos, *newpos; +bool passages; +{ + reg int y, x, ch; + + 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; + ch = winat(y, x); + if (ch == FLOOR || (passages && ch == PASSAGE)) { + newpos->y = y; + newpos->x = x; + return TRUE; + } + } + } + return FALSE; +}