From 76d7044872f1a401a164aaaeff9f9e5c7bfbb91e Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 6 Feb 2017 16:42:33 +0200 Subject: [PATCH] Fix #H5056/bz1086: Bug in Achievement Recording Bug report was: > "Completed sokoban" achievement was logged when picking up > a randomly generated bag of holding in the gnomish mines. The picking-up code was missing checks for the branches, so you could get the achievements outside the correct branches. --- doc/fixes36.1 | 1 + include/obj.h | 8 ++++++++ src/invent.c | 6 ++---- src/sp_lev.c | 6 +----- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 56916b68e..b2972a89a 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -366,6 +366,7 @@ when sitting at a trap spot: You sit down. You step on a level teleporter. (likewise for polymorph trap, and similar issue for web) show all statusline information in #attributes add option status_updates to prevent bottom of screen status line updates +fix achievement recording bug with mines and sokoban prizes Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/include/obj.h b/include/obj.h index e2dc585d4..824ccca39 100644 --- a/include/obj.h +++ b/include/obj.h @@ -342,6 +342,14 @@ struct obj { && !undiscovered_artifact(ART_EYES_OF_THE_OVERWORLD))) #define pair_of(o) ((o)->otyp == LENSES || is_gloves(o) || is_boots(o)) +#define is_mines_prize(o) \ + ((o)->otyp == LUCKSTONE && Is_mineend_level(&u.uz)) +#define is_soko_prize(o) \ + (((o)->otyp == AMULET_OF_REFLECTION \ + || (o)->otyp == BAG_OF_HOLDING) \ + && Is_sokoend_level(&u.uz)) + + /* Flags for get_obj_location(). */ #define CONTAINED_TOO 0x1 #define BURIED_TOO 0x2 diff --git a/src/invent.c b/src/invent.c index fa478b516..fb0099bb8 100644 --- a/src/invent.c +++ b/src/invent.c @@ -513,12 +513,10 @@ struct obj *obj; } set_artifact_intrinsic(obj, 1, W_ART); } - if (obj->otyp == LUCKSTONE && obj->record_achieve_special) { + if (is_mines_prize(obj) && obj->record_achieve_special) { u.uachieve.mines_luckstone = 1; obj->record_achieve_special = 0; - } else if ((obj->otyp == AMULET_OF_REFLECTION - || obj->otyp == BAG_OF_HOLDING) - && obj->record_achieve_special) { + } else if (is_soko_prize(obj) && obj->record_achieve_special) { u.uachieve.finish_sokoban = 1; obj->record_achieve_special = 0; } diff --git a/src/sp_lev.c b/src/sp_lev.c index 6f0445bd5..179d45fa3 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1951,11 +1951,7 @@ struct mkroom *croom; * "prize" and then set record_achieve_special (maps to corpsenm) * for the object. That field will later be checked to find out if * the player obtained the prize. */ - if (otmp->otyp == LUCKSTONE && Is_mineend_level(&u.uz)) { - otmp->record_achieve_special = 1; - } else if ((otmp->otyp == AMULET_OF_REFLECTION - || otmp->otyp == BAG_OF_HOLDING) - && Is_sokoend_level(&u.uz)) { + if (is_mines_prize(otmp) || is_soko_prize(otmp)) { otmp->record_achieve_special = 1; }