fix mention_walls reporting secret doors as solid stone
jumping over water unintentionally moved hero through that water, causing
drowning if not able to water walk or fly
+try again to fix achievement recording bug with mines and sokoban prizes
Platform- and/or Interface-Specific Fixes
-/* NetHack 3.6 flag.h $NHDT-Date: 1505214875 2017/09/12 11:14:35 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.123 $ */
+/* NetHack 3.6 flag.h $NHDT-Date: 1508827590 2017/10/24 06:46:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.129 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
int wc_fontsiz_menu; /* font size for the menu window */
int wc_fontsiz_text; /* font size for text windows */
int wc_scroll_amount; /* scroll this amount at scroll_margin */
- int wc_scroll_margin; /* scroll map when this far from
- the edge */
+ int wc_scroll_margin; /* scroll map when this far from the edge */
int wc_map_mode; /* specify map viewing options, mostly
- for backward compatibility */
+ * for backward compatibility */
int wc_player_selection; /* method of choosing character */
boolean wc_splash_screen; /* display an opening splash screen or not */
boolean wc_popup_dialog; /* put queries in pop up dialogs instead of
- in the message window */
+ * in the message window */
boolean wc_eight_bit_input; /* allow eight bit input */
boolean wc_mouse_support; /* allow mouse support */
boolean wc2_fullscreen; /* run fullscreen */
boolean wc2_softkeyboard; /* use software keyboard */
boolean wc2_wraptext; /* wrap text */
boolean wc2_selectsaved; /* display a menu of user's saved games */
- boolean wc2_darkgray; /* try to use dark-gray color for black glyphs */
- boolean wc2_hitpointbar; /* show graphical bar representing hit points */
- boolean cmdassist; /* provide detailed assistance for some commands */
- boolean clicklook; /* allow right-clicking for look */
- boolean obsolete; /* obsolete options can point at this, it isn't used */
+ boolean wc2_darkgray; /* try to use dark-gray color for black glyphs */
+ boolean wc2_hitpointbar; /* show graphical bar representing hit points */
+ boolean cmdassist; /* provide detailed assistance for some commands */
+ boolean clicklook; /* allow right-clicking for look */
+ boolean obsolete; /* obsolete options can point at this, it isn't used */
struct autopickup_exception *autopickup_exceptions[2];
#define AP_LEAVE 0
#define AP_GRAB 1
Bitfield(save_uswallow, 1);
Bitfield(save_uinwater, 1);
Bitfield(save_uburied, 1);
+ /* item types used to acomplish "special achievements"; find the target
+ object and you'll be flagged as having achieved something... */
+ short mines_prize_type; /* luckstone */
+ short soko_prize_type1; /* bag of holding or */
+ short soko_prize_type2; /* amulet of reflection */
};
/*
-/* NetHack 3.6 obj.h $NHDT-Date: 1456618994 2016/02/28 00:23:14 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.53 $ */
+/* NetHack 3.6 obj.h $NHDT-Date: 1508827590 2017/10/24 06:46:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.60 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
&& !undiscovered_artifact(ART_EYES_OF_THE_OVERWORLD)))
#define pair_of(o) ((o)->otyp == LENSES || is_gloves(o) || is_boots(o))
+/* 'PRIZE' values override obj->corpsenm so prizes mustn't be object types
+ which use that field for monster type (or other overloaded purpose) */
+#define MINES_PRIZE 1
+#define SOKO_PRIZE1 2
+#define SOKO_PRIZE2 3
#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))
-
+ ((o)->otyp == iflags.mines_prize_type \
+ && (o)->record_achieve_special == MINES_PRIZE)
+#define is_soko_prize(o) \
+ (((o)->otyp == iflags.soko_prize_type1 \
+ && (o)->record_achieve_special == SOKO_PRIZE1) \
+ || ((o)->otyp == iflags.soko_prize_type2 \
+ && (o)->record_achieve_special == SOKO_PRIZE2))
/* Flags for get_obj_location(). */
#define CONTAINED_TOO 0x1
-/* NetHack 3.6 bones.c $NHDT-Date: 1503309019 2017/08/21 09:50:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.70 $ */
+/* NetHack 3.6 bones.c $NHDT-Date: 1508827591 2017/10/24 06:46:31 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.71 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
/* NetHack may be freely redistributed. See license for details. */
otmp->spe = 1;
#endif
} else if (otmp->otyp == EGG) {
- otmp->spe = 0;
+ otmp->spe = 0; /* not "laid by you" in next game */
} else if (otmp->otyp == TIN) {
/* make tins of unique monster's meat be empty */
if (otmp->corpsenm >= LOW_PM
} else if (otmp->otyp == CORPSE || otmp->otyp == STATUE) {
int mnum = otmp->corpsenm;
- /* Discard incarnation details of unique
- monsters (by passing null instead of otmp
- for object), shopkeepers (by passing false
- for revival flag), temple priests, and
- vault guards in order to prevent corpse
- revival or statue reanimation. */
+ /* Discard incarnation details of unique monsters
+ (by passing null instead of otmp for object),
+ shopkeepers (by passing false for revival flag),
+ temple priests, and vault guards in order to
+ prevent corpse revival or statue reanimation. */
if (has_omonst(otmp)
&& cant_revive(&mnum, FALSE, (struct obj *) 0)) {
free_omonst(otmp);
- /* mnum is now either human_zombie or
- doppelganger; for corpses of uniques,
- we need to force the transformation
- now rather than wait until a revival
- attempt, otherwise eating this corpse
+ /* mnum is now either human_zombie or doppelganger;
+ for corpses of uniques, we need to force the
+ transformation now rather than wait until a
+ revival attempt, otherwise eating this corpse
would behave as if it remains unique */
if (mnum == PM_DOPPELGANGER && otmp->otyp == CORPSE)
set_corpsenm(otmp, mnum);
}
+ } else if ((otmp->otyp == iflags.mines_prize_type
+ && !Is_mineend_level(&u.uz))
+ || ((otmp->otyp == iflags.soko_prize_type1
+ || otmp->otyp == iflags.soko_prize_type2)
+ && !Is_sokoend_level(&u.uz))) {
+ /* "special prize" in this game becomes ordinary object
+ if loaded into another game */
+ otmp->record_achieve_special = NON_PM;
} else if (otmp->otyp == AMULET_OF_YENDOR) {
/* no longer the real Amulet */
otmp->otyp = FAKE_AMULET_OF_YENDOR;
char *namebuf;
{
int c;
- boolean strip_8th_bit =
- !strcmp(windowprocs.name, "tty") && !iflags.wc_eight_bit_input;
+ boolean strip_8th_bit = (!strcmp(windowprocs.name, "tty")
+ && !iflags.wc_eight_bit_input);
/* it's tempting to skip this for single-user platforms, since
only the current player could have left these bones--except
-/* NetHack 3.6 invent.c $NHDT-Date: 1498078873 2017/06/21 21:01:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.214 $ */
+/* NetHack 3.6 invent.c $NHDT-Date: 1508827592 2017/10/24 06:46:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.220 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
}
set_artifact_intrinsic(obj, 1, W_ART);
}
- if (is_mines_prize(obj) && obj->record_achieve_special) {
+
+ /* "special achievements" aren't discoverable during play, they
+ end up being recorded in XLOGFILE at end of game, nowhere else;
+ record_achieve_special overloads corpsenm which is ordinarily
+ initialized to NON_PM (-1) rather than to 0; any special prize
+ must never be a corpse, egg, tin, figurine, or statue because
+ their use of obj->corpsenm for monster type would conflict,
+ nor be a leash (corpsenm overloaded for m_id of leashed
+ monster) or a novel (corpsenm overloaded for novel index) */
+ if (is_mines_prize(obj)) {
u.uachieve.mines_luckstone = 1;
- obj->record_achieve_special = 0;
- } else if (is_soko_prize(obj) && obj->record_achieve_special) {
+ obj->record_achieve_special = NON_PM;
+ } else if (is_soko_prize(obj)) {
u.uachieve.finish_sokoban = 1;
- obj->record_achieve_special = 0;
+ obj->record_achieve_special = NON_PM;
}
}
-/* NetHack 3.6 options.c $NHDT-Date: 1507846854 2017/10/12 22:20:54 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.315 $ */
+/* NetHack 3.6 options.c $NHDT-Date: 1508827592 2017/10/24 06:46:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.316 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
iflags.travelcc.x = iflags.travelcc.y = -1;
+ /* for "special achievement" tracking (see obj.h,
+ create_object(sp_lev.c), addinv_core1(invent.c) */
+ iflags.mines_prize_type = LUCKSTONE;
+ iflags.soko_prize_type1 = BAG_OF_HOLDING;
+ iflags.soko_prize_type2 = AMULET_OF_REFLECTION;
+
/* assert( sizeof flags.inv_order == sizeof def_inv_order ); */
(void) memcpy((genericptr_t) flags.inv_order,
(genericptr_t) def_inv_order, sizeof flags.inv_order);
-/* NetHack 3.6 sp_lev.c $NHDT-Date: 1449269920 2015/12/04 22:58:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.77 $ */
+/* NetHack 3.6 sp_lev.c $NHDT-Date: 1508827593 2017/10/24 06:46:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.89 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */
}
} else {
struct obj *cobj = container_obj[container_idx - 1];
+
remove_object(otmp);
if (cobj) {
(void) add_to_container(cobj, otmp);
}
}
- /* Nasty hack here: try to determine if this is the Mines or Sokoban
- * "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 (is_mines_prize(otmp) || is_soko_prize(otmp)) {
- otmp->record_achieve_special = 1;
+ if (o->id != -1) {
+ static const char prize_warning[] = "multiple prizes on %s level";
+ static int mcount = 0, scount = 0;
+
+ /* if this is a specific item of the right type and it is being
+ created on the right level, flag it as the designated item
+ used to detect a special achievement (to whit, reaching and
+ exploring the target level, although the exploration part
+ might be short-circuited if a monster brings object to hero) */
+ if (Is_mineend_level(&u.uz)) {
+ if (otmp->otyp == iflags.mines_prize_type) {
+ otmp->record_achieve_special = MINES_PRIZE;
+ if (++mcount > 1)
+ impossible(prize_warning, "mines end");
+ }
+ } else if (Is_sokoend_level(&u.uz)) {
+ if (otmp->otyp == iflags.soko_prize_type1) {
+ otmp->record_achieve_special = SOKO_PRIZE1;
+ if (++scount > 1)
+ impossible(prize_warning, "sokoban end");
+ } else if (otmp->otyp == iflags.soko_prize_type2) {
+ otmp->record_achieve_special = SOKO_PRIZE2;
+ if (++scount > 1)
+ impossible(prize_warning, "sokoban end");
+ }
+ }
}
stackobj(otmp);