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
+1
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 wizard #poly and #levelchange (originally levelgain; Dylan O'Donnell),
add Jason Short's additional lenses use patch add Jason Short's additional lenses use patch
add new Gnomish Mines levels from Kelly Bailey's 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 Platform- and/or Interface-Specific New Features
+1
View File
@@ -425,6 +425,7 @@ E int NDECL(dothrow);
E int NDECL(dofire); E int NDECL(dofire);
E void FDECL(hitfloor, (struct obj *)); E void FDECL(hitfloor, (struct obj *));
E void FDECL(hurtle, (int,int,int,BOOLEAN_P)); 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 void FDECL(throwit, (struct obj *,long,BOOLEAN_P));
E int FDECL(omon_adj, (struct monst *,struct obj *,BOOLEAN_P)); E int FDECL(omon_adj, (struct monst *,struct obj *,BOOLEAN_P));
E int FDECL(thitmonst, (struct monst *,struct obj *)); E int FDECL(thitmonst, (struct monst *,struct obj *));
+56 -1
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(toss_up,(struct obj *, BOOLEAN_P));
STATIC_DCL boolean FDECL(throwing_weapon, (struct obj *)); STATIC_DCL boolean FDECL(throwing_weapon, (struct obj *));
STATIC_DCL void FDECL(sho_obj_return_to_u, (struct obj *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[] = 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, * Single step for the hero flying through the air from jumping, flying,
* etc. Called from hurtle() and jump() via walk_path(). We expect the * etc. Called from hurtle() and jump() via walk_path(). We expect the
* argument to be a pointer to an integer -- the range -- which is * 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 * 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 * 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; 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 * The player moves through the air for a few squares as a result of
* throwing or kicking something. * throwing or kicking something.
@@ -584,6 +605,40 @@ hurtle(dx, dy, range, verbose)
(void) walk_path(&uc, &cc, hurtle_step, (genericptr_t)&range); (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 STATIC_OVL void
check_shop_obj(obj, x, y, broken) check_shop_obj(obj, x, y, broken)
register struct obj *obj; register struct obj *obj;
+18 -17
View File
@@ -503,6 +503,9 @@ int thrown;
boolean get_dmg_bonus = TRUE; boolean get_dmg_bonus = TRUE;
boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE; boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE;
boolean silvermsg = FALSE; boolean silvermsg = FALSE;
#ifdef STEED
boolean jousting = FALSE;
#endif
boolean valid_weapon_attack = FALSE; boolean valid_weapon_attack = FALSE;
int wtype; int wtype;
struct obj *monwep; struct obj *monwep;
@@ -606,6 +609,11 @@ int thrown;
if (objects[obj->otyp].oc_material == SILVER if (objects[obj->otyp].oc_material == SILVER
&& hates_silver(mdat)) && hates_silver(mdat))
silvermsg = TRUE; 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 && if(!thrown && obj == uwep && obj->otyp == BOOMERANG &&
!rnl(3)) { !rnl(3)) {
pline("As you hit %s, %s breaks into splinters.", 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. */ /* VERY small chance of stunning opponent if unarmed. */
if (tmp > 1 && !thrown && !obj && !uwep && !uarm && !uarms && !Upolyd) { if (tmp > 1 && !thrown && !obj && !uwep && !uarm && !uarms && !Upolyd) {
if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) && if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) &&
@@ -891,24 +908,8 @@ int thrown;
if (canspotmon(mon)) if (canspotmon(mon))
pline("%s %s from your powerful strike!", Monnam(mon), pline("%s %s from your powerful strike!", Monnam(mon),
makeplural(stagger(mon->data, "stagger"))); makeplural(stagger(mon->data, "stagger")));
mon->mstun = 1; mhurtle(mon, u.dx, u.dy, 1, TRUE);
hittxt = 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);
}
}
} }
} }