From: kmhugo Date: Sun, 20 Jan 2002 05:44:46 +0000 (+0000) Subject: Jousting X-Git-Tag: MOVE2GIT~3420 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bb88bd1a4a93c4428324a66041820b989376bf47;p=nethack 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. --- diff --git a/doc/fixes33.2 b/doc/fixes33.2 index ab716e1be..5fa8064a4 100644 --- a/doc/fixes33.2 +++ b/doc/fixes33.2 @@ -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 diff --git a/include/extern.h b/include/extern.h index 2a40f3df4..7671052f8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 *)); diff --git a/src/dothrow.c b/src/dothrow.c index 24dc1d217..c1e581818 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -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; diff --git a/src/uhitm.c b/src/uhitm.c index ee0d00172..24efaf773 100644 --- a/src/uhitm.c +++ b/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); - } - } } }