Mercurial > hg > early-roguelike
diff arogue5/weapons.c @ 63:0ed67132cf10
Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Thu, 09 Aug 2012 22:58:48 +0000 |
parents | |
children | c49f7927b0fa |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arogue5/weapons.c Thu Aug 09 22:58:48 2012 +0000 @@ -0,0 +1,310 @@ +/* + * Functions for dealing with problems brought about by weapons + * + * Advanced Rogue + * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T + * 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 "curses.h" +#include <ctype.h> +#include "rogue.h" + + + +/* + * do the actual motion on the screen done by an object traveling + * across the room + */ +do_motion(obj, ydelta, xdelta, tp) +register struct object *obj; +register int ydelta, xdelta; +register struct thing *tp; +{ + + /* + * Come fly with us ... + */ + obj->o_pos = tp->t_pos; + for (; ;) { + register int ch; + /* + * Erase the old one + */ + if (!ce(obj->o_pos, tp->t_pos) && + cansee(unc(obj->o_pos)) && + mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') { + mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, show(obj->o_pos.y, obj->o_pos.x)); + } + /* + * Get the new position + */ + obj->o_pos.y += ydelta; + obj->o_pos.x += xdelta; + if (shoot_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR && !ce(obj->o_pos, hero)) { + /* + * It hasn't hit anything yet, so display it + * If it alright. + */ + if (cansee(unc(obj->o_pos)) && + mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') { + mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, obj->o_type); + draw(cw); + } + continue; + } + break; + } +} + + +/* + * fall: + * Drop an item someplace around here. + */ + +fall(item, pr) +register struct linked_list *item; +bool pr; +{ + register struct object *obj; + register struct room *rp; + register int i; + coord *fpos = NULL; + + obj = OBJPTR(item); + /* + * try to drop the item, look up to 3 squares away for now + */ + for (i=1; i<4; i++) { + if ((fpos = fallpos(&obj->o_pos, FALSE, i)) != NULL) + break; + } + + if (fpos != NULL) { + mvaddch(fpos->y, fpos->x, obj->o_type); + obj->o_pos = *fpos; + if ((rp = roomin(&hero)) != NULL && + lit_room(rp)) { + 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("The %s vanishes as it hits the ground.", + weaps[obj->o_which].w_name); + else + msg("%s vanishes as it hits the ground.", inv_name(obj,TRUE)); + } + o_discard(item); +} + + +/* + * Does the missile hit the monster + */ + +hit_monster(y, x, obj, tp) +register int y, x; +struct object *obj; +register struct thing *tp; +{ + static coord mp; + + mp.y = y; + mp.x = x; + if (tp == &player) { + /* Make sure there is a monster where it landed */ + if (!isalpha(mvwinch(mw, y, x))) { + return(FALSE); + } + return(fight(&mp, obj, TRUE)); + } else { + if (!ce(mp, hero)) { + return(FALSE); + } + return(attack(tp, obj, TRUE)); + } +} + +/* + * init_weapon: + * Set up the initial goodies for a weapon + */ + +init_weapon(weap, type) +register struct object *weap; +char type; +{ + register struct init_weps *iwp; + + 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; + if (weap->o_flags & ISMANY) { + weap->o_count = rnd(8) + 8; + weap->o_group = newgrp(); + } else { + weap->o_count = 1; + } +} + +/* + * missile: + * Fire a missile in a given direction + */ + +missile(ydelta, xdelta, item, tp) +int ydelta, xdelta; +register struct linked_list *item; +register struct thing *tp; +{ + register struct object *obj; + register struct linked_list *nitem; + char ch; + + /* + * Get which thing we are hurling + */ + if (item == NULL) { + return; + } + obj = OBJPTR(item); + +#if 0 /* Do we really want to make this check */ + if (is_current(obj)) { /* Are we holding it? */ + msg(terse ? "Holding it." : "You are already holding it."); + return; + } +#endif + + if (!dropcheck(obj)) return; /* Can we get rid of it? */ + + if(!(obj->o_flags & ISMISL)) { + for(;;) { + msg(terse ? "Really throw? (y or n): " + : "Do you really want to throw %s? (y or n): ", + inv_name(obj, TRUE)); + mpos = 0; + ch = readchar(); + if (ch == 'n' || ch == ESCAPE) { + after = FALSE; + return; + } + if (ch == 'y') + break; + } + } + /* + * 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(tp->t_pack, item); + if (tp->t_pack == pack) { + inpack--; + } + } + else { + obj->o_count--; + nitem = (struct linked_list *) new_item(sizeof *obj); + obj = OBJPTR(nitem); + *obj = *(OBJPTR(item)); + obj->o_count = 1; + item = nitem; + } + updpack (FALSE); + do_motion(obj, ydelta, xdelta, tp); + /* + * 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 (!hit_monster(unc(obj->o_pos), obj, tp)) { + fall(item, TRUE); + } + mvwaddch(cw, hero.y, hero.x, PLAYER); +} + +/* + * num: + * Figure out the plus number for armor/weapons + */ + +char * +num(n1, n2) +register int n1, n2; +{ + static char numbuf[LINELEN]; + + 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() +{ + register struct linked_list *item; + register struct object *obj, *oweapon; + + if ((oweapon = cur_weapon) != NULL) { + if (!dropcheck(cur_weapon)) { + cur_weapon = oweapon; + return; + } + if (terse) + addmsg("Was "); + else + addmsg("You were "); + msg("wielding %s", inv_name(oweapon, TRUE)); + } + if ((item = get_item(pack, "wield", WIELDABLE)) == NULL) { + after = FALSE; + return; + } + obj = OBJPTR(item); + if (is_current(obj)) { + msg("Item in use."); + after = FALSE; + return; + } + if (player.t_ctype != C_FIGHTER && + obj->o_type == WEAPON && + (obj->o_which == TWOSWORD || obj->o_which == BASWORD)) { + msg("Only fighters can wield a %s", weaps[obj->o_which].w_name); + return; + } + if (terse) { + addmsg("W"); + } else { + addmsg("You are now w"); + } + msg("ielding %s", inv_name(obj, TRUE)); + cur_weapon = obj; +} +