fix issue #1377 - Forcefight vs displacer beasts
Issue reported by elunna: Using the 'F' prefix against a displacer beast prevented swapping places. This doesn't use the suggested fix. It is quite short but there is a large diff due to change in indentation and reformatting several comments because of that. Attacking a displacer beast either with or without 'F' might miss, hit, or swap places. It won't "harmlessly attack thin air." Fixes #1377
This commit is contained in:
@@ -2098,6 +2098,8 @@ when walking into/against a locked closed door, 'autounlock'==kick didn't
|
|||||||
having a 1% chance of creating rideable monsters with worn saddle gave knights
|
having a 1% chance of creating rideable monsters with worn saddle gave knights
|
||||||
a 1% chance of creating an extra saddle for starting pony; it wasn't
|
a 1% chance of creating an extra saddle for starting pony; it wasn't
|
||||||
tracked with other objects so produced a trivial memory leak
|
tracked with other objects so produced a trivial memory leak
|
||||||
|
hen attacking a displacer beast, using the 'F' forcefight prefix prevented it
|
||||||
|
from swapping places with the hero
|
||||||
|
|
||||||
|
|
||||||
Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository
|
Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository
|
||||||
|
|||||||
+22
-17
@@ -1956,10 +1956,12 @@ domove_attackmon_at(
|
|||||||
&& bad_rock(gy.youmonst.data, x, u.uy0))))
|
&& bad_rock(gy.youmonst.data, x, u.uy0))))
|
||||||
&& goodpos(u.ux0, u.uy0, mtmp, GP_ALLOW_U));
|
&& goodpos(u.ux0, u.uy0, mtmp, GP_ALLOW_U));
|
||||||
/* if not displacing, try to attack; note that it might evade;
|
/* if not displacing, try to attack; note that it might evade;
|
||||||
also, we don't attack tame when _safepet_ */
|
also, we don't attack tame or peaceful when safemon() */
|
||||||
if (!*displaceu && do_attack(mtmp))
|
if (!*displaceu) {
|
||||||
|
if (do_attack(mtmp))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2696,6 +2698,8 @@ domove_core(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!displaceu) {
|
||||||
|
|
||||||
if (domove_fight_ironbars(x, y))
|
if (domove_fight_ironbars(x, y))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -2718,9 +2722,9 @@ domove_core(void)
|
|||||||
/* treat entering a visible gas cloud region like entering a trap;
|
/* treat entering a visible gas cloud region like entering a trap;
|
||||||
there could be a known trap as well as a region at the target spot;
|
there could be a known trap as well as a region at the target spot;
|
||||||
if so, ask about entring the region first; even though this could
|
if so, ask about entring the region first; even though this could
|
||||||
lead to two consecutive confirmation prompts, the situation seems to
|
lead to two consecutive confirmation prompts, the situation seems
|
||||||
be too uncommon to warrant a separate case with combined trap+region
|
to be too uncommon to warrant a separate case with combined
|
||||||
confirmation */
|
trap+region confirmation */
|
||||||
if (ParanoidTrap && !Blind && !Stunned && !Confusion && !Hallucination
|
if (ParanoidTrap && !Blind && !Stunned && !Confusion && !Hallucination
|
||||||
/* skip if player used 'm' prefix or is moving recklessly */
|
/* skip if player used 'm' prefix or is moving recklessly */
|
||||||
&& (!svc.context.nopick || svc.context.run)
|
&& (!svc.context.nopick || svc.context.run)
|
||||||
@@ -2729,12 +2733,14 @@ domove_core(void)
|
|||||||
&& ((oldreg = visible_region_at(u.ux, u.uy)) == 0
|
&& ((oldreg = visible_region_at(u.ux, u.uy)) == 0
|
||||||
/* if moving from one region into another, only ask for
|
/* if moving from one region into another, only ask for
|
||||||
confirmation if the one potentially being entered inflicts
|
confirmation if the one potentially being entered inflicts
|
||||||
damage (poison gas) and the one being exited doesn't (vapor) */
|
damage (poison gas) and the one being exited doesn't
|
||||||
|
(vapor) */
|
||||||
|| (reg_damg(newreg) > 0 && reg_damg(oldreg) == 0))
|
|| (reg_damg(newreg) > 0 && reg_damg(oldreg) == 0))
|
||||||
/* check whether attempted move will be viable */
|
/* check whether attempted move will be viable */
|
||||||
&& test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE)
|
&& test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE)
|
||||||
/* we don't override confirmation for poison resistance since the
|
/* we don't override confirmation for poison resistance since
|
||||||
region also hinders hero's vision even if/when no damage is done */
|
the region also hinders hero's vision even if/when no damage
|
||||||
|
is done */
|
||||||
) {
|
) {
|
||||||
char qbuf[QBUFSZ];
|
char qbuf[QBUFSZ];
|
||||||
|
|
||||||
@@ -2747,18 +2753,13 @@ domove_core(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* maybe ask player for confirmation before walking into known traps */
|
/* maybe ask player for confirmation before walking into known trap */
|
||||||
if (ParanoidTrap && !Stunned && !Confusion
|
if (ParanoidTrap && !Stunned && !Confusion
|
||||||
/* skip if player used 'm' prefix or is moving recklessly */
|
/* skip if player used 'm' prefix or is moving recklessly */
|
||||||
&& (!svc.context.nopick || svc.context.run)
|
&& (!svc.context.nopick || svc.context.run)
|
||||||
/* check for discovered trap */
|
/* check for discovered trap */
|
||||||
&& (trap = t_at(x, y)) != 0 && trap->tseen
|
&& (trap = t_at(x, y)) != 0 && trap->tseen
|
||||||
/* check whether attempted move will be viable */
|
/* check whether attempted move will be viable */
|
||||||
/*
|
|
||||||
* FIXME:
|
|
||||||
* this will result in "Really step into trap?" if there is a
|
|
||||||
* peaceful or tame monster already there.
|
|
||||||
*/
|
|
||||||
&& test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE)
|
&& test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE)
|
||||||
/* override confirmation if the trap is harmless to the hero */
|
/* override confirmation if the trap is harmless to the hero */
|
||||||
&& (immune_to_trap(&gy.youmonst, trap->ttyp) != TRAP_CLEARLY_IMMUNE
|
&& (immune_to_trap(&gy.youmonst, trap->ttyp) != TRAP_CLEARLY_IMMUNE
|
||||||
@@ -2766,7 +2767,8 @@ domove_core(void)
|
|||||||
hero can't tell what they are, so treat as dangerous */
|
hero can't tell what they are, so treat as dangerous */
|
||||||
|| Hallucination)) {
|
|| Hallucination)) {
|
||||||
char qbuf[QBUFSZ];
|
char qbuf[QBUFSZ];
|
||||||
int traptype = (Hallucination ? rnd(TRAPNUM - 1) : (int) trap->ttyp);
|
int traptype = (Hallucination ? rnd(TRAPNUM - 1)
|
||||||
|
: (int) trap->ttyp);
|
||||||
boolean into = into_vs_onto(traptype);
|
boolean into = into_vs_onto(traptype);
|
||||||
|
|
||||||
Snprintf(qbuf, sizeof qbuf, "Really %s %s that %s?",
|
Snprintf(qbuf, sizeof qbuf, "Really %s %s that %s?",
|
||||||
@@ -2783,14 +2785,15 @@ domove_core(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u.utrap) {
|
if (u.utrap) { /* when u.utrap is True, displaceu is False */
|
||||||
boolean moved = trapmove(x, y, trap);
|
boolean moved = trapmove(x, y, trap);
|
||||||
|
|
||||||
if (!u.utrap) {
|
if (!u.utrap) {
|
||||||
disp.botl = TRUE;
|
disp.botl = TRUE;
|
||||||
reset_utrap(TRUE); /* might resume levitation or flight */
|
reset_utrap(TRUE); /* might resume levitation or flight */
|
||||||
}
|
}
|
||||||
/* might not have escaped, or did escape but remain in same spot */
|
/* might not have escaped, or did escape but remain in the same
|
||||||
|
spot */
|
||||||
if (!moved)
|
if (!moved)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2810,6 +2813,8 @@ domove_core(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} /* !dislacedu */
|
||||||
|
|
||||||
/* Move ball and chain. */
|
/* Move ball and chain. */
|
||||||
if (Punished)
|
if (Punished)
|
||||||
if (!drag_ball(x, y, &bc_control, &ballx, &bally, &chainx, &chainy,
|
if (!drag_ball(x, y, &bc_control, &ballx, &bally, &chainx, &chainy,
|
||||||
|
|||||||
Reference in New Issue
Block a user