Players wielding a lance while riding will "joust" monsters
they attack.

Note that monsters don't get pushed into inaccessable tiles such
as walls, doors, iron bars, water, or lava; they stay at the edge.
Further refinements are possible for these cases.
This commit is contained in:
kmhugo
2002-01-20 05:44:46 +00:00
parent 8efbbdc0cc
commit bb88bd1a4a
4 changed files with 76 additions and 18 deletions

View File

@@ -490,6 +490,7 @@ add Tom Friedetzky's BUC-patch (applies to full menustyle only)
add wizard #poly and #levelchange (originally levelgain; Dylan O'Donnell),
add Jason Short's additional lenses use patch
add new Gnomish Mines levels from Kelly Bailey's patch
jousting by players wielding a lance while riding
Platform- and/or Interface-Specific New Features

View File

@@ -425,6 +425,7 @@ E int NDECL(dothrow);
E int NDECL(dofire);
E void FDECL(hitfloor, (struct obj *));
E void FDECL(hurtle, (int,int,int,BOOLEAN_P));
E void FDECL(mhurtle, (struct monst *,int,int,int,BOOLEAN_P));
E void FDECL(throwit, (struct obj *,long,BOOLEAN_P));
E int FDECL(omon_adj, (struct monst *,struct obj *,BOOLEAN_P));
E int FDECL(thitmonst, (struct monst *,struct obj *));

View File

@@ -16,6 +16,7 @@ STATIC_DCL void FDECL(breakmsg, (struct obj *,BOOLEAN_P));
STATIC_DCL boolean FDECL(toss_up,(struct obj *, BOOLEAN_P));
STATIC_DCL boolean FDECL(throwing_weapon, (struct obj *));
STATIC_DCL void FDECL(sho_obj_return_to_u, (struct obj *obj));
STATIC_DCL boolean FDECL(mhurtle_step, (genericptr_t,int,int));
static NEARDATA const char toss_objs[] =
@@ -407,7 +408,7 @@ walk_path(src_cc, dest_cc, check_proc, arg)
* Single step for the hero flying through the air from jumping, flying,
* etc. Called from hurtle() and jump() via walk_path(). We expect the
* argument to be a pointer to an integer -- the range -- which is
* used in the calculation of points off it we hit something.
* used in the calculation of points off if we hit something.
*
* Bumping into monsters won't cause damage but will wake them and make
* them angry. Auto-pickup isn't done, since you don't have control over
@@ -524,6 +525,26 @@ hurtle_step(arg, x, y)
return TRUE;
}
STATIC_OVL boolean
mhurtle_step(arg, x, y)
genericptr_t arg;
int x, y;
{
struct monst *mon = (struct monst *)arg;
/* TODO: Treat walls, doors, iron bars, pools, lava, etc. specially
* rather than just stopping before.
*/
if (goodpos(x, y, mon) && m_in_out_region(mon, x, y)) {
remove_monster(mon->mx, mon->my);
newsym(mon->mx, mon->my);
place_monster(mon, x, y);
newsym(mon->mx, mon->my);
set_apparxy(mon);
(void) mintrap(mon);
}
}
/*
* The player moves through the air for a few squares as a result of
* throwing or kicking something.
@@ -584,6 +605,40 @@ hurtle(dx, dy, range, verbose)
(void) walk_path(&uc, &cc, hurtle_step, (genericptr_t)&range);
}
/* Move a monster through the air for a few squares.
*/
void
mhurtle(mon, dx, dy, range, verbose)
struct monst *mon;
int dx, dy, range;
boolean verbose;
{
coord mc, cc;
/* At the very least, debilitate the monster */
mon->movement = 0;
mon->mstun = 1;
/* Is the monster stuck or too heavy to push?
* (very large monsters have too much inertia, even floaters and flyers)
*/
if (mon->data->msize >= MZ_HUGE || mon == u.ustuck || mon->mtrapped)
return;
/* Make sure dx and dy are [-1,0,1] */
dx = sgn(dx);
dy = sgn(dy);
if(!range || (!dx && !dy)) return; /* paranoia */
/* Send the monster along the path */
mc.x = mon->mx;
mc.y = mon->my;
cc.x = mon->mx + (dx * range);
cc.y = mon->my + (dy * range);
(void) walk_path(&mc, &cc, mhurtle_step, (genericptr_t)mon);
return;
}
STATIC_OVL void
check_shop_obj(obj, x, y, broken)
register struct obj *obj;

View File

@@ -503,6 +503,9 @@ int thrown;
boolean get_dmg_bonus = TRUE;
boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE;
boolean silvermsg = FALSE;
#ifdef STEED
boolean jousting = FALSE;
#endif
boolean valid_weapon_attack = FALSE;
int wtype;
struct obj *monwep;
@@ -606,6 +609,11 @@ int thrown;
if (objects[obj->otyp].oc_material == SILVER
&& hates_silver(mdat))
silvermsg = TRUE;
#ifdef STEED
if (u.usteed && !thrown &&
weapon_type(obj) == P_LANCE && mon != u.ustuck)
jousting = TRUE;
#endif
if(!thrown && obj == uwep && obj->otyp == BOOMERANG &&
!rnl(3)) {
pline("As you hit %s, %s breaks into splinters.",
@@ -884,6 +892,15 @@ int thrown;
}
}
#ifdef STEED
if (jousting) {
You("joust %s%s",
mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
mhurtle(mon, u.dx, u.dy, 1, TRUE);
hittxt = TRUE;
} else
#endif
/* VERY small chance of stunning opponent if unarmed. */
if (tmp > 1 && !thrown && !obj && !uwep && !uarm && !uarms && !Upolyd) {
if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) &&
@@ -891,24 +908,8 @@ int thrown;
if (canspotmon(mon))
pline("%s %s from your powerful strike!", Monnam(mon),
makeplural(stagger(mon->data, "stagger")));
mon->mstun = 1;
mhurtle(mon, u.dx, u.dy, 1, TRUE);
hittxt = TRUE;
if (mon->mcanmove && mon != u.ustuck && !mon->mtrapped) {
xchar mdx, mdy;
/* see if the monster has a place to move into */
mdx = mon->mx + u.dx;
mdy = mon->my + u.dy;
if (goodpos(mdx, mdy, mon) &&
m_in_out_region(mon, mdx, mdy)) {
remove_monster(mon->mx, mon->my);
newsym(mon->mx, mon->my);
place_monster(mon, mdx, mdy);
newsym(mon->mx, mon->my);
set_apparxy(mon);
(void) mintrap(mon);
}
}
}
}