Mercurial > hg > early-roguelike
diff rogue5/weapons.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Mon, 24 May 2010 20:10:59 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rogue5/weapons.c Mon May 24 20:10:59 2010 +0000 @@ -0,0 +1,286 @@ +/* + * Functions for dealing with problems brought about by weapons + * + * @(#)weapons.c 4.34 (Berkeley) 02/05/99 + * + * Rogue: Exploring the Dungeons of Doom + * Copyright (C) 1980-1983, 1985, 1999 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 <string.h> +#include <ctype.h> +#include "rogue.h" + +#define NO_WEAPON -1 + +static const struct init_weaps { + char *iw_dam; /* Damage when wielded */ + char *iw_hrl; /* Damage when thrown */ + int iw_launch; /* Launching weapon */ + int iw_flags; /* Miscellaneous flags */ +} init_dam[MAXWEAPONS] = { + { "2x4", "1x3", NO_WEAPON, 0, }, /* Mace */ + { "3x4", "1x2", NO_WEAPON, 0, }, /* Long sword */ + { "1x1", "1x1", NO_WEAPON, 0, }, /* Bow */ + { "1x1", "2x3", BOW, ISMANY|ISMISL, }, /* Arrow */ + { "1x6", "1x4", NO_WEAPON, ISMISL|ISMISL, }, /* Dagger */ + { "4x4", "1x2", NO_WEAPON, 0, }, /* 2h sword */ + { "1x1", "1x3", NO_WEAPON, ISMANY|ISMISL, }, /* Dart */ + { "1x2", "2x4", NO_WEAPON, ISMANY|ISMISL, }, /* Shuriken */ + { "2x3", "1x6", NO_WEAPON, ISMISL, }, /* Spear */ +}; + +/* + * missile: + * Fire a missile in a given direction + */ + +void +missile(int ydelta, int xdelta) +{ + THING *obj; + + /* + * Get which thing we are hurling + */ + if ((obj = get_item("throw", WEAPON)) == NULL) + return; + if (!dropcheck(obj) || is_current(obj)) + return; + obj = leave_pack(obj, TRUE, FALSE); + 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) +{ + int ch; + + /* + * Come fly with us ... + */ + obj->o_pos = hero; + for (;;) + { + /* + * Erase the old one + */ + if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)) && !terse) + { + ch = chat(obj->o_pos.y, obj->o_pos.x); + if (ch == FLOOR && !show_floor()) + ch = ' '; + mvaddch(obj->o_pos.y, obj->o_pos.x, ch); + } + /* + * 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)) && !terse) + { + 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, int pr) +{ + PLACE *pp; + coord fpos; + + if (fallpos(&obj->o_pos, &fpos)) + { + pp = INDEX(fpos.y, fpos.x); + pp->p_ch = obj->o_type; + obj->o_pos = fpos; + if (cansee(fpos.y, fpos.x)) + { + if (pp->p_monst != NULL) + pp->p_monst->t_oldch = obj->o_type; + else + mvaddch(fpos.y, fpos.x, obj->o_type); + } + attach(lvl_obj, obj); + return; + } + if (pr) + { + if (has_hit) + { + endmsg(); + has_hit = FALSE; + } + msg("the %s vanishes as it hits the ground", + weap_info[obj->o_which].oi_name); + } + discard(obj); +} + +/* + * init_weapon: + * Set up the initial goodies for a weapon + */ + +void +init_weapon(THING *weap, int which) +{ + const struct init_weaps *iwp; + + weap->o_type = WEAPON; + weap->o_which = which; + iwp = &init_dam[which]; + strncpy(weap->o_damage, iwp->iw_dam, sizeof(weap->o_damage)); + strncpy(weap->o_hurldmg,iwp->iw_hrl, sizeof(weap->o_hurldmg)); + weap->o_launch = iwp->iw_launch; + weap->o_flags = iwp->iw_flags; + weap->o_hplus = 0; + weap->o_dplus = 0; + if (which == DAGGER) + { + weap->o_count = rnd(4) + 2; + weap->o_group = group++; + } + else if (weap->o_flags & ISMANY) + { + weap->o_count = rnd(8) + 8; + weap->o_group = group++; + } + else + { + weap->o_count = 1; + weap->o_group = 0; + } +} + +/* + * hit_monster: + * Does the missile hit the monster? + */ +int +hit_monster(int y, int x, const THING *obj) +{ + coord mp; + + mp.y = y; + mp.x = x; + return fight(&mp, obj, TRUE); +} + +/* + * num: + * Figure out the plus number for armor/weapons + */ +const char * +num(int n1, int n2, int type) +{ + static char numbuf[10]; + + sprintf(numbuf, n1 < 0 ? "%d" : "+%d", n1); + if (type == WEAPON) + sprintf(&numbuf[strlen(numbuf)], n2 < 0 ? ",%d" : ",+%d", n2); + return numbuf; +} + +/* + * wield: + * Pull out a certain weapon + */ + +void +wield(void) +{ + THING *obj, *oweapon; + 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, obj->o_packch); +} + +/* + * fallpos: + * Pick a random position around the give (y, x) coordinates + */ +int +fallpos(const coord *pos, coord *newpos) +{ + 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 || ch == PASSAGE) + && rnd(++cnt) == 0) + { + newpos->y = y; + newpos->x = x; + } + } + return (cnt != 0); +}