fix gamelog 1st kill vs 1st weapon hit sequencing
If the first monster the hero kills is killed by the hero's first hit with a wielded weapon, report the hit first and kill second instead of the other way around. Not as hard to manage as I feared, but bound to be more fragile than the simpler handling that produced the odd order. Also while testing it I knocked something into a polymorph trap and it changed form without any feedback. Give foo-changes-into-bar message if the hero is moving and can see it happening. It isn't needed with a monster moves deliberately into a polymorph trap but probably would be useful when that's is unintentional. The "<hero> enters the dungeon" log message had a trailing period but other log messages don't have sentence punctuation, so take that off.
This commit is contained in:
+1
-1
@@ -762,7 +762,7 @@ welcome(boolean new_game) /* false => restoring an old game */
|
|||||||
|
|
||||||
l_nhcore_call(new_game ? NHCORE_START_NEW_GAME : NHCORE_RESTORE_OLD_GAME);
|
l_nhcore_call(new_game ? NHCORE_START_NEW_GAME : NHCORE_RESTORE_OLD_GAME);
|
||||||
if (new_game)
|
if (new_game)
|
||||||
livelog_printf(LL_MINORAC, "%s the%s entered the dungeon.",
|
livelog_printf(LL_MINORAC, "%s the%s entered the dungeon",
|
||||||
g.plname, buf);
|
g.plname, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -2129,7 +2129,12 @@ trapeffect_poly_trap(
|
|||||||
if (resists_magm(mtmp)) {
|
if (resists_magm(mtmp)) {
|
||||||
shieldeff(mtmp->mx, mtmp->my);
|
shieldeff(mtmp->mx, mtmp->my);
|
||||||
} else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
|
} else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
|
||||||
(void) newcham(mtmp, (struct permonst *) 0, FALSE, FALSE);
|
(void) newcham(mtmp, (struct permonst *) 0, FALSE,
|
||||||
|
/* if hero is moving, he probably just swapped
|
||||||
|
places with a pet or perhaps used a joust
|
||||||
|
attack to push mtmp into the trap; describe
|
||||||
|
mtmp's transformation into another shape */
|
||||||
|
(!g.context.mon_moving && in_sight));
|
||||||
if (in_sight)
|
if (in_sight)
|
||||||
seetrap(trap);
|
seetrap(trap);
|
||||||
}
|
}
|
||||||
|
|||||||
+61
-19
@@ -23,6 +23,9 @@ static void end_engulf(void);
|
|||||||
static int gulpum(struct monst *, struct attack *);
|
static int gulpum(struct monst *, struct attack *);
|
||||||
static boolean hmonas(struct monst *);
|
static boolean hmonas(struct monst *);
|
||||||
static void nohandglow(struct monst *);
|
static void nohandglow(struct monst *);
|
||||||
|
static boolean mhurtle_to_doom(struct monst *, int, struct permonst **,
|
||||||
|
boolean);
|
||||||
|
static void first_weapon_hit(void);
|
||||||
static boolean shade_aware(struct obj *);
|
static boolean shade_aware(struct obj *);
|
||||||
|
|
||||||
#define PROJECTILE(obj) ((obj) && is_ammo(obj))
|
#define PROJECTILE(obj) ((obj) && is_ammo(obj))
|
||||||
@@ -568,10 +571,6 @@ known_hitum(
|
|||||||
if (mon->wormno && *mhit)
|
if (mon->wormno && *mhit)
|
||||||
cutworm(mon, g.bhitpos.x, g.bhitpos.y, slice_or_chop);
|
cutworm(mon, g.bhitpos.x, g.bhitpos.y, slice_or_chop);
|
||||||
}
|
}
|
||||||
if (u.uconduct.weaphit && !oldweaphit)
|
|
||||||
livelog_printf(LL_CONDUCT,
|
|
||||||
"hit with a wielded weapon for the first time");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return malive;
|
return malive;
|
||||||
}
|
}
|
||||||
@@ -743,6 +742,11 @@ hmon_hitmon(
|
|||||||
* damage it did _before_ outputting a hit message, but any messages
|
* damage it did _before_ outputting a hit message, but any messages
|
||||||
* associated with the damage don't come out until _after_ outputting
|
* associated with the damage don't come out until _after_ outputting
|
||||||
* a hit message.
|
* a hit message.
|
||||||
|
*
|
||||||
|
* More complications: first_weapon_hit() should be called before
|
||||||
|
* xkilled() in order to have the gamelog messages in the right order.
|
||||||
|
* So it can't be deferred until end of known_hitum() as was originally
|
||||||
|
* done. We might call it directly or indirectly via mhurtle_to_doom().
|
||||||
*/
|
*/
|
||||||
boolean hittxt = FALSE, destroyed = FALSE, already_killed = FALSE;
|
boolean hittxt = FALSE, destroyed = FALSE, already_killed = FALSE;
|
||||||
boolean get_dmg_bonus = TRUE;
|
boolean get_dmg_bonus = TRUE;
|
||||||
@@ -1300,13 +1304,8 @@ hmon_hitmon(
|
|||||||
useup(obj);
|
useup(obj);
|
||||||
obj = (struct obj *) 0;
|
obj = (struct obj *) 0;
|
||||||
}
|
}
|
||||||
/* avoid migrating a dead monster */
|
if (mhurtle_to_doom(mon, tmp, &mdat, TRUE))
|
||||||
if (mon->mhp > tmp) {
|
already_killed = TRUE;
|
||||||
mhurtle(mon, u.dx, u.dy, 1);
|
|
||||||
mdat = mon->data; /* in case of a polymorph trap */
|
|
||||||
if (DEADMONSTER(mon))
|
|
||||||
already_killed = TRUE;
|
|
||||||
}
|
|
||||||
hittxt = TRUE;
|
hittxt = TRUE;
|
||||||
} else if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) {
|
} else if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) {
|
||||||
/* VERY small chance of stunning opponent if unarmed. */
|
/* VERY small chance of stunning opponent if unarmed. */
|
||||||
@@ -1315,19 +1314,21 @@ hmon_hitmon(
|
|||||||
if (canspotmon(mon))
|
if (canspotmon(mon))
|
||||||
pline("%s %s from your powerful strike!", Monnam(mon),
|
pline("%s %s from your powerful strike!", Monnam(mon),
|
||||||
makeplural(stagger(mon->data, "stagger")));
|
makeplural(stagger(mon->data, "stagger")));
|
||||||
/* avoid migrating a dead monster */
|
if (mhurtle_to_doom(mon, tmp, &mdat, FALSE))
|
||||||
if (mon->mhp > tmp) {
|
already_killed = TRUE;
|
||||||
mhurtle(mon, u.dx, u.dy, 1);
|
|
||||||
mdat = mon->data; /* in case of a polymorph trap */
|
|
||||||
if (DEADMONSTER(mon))
|
|
||||||
already_killed = TRUE;
|
|
||||||
}
|
|
||||||
hittxt = TRUE;
|
hittxt = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!already_killed)
|
if (!already_killed) {
|
||||||
|
if (obj && (obj == uwep || (obj == uswapwep && u.twoweap))
|
||||||
|
&& (thrown == HMON_MELEE || thrown == HMON_APPLIED)
|
||||||
|
/* note: caller has already incremented u.uconduct.weaphit
|
||||||
|
so we test for 1; 0 shouldn't be able to happen here... */
|
||||||
|
&& tmp > 0 && u.uconduct.weaphit <= 1)
|
||||||
|
first_weapon_hit();
|
||||||
mon->mhp -= tmp;
|
mon->mhp -= tmp;
|
||||||
|
}
|
||||||
/* adjustments might have made tmp become less than what
|
/* adjustments might have made tmp become less than what
|
||||||
a level draining artifact has already done to max HP */
|
a level draining artifact has already done to max HP */
|
||||||
if (mon->mhp > mon->mhpmax)
|
if (mon->mhp > mon->mhpmax)
|
||||||
@@ -1483,6 +1484,47 @@ hmon_hitmon(
|
|||||||
return destroyed ? FALSE : TRUE;
|
return destroyed ? FALSE : TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* joust or martial arts punch is knocking the target back; that might
|
||||||
|
kill 'mon' (via trap) before known_hitum() has a chance to do so;
|
||||||
|
return True if we kill mon, False otherwise */
|
||||||
|
static boolean
|
||||||
|
mhurtle_to_doom(
|
||||||
|
struct monst *mon, /* target monster */
|
||||||
|
int tmp, /* amount of pending damage */
|
||||||
|
struct permonst **mptr, /* caller's cached copy of mon->data */
|
||||||
|
boolean by_wielded_weapon) /* True: violating a potential conduct */
|
||||||
|
{
|
||||||
|
/* if this hit is breaking the never-hit-with-wielded-weapon conduct
|
||||||
|
(handled by caller's caller...) we need to log the message about
|
||||||
|
that before mon is killed; without this, the log entry sequence
|
||||||
|
N : killed for the first time
|
||||||
|
N : hit with a wielded weapon for the first time
|
||||||
|
reported on the same turn (N) looks "suboptimal";
|
||||||
|
u.uconduct.weaphit has already been incremented => 1 is first hit */
|
||||||
|
if (by_wielded_weapon && u.uconduct.weaphit <= 1)
|
||||||
|
first_weapon_hit();
|
||||||
|
|
||||||
|
/* only hurtle if pending physical damage (tmp) isn't going to kill mon */
|
||||||
|
if (tmp < mon->mhp) {
|
||||||
|
mhurtle(mon, u.dx, u.dy, 1);
|
||||||
|
/* update caller's cached mon->data in case mon was pushed into
|
||||||
|
a polymorph trap or is a vampshifter whose current form has
|
||||||
|
been killed by a trap so that it reverted to original form */
|
||||||
|
*mptr = mon->data;
|
||||||
|
if (DEADMONSTER(mon))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE; /* mon isn't dead yet */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gamelog version of "you've broken never-hit-with-wielded-weapon conduct;
|
||||||
|
the conduct is tracked in known_hitum(); we're called by hmon_hitmon() */
|
||||||
|
static void
|
||||||
|
first_weapon_hit(void)
|
||||||
|
{
|
||||||
|
livelog_printf(LL_CONDUCT, "hit with a wielded weapon for the first time");
|
||||||
|
}
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
shade_aware(struct obj *obj)
|
shade_aware(struct obj *obj)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user