skipping stones (trunk only)

Allow a chance of rocks thrown over water to skip
in such a way that they could bounce right over a water
creature.
This commit is contained in:
nethack.allison
2004-06-06 18:37:46 +00:00
parent 003dd4452f
commit fd9db92705
2 changed files with 56 additions and 1 deletions
+1
View File
@@ -107,6 +107,7 @@ debug-mode wishing for random monster(s) via '*'
health-food store that stocks monk-appropriate foods in mine town when monk health-food store that stocks monk-appropriate foods in mine town when monk
give more information about your attributes in debug mode give more information about your attributes in debug mode
polywarn to give intrinsic monster detection of limited species while polymorphed polywarn to give intrinsic monster detection of limited species while polymorphed
rocks can skip on the water sometimes allowing them to pass over water creatures
Platform- and/or Interface-Specific New Features Platform- and/or Interface-Specific New Features
+55 -1
View File
@@ -29,6 +29,7 @@ STATIC_DCL void FDECL(revive_egg, (struct obj *));
#ifdef STEED #ifdef STEED
STATIC_DCL boolean FDECL(zap_steed, (struct obj *)); STATIC_DCL boolean FDECL(zap_steed, (struct obj *));
#endif #endif
STATIC_DCL void FDECL(skiprange, (int,int *,int *));
STATIC_DCL int FDECL(zap_hit, (int,int)); STATIC_DCL int FDECL(zap_hit, (int,int));
STATIC_DCL void FDECL(backfire, (struct obj *)); STATIC_DCL void FDECL(backfire, (struct obj *));
@@ -50,6 +51,10 @@ STATIC_DCL int FDECL(spell_hit_bonus, (int));
#define is_hero_spell(type) ((type) >= 10 && (type) < 20) #define is_hero_spell(type) ((type) >= 10 && (type) < 20)
#define M_IN_WATER(ptr) ((ptr)->mlet == S_EEL || \
amphibious(ptr) || \
is_swimmer(ptr))
STATIC_VAR const char are_blinded_by_the_flash[] = "are blinded by the flash!"; STATIC_VAR const char are_blinded_by_the_flash[] = "are blinded by the flash!";
const char * const flash_types[] = { /* also used in buzzmu(mcastu.c) */ const char * const flash_types[] = { /* also used in buzzmu(mcastu.c) */
@@ -2602,6 +2607,16 @@ register struct monst *mtmp;
mon_nam(mtmp) : "it"); mon_nam(mtmp) : "it");
} }
STATIC_OVL void
skiprange(range, skipstart, skipend)
int range, *skipstart, *skipend;
{
int tmp = range - (rnd(range / 4));
*skipstart = tmp;
*skipend = tmp - ((tmp / 4) * rnd(3));
if (*skipend >= tmp) *skipend = tmp - 1;
}
/* /*
* Called for the following distance effects: * Called for the following distance effects:
* when a weapon is thrown (weapon == THROWN_WEAPON) * when a weapon is thrown (weapon == THROWN_WEAPON)
@@ -2631,6 +2646,8 @@ struct obj *obj; /* object tossed/used */
struct monst *mtmp; struct monst *mtmp;
uchar typ; uchar typ;
boolean shopdoor = FALSE, point_blank = TRUE; boolean shopdoor = FALSE, point_blank = TRUE;
boolean in_skip = FALSE, allow_skip = FALSE;
int skiprange_start = 0, skiprange_end = 0, skipcount = 0;
if (weapon == KICKED_WEAPON) { if (weapon == KICKED_WEAPON) {
/* object starts one square in front of player */ /* object starts one square in front of player */
@@ -2642,6 +2659,11 @@ struct obj *obj; /* object tossed/used */
bhitpos.y = u.uy; bhitpos.y = u.uy;
} }
if (weapon == THROWN_WEAPON && obj && obj->otyp == ROCK) {
skiprange(range, &skiprange_start, &skiprange_end);
allow_skip = !rn2(3);
}
if (weapon == FLASHED_LIGHT) { if (weapon == FLASHED_LIGHT) {
tmp_at(DISP_BEAM, cmap_to_glyph(S_flashbeam)); tmp_at(DISP_BEAM, cmap_to_glyph(S_flashbeam));
} else if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM) } else if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM)
@@ -2704,7 +2726,39 @@ struct obj *obj; /* object tossed/used */
break; break;
} }
if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) { mtmp = m_at(bhitpos.x, bhitpos.y);
/*
* skipping rocks
*
* skiprange_start is only set if this is a thrown rock
*/
if (skiprange_start && (range == skiprange_start) && allow_skip) {
if (is_pool(bhitpos.x, bhitpos.y) && !mtmp) {
in_skip = TRUE;
if (!Blind) pline("%s %s%s.", Yname2(obj),
otense(obj, "skip"),
skipcount ? " again" : "");
else if (!Deaf) You_hear("%s skip.", Yname2(obj));
skipcount++;
} else if (skiprange_start > skiprange_end + 1) {
--skiprange_start;
}
}
if (in_skip) {
if (range <= skiprange_end) {
in_skip = FALSE;
if (range > 3) /* another bounce? */
skiprange(range, &skiprange_start, &skiprange_end);
} else if (mtmp && M_IN_WATER(mtmp->data)) {
if ((!Blind && canseemon(mtmp)) || sensemon(mtmp))
pline("%s %s over %s.",
Yname2(obj), otense(obj, "pass"),
mon_nam(mtmp));
}
}
if (mtmp && !(in_skip && M_IN_WATER(mtmp->data))) {
notonhead = (bhitpos.x != mtmp->mx || notonhead = (bhitpos.x != mtmp->mx ||
bhitpos.y != mtmp->my); bhitpos.y != mtmp->my);
if (weapon != FLASHED_LIGHT) { if (weapon != FLASHED_LIGHT) {