knockback feedback
Adjust the message given when an attack knocks its target back. Say |<defender> is knocked backward by <attacker> if target will actually move or |<defender> is knocked back by <attacker> if there's something preventing the move. Most players probably won't even notice the difference. (Possibly "rocked back" would be better when not changing location but this hasn't gone that far.) Also make the knock back distance be 1 step 2/3 of the time or 2 steps 1/3 instead of 50:50 chance for 1 or 2 steps.
This commit is contained in:
@@ -644,6 +644,9 @@ extern int dothrow(void);
|
||||
extern int dofire(void);
|
||||
extern void endmultishot(boolean);
|
||||
extern void hitfloor(struct obj *, boolean);
|
||||
extern boolean hurtle_jump(genericptr_t, coordxy, coordxy);
|
||||
extern boolean hurtle_step(genericptr_t, coordxy, coordxy);
|
||||
extern boolean will_hurtle(struct monst *, coordxy, coordxy);
|
||||
extern void hurtle(int, int, int, boolean);
|
||||
extern void mhurtle(struct monst *, int, int, int);
|
||||
extern boolean harmless_missile(struct obj *);
|
||||
@@ -658,8 +661,6 @@ extern void breakobj(struct obj *, coordxy, coordxy, boolean, boolean);
|
||||
extern boolean breaktest(struct obj *);
|
||||
extern boolean walk_path(coord *, coord *,
|
||||
boolean(*)(void *, coordxy, coordxy), genericptr_t);
|
||||
extern boolean hurtle_jump(genericptr_t, coordxy, coordxy);
|
||||
extern boolean hurtle_step(genericptr_t, coordxy, coordxy);
|
||||
|
||||
/* ### drawing.c ### */
|
||||
|
||||
|
||||
@@ -975,20 +975,30 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* used by mhurtle_step() for actual hurtling and also to vary message
|
||||
if target will/won't change location when knocked back */
|
||||
boolean
|
||||
will_hurtle(struct monst *mon, coordxy x, coordxy y)
|
||||
{
|
||||
if (!isok(x, y))
|
||||
return FALSE;
|
||||
/*
|
||||
* TODO: Treat walls, doors, iron bars, etc. specially
|
||||
* rather than just stopping before.
|
||||
*/
|
||||
return goodpos(x, y, mon, MM_IGNOREWATER | MM_IGNORELAVA);
|
||||
}
|
||||
|
||||
static boolean
|
||||
mhurtle_step(genericptr_t arg, coordxy x, coordxy y)
|
||||
{
|
||||
struct monst *mon = (struct monst *) arg;
|
||||
struct monst *mtmp;
|
||||
|
||||
/* TODO: Treat walls, doors, iron bars, etc. specially
|
||||
* rather than just stopping before.
|
||||
*/
|
||||
if (!isok(x, y))
|
||||
return FALSE;
|
||||
|
||||
if (goodpos(x, y, mon, MM_IGNOREWATER | MM_IGNORELAVA)
|
||||
&& m_in_out_region(mon, x, y)) {
|
||||
if (will_hurtle(mon, x, y) && m_in_out_region(mon, x, y)) {
|
||||
int res;
|
||||
|
||||
if (mon != u.usteed) {
|
||||
|
||||
67
src/uhitm.c
67
src/uhitm.c
@@ -4843,20 +4843,26 @@ mhitm_knockback(
|
||||
{
|
||||
char magrbuf[BUFSZ], mdefbuf[BUFSZ];
|
||||
struct obj *otmp;
|
||||
const char *knockedhow;
|
||||
coordxy dx, dy, defx, defy;
|
||||
int knockdistance = rn2(3) ? 1 : 2; /* 67%: 1 step, 33%: 2 steps */
|
||||
boolean u_agr = (magr == &gy.youmonst);
|
||||
boolean u_def = (mdef == &gy.youmonst);
|
||||
boolean was_u = FALSE;
|
||||
boolean was_u = FALSE, dismount = FALSE;
|
||||
|
||||
/* 1/6 chance of attack knocking back a monster */
|
||||
if (rn2(6))
|
||||
return FALSE;
|
||||
|
||||
/* if hero is stuck to a cursed saddle, knock the steed back */
|
||||
if (u_def && u.usteed
|
||||
&& (otmp = which_armor(u.usteed, W_SADDLE)) != 0 && otmp->cursed) {
|
||||
mdef = u.usteed;
|
||||
was_u = TRUE;
|
||||
u_def = FALSE;
|
||||
if (u_def && u.usteed) {
|
||||
if ((otmp = which_armor(u.usteed, W_SADDLE)) != 0 && otmp->cursed) {
|
||||
mdef = u.usteed;
|
||||
was_u = TRUE;
|
||||
u_def = FALSE;
|
||||
} else {
|
||||
dismount = TRUE; /* saddle is not cursed; knock hero out of it */
|
||||
}
|
||||
}
|
||||
|
||||
/* monsters must be alive */
|
||||
@@ -4899,10 +4905,20 @@ mhitm_knockback(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* decide where the first step will place the target; not accurate
|
||||
for being knocked out of saddle but doesn't need to be; used for
|
||||
message before actual hurtle */
|
||||
defx = u_def ? u.ux : mdef->mx;
|
||||
defy = u_def ? u.uy : mdef->my;
|
||||
dx = sgn(defx - (u_agr ? u.ux : magr->mx));
|
||||
dy = sgn(defy - (u_agr ? u.uy : magr->my));
|
||||
/* subtly vary the message text if monster won't actually move */
|
||||
knockedhow = dismount ? "out of your saddle"
|
||||
: will_hurtle(mdef, defx + dx, defy + dy) ? "backward"
|
||||
: "back";
|
||||
|
||||
/* give the message */
|
||||
if (u_def || canseemon(mdef)) {
|
||||
boolean dosteed = u_def && u.usteed;
|
||||
|
||||
Strcpy(magrbuf, u_agr ? "You" : Monnam(magr));
|
||||
Strcpy(mdefbuf, (u_def || was_u) ? "you" : y_monnam(mdef));
|
||||
if (was_u)
|
||||
@@ -4914,36 +4930,33 @@ mhitm_knockback(
|
||||
* mhitm: The fire giant knocks the gnome back with a forceful strike!
|
||||
*/
|
||||
pline("%s %s %s %s with a %s %s!",
|
||||
magrbuf, vtense(magrbuf, "knock"), mdefbuf,
|
||||
dosteed ? "out of your saddle" : "back",
|
||||
magrbuf, vtense(magrbuf, "knock"), mdefbuf, knockedhow,
|
||||
rn2(2) ? "forceful" : "powerful", rn2(2) ? "blow" : "strike");
|
||||
} else if (u_agr) {
|
||||
/* hero knocks unseen foe back; noticed by touch */
|
||||
You("knock %s back!", some_mon_nam(mdef));
|
||||
You_feel("%s be knocked %s!", some_mon_nam(mdef), knockedhow);
|
||||
}
|
||||
|
||||
/* do the actual knockback effect */
|
||||
if (u_def) {
|
||||
/* normally dx,dy indicates direction hero is throwing, zapping, &c
|
||||
but here it is used to pass the preferred direction for dismount
|
||||
to dismount_steed (used for DISMOUNT_KNOCKED only) */
|
||||
u.dx = sgn(u.ux - magr->mx); /* [sgn() is superfluous here] */
|
||||
u.dy = sgn(u.uy - magr->my); /* [ditto] */
|
||||
if (u.usteed)
|
||||
if (dismount) {
|
||||
/* normally u.dx,u.dy indicates the direction hero is throwing,
|
||||
zapping, &c but here it is used to pass preferred direction
|
||||
for dismount to dismount_steed (for DISMOUNT_KNOCKED only) */
|
||||
u.dx = dx;
|
||||
u.dy = dy;
|
||||
dismount_steed(DISMOUNT_KNOCKED);
|
||||
else
|
||||
hurtle(u.dx, u.dy, rnd(2), FALSE);
|
||||
|
||||
} else {
|
||||
hurtle(dx, dy, knockdistance, FALSE);
|
||||
}
|
||||
set_apparxy(magr); /* update magr's idea of where you are */
|
||||
if (!Stunned && !rn2(4))
|
||||
make_stunned((long) rn1(2, 2), TRUE); /* 0..1 + 2 => 2..3 */
|
||||
make_stunned((long) (knockdistance + 1), TRUE); /* 2 or 3 */
|
||||
} else {
|
||||
coordxy x = u_agr ? u.ux : magr->mx;
|
||||
coordxy y = u_agr ? u.uy : magr->my;
|
||||
|
||||
mhurtle(mdef, mdef->mx - x, mdef->my - y, rnd(2));
|
||||
if (DEADMONSTER(mdef) && !was_u) {
|
||||
*hitflags |= MM_DEF_DIED;
|
||||
mhurtle(mdef, dx, dy, knockdistance);
|
||||
if (DEADMONSTER(mdef)) {
|
||||
if (!was_u)
|
||||
*hitflags |= MM_DEF_DIED;
|
||||
} else if (!rn2(4)) {
|
||||
mdef->mstun = 1;
|
||||
/* if steed and hero were knocked back, update attacker's idea
|
||||
|
||||
Reference in New Issue
Block a user