Jousting
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:
@@ -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
|
||||
|
||||
@@ -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 *));
|
||||
|
||||
@@ -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;
|
||||
|
||||
35
src/uhitm.c
35
src/uhitm.c
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user