From: PatR Date: Thu, 28 Apr 2022 09:21:46 +0000 (-0700) Subject: forcefight against edge of map X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5e1fba6e29419d20a0c10af5a9f3ef7d083417fb;p=nethack forcefight against edge of map Noticed when testing the forcefight against obscured furniture fix: if you attempted forcefight against the edge of the map, you got feedback about having already moved as far in as possible rather than about forcefight failing to attack anything. Have the can't move out bounds test check for forcefight before deciding to give to its normal feedback. --- diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 996971424..64e9bbcb9 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -896,6 +896,8 @@ with two-weapon combat or Cleaver attacking multiple targets, hero kept going with next attack after being paralyzed by passive counter-attack trap detection could falsely find trapped secret doors; those can't be trapped due to details of how they use overlaid fields in the rm structure +for force-fight against edge of level, report "you harmlessly attack unknown + obstacle" rather than "you have moved as far as possible" Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/hack.c b/src/hack.c index 04a2b7f2c..5ec41191e 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1839,7 +1839,14 @@ domove_swap_with_pet(struct monst *mtmp, xchar x, xchar y) static boolean domove_fight_empty(xchar x, xchar y) { - int glyph = glyph_at(x, y); + static const char unknown_obstacle[] = "an unknown obstacle"; + boolean off_edge = !isok(x, y); + int glyph = !off_edge ? glyph_at(x, y) : GLYPH_UNEXPLORED; + + if (off_edge) + x = y = 0; /* for forcefight against the edge of the map; make + * sure 'bad' coordinates are within array bounds in + * case a bounds check gets overlooked */ /* specifying 'F' with no monster wastes a turn */ if (g.context.forcefight @@ -1847,9 +1854,16 @@ domove_fight_empty(xchar x, xchar y) || (glyph_is_invisible(glyph) && !g.context.nopick)) { struct obj *boulder = 0; boolean explo = (Upolyd && attacktype(g.youmonst.data, AT_EXPL)), - solid = (!accessible(x, y) || IS_FURNITURE(levl[x][y].typ)); + solid = (off_edge || (!accessible(x, y) + || IS_FURNITURE(levl[x][y].typ))); char buf[BUFSZ]; + if (off_edge) { + /* treat as if solid rock, even on planes' levels */ + Strcpy(buf, unknown_obstacle); + goto futile; + } + if (!Underwater) { boulder = sobj_at(BOULDER, x, y); /* if a statue is displayed at the target location, @@ -1900,7 +1914,7 @@ domove_fight_empty(xchar x, xchar y) glyph = back_to_glyph(x, y); Strcpy(buf, the(defsyms[glyph_to_cmap(glyph)].explanation)); } else { - Strcpy(buf, "an unknown obstacle"); + Strcpy(buf, unknown_obstacle); } /* note: 'solid' is misleadingly named and catches pools of water and lava as well as rock and walls; @@ -1908,16 +1922,20 @@ domove_fight_empty(xchar x, xchar y) } else { Strcpy(buf, "thin air"); } + + futile: You("%s%s %s.", !(boulder || solid) ? "" : !explo ? "harmlessly " : "futilely ", explo ? "explode at" : "attack", buf); nomul(0); if (explo) { - struct attack *attk; + struct attack *attk + = attacktype_fordmg(g.youmonst.data, AT_EXPL, AD_ANY); + /* no monster has been attacked so we have bypassed explum() */ wake_nearto(u.ux, u.uy, 7 * 7); /* same radius as explum() */ - if ((attk = attacktype_fordmg(g.youmonst.data, AT_EXPL, AD_ANY))) + if (attk) explum((struct monst *) 0, attk); u.mh = -1; /* dead in the current form */ rehumanize(); @@ -2079,6 +2097,9 @@ static boolean move_out_of_bounds(xchar x, xchar y) { if (!isok(x, y)) { + if (g.context.forcefight) + return domove_fight_empty(x, y); + if (flags.mention_walls) { int dx = u.dx, dy = u.dy; @@ -2236,7 +2257,7 @@ domove_core(void) if (water_turbulence(&x, &y)) return; - if (move_out_of_bounds(x,y)) + if (move_out_of_bounds(x, y)) return; if (avoid_running_into_trap_or_liquid(x, y))