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

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
give more information about your attributes in debug mode
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

View File

@@ -29,6 +29,7 @@ STATIC_DCL void FDECL(revive_egg, (struct obj *));
#ifdef STEED
STATIC_DCL boolean FDECL(zap_steed, (struct obj *));
#endif
STATIC_DCL void FDECL(skiprange, (int,int *,int *));
STATIC_DCL int FDECL(zap_hit, (int,int));
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 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!";
const char * const flash_types[] = { /* also used in buzzmu(mcastu.c) */
@@ -2602,6 +2607,16 @@ register struct monst *mtmp;
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:
* when a weapon is thrown (weapon == THROWN_WEAPON)
@@ -2631,6 +2646,8 @@ struct obj *obj; /* object tossed/used */
struct monst *mtmp;
uchar typ;
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) {
/* object starts one square in front of player */
@@ -2642,6 +2659,11 @@ struct obj *obj; /* object tossed/used */
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) {
tmp_at(DISP_BEAM, cmap_to_glyph(S_flashbeam));
} else if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM)
@@ -2704,7 +2726,39 @@ struct obj *obj; /* object tossed/used */
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 ||
bhitpos.y != mtmp->my);
if (weapon != FLASHED_LIGHT) {