From 48ea3572661a8002bb4c1c1e54d308009a06e5c9 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 18 Feb 2019 13:24:58 -0800 Subject: [PATCH] poly'd hero movement Noticed while fixing the 'monster intrinsics from worn gear' bug(s): set_uasmon() calls set_mon_data(&youmonst,...) which updates movement when the monster polymorphs into something slower, then it did the same thing to youmonst.movement itself, hitting the hero with a double dose of reduction for any movement points not yet spent on current turn. Remove the set_uasmon() side of that, and change set_mon_data() side to add a redundant non-zero test to prevent static analysis from warning that it might be dividing by 0. --- src/mondata.c | 16 ++++++++++++---- src/polyself.c | 12 +----------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/mondata.c b/src/mondata.c index aeb56d56b..fae34e8b7 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mondata.c $NHDT-Date: 1550524563 2019/02/18 21:16:03 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.71 $ */ +/* NetHack 3.6 mondata.c $NHDT-Date: 1550525093 2019/02/18 21:24:53 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.72 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -19,13 +19,21 @@ struct permonst *ptr; mon->data = ptr; mon->mnum = (short) monsndx(ptr); - if (mon->movement) { /* same adjustment as poly'd hero undergoes */ + if (mon->movement) { /* used to adjust poly'd hero as well as monsters */ new_speed = ptr->mmove; /* prorate unused movement if new form is slower so that it doesn't get extra moves leftover from previous form; if new form is faster, leave unused movement as is */ - if (new_speed < old_speed) - mon->movement = new_speed * mon->movement / old_speed; + if (new_speed < old_speed) { + /* + * Some static analysis warns that this might divide by 0 + mon->movement = new_speed * mon->movement / old_speed; + * so add a redundant test to suppress that. + */ + mon->movement *= new_speed; + if (old_speed > 0) /* old > new and new >= 0, so always True */ + mon->movement /= old_speed; + } } return; } diff --git a/src/polyself.c b/src/polyself.c index 59a21397f..b9e6fa81b 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 polyself.c $NHDT-Date: 1550524564 2019/02/18 21:16:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.127 $ */ +/* NetHack 3.6 polyself.c $NHDT-Date: 1550525094 2019/02/18 21:24:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.128 $ */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -41,7 +41,6 @@ void set_uasmon() { struct permonst *mdat = &mons[u.umonnum]; - int new_speed, old_speed = youmonst.data ? youmonst.data->mmove : 0; set_mon_data(&youmonst, mdat); @@ -101,15 +100,6 @@ set_uasmon() float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */ polysense(); - if (youmonst.movement) { - new_speed = mdat->mmove; - /* prorate unused movement if new form is slower so that - it doesn't get extra moves leftover from previous form; - if new form is faster, leave unused movement as is */ - if (new_speed < old_speed) - youmonst.movement = new_speed * youmonst.movement / old_speed; - } - #ifdef STATUS_HILITES status_initialize(REASSESS_ONLY); #endif -- 2.40.0