]> granicus.if.org Git - nethack/commitdiff
Jousting
authorkmhugo <kmhugo>
Sun, 20 Jan 2002 05:44:46 +0000 (05:44 +0000)
committerkmhugo <kmhugo>
Sun, 20 Jan 2002 05:44:46 +0000 (05:44 +0000)
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.

doc/fixes33.2
include/extern.h
src/dothrow.c
src/uhitm.c

index ab716e1be78deda3ab0de1569b4f284e4f2c954a..5fa8064a4f6d87005684af7f0542b8b211a81c14 100644 (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
index 2a40f3df43915a610d2597ca879eeed8eea066a1..7671052f8b605016815264d97bf51416baa740ef 100644 (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 *));
index 24dc1d217b8abef0b16f1ab2e03d3b04c546f34a..c1e581818d82f998ae6f007a966372f003ae4ac9 100644 (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;
index ee0d0017294c92fb93991d22c98cca2b1455a092..24efaf773575c49a28220e0ef1e9bd9f66b0c25a 100644 (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);
-                   }
-               }
            }
        }