rogue

Ken Arnold's Rogue
git clone https://git.woozle.org/neale/rogue.git

Neale Pickett  ·  2011-10-13

system.c

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