breaking wielded fragile item against iron bars
Reported by entrez, wielding something fragile (potion of acid perhaps), and using F to smash it against iron bars called breaktest() directly, then a second time indirectly through hero_breaks() via hit_bars(). There is a random chance to resist breaking (99% for artifacts, 1% for other items) so breaktest() might say that something will break on the first call and that it will not break on the second call, or vice versa. That could remove uwep from inventory then leave it in limbo without destroying it, or destroy uwep without removing it from inventory first triggering impossible "obfree: deleting worn obj".
This commit is contained in:
@@ -565,7 +565,7 @@ extern boolean throwing_weapon(struct obj *);
|
||||
extern void throwit(struct obj *, long, boolean, struct obj *);
|
||||
extern int omon_adj(struct monst *, struct obj *, boolean);
|
||||
extern int thitmonst(struct monst *, struct obj *);
|
||||
extern int hero_breaks(struct obj *, xchar, xchar, boolean);
|
||||
extern int hero_breaks(struct obj *, xchar, xchar, unsigned);
|
||||
extern int breaks(struct obj *, xchar, xchar);
|
||||
extern void release_camera_demon(struct obj *, xchar, xchar);
|
||||
extern void breakobj(struct obj *, xchar, xchar, boolean, boolean);
|
||||
@@ -1637,7 +1637,7 @@ extern int breamm(struct monst *, struct attack *, struct monst *);
|
||||
extern void m_useupall(struct monst *, struct obj *);
|
||||
extern void m_useup(struct monst *, struct obj *);
|
||||
extern void m_throw(struct monst *, int, int, int, int, int, struct obj *);
|
||||
extern void hit_bars(struct obj **, int, int, int, int, boolean, boolean);
|
||||
extern void hit_bars(struct obj **, int, int, int, int, unsigned);
|
||||
extern boolean hits_bars(struct obj **, int, int, int, int, int, int);
|
||||
|
||||
/* ### muse.c ### */
|
||||
|
||||
@@ -522,6 +522,15 @@ enum bodypart_types {
|
||||
exiting early with "You don't have anything to
|
||||
foo" if nothing in inventory is valid) */
|
||||
|
||||
/* flags for hero_breaks() and hits_bars(); BRK_KNOWN* let callers who have
|
||||
already called breaktest() prevent it from being called again since it
|
||||
has a random factor which makes it be non-deterministic */
|
||||
#define BRK_BY_HERO 1
|
||||
#define BRK_FROM_INV 2
|
||||
#define BRK_KNOWN2BREAK 4
|
||||
#define BRK_KNOWN2NOTBREAK 8
|
||||
#define BRK_KNOWN_OUTCOME (BRK_KNOWN2BREAK | BRK_KNOWN2NOTBREAK)
|
||||
|
||||
/* values returned from getobj() callback functions */
|
||||
enum getobj_callback_returns {
|
||||
/* generally invalid - can't be used for this purpose. will give a "silly
|
||||
|
||||
Reference in New Issue
Block a user