Merge remote-tracking branch 'origin/NetHack-3.6.0'

This commit is contained in:
keni
2017-11-04 16:31:11 -04:00
43 changed files with 1481 additions and 1008 deletions
+5 -2
View File
@@ -1126,6 +1126,8 @@ Teleport around the level. Default key is '^T'.
.lp #terrain .lp #terrain
Show bare map without displaying monsters, objects, or traps. Show bare map without displaying monsters, objects, or traps.
Autocompletes. Autocompletes.
.lp #therecmdmenu
Show a menu of possible actions in a location next to you.
.lp #throw .lp #throw
Throw something. Default key is 't'. Throw something. Default key is 't'.
.lp #timeout .lp #timeout
@@ -2559,8 +2561,9 @@ off makes just looking at things faster, since you aren't interrupted with the
``More info?'' prompt, but it also means that you might miss some ``More info?'' prompt, but it also means that you might miss some
interesting and/or important information. Persistent. interesting and/or important information. Persistent.
.lp herecmd_menu .lp herecmd_menu
When using a windowport that supports mouse and clicking on yourself, show When using a windowport that supports mouse and clicking on yourself or
a menu of possible actions for this location. Same as herecmdmenu command. next to you, show a menu of possible actions for the location.
Same as herecmdmenu and therecmdmenu commands.
.lp hilite_pet .lp hilite_pet
Visually distinguish pets from similar animals (default off). Visually distinguish pets from similar animals (default off).
The behavior of this option depends on the type of windowing you use. The behavior of this option depends on the type of windowing you use.
+9 -2
View File
@@ -1186,6 +1186,9 @@ Show what type of thing a map symbol corresponds to. Default key is '{\tt ;}'.
\item[\tb{\#help}] \item[\tb{\#help}]
Show the help menu. Default key is '{\tt ?}', and '{\tt h}' if {\it number\verb+_+pad\/} is on. Show the help menu. Default key is '{\tt ?}', and '{\tt h}' if {\it number\verb+_+pad\/} is on.
%.lp %.lp
\item[\tb{\#herecmdmenu}]
Show a menu of possible actions in your current location.
%.lp
\item[\tb{\#history}] \item[\tb{\#history}]
Show long version and game history. Default key is '{\tt V}'. Show long version and game history. Default key is '{\tt V}'.
%.lp %.lp
@@ -1386,6 +1389,9 @@ Teleport around the level. Default key is '{\tt \^{}T}'.
Show bare map without displaying monsters, objects, or traps. Show bare map without displaying monsters, objects, or traps.
Autocompletes. Autocompletes.
%.lp %.lp
\item[\tb{\#therecmdmenu}]
Show a menu of possible actions in a location next to you.
%.lp
\item[\tb{\#throw}] \item[\tb{\#throw}]
Throw something. Default key is '{\tt t}'. Throw something. Default key is '{\tt t}'.
%.lp %.lp
@@ -3125,8 +3131,9 @@ interrupted with the ``{\tt More info?}'' prompt, but it also means that you
might miss some interesting and/or important information. Persistent. might miss some interesting and/or important information. Persistent.
%.lp %.lp
\item[\ib{herecmd\verb+_+menu}] \item[\ib{herecmd\verb+_+menu}]
When using a windowport that supports mouse and clicking on yourself, show When using a windowport that supports mouse and clicking on yourself or
a menu of possible actions for this location. Same as herecmdmenu command. next to you, show a menu of possible actions for the location.
Same as herecmdmenu and therecmdmenu commands.
%.lp %.lp
\item[\ib{hilite\verb+_+pet}] \item[\ib{hilite\verb+_+pet}]
Visually distinguish pets from similar animals (default off). Visually distinguish pets from similar animals (default off).
+14
View File
@@ -462,6 +462,15 @@ when poly'd into a giant and moving onto a boulder's spot, you could get "you
it up", "you are carrying too much stuff to pick up another boulder" it up", "you are carrying too much stuff to pick up another boulder"
improve #adjust command's handling of the '$' and '#' inventory slots improve #adjust command's handling of the '$' and '#' inventory slots
prevent #adjust from allowing anything to be moved into the special '-' slot prevent #adjust from allowing anything to be moved into the special '-' slot
sometimes rings dropped into sinks can be found in the pipes
doors in special levels were always generated in vertical orientation
assigning a type name to a potion on the floor which is actually a mimic could
prompt "Call a stream of <potion-type> fluid:" (bogus 'fromsink')
with perm_invent option enabled and no inventory, 'i' put up an empty menu
charisma affects the leeway in demon lord bribes
make Vlad slightly tougher
reduce the amount of gold laying on the floor
locked chests and large boxes contain more stuff
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
@@ -521,6 +530,7 @@ hero poly'd into vampire could drain monster down to 0 HP without killing it,
fix mention_walls reporting secret doors as solid stone fix mention_walls reporting secret doors as solid stone
jumping over water unintentionally moved hero through that water, causing jumping over water unintentionally moved hero through that water, causing
drowning if not able to water walk or fly 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 Platform- and/or Interface-Specific Fixes
@@ -583,6 +593,9 @@ X11/USE_XPM: [post-3.6.0 issue] the 'tiles' bug of incorrect total_tiles_used
for STATUES_LOOK_LIKE_MONSTERS broke XPM manipulation of tiles data for STATUES_LOOK_LIKE_MONSTERS broke XPM manipulation of tiles data
PANICTRACE: PANICTRACE_GDB used wrong value for ARGV0 when launching gdb if PANICTRACE: PANICTRACE_GDB used wrong value for ARGV0 when launching gdb if
'nethack -dpath' was used to specify non-default playground directory 'nethack -dpath' was used to specify non-default playground directory
win32gui: gather raw_print error messages into a single dialog window
win32tty: fix display errors when using a font with double wide or ambiguous
width characters
General New Features General New Features
@@ -720,6 +733,7 @@ X11: more terminal-like default resources
win32gui: save and load map colors from registry win32gui: save and load map colors from registry
X11: add new character selection dialog, and obey player_selection:dialog X11: add new character selection dialog, and obey player_selection:dialog
unix: reduce makefile verbosity by default unix: reduce makefile verbosity by default
win32gui: new player selection dialog
NetHack Community Patches (or Variation) Included NetHack Community Patches (or Variation) Included
+11 -9
View File
@@ -56,14 +56,16 @@ struct artifact {
}; };
/* invoked properties with special powers */ /* invoked properties with special powers */
#define TAMING (LAST_PROP + 1) enum invoke_prop_types {
#define HEALING (LAST_PROP + 2) TAMING = (LAST_PROP + 1),
#define ENERGY_BOOST (LAST_PROP + 3) HEALING,
#define UNTRAP (LAST_PROP + 4) ENERGY_BOOST,
#define CHARGE_OBJ (LAST_PROP + 5) UNTRAP,
#define LEV_TELE (LAST_PROP + 6) CHARGE_OBJ,
#define CREATE_PORTAL (LAST_PROP + 7) LEV_TELE,
#define ENLIGHTENING (LAST_PROP + 8) CREATE_PORTAL,
#define CREATE_AMMO (LAST_PROP + 9) ENLIGHTENING,
CREATE_AMMO
};
#endif /* ARTIFACT_H */ #endif /* ARTIFACT_H */
+5
View File
@@ -924,6 +924,11 @@ E int NDECL(phase_of_the_moon);
E boolean NDECL(friday_13th); E boolean NDECL(friday_13th);
E int NDECL(night); E int NDECL(night);
E int NDECL(midnight); E int NDECL(midnight);
E void FDECL(strbuf_init, (strbuf_t *));
E void FDECL(strbuf_append, (strbuf_t *, const char *));
E void FDECL(strbuf_reserve, (strbuf_t *, int));
E void FDECL(strbuf_empty, (strbuf_t *));
E void FDECL(strbuf_nl_to_crlf, (strbuf_t *));
/* ### invent.c ### */ /* ### invent.c ### */
+15 -10
View File
@@ -1,4 +1,4 @@
/* 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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -191,6 +191,7 @@ struct instance_flags {
* behaviour of various NetHack functions and probably warrant * behaviour of various NetHack functions and probably warrant
* a structure of their own elsewhere some day. * a structure of their own elsewhere some day.
*/ */
boolean defer_plname; /* X11 hack: askname() might not set plname */
boolean herecmd_menu; /* use menu when mouseclick on yourself */ boolean herecmd_menu; /* use menu when mouseclick on yourself */
boolean invis_goldsym; /* gold symbol is ' '? */ boolean invis_goldsym; /* gold symbol is ' '? */
int parse_config_file_src; /* hack for parse_config_line() */ int parse_config_file_src; /* hack for parse_config_line() */
@@ -349,25 +350,24 @@ struct instance_flags {
int wc_fontsiz_menu; /* font size for the menu window */ int wc_fontsiz_menu; /* font size for the menu window */
int wc_fontsiz_text; /* font size for text windows */ int wc_fontsiz_text; /* font size for text windows */
int wc_scroll_amount; /* scroll this amount at scroll_margin */ int wc_scroll_amount; /* scroll this amount at scroll_margin */
int wc_scroll_margin; /* scroll map when this far from int wc_scroll_margin; /* scroll map when this far from the edge */
the edge */
int wc_map_mode; /* specify map viewing options, mostly int wc_map_mode; /* specify map viewing options, mostly
for backward compatibility */ * for backward compatibility */
int wc_player_selection; /* method of choosing character */ int wc_player_selection; /* method of choosing character */
boolean wc_splash_screen; /* display an opening splash screen or not */ boolean wc_splash_screen; /* display an opening splash screen or not */
boolean wc_popup_dialog; /* put queries in pop up dialogs instead of 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_eight_bit_input; /* allow eight bit input */
boolean wc_mouse_support; /* allow mouse support */ boolean wc_mouse_support; /* allow mouse support */
boolean wc2_fullscreen; /* run fullscreen */ boolean wc2_fullscreen; /* run fullscreen */
boolean wc2_softkeyboard; /* use software keyboard */ boolean wc2_softkeyboard; /* use software keyboard */
boolean wc2_wraptext; /* wrap text */ boolean wc2_wraptext; /* wrap text */
boolean wc2_selectsaved; /* display a menu of user's saved games */ 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_darkgray; /* try to use dark-gray color for black glyphs */
boolean wc2_hitpointbar; /* show graphical bar representing hit points */ boolean wc2_hitpointbar; /* show graphical bar representing hit points */
boolean cmdassist; /* provide detailed assistance for some commands */ boolean cmdassist; /* provide detailed assistance for some commands */
boolean clicklook; /* allow right-clicking for look */ boolean clicklook; /* allow right-clicking for look */
boolean obsolete; /* obsolete options can point at this, it isn't used */ boolean obsolete; /* obsolete options can point at this, it isn't used */
struct autopickup_exception *autopickup_exceptions[2]; struct autopickup_exception *autopickup_exceptions[2];
#define AP_LEAVE 0 #define AP_LEAVE 0
#define AP_GRAB 1 #define AP_GRAB 1
@@ -381,6 +381,11 @@ struct instance_flags {
Bitfield(save_uswallow, 1); Bitfield(save_uswallow, 1);
Bitfield(save_uinwater, 1); Bitfield(save_uinwater, 1);
Bitfield(save_uburied, 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 */
}; };
/* /*
+6
View File
@@ -151,6 +151,12 @@ enum game_end_types {
ASCENDED ASCENDED
}; };
typedef struct strbuf {
int len;
char * str;
char buf[256];
} strbuf_t;
#include "align.h" #include "align.h"
#include "dungeon.h" #include "dungeon.h"
#include "monsym.h" #include "monsym.h"
+13 -7
View File
@@ -1,4 +1,4 @@
/* 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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -343,13 +343,19 @@ struct obj {
&& !undiscovered_artifact(ART_EYES_OF_THE_OVERWORLD))) && !undiscovered_artifact(ART_EYES_OF_THE_OVERWORLD)))
#define pair_of(o) ((o)->otyp == LENSES || is_gloves(o) || is_boots(o)) #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) \ #define is_mines_prize(o) \
((o)->otyp == LUCKSTONE && Is_mineend_level(&u.uz)) ((o)->otyp == iflags.mines_prize_type \
#define is_soko_prize(o) \ && (o)->record_achieve_special == MINES_PRIZE)
(((o)->otyp == AMULET_OF_REFLECTION \ #define is_soko_prize(o) \
|| (o)->otyp == BAG_OF_HOLDING) \ (((o)->otyp == iflags.soko_prize_type1 \
&& Is_sokoend_level(&u.uz)) && (o)->record_achieve_special == SOKO_PRIZE1) \
|| ((o)->otyp == iflags.soko_prize_type2 \
&& (o)->record_achieve_special == SOKO_PRIZE2))
/* Flags for get_obj_location(). */ /* Flags for get_obj_location(). */
#define CONTAINED_TOO 0x1 #define CONTAINED_TOO 0x1
+75 -73
View File
@@ -11,79 +11,81 @@
* Property #0 is not used. * Property #0 is not used.
*/ */
/* Resistances to troubles */ /* Resistances to troubles */
#define FIRE_RES 1 enum prop_types {
#define COLD_RES 2 FIRE_RES = 1,
#define SLEEP_RES 3 COLD_RES,
#define DISINT_RES 4 SLEEP_RES,
#define SHOCK_RES 5 DISINT_RES,
#define POISON_RES 6 SHOCK_RES,
#define ACID_RES 7 POISON_RES,
#define STONE_RES 8 ACID_RES,
/* note: for the first eight properties, MR_xxx == (1 << (xxx_RES - 1)) */ STONE_RES,
#define DRAIN_RES 9 /* note: for the first eight properties, MR_xxx == (1 << (xxx_RES - 1)) */
#define SICK_RES 10 DRAIN_RES,
#define INVULNERABLE 11 SICK_RES,
#define ANTIMAGIC 12 INVULNERABLE,
/* Troubles */ ANTIMAGIC,
#define STUNNED 13 /* Troubles */
#define CONFUSION 14 STUNNED,
#define BLINDED 15 CONFUSION,
#define DEAF 16 BLINDED,
#define SICK 17 DEAF,
#define STONED 18 SICK,
#define STRANGLED 19 STONED,
#define VOMITING 20 STRANGLED,
#define GLIB 21 VOMITING,
#define SLIMED 22 GLIB,
#define HALLUC 23 SLIMED,
#define HALLUC_RES 24 HALLUC,
#define FUMBLING 25 HALLUC_RES,
#define WOUNDED_LEGS 26 FUMBLING,
#define SLEEPY 27 WOUNDED_LEGS,
#define HUNGER 28 SLEEPY,
/* Vision and senses */ HUNGER,
#define SEE_INVIS 29 /* Vision and senses */
#define TELEPAT 30 SEE_INVIS,
#define WARNING 31 TELEPAT,
#define WARN_OF_MON 32 WARNING,
#define WARN_UNDEAD 33 WARN_OF_MON,
#define SEARCHING 34 WARN_UNDEAD,
#define CLAIRVOYANT 35 SEARCHING,
#define INFRAVISION 36 CLAIRVOYANT,
#define DETECT_MONSTERS 37 INFRAVISION,
/* Appearance and behavior */ DETECT_MONSTERS,
#define ADORNED 38 /* Appearance and behavior */
#define INVIS 39 ADORNED,
#define DISPLACED 40 INVIS,
#define STEALTH 41 DISPLACED,
#define AGGRAVATE_MONSTER 42 STEALTH,
#define CONFLICT 43 AGGRAVATE_MONSTER,
/* Transportation */ CONFLICT,
#define JUMPING 44 /* Transportation */
#define TELEPORT 45 JUMPING,
#define TELEPORT_CONTROL 46 TELEPORT,
#define LEVITATION 47 TELEPORT_CONTROL,
#define FLYING 48 LEVITATION,
#define WWALKING 49 FLYING,
#define SWIMMING 50 WWALKING,
#define MAGICAL_BREATHING 51 SWIMMING,
#define PASSES_WALLS 52 MAGICAL_BREATHING,
/* Physical attributes */ PASSES_WALLS,
#define SLOW_DIGESTION 53 /* Physical attributes */
#define HALF_SPDAM 54 SLOW_DIGESTION,
#define HALF_PHDAM 55 HALF_SPDAM,
#define REGENERATION 56 HALF_PHDAM,
#define ENERGY_REGENERATION 57 REGENERATION,
#define PROTECTION 58 ENERGY_REGENERATION,
#define PROT_FROM_SHAPE_CHANGERS 59 PROTECTION,
#define POLYMORPH 60 PROT_FROM_SHAPE_CHANGERS,
#define POLYMORPH_CONTROL 61 POLYMORPH,
#define UNCHANGING 62 POLYMORPH_CONTROL,
#define FAST 63 UNCHANGING,
#define REFLECTING 64 FAST,
#define FREE_ACTION 65 REFLECTING,
#define FIXED_ABIL 66 FREE_ACTION,
#define LIFESAVED 67 FIXED_ABIL,
LIFESAVED
};
#define LAST_PROP (LIFESAVED) #define LAST_PROP (LIFESAVED)
/*** Where the properties come from ***/ /*** Where the properties come from ***/
+4 -1
View File
@@ -85,7 +85,8 @@ enum levl_typ_types {
#define IS_STWALL(typ) ((typ) <= DBWALL) /* STONE <= (typ) <= DBWALL */ #define IS_STWALL(typ) ((typ) <= DBWALL) /* STONE <= (typ) <= DBWALL */
#define IS_ROCK(typ) ((typ) < POOL) /* absolutely nonaccessible */ #define IS_ROCK(typ) ((typ) < POOL) /* absolutely nonaccessible */
#define IS_DOOR(typ) ((typ) == DOOR) #define IS_DOOR(typ) ((typ) == DOOR)
#define IS_TREE(typ) \ #define IS_DOORJOIN(typ) (IS_ROCK(typ) || (typ) == IRONBARS)
#define IS_TREE(typ) \
((typ) == TREE || (level.flags.arboreal && (typ) == STONE)) ((typ) == TREE || (level.flags.arboreal && (typ) == STONE))
#define ACCESSIBLE(typ) ((typ) >= DOOR) /* good position */ #define ACCESSIBLE(typ) ((typ) >= DOOR) /* good position */
#define IS_ROOM(typ) ((typ) >= ROOM) /* ROOM, STAIRS, furniture.. */ #define IS_ROOM(typ) ((typ) >= ROOM) /* ROOM, STAIRS, furniture.. */
@@ -300,6 +301,8 @@ extern const struct symdef defsyms[MAXPCHARS]; /* defaults */
extern const struct symdef def_warnsyms[WARNCOUNT]; extern const struct symdef def_warnsyms[WARNCOUNT];
extern int currentgraphics; /* from drawing.c */ extern int currentgraphics; /* from drawing.c */
extern nhsym showsyms[]; extern nhsym showsyms[];
extern nhsym l_syms[];
extern nhsym r_syms[];
extern struct symsetentry symset[NUM_GRAPHICS]; /* from drawing.c */ extern struct symsetentry symset[NUM_GRAPHICS]; /* from drawing.c */
#define SYMHANDLING(ht) (symset[currentgraphics].handling == (ht)) #define SYMHANDLING(ht) (symset[currentgraphics].handling == (ht))
+21 -15
View File
@@ -1,4 +1,4 @@
/* 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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -127,7 +127,7 @@ boolean restore;
otmp->spe = 1; otmp->spe = 1;
#endif #endif
} else if (otmp->otyp == EGG) { } else if (otmp->otyp == EGG) {
otmp->spe = 0; otmp->spe = 0; /* not "laid by you" in next game */
} else if (otmp->otyp == TIN) { } else if (otmp->otyp == TIN) {
/* make tins of unique monster's meat be empty */ /* make tins of unique monster's meat be empty */
if (otmp->corpsenm >= LOW_PM if (otmp->corpsenm >= LOW_PM
@@ -136,24 +136,30 @@ boolean restore;
} else if (otmp->otyp == CORPSE || otmp->otyp == STATUE) { } else if (otmp->otyp == CORPSE || otmp->otyp == STATUE) {
int mnum = otmp->corpsenm; int mnum = otmp->corpsenm;
/* Discard incarnation details of unique /* Discard incarnation details of unique monsters
monsters (by passing null instead of otmp (by passing null instead of otmp for object),
for object), shopkeepers (by passing false shopkeepers (by passing false for revival flag),
for revival flag), temple priests, and temple priests, and vault guards in order to
vault guards in order to prevent corpse prevent corpse revival or statue reanimation. */
revival or statue reanimation. */
if (has_omonst(otmp) if (has_omonst(otmp)
&& cant_revive(&mnum, FALSE, (struct obj *) 0)) { && cant_revive(&mnum, FALSE, (struct obj *) 0)) {
free_omonst(otmp); free_omonst(otmp);
/* mnum is now either human_zombie or /* mnum is now either human_zombie or doppelganger;
doppelganger; for corpses of uniques, for corpses of uniques, we need to force the
we need to force the transformation transformation now rather than wait until a
now rather than wait until a revival revival attempt, otherwise eating this corpse
attempt, otherwise eating this corpse
would behave as if it remains unique */ would behave as if it remains unique */
if (mnum == PM_DOPPELGANGER && otmp->otyp == CORPSE) if (mnum == PM_DOPPELGANGER && otmp->otyp == CORPSE)
set_corpsenm(otmp, mnum); 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) { } else if (otmp->otyp == AMULET_OF_YENDOR) {
/* no longer the real Amulet */ /* no longer the real Amulet */
otmp->otyp = FAKE_AMULET_OF_YENDOR; otmp->otyp = FAKE_AMULET_OF_YENDOR;
@@ -186,8 +192,8 @@ sanitize_name(namebuf)
char *namebuf; char *namebuf;
{ {
int c; int c;
boolean strip_8th_bit = boolean strip_8th_bit = (!strcmp(windowprocs.name, "tty")
!strcmp(windowprocs.name, "tty") && !iflags.wc_eight_bit_input; && !iflags.wc_eight_bit_input);
/* it's tempting to skip this for single-user platforms, since /* it's tempting to skip this for single-user platforms, since
only the current player could have left these bones--except only the current player could have left these bones--except
+7 -5
View File
@@ -1794,7 +1794,7 @@ boolean from_configfile;
numeric = TRUE; numeric = TRUE;
tmp = tmpbuf; tmp = tmpbuf;
if (strlen(tmp) > 0) { if (strlen(tmp) > 0) {
dt = blstats[0][fld].anytype; dt = initblstats[fld].anytype;
if (percent) if (percent)
dt = ANY_INT; dt = ANY_INT;
(void) s_to_anything(&hilite.value, tmp, dt); (void) s_to_anything(&hilite.value, tmp, dt);
@@ -2593,7 +2593,7 @@ int fld;
nopts++; nopts++;
} }
if (fld != BL_CAP && (at == ANY_INT || at == ANY_LONG || at == ANY_UINT)) { if (fld != BL_CAP && fld != BL_HUNGER && (at == ANY_INT || at == ANY_LONG || at == ANY_UINT)) {
any = zeroany; any = zeroany;
any.a_int = onlybeh = BL_TH_VAL_ABSOLUTE; any.a_int = onlybeh = BL_TH_VAL_ABSOLUTE;
add_menu(tmpwin, NO_GLYPH, &any, 'n', 0, ATR_NONE, add_menu(tmpwin, NO_GLYPH, &any, 'n', 0, ATR_NONE,
@@ -2609,7 +2609,7 @@ int fld;
nopts++; nopts++;
} }
if (initblstats[fld].anytype == ANY_STR || fld == BL_CAP) { if (initblstats[fld].anytype == ANY_STR || fld == BL_CAP || fld == BL_HUNGER) {
any = zeroany; any = zeroany;
any.a_int = onlybeh = BL_TH_TEXTMATCH; any.a_int = onlybeh = BL_TH_TEXTMATCH;
Sprintf(buf, "%s text match", initblstats[fld].fldname); Sprintf(buf, "%s text match", initblstats[fld].fldname);
@@ -2878,7 +2878,7 @@ choose_value:
hilite.rel = TXT_VALUE; hilite.rel = TXT_VALUE;
Strcpy(hilite.textmatch, aligntxt[rv]); Strcpy(hilite.textmatch, aligntxt[rv]);
} else if (fld == BL_HUNGER) { } else if (fld == BL_HUNGER) {
const char *hutxt[] = {"Satiated", "", "Hungry", "Weak", const char *hutxt[] = {"Satiated", (char *)0, "Hungry", "Weak",
"Fainting", "Fainted", "Starved"}; "Fainting", "Fainted", "Starved"};
int rv = query_arrayvalue(qry_buf, int rv = query_arrayvalue(qry_buf,
hutxt, hutxt,
@@ -3163,7 +3163,9 @@ status_hilites_viewall()
datawin = create_nhwindow(NHW_TEXT); datawin = create_nhwindow(NHW_TEXT);
while (hlstr) { while (hlstr) {
Sprintf(buf, "OPTIONS=hilite_status: %s", hlstr->str); Sprintf(buf, "OPTIONS=hilite_status: %.*s",
(int)(BUFSZ - sizeof "OPTIONS=hilite_status: " - 1),
hlstr->str);
putstr(datawin, 0, buf); putstr(datawin, 0, buf);
hlstr = hlstr->next; hlstr = hlstr->next;
} }
+2 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 cmd.c $NHDT-Date: 1494985492 2017/05/17 01:44:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.258 $ */ /* NetHack 3.6 cmd.c $NHDT-Date: 1508880573 2017/10/24 21:29:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.275 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -3005,7 +3005,7 @@ struct ext_func_tab extcmdlist[] = {
{ '\0', "terrain", "show map without obstructions", { '\0', "terrain", "show map without obstructions",
doterrain, IFBURIED | AUTOCOMPLETE }, doterrain, IFBURIED | AUTOCOMPLETE },
{ '\0', "therecmdmenu", { '\0', "therecmdmenu",
"show menu of commands you can do from here to adjacent spot", "menu of commands you can do from here to adjacent spot",
dotherecmdmenu }, dotherecmdmenu },
{ 't', "throw", "throw something", dothrow }, { 't', "throw", "throw something", dothrow },
{ '\0', "timeout", "look at timeout queue and hero's timed intrinsics", { '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
+6
View File
@@ -501,6 +501,12 @@ register struct obj *obj;
pline_The("sink backs up, leaving %s.", doname(obj)); pline_The("sink backs up, leaving %s.", doname(obj));
obj->in_use = FALSE; obj->in_use = FALSE;
dropx(obj); dropx(obj);
} else if (!rn2(5)) {
freeinv(obj);
obj->in_use = FALSE;
obj->ox = u.ux;
obj->oy = u.uy;
add_to_buried(obj);
} else } else
useup(obj); useup(obj);
} }
+12 -5
View File
@@ -1086,11 +1086,18 @@ int after; /* this is extra fast monster movement */
continue; continue;
/* lessen the chance of backtracking to previous position(s) */ /* lessen the chance of backtracking to previous position(s) */
k = has_edog ? uncursedcnt : cnt; /* This causes unintended issues for pets trying to follow
for (j = 0; j < MTSZ && j < k - 1; j++) the hero. Thus, only run it if not leashed and >5 tiles
if (nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) away. */
if (rn2(MTSZ * (k - j))) if (!mtmp->mleashed &&
goto nxti; distmin(mtmp->mx, mtmp->my, u.ux, u.uy) > 5) {
k = has_edog ? uncursedcnt : cnt;
for (j = 0; j < MTSZ && j < k - 1; j++)
if (nx == mtmp->mtrack[j].x &&
ny == mtmp->mtrack[j].y)
if (rn2(MTSZ * (k - j)))
goto nxti;
}
j = ((ndist = GDIST(nx, ny)) - nidist) * appr; j = ((ndist = GDIST(nx, ny)) - nidist) * appr;
if ((j == 0 && !rn2(++chcnt)) || j < 0 if ((j == 0 && !rn2(++chcnt)) || j < 0
+6 -2
View File
@@ -1274,8 +1274,11 @@ int how;
if (have_windows) { if (have_windows) {
wait_synch(); wait_synch();
free_pickinv_cache(); /* extra persistent window if perm_invent */ free_pickinv_cache(); /* extra persistent window if perm_invent */
if (WIN_INVEN != WIN_ERR) if (WIN_INVEN != WIN_ERR) {
destroy_nhwindow(WIN_INVEN), WIN_INVEN = WIN_ERR; destroy_nhwindow(WIN_INVEN), WIN_INVEN = WIN_ERR;
/* precaution in case any late update_inventory() calls occur */
flags.perm_invent = 0;
}
display_nhwindow(WIN_MESSAGE, TRUE); display_nhwindow(WIN_MESSAGE, TRUE);
destroy_nhwindow(WIN_MAP), WIN_MAP = WIN_ERR; destroy_nhwindow(WIN_MAP), WIN_MAP = WIN_ERR;
#ifndef STATUS_HILITES #ifndef STATUS_HILITES
@@ -1315,7 +1318,7 @@ int how;
? (const char *) ((flags.female && urole.name.f) ? (const char *) ((flags.female && urole.name.f)
? urole.name.f ? urole.name.f
: urole.name.m) : urole.name.m)
: (const char *) (flags.female ? "Demigoddess" : "Demigod")); : (const char *) (flags.female ? "Demigoddess" : "Demigod"));
dump_forward_putstr(endwin, 0, pbuf, done_stopprint); dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
dump_forward_putstr(endwin, 0, "", done_stopprint); dump_forward_putstr(endwin, 0, "", done_stopprint);
@@ -1350,6 +1353,7 @@ int how;
Schroedingers_cat = odds_and_ends(invent, CAT_CHECK); Schroedingers_cat = odds_and_ends(invent, CAT_CHECK);
if (Schroedingers_cat) { if (Schroedingers_cat) {
int mhp, m_lev = adj_lev(&mons[PM_HOUSECAT]); int mhp, m_lev = adj_lev(&mons[PM_HOUSECAT]);
mhp = d(m_lev, 8); mhp = d(m_lev, 8);
nowrap_add(u.urexp, mhp); nowrap_add(u.urexp, mhp);
Strcat(eos(pbuf), " and Schroedinger's cat"); Strcat(eos(pbuf), " and Schroedinger's cat");
+85 -1
View File
@@ -61,6 +61,11 @@
boolean friday_13th (void) boolean friday_13th (void)
int night (void) int night (void)
int midnight (void) int midnight (void)
void strbuf_init (strbuf *, const char *)
void strbuf_append (strbuf *, const char *)
void strbuf_reserve (strbuf *, int)
void strbuf_empty (strbuf *)
void strbuf_nl_to_crlf (strbuf_t *)
=*/ =*/
#ifdef LINT #ifdef LINT
#define Static /* pacify lint */ #define Static /* pacify lint */
@@ -183,7 +188,7 @@ char *
strip_newline(str) strip_newline(str)
char *str; char *str;
{ {
char *p = index(str, '\n'); char *p = rindex(str, '\n');
if (p) { if (p) {
if (p > str && *(p - 1) == '\r') if (p > str && *(p - 1) == '\r')
@@ -1101,4 +1106,83 @@ midnight()
return (getlt()->tm_hour == 0); return (getlt()->tm_hour == 0);
} }
/* strbuf_init() initializes strbuf state for use */
void
strbuf_init(strbuf)
strbuf_t *strbuf;
{
strbuf->str = NULL;
strbuf->len = 0;
}
/* strbuf_append() appends given str to strbuf->str */
void
strbuf_append(strbuf, str)
strbuf_t *strbuf;
const char *str;
{
int len = (int) strlen(str) + 1;
strbuf_reserve(strbuf,
len + (strbuf->str ? (int) strlen(strbuf->str) : 0));
Strcat(strbuf->str, str);
}
/* strbuf_reserve() ensure strbuf->str has storage for len characters */
void
strbuf_reserve(strbuf, len)
strbuf_t *strbuf;
int len;
{
if (strbuf->str == NULL) {
strbuf->str = strbuf->buf;
strbuf->str[0] = '\0';
strbuf->len = (int) sizeof strbuf->buf;
}
if (len > strbuf->len) {
char *oldbuf = strbuf->str;
strbuf->len = len + (int) sizeof strbuf->buf;
strbuf->str = (char *) alloc(strbuf->len);
Strcpy(strbuf->str, oldbuf);
if (oldbuf != strbuf->buf)
free((genericptr_t) oldbuf);
}
}
/* strbuf_empty() frees allocated memory and set strbuf to initial state */
void
strbuf_empty(strbuf)
strbuf_t *strbuf;
{
if (strbuf->str != NULL && strbuf->str != strbuf->buf)
free((genericptr_t) strbuf->str);
strbuf_init(strbuf);
}
/* strbuf_nl_to_crlf() converts all occurences of \n to \r\n */
void
strbuf_nl_to_crlf(strbuf)
strbuf_t *strbuf;
{
if (strbuf->str) {
int len = (int) strlen(strbuf->str);
int count = 0;
char *cp = strbuf->str;
while (*cp)
if (*cp++ == '\n')
count++;
if (count) {
strbuf_reserve(strbuf, len + count + 1);
for (cp = strbuf->str + len + count; count; --cp)
if ((*cp = cp[-count]) == '\n') {
*--cp = '\r';
--count;
}
}
}
}
/*hacklib.c*/ /*hacklib.c*/
+30 -10
View File
@@ -1,4 +1,4 @@
/* 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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -504,12 +504,21 @@ struct obj *obj;
} }
set_artifact_intrinsic(obj, 1, W_ART); 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; u.uachieve.mines_luckstone = 1;
obj->record_achieve_special = 0; obj->record_achieve_special = NON_PM;
} else if (is_soko_prize(obj) && obj->record_achieve_special) { } else if (is_soko_prize(obj)) {
u.uachieve.finish_sokoban = 1; u.uachieve.finish_sokoban = 1;
obj->record_achieve_special = 0; obj->record_achieve_special = NON_PM;
} }
} }
@@ -2171,6 +2180,7 @@ const char *query;
boolean want_reply; boolean want_reply;
long *out_cnt; long *out_cnt;
{ {
static const char not_carrying_anything[] = "Not carrying anything";
struct obj *otmp; struct obj *otmp;
char ilet, ret; char ilet, ret;
char *invlet = flags.inv_order; char *invlet = flags.inv_order;
@@ -2217,7 +2227,7 @@ long *out_cnt;
++n; ++n;
if (n == 0) { if (n == 0) {
pline("Not carrying anything."); pline("%s.", not_carrying_anything);
return 0; return 0;
} }
@@ -2305,14 +2315,24 @@ nextclass:
goto nextclass; goto nextclass;
} }
} }
if (iflags.force_invmenu && lets && want_reply) { if (iflags.force_invmenu && lets && want_reply) {
any = zeroany; any = zeroany;
add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, "Special", MENU_UNSELECTED); add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
"Special", MENU_UNSELECTED);
any.a_char = '*'; any.a_char = '*';
add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE, "(list everything)", MENU_UNSELECTED); add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE,
"(list everything)", MENU_UNSELECTED);
}
/* for permanent inventory where we intend to show everything but
nothing has been listed (because there isn't anyhing to list;
recognized via any.a_char still being zero; the n==0 case above
gets skipped for perm_invent), put something into the menu */
if (flags.perm_invent && !lets && !any.a_char) {
any = zeroany;
add_menu(win, NO_GLYPH, &any, 0, 0, 0,
not_carrying_anything, MENU_UNSELECTED);
want_reply = FALSE;
} }
end_menu(win, query && *query ? query : (char *) 0); end_menu(win, query && *query ? query : (char *) 0);
n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected); n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected);
+2 -1
View File
@@ -279,7 +279,8 @@ register struct monst *mtmp;
if ((offer = bribe(mtmp)) >= demand) { if ((offer = bribe(mtmp)) >= demand) {
pline("%s vanishes, laughing about cowardly mortals.", pline("%s vanishes, laughing about cowardly mortals.",
Amonnam(mtmp)); Amonnam(mtmp));
} else if (offer > 0L && (long) rnd(40) > (demand - offer)) { } else if (offer > 0L
&& (long) rnd(5 * ACURR(A_CHA)) > (demand - offer)) {
pline("%s scowls at you menacingly, then vanishes.", pline("%s scowls at you menacingly, then vanishes.",
Amonnam(mtmp)); Amonnam(mtmp));
} else { } else {
+31 -23
View File
@@ -223,6 +223,7 @@ boolean init, artif;
return otmp; return otmp;
} }
/* mkobj(): select a type of item from a class, use mksobj() to create it */
struct obj * struct obj *
mkobj(oclass, artif) mkobj(oclass, artif)
char oclass; char oclass;
@@ -265,10 +266,10 @@ struct obj *box;
n = 20; n = 20;
break; break;
case CHEST: case CHEST:
n = 5; n = box->olocked ? 7 : 5;
break; break;
case LARGE_BOX: case LARGE_BOX:
n = 3; n = box->olocked ? 5 : 3;
break; break;
case SACK: case SACK:
case OILSKIN_SACK: case OILSKIN_SACK:
@@ -277,7 +278,7 @@ struct obj *box;
n = 0; n = 0;
break; break;
} }
/*else FALLTHRU*/ /*else FALLTHRU*/
case BAG_OF_HOLDING: case BAG_OF_HOLDING:
n = 1; n = 1;
break; break;
@@ -712,6 +713,7 @@ static const char dknowns[] = { WAND_CLASS, RING_CLASS, POTION_CLASS,
SCROLL_CLASS, GEM_CLASS, SPBOOK_CLASS, SCROLL_CLASS, GEM_CLASS, SPBOOK_CLASS,
WEAPON_CLASS, TOOL_CLASS, 0 }; WEAPON_CLASS, TOOL_CLASS, 0 };
/* mksobj(): create a specific type of object */
struct obj * struct obj *
mksobj(otyp, init, artif) mksobj(otyp, init, artif)
int otyp; int otyp;
@@ -743,7 +745,7 @@ boolean artif;
otmp->cknown = 0; otmp->cknown = 0;
otmp->corpsenm = NON_PM; otmp->corpsenm = NON_PM;
if (init) if (init) {
switch (let) { switch (let) {
case WEAPON_CLASS: case WEAPON_CLASS:
otmp->quan = is_multigen(otmp) ? (long) rn1(6, 6) : 1L; otmp->quan = is_multigen(otmp) ? (long) rn1(6, 6) : 1L;
@@ -773,9 +775,8 @@ boolean artif;
&& (--tryct > 0)); && (--tryct > 0));
if (tryct == 0) { if (tryct == 0) {
/* perhaps rndmonnum() only wants to make G_NOCORPSE /* perhaps rndmonnum() only wants to make G_NOCORPSE
monsters on monsters on this level; create an adventurer's
this level; let's create an adventurer's corpse corpse instead, then */
instead, then */
otmp->corpsenm = PM_HUMAN; otmp->corpsenm = PM_HUMAN;
} }
/* timer set below */ /* timer set below */
@@ -889,14 +890,13 @@ boolean artif;
case BAG_OF_TRICKS: case BAG_OF_TRICKS:
otmp->spe = rnd(20); otmp->spe = rnd(20);
break; break;
case FIGURINE: { case FIGURINE:
int tryct2 = 0; tryct = 0;
do do
otmp->corpsenm = rndmonnum(); otmp->corpsenm = rndmonnum();
while (is_human(&mons[otmp->corpsenm]) && tryct2++ < 30); while (is_human(&mons[otmp->corpsenm]) && tryct++ < 30);
blessorcurse(otmp, 4); blessorcurse(otmp, 4);
break; break;
}
case BELL_OF_OPENING: case BELL_OF_OPENING:
otmp->spe = 3; otmp->spe = 3;
break; break;
@@ -918,15 +918,12 @@ boolean artif;
curse(otmp); curse(otmp);
} else } else
blessorcurse(otmp, 10); blessorcurse(otmp, 10);
break;
case VENOM_CLASS: case VENOM_CLASS:
case CHAIN_CLASS: case CHAIN_CLASS:
case BALL_CLASS: case BALL_CLASS:
break; break;
case POTION_CLASS: case POTION_CLASS: /* note: potions get some additional init below */
otmp->fromsink = 0;
if (otmp->otyp == POT_OIL)
otmp->age = MAX_OIL_IN_FLASK; /* amount of oil */
/* fall through */
case SCROLL_CLASS: case SCROLL_CLASS:
#ifdef MAIL #ifdef MAIL
if (otmp->otyp != SCR_MAIL) if (otmp->otyp != SCR_MAIL)
@@ -1012,27 +1009,36 @@ boolean artif;
objects[otmp->otyp].oc_class); objects[otmp->otyp].oc_class);
return (struct obj *) 0; return (struct obj *) 0;
} }
}
/* some things must get done (corpsenm, timers) even if init = 0 */ /* some things must get done (corpsenm, timers) even if init = 0 */
switch (otmp->otyp) { switch ((otmp->oclass == POTION_CLASS && otmp->otyp != POT_OIL)
? POT_WATER
: otmp->otyp) {
case CORPSE: case CORPSE:
if (otmp->corpsenm == NON_PM) { if (otmp->corpsenm == NON_PM) {
otmp->corpsenm = undead_to_corpse(rndmonnum()); otmp->corpsenm = undead_to_corpse(rndmonnum());
if (mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE | G_GONE)) if (mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE | G_GONE))
otmp->corpsenm = urole.malenum; otmp->corpsenm = urole.malenum;
} }
/*FALLTHRU*/ /*FALLTHRU*/
case STATUE: case STATUE:
case FIGURINE: case FIGURINE:
if (otmp->corpsenm == NON_PM) if (otmp->corpsenm == NON_PM)
otmp->corpsenm = rndmonnum(); otmp->corpsenm = rndmonnum();
/*FALLTHRU*/ /*FALLTHRU*/
case EGG: case EGG:
/* case TIN: */ /* case TIN: */
set_corpsenm(otmp, otmp->corpsenm); set_corpsenm(otmp, otmp->corpsenm);
break; break;
case POT_OIL:
otmp->age = MAX_OIL_IN_FLASK; /* amount of oil */
/*FALLTHRU*/
case POT_WATER: /* POTION_CLASS */
otmp->fromsink = 0; /* overloads corpsenm, which was set to NON_PM */
break;
case LEASH: case LEASH:
otmp->leashmon = 0; otmp->leashmon = 0; /* overloads corpsenm, which was set to NON_PM */
break; break;
case SPE_NOVEL: case SPE_NOVEL:
otmp->novelidx = -1; /* "none of the above"; will be changed */ otmp->novelidx = -1; /* "none of the above"; will be changed */
@@ -1412,8 +1418,10 @@ int x, y;
{ {
register struct obj *gold = g_at(x, y); register struct obj *gold = g_at(x, y);
if (amount <= 0L) if (amount <= 0L) {
amount = (long) (1 + rnd(level_difficulty() + 2) * rnd(30)); long mul = rnd(30 / max(12-depth(&u.uz), 2));
amount = (long) (1 + rnd(level_difficulty() + 2) * mul);
}
if (gold) { if (gold) {
gold->quan += amount; gold->quan += amount;
} else { } else {
+7 -2
View File
@@ -2787,8 +2787,13 @@ wake_nearby()
mtmp->msleeping = 0; mtmp->msleeping = 0;
if (!unique_corpstat(mtmp->data)) if (!unique_corpstat(mtmp->data))
mtmp->mstrategy &= ~STRAT_WAITMASK; mtmp->mstrategy &= ~STRAT_WAITMASK;
if (mtmp->mtame && !mtmp->isminion) if (mtmp->mtame) {
EDOG(mtmp)->whistletime = moves; if (!mtmp->isminion)
EDOG(mtmp)->whistletime = moves;
/* Clear mtrack. This is to fix up a pet who is
stuck "fleeing" its master. */
memset(mtmp->mtrack, 0, sizeof(mtmp->mtrack));
}
} }
} }
} }
+2 -2
View File
@@ -1878,9 +1878,9 @@ struct permonst _mons2[] = {
| M2_MALE | M2_MAGIC | M2_SHAPESHIFTER, | M2_MALE | M2_MAGIC | M2_SHAPESHIFTER,
M3_INFRAVISIBLE, HI_ZAP), M3_INFRAVISIBLE, HI_ZAP),
#endif #endif
MON("Vlad the Impaler", S_VAMPIRE, LVL(14, 18, -3, 80, -10), MON("Vlad the Impaler", S_VAMPIRE, LVL(28, 26, -6, 80, -10),
(G_NOGEN | G_NOCORPSE | G_UNIQ), (G_NOGEN | G_NOCORPSE | G_UNIQ),
A(ATTK(AT_WEAP, AD_PHYS, 1, 10), ATTK(AT_BITE, AD_DRLI, 1, 10), A(ATTK(AT_WEAP, AD_PHYS, 2, 10), ATTK(AT_BITE, AD_DRLI, 1, 12),
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_HUMAN, 400, MS_VAMPIRE, MZ_HUMAN), MR_SLEEP | MR_POISON, 0, SIZ(WT_HUMAN, 400, MS_VAMPIRE, MZ_HUMAN), MR_SLEEP | MR_POISON, 0,
M1_FLY | M1_BREATHLESS | M1_HUMANOID | M1_POIS | M1_REGEN, M1_FLY | M1_BREATHLESS | M1_HUMANOID | M1_POIS | M1_REGEN,
+8 -1
View File
@@ -1,4 +1,4 @@
/* 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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -724,6 +724,12 @@ initoptions_init()
iflags.travelcc.x = iflags.travelcc.y = -1; 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 ); */ /* assert( sizeof flags.inv_order == sizeof def_inv_order ); */
(void) memcpy((genericptr_t) flags.inv_order, (void) memcpy((genericptr_t) flags.inv_order,
(genericptr_t) def_inv_order, sizeof flags.inv_order); (genericptr_t) def_inv_order, sizeof flags.inv_order);
@@ -5108,6 +5114,7 @@ boolean setinitial, setfromfile;
assign_graphics(ROGUESET); assign_graphics(ROGUESET);
} else if (!rogueflag) } else if (!rogueflag)
assign_graphics(PRIMARY); assign_graphics(PRIMARY);
preference_update("symset");
need_redraw = TRUE; need_redraw = TRUE;
return TRUE; return TRUE;
+1 -1
View File
@@ -195,7 +195,7 @@ struct obj **obj_p;
glyph among floor and buried objects; when !Blind, any buried glyph among floor and buried objects; when !Blind, any buried
object's glyph will have been replaced by whatever is present object's glyph will have been replaced by whatever is present
on the surface as soon as we moved next to its spot */ on the surface as soon as we moved next to its spot */
&& otmp->where == OBJ_FLOOR /* not buried */ && (fakeobj || otmp->where == OBJ_FLOOR) /* not buried */
/* terrain mode views what's already known, doesn't learn new stuff */ /* terrain mode views what's already known, doesn't learn new stuff */
&& !iflags.terrainmode) /* so don't set dknown when in terrain mode */ && !iflags.terrainmode) /* so don't set dknown when in terrain mode */
otmp->dknown = 1; /* if a pile, clearly see the top item only */ otmp->dknown = 1; /* if a pile, clearly see the top item only */
+2 -2
View File
@@ -1714,7 +1714,7 @@ plnamesuffix()
do { do {
if (!*plname) if (!*plname)
askname(); /* fill plname[] if necessary */ askname(); /* fill plname[] if necessary, or set defer_plname */
/* Look for tokens delimited by '-' */ /* Look for tokens delimited by '-' */
if ((eptr = index(plname, '-')) != (char *) 0) if ((eptr = index(plname, '-')) != (char *) 0)
@@ -1735,7 +1735,7 @@ plnamesuffix()
else if ((i = str2align(sptr)) != ROLE_NONE) else if ((i = str2align(sptr)) != ROLE_NONE)
flags.initalign = i; flags.initalign = i;
} }
} while (!*plname); } while (!*plname && !iflags.defer_plname);
/* commas in the plname confuse the record file, convert to spaces */ /* commas in the plname confuse the record file, convert to spaces */
for (sptr = plname; *sptr; sptr++) { for (sptr = plname; *sptr; sptr++) {
+46 -13
View File
@@ -1,4 +1,4 @@
/* 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: 1508879840 2017/10/24 21:17:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.90 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */ /* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -198,13 +198,14 @@ static NEARDATA char xsize, ysize;
char *lev_message = 0; char *lev_message = 0;
lev_region *lregions = 0; lev_region *lregions = 0;
int num_lregions = 0; int num_lregions = 0;
boolean splev_init_present = FALSE;
boolean icedpools = FALSE;
struct obj *container_obj[MAX_CONTAINMENT]; static boolean splev_init_present = FALSE;
int container_idx = 0; static boolean icedpools = FALSE;
static int mines_prize_count = 0, soko_prize_count = 0; /* achievements */
struct monst *invent_carrying_monster = NULL; static struct obj *container_obj[MAX_CONTAINMENT];
static int container_idx = 0;
static struct monst *invent_carrying_monster = NULL;
#define SPLEV_STACK_RESERVE 128 #define SPLEV_STACK_RESERVE 128
@@ -1881,6 +1882,7 @@ struct mkroom *croom;
} }
} else { } else {
struct obj *cobj = container_obj[container_idx - 1]; struct obj *cobj = container_obj[container_idx - 1];
remove_object(otmp); remove_object(otmp);
if (cobj) { if (cobj) {
(void) add_to_container(cobj, otmp); (void) add_to_container(cobj, otmp);
@@ -1941,12 +1943,31 @@ struct mkroom *croom;
} }
} }
/* Nasty hack here: try to determine if this is the Mines or Sokoban if (o->id != -1) {
* "prize" and then set record_achieve_special (maps to corpsenm) static const char prize_warning[] = "multiple prizes on %s level";
* for the object. That field will later be checked to find out if
* the player obtained the prize. */ /* if this is a specific item of the right type and it is being
if (is_mines_prize(otmp) || is_soko_prize(otmp)) { created on the right level, flag it as the designated item
otmp->record_achieve_special = 1; 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 (++mines_prize_count > 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 (++soko_prize_count > 1)
impossible(prize_warning, "sokoban end");
} else if (otmp->otyp == iflags.soko_prize_type2) {
otmp->record_achieve_special = SOKO_PRIZE2;
if (++soko_prize_count > 1)
impossible(prize_warning, "sokoban end");
}
}
} }
stackobj(otmp); stackobj(otmp);
@@ -4176,6 +4197,13 @@ genericptr_t arg;
if (typ < D_CLOSED) if (typ < D_CLOSED)
typ = D_CLOSED; typ = D_CLOSED;
} }
if (((isok(x-1,y) && IS_DOORJOIN(levl[x-1][y].typ)) || !isok(x-1,y))
|| (isok(x+1,y) && IS_DOORJOIN(levl[x+1][y].typ)) || !isok(x+1,y))
levl[x][y].horizontal = 1;
else
levl[x][y].horizontal = 0;
levl[x][y].doormask = typ; levl[x][y].doormask = typ;
SpLev_Map[x][y] = 1; SpLev_Map[x][y] = 1;
} }
@@ -5186,7 +5214,7 @@ sp_lev *lvl;
long room_stack = 0; long room_stack = 0;
unsigned long max_execution = SPCODER_MAX_RUNTIME; unsigned long max_execution = SPCODER_MAX_RUNTIME;
struct sp_coder *coder = struct sp_coder *coder =
(struct sp_coder *) alloc(sizeof(struct sp_coder)); (struct sp_coder *) alloc(sizeof (struct sp_coder));
coder->frame = frame_new(0); coder->frame = frame_new(0);
coder->stack = NULL; coder->stack = NULL;
@@ -5200,9 +5228,14 @@ sp_lev *lvl;
splev_init_present = FALSE; splev_init_present = FALSE;
icedpools = FALSE; icedpools = FALSE;
/* achievement tracking; static init would suffice except we need to
reset if #wizmakemap is used to recreate mines' end or sokoban end;
once either level is created, these values can be forgotten */
mines_prize_count = soko_prize_count = 0;
if (wizard) { if (wizard) {
char *met = nh_getenv("SPCODER_MAX_RUNTIME"); char *met = nh_getenv("SPCODER_MAX_RUNTIME");
if (met && met[0] == '1') if (met && met[0] == '1')
max_execution = (1 << 30) - 1; max_execution = (1 << 30) - 1;
} }
+9
View File
@@ -139,6 +139,15 @@ char *argv[];
/* use STDERR by default /* use STDERR by default
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
/* Heap Debugging
_CrtSetDbgFlag( _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)
| _CRTDBG_ALLOC_MEM_DF
| _CRTDBG_CHECK_ALWAYS_DF
| _CRTDBG_CHECK_CRT_DF
| _CRTDBG_DELAY_FREE_MEM_DF
| _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(1423);
*/
# endif # endif
#endif #endif
+2
View File
@@ -546,6 +546,8 @@ msexit()
getreturn("to end"); getreturn("to end");
synch_cursor(); synch_cursor();
#endif #endif
getreturn_enabled = TRUE;
wait_synch();
return; return;
} }
#endif /* MICRO || WIN32 || OS2 */ #endif /* MICRO || WIN32 || OS2 */
+1 -1
View File
@@ -20,7 +20,7 @@ VARDIR = $(HACKDIR)
POSTINSTALL= cp -n sys/unix/sysconf $(INSTDIR)/sysconf; $(CHOWN) $(GAMEUID) $(INSTDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(INSTDIR)/sysconf; chmod $(VARFILEPERM) $(INSTDIR)/sysconf; POSTINSTALL= cp -n sys/unix/sysconf $(INSTDIR)/sysconf; $(CHOWN) $(GAMEUID) $(INSTDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(INSTDIR)/sysconf; chmod $(VARFILEPERM) $(INSTDIR)/sysconf;
POSTINSTALL+= bdftopcf win/X11/nh10.bdf > $(INSTDIR)/nh10.pcf; (cd $(INSTDIR); mkfontdir); POSTINSTALL+= bdftopcf win/X11/nh10.bdf > $(INSTDIR)/nh10.pcf; (cd $(INSTDIR); mkfontdir);
CFLAGS=-O -I../include -DNOTPARMDECL CFLAGS=-g -O -I../include -DNOTPARMDECL
CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\"
CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\"
CFLAGS+=-DX11_GRAPHICS -DDEFAULT_WINDOW_SYS=\"X11\" -DNOTTYGRAPHICS CFLAGS+=-DX11_GRAPHICS -DDEFAULT_WINDOW_SYS=\"X11\" -DNOTTYGRAPHICS
+26 -16
View File
@@ -55,6 +55,7 @@ char *argv[];
#endif #endif
boolean exact_username; boolean exact_username;
boolean resuming = FALSE; /* assume new game */ boolean resuming = FALSE; /* assume new game */
boolean plsel_once = FALSE;
sys_early_init(); sys_early_init();
@@ -237,19 +238,6 @@ char *argv[];
(void) signal(SIGQUIT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN);
(void) signal(SIGINT, SIG_IGN); (void) signal(SIGINT, SIG_IGN);
} }
/*
* getlock() complains and quits if there is already a game
* in progress for current character name (when locknum == 0)
* or if there are too many active games (when locknum > 0).
* When proceeding, it creates an empty <lockname>.0 file to
* designate the current game.
* getlock() constructs <lockname> based on the character
* name (for !locknum) or on first available of alock, block,
* clock, &c not currently in use in the playground directory
* (for locknum > 0).
*/
getlock();
program_state.preserve_locks = 0; /* after getlock() */
dlb_init(); /* must be before newgame() */ dlb_init(); /* must be before newgame() */
@@ -266,7 +254,24 @@ char *argv[];
* We'll return here if new game player_selection() renames the hero. * We'll return here if new game player_selection() renames the hero.
*/ */
attempt_restore: attempt_restore:
if ((fd = restore_saved_game()) >= 0) {
/*
* getlock() complains and quits if there is already a game
* in progress for current character name (when locknum == 0)
* or if there are too many active games (when locknum > 0).
* When proceeding, it creates an empty <lockname>.0 file to
* designate the current game.
* getlock() constructs <lockname> based on the character
* name (for !locknum) or on first available of alock, block,
* clock, &c not currently in use in the playground directory
* (for locknum > 0).
*/
if (*plname) {
getlock();
program_state.preserve_locks = 0; /* after getlock() */
}
if (*plname && (fd = restore_saved_game()) >= 0) {
const char *fq_save = fqname(SAVEF, SAVEPREFIX, 1); const char *fq_save = fqname(SAVEF, SAVEPREFIX, 1);
(void) chmod(fq_save, 0); /* disallow parallel restores */ (void) chmod(fq_save, 0); /* disallow parallel restores */
@@ -297,12 +302,17 @@ attempt_restore:
} }
if (!resuming) { if (!resuming) {
boolean neednewlock = (!*plname);
/* new game: start by choosing role, race, etc; /* new game: start by choosing role, race, etc;
player might change the hero's name while doing that, player might change the hero's name while doing that,
in which case we try to restore under the new name in which case we try to restore under the new name
and skip selection this time if that didn't succeed */ and skip selection this time if that didn't succeed */
if (!iflags.renameinprogress) { if (!iflags.renameinprogress || iflags.defer_plname || neednewlock) {
player_selection(); if (!plsel_once)
player_selection();
plsel_once = TRUE;
if (neednewlock && *plname)
goto attempt_restore;
if (iflags.renameinprogress) { if (iflags.renameinprogress) {
/* player has renamed the hero while selecting role; /* player has renamed the hero while selecting role;
if locking alphabetically, the existing lock file if locking alphabetically, the existing lock file
+2 -2
View File
@@ -247,8 +247,8 @@ guilflags = $(lflags) -subsystem:windows,$(EXEVER)
dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll
# basic subsystem specific libraries, less the C Run-Time # basic subsystem specific libraries, less the C Run-Time
baselibs = kernel32.lib $(optlibs) $(winsocklibs) advapi32.lib baselibs = kernel32.lib $(optlibs) $(winsocklibs) advapi32.lib gdi32.lib
winlibs = $(baselibs) user32.lib gdi32.lib comdlg32.lib winspool.lib winlibs = $(baselibs) user32.lib comdlg32.lib winspool.lib
# for Windows applications that use the C Run-Time libraries # for Windows applications that use the C Run-Time libraries
conlibs = $(baselibs) conlibs = $(baselibs)
+229 -35
View File
@@ -44,6 +44,10 @@ int FDECL(process_keystroke,
(INPUT_RECORD *, boolean *, BOOLEAN_P numberpad, int portdebug)); (INPUT_RECORD *, boolean *, BOOLEAN_P numberpad, int portdebug));
static void NDECL(init_ttycolor); static void NDECL(init_ttycolor);
static void NDECL(really_move_cursor); static void NDECL(really_move_cursor);
static void NDECL(check_and_set_font);
static boolean NDECL(check_font_widths);
static void NDECL(set_known_good_console_font);
static void NDECL(restore_original_console_font);
/* Win32 Console handles for input and output */ /* Win32 Console handles for input and output */
HANDLE hConIn; HANDLE hConIn;
@@ -54,6 +58,11 @@ CONSOLE_SCREEN_BUFFER_INFO csbi, origcsbi;
COORD ntcoord; COORD ntcoord;
INPUT_RECORD ir; INPUT_RECORD ir;
/* Support for changing console font if existing glyph widths are too wide */
boolean console_font_changed;
CONSOLE_FONT_INFOEX original_console_font_info;
UINT original_console_code_page;
extern boolean getreturn_enabled; /* from sys/share/pcsys.c */ extern boolean getreturn_enabled; /* from sys/share/pcsys.c */
extern int redirect_stdout; extern int redirect_stdout;
@@ -148,6 +157,10 @@ KEYHANDLERNAME pKeyHandlerName;
void void
gettty() gettty()
{ {
console_font_changed = FALSE;
check_and_set_font();
#ifndef TEXTCOLOR #ifndef TEXTCOLOR
int k; int k;
#endif #endif
@@ -171,6 +184,8 @@ const char *s;
end_screen(); end_screen();
if (s) if (s)
raw_print(s); raw_print(s);
restore_original_console_font();
} }
/* called by init_nhwindows() and resume_nhwindows() */ /* called by init_nhwindows() and resume_nhwindows() */
@@ -514,45 +529,47 @@ char ch;
* Overrides wintty.c function of the same name * Overrides wintty.c function of the same name
* for win32. It is used for glyphs only, not text. * for win32. It is used for glyphs only, not text.
*/ */
/* CP437 to Unicode mapping according to the Unicode Consortium */
static const WCHAR cp437[] = {
0x0020, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8,
0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
};
void void
g_putch(in_ch) g_putch(in_ch)
int in_ch; int in_ch;
{ {
/* CP437 to Unicode mapping according to the Unicode Consortium */
static const WCHAR cp437[] = {
0x0020, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8,
0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
};
boolean inverse = FALSE; boolean inverse = FALSE;
unsigned char ch = (unsigned char) in_ch; unsigned char ch = (unsigned char) in_ch;
@@ -853,6 +870,8 @@ const char *pref;
toggle_mouse_support(); toggle_mouse_support();
#endif #endif
} }
if (stricmp(pref, "symset") == 0)
check_and_set_font();
return; return;
} }
@@ -1466,4 +1485,179 @@ GetConsoleHwnd(void)
return hwndFound; return hwndFound;
} }
#endif /*CHANGE_COLOR*/ #endif /*CHANGE_COLOR*/
static int CALLBACK EnumFontCallback(
const LOGFONTW * lf, const TEXTMETRICW * tm, DWORD fontType, LPARAM lParam)
{
LOGFONTW * lf_ptr = (LOGFONTW *) lParam;
*lf_ptr = *lf;
return 0;
}
/* check_and_set_font ensures that the current font will render the symbols
* that are currently being used correctly. If they will not be rendered
* correctly, then it will change the font to a known good font.
*/
void
check_and_set_font()
{
if (!check_font_widths()) {
raw_print("WARNING: glyphs too wide in console font."
" Changing code page to 437 and font to Consolas\n");
set_known_good_console_font();
}
}
/* check_font_widths returns TRUE if all glyphs in current console font
* fit within the width of a single console cell.
*/
boolean
check_font_widths()
{
CONSOLE_FONT_INFOEX console_font_info;
console_font_info.cbSize = sizeof(console_font_info);
BOOL success = GetCurrentConsoleFontEx(hConOut, FALSE,
&console_font_info);
/* get console window and DC
* NOTE: the DC from the console window does not have the correct
* font selected at this point.
*/
HWND hWnd = GetConsoleWindow();
HDC hDC = GetDC(hWnd);
LOGFONTW logical_font;
logical_font.lfCharSet = DEFAULT_CHARSET;
wcscpy(logical_font.lfFaceName, console_font_info.FaceName);
logical_font.lfPitchAndFamily = 0;
/* getting matching console font */
LOGFONTW matching_log_font = { 0 };
EnumFontFamiliesExW(hDC, &logical_font, EnumFontCallback,
(LPARAM) &matching_log_font, 0);
if (matching_log_font.lfHeight == 0) {
raw_print("Unable to enumerate system fonts\n");
return FALSE;
}
/* create font matching console font */
LOGFONTW console_font_log_font = matching_log_font;
console_font_log_font.lfWeight = console_font_info.FontWeight;
console_font_log_font.lfHeight = console_font_info.dwFontSize.Y;
console_font_log_font.lfWidth = 0;
HFONT console_font = CreateFontIndirectW(&console_font_log_font);
if (console_font == NULL) {
raw_print("Unable to create console font\n");
return FALSE;
}
/* select font */
HGDIOBJ saved_font = SelectObject(hDC, console_font);
/* determine whether it is a true type font */
TEXTMETRICA tm;
success = GetTextMetricsA(hDC, &tm);
if (!success) {
raw_print("Unable to get console font text metrics\n");
goto clean_up;
}
boolean isTrueType = (tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0;
/* determine which glyphs are used */
boolean used[256];
memset(used, 0, sizeof(used));
for (int i = 0; i < SYM_MAX; i++) {
used[l_syms[i]] = TRUE;
used[r_syms[i]] = TRUE;
}
int wcUsedCount = 0;
wchar_t wcUsed[256];
for (int i = 0; i < sizeof(used); i++)
if (used[i])
wcUsed[wcUsedCount++] = cp437[i];
/* measure the set of used glyphs to ensure they fit */
boolean all_glyphs_fit = TRUE;
for (int i = 0; i < wcUsedCount; i++) {
int width;
if (isTrueType) {
ABC abc;
success = GetCharABCWidthsW(hDC, wcUsed[i], wcUsed[i], &abc);
width = abc.abcA + abc.abcB + abc.abcC;
} else {
success = GetCharWidthW(hDC, wcUsed[i], wcUsed[i], &width);
}
if (success && width > console_font_info.dwFontSize.X) {
all_glyphs_fit = FALSE;
break;
}
}
clean_up:
SelectObject(hDC, saved_font);
DeleteObject(console_font);
return all_glyphs_fit;
}
/* set_known_good_console_font sets the code page and font used by the console
* to settings know to work well with NetHack. It also saves the original
* settings so that they can be restored prior to NetHack exit.
*/
void
set_known_good_console_font()
{
CONSOLE_FONT_INFOEX console_font_info;
console_font_info.cbSize = sizeof(console_font_info);
BOOL success = GetCurrentConsoleFontEx(hConOut, FALSE,
&console_font_info);
console_font_changed = TRUE;
original_console_font_info = console_font_info;
original_console_code_page = GetConsoleOutputCP();
wcscpy_s(console_font_info.FaceName,
sizeof(console_font_info.FaceName)
/ sizeof(console_font_info.FaceName[0]),
L"Consolas");
success = SetConsoleOutputCP(437);
if (!success)
raw_print("Unable to set console code page to 437\n");
success = SetCurrentConsoleFontEx(hConOut, FALSE, &console_font_info);
if (!success)
raw_print("Unable to set console font to Consolas\n");
}
/* restore_original_console_font will restore the console font and code page
* settings to what they were when NetHack was launched.
*/
void
restore_original_console_font()
{
if (console_font_changed) {
BOOL success;
raw_print("Restoring original font and code page\n");
success = SetConsoleOutputCP(original_console_code_page);
if (!success)
raw_print("Unable to restore original code page\n");
success = SetCurrentConsoleFontEx(hConOut, FALSE,
&original_console_font_info);
if (!success)
raw_print("Unable to restore original font\n");
console_font_changed = FALSE;
}
}
#endif /* WIN32 */ #endif /* WIN32 */
+1 -1
View File
@@ -157,7 +157,7 @@ FILE *fp;
Fprintf(fp, "\",\n"); Fprintf(fp, "\",\n");
} }
return Fprintf(fp, "};\n") >= 0; return fprintf(fp, "};\n") >= 0;
} }
#endif /* USE_XPM */ #endif /* USE_XPM */
+1 -8
View File
@@ -1474,18 +1474,11 @@ X11_askname()
{ {
Widget popup, dialog; Widget popup, dialog;
Arg args[1]; Arg args[1];
char *defplname = (char *)0;
#ifdef UNIX
defplname = get_login_name();
#endif
(void) strncpy(plname, defplname ? defplname : "Mumbles",
sizeof plname - 1);
plname[sizeof plname - 1] = '\0';
if (iflags.wc_player_selection == VIA_DIALOG) { if (iflags.wc_player_selection == VIA_DIALOG) {
/* X11_player_selection_dialog() handles name query */ /* X11_player_selection_dialog() handles name query */
plsel_ask_name = TRUE; plsel_ask_name = TRUE;
iflags.defer_plname = TRUE;
return; return;
} /* else iflags.wc_player_selection == VIA_PROMPTS */ } /* else iflags.wc_player_selection == VIA_PROMPTS */
+16
View File
@@ -352,8 +352,13 @@ plsel_dialog_acceptvalues()
XtSetArg(args[0], nhStr(XtNstring), &s); XtSetArg(args[0], nhStr(XtNstring), &s);
XtGetValues(plsel_name_input, args, ONE); XtGetValues(plsel_name_input, args, ONE);
(void) strncpy(plname, (char *) s, sizeof plname - 1); (void) strncpy(plname, (char *) s, sizeof plname - 1);
plname[sizeof plname - 1] = '\0'; plname[sizeof plname - 1] = '\0';
(void) mungspaces(plname);
if (strlen(plname) < 1)
(void) strcpy(plname, "Mumbles");
iflags.renameinprogress = FALSE;
} }
/* ARGSUSED */ /* ARGSUSED */
@@ -1553,6 +1558,17 @@ void
X11_player_selection() X11_player_selection()
{ {
if (iflags.wc_player_selection == VIA_DIALOG) { if (iflags.wc_player_selection == VIA_DIALOG) {
if (!*plname) {
#ifdef UNIX
char *defplname = get_login_name();
#else
char *defplname = (char *)0;
#endif
(void) strncpy(plname, defplname ? defplname : "Mumbles",
sizeof plname - 1);
plname[sizeof plname - 1] = '\0';
iflags.renameinprogress = TRUE;
}
X11_player_selection_dialog(); X11_player_selection_dialog();
} else { /* iflags.wc_player_selection == VIA_PROMPTS */ } else { /* iflags.wc_player_selection == VIA_PROMPTS */
X11_player_selection_prompts(); X11_player_selection_prompts();
+427 -447
View File
@@ -10,6 +10,8 @@
#include "resource.h" #include "resource.h"
#include "mhdlg.h" #include "mhdlg.h"
#include <assert.h>
/*---------------------------------------------------------------*/ /*---------------------------------------------------------------*/
/* data for getlin dialog */ /* data for getlin dialog */
struct getlin_data { struct getlin_data {
@@ -256,34 +258,51 @@ ExtCmdDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
} }
/*---------------------------------------------------------------*/ /*---------------------------------------------------------------*/
/* player selector dialog data */ /* player selector dialog */
struct plsel_data { typedef struct plsel_data {
int *selection; int config_race;
}; int config_role;
int config_gender;
int config_alignment;
HWND control_role;
HWND control_race;
HWND control_genders[ROLE_GENDERS];
HWND control_aligns[ROLE_ALIGNS];
int role_count;
int race_count;
HWND focus;
} plsel_data_t;
INT_PTR CALLBACK PlayerSelectorDlgProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK PlayerSelectorDlgProc(HWND, UINT, WPARAM, LPARAM);
static void plselInitDialog(HWND hWnd); static void plselInitDialog(HWND hWnd);
static void plselAdjustLists(HWND hWnd, int changed_opt); static void plselAdjustSelections(HWND hWnd);
static int plselFinalSelection(HWND hWnd, int *selection); static boolean plselRandomize(plsel_data_t * data);
static BOOL plselDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam);
int boolean
mswin_player_selection_window(int *selection) mswin_player_selection_window()
{ {
INT_PTR ret; INT_PTR ret;
struct plsel_data data; plsel_data_t data;
boolean ok = TRUE;
/* init dialog data */ /* save away configuration settings */
ZeroMemory(&data, sizeof(data)); data.config_role = flags.initrole;
data.selection = selection; data.config_race = flags.initrace;
data.config_gender = flags.initgend;
data.config_alignment = flags.initalign;
/* create modal dialog */ if (!plselRandomize(&data)) {
ret = DialogBoxParam( /* create modal dialog */
GetNHApp()->hApp, MAKEINTRESOURCE(IDD_PLAYER_SELECTOR), ret = DialogBoxParam(
GetNHApp()->hMainWnd, PlayerSelectorDlgProc, (LPARAM) &data); GetNHApp()->hApp, MAKEINTRESOURCE(IDD_PLAYER_SELECTOR),
if (ret == -1) GetNHApp()->hMainWnd, PlayerSelectorDlgProc, (LPARAM) &data);
panic("Cannot create getlin window"); if (ret == -1)
panic("Cannot create getlin window");
ok = (ret == IDOK);
}
return (int) ret; return ok;
} }
INT_PTR CALLBACK INT_PTR CALLBACK
@@ -315,11 +334,94 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
/* init dialog */ /* init dialog */
plselInitDialog(hWnd); plselInitDialog(hWnd);
/* set focus on the role checkbox (random) field */ /* tell windows to set the focus */
SetFocus(GetDlgItem(hWnd, IDC_PLSEL_ROLE_RANDOM)); return TRUE;
break;
/* tell windows we set the focus */ case WM_DRAWITEM:
return FALSE; if (wParam == IDC_PLSEL_ROLE_LIST || wParam == IDC_PLSEL_RACE_LIST)
return plselDrawItem(hWnd, wParam, lParam);
break;
case WM_NOTIFY:
{
LPNMHDR nmhdr = (LPNMHDR)lParam;
HWND control = nmhdr->hwndFrom;
data = (struct plsel_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
switch (nmhdr->code) {
case LVN_KEYDOWN:
{
LPNMLVKEYDOWN lpnmkeydown = (LPNMLVKEYDOWN) lParam;
if (lpnmkeydown->wVKey == ' ') {
if (control == data->control_role) {
int i = ListView_GetNextItem(data->control_role, -1, LVNI_FOCUSED);
assert(i == -1 || ListView_GetNextItem(data->control_role, i, LVNI_FOCUSED) == -1);
flags.initrole = i;
plselAdjustSelections(hWnd);
} else if (control == data->control_race) {
int i = ListView_GetNextItem(data->control_race, -1, LVNI_FOCUSED);
assert(i == -1 || ListView_GetNextItem(data->control_race, i, LVNI_FOCUSED) == -1);
if (ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM)) {
flags.initrace = i;
plselAdjustSelections(hWnd);
}
}
}
}
break;
case NM_CLICK:
{
LPNMLISTVIEW lpnmitem = (LPNMLISTVIEW)lParam;
int i = lpnmitem->iItem;
if (i == -1)
return FALSE;
if (control == data->control_role) {
flags.initrole = i;
plselAdjustSelections(hWnd);
} else if(control == data->control_race) {
if (ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM)) {
flags.initrace = i;
plselAdjustSelections(hWnd);
}
}
}
break;
case NM_KILLFOCUS:
{
char buf[64];
sprintf(buf, "KILLFOCUS %lx\n", (unsigned long) control);
OutputDebugStringA(buf);
if (data->focus == data->control_race) {
data->focus = NULL;
ListView_RedrawItems(data->control_race, 0, data->race_count - 1);
} else if (data->focus == data->control_role) {
data->focus = NULL;
ListView_RedrawItems(data->control_role, 0, data->role_count - 1);
}
}
break;
case NM_SETFOCUS:
{
char buf[64];
sprintf(buf, "SETFOCUS %lx\n", (unsigned long) control);
OutputDebugStringA(buf);
data->focus = control;
if (control == data->control_race) {
data->focus = data->control_race;
plselAdjustSelections(hWnd);
} else if (control == data->control_role) {
data->focus = data->control_role;
plselAdjustSelections(hWnd);
}
}
break;
}
}
break; break;
case WM_COMMAND: case WM_COMMAND:
@@ -327,483 +429,361 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (LOWORD(wParam)) { switch (LOWORD(wParam)) {
/* OK button was clicked */ /* OK button was clicked */
case IDOK: case IDOK:
if (plselFinalSelection(hWnd, data->selection)) { EndDialog(hWnd, wParam);
EndDialog(hWnd, wParam);
} else {
NHMessageBox(
hWnd, TEXT("Cannot match this role. Try something else."),
MB_ICONSTOP | MB_OK);
}
return TRUE; return TRUE;
/* CANCEL button was clicked */ /* CANCEL button was clicked */
case IDCANCEL: case IDCANCEL:
*data->selection = -1;
EndDialog(hWnd, wParam); EndDialog(hWnd, wParam);
return TRUE; return TRUE;
/* following are events from dialog controls: case IDC_PLSEL_RANDOM:
"random" checkboxes send BN_CLICKED messages; plselRandomize(data);
role/race/... combo-boxes send CBN_SELENDOK plselAdjustSelections(hWnd);
if something was selected; return TRUE;
*/
case IDC_PLSEL_ROLE_RANDOM: case IDC_PLSEL_GENDER_MALE:
case IDC_PLSEL_GENDER_FEMALE:
if (HIWORD(wParam) == BN_CLICKED) { if (HIWORD(wParam) == BN_CLICKED) {
/* enable corresponding list window if "random" int i = LOWORD(wParam) - IDC_PLSEL_GENDER_MALE;
checkbox was "unchecked" */ if (ok_gend(flags.initrole, flags.initrace, i, ROLE_RANDOM)) {
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST), flags.initgend = i;
SendMessage((HWND) lParam, BM_GETCHECK, 0, 0) plselAdjustSelections(hWnd);
== BST_UNCHECKED); }
} }
break; break;
case IDC_PLSEL_RACE_RANDOM:
case IDC_PLSEL_ALIGN_LAWFUL:
case IDC_PLSEL_ALIGN_NEUTRAL:
case IDC_PLSEL_ALIGN_CHAOTIC:
if (HIWORD(wParam) == BN_CLICKED) { if (HIWORD(wParam) == BN_CLICKED) {
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST), int i = LOWORD(wParam) - IDC_PLSEL_ALIGN_LAWFUL;
SendMessage((HWND) lParam, BM_GETCHECK, 0, 0) if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) {
== BST_UNCHECKED); flags.initalign = i;
plselAdjustSelections(hWnd);
}
} }
break; break;
case IDC_PLSEL_GENDER_RANDOM:
if (HIWORD(wParam) == BN_CLICKED) {
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST),
SendMessage((HWND) lParam, BM_GETCHECK, 0, 0)
== BST_UNCHECKED);
}
break;
case IDC_PLSEL_ALIGN_RANDOM:
if (HIWORD(wParam) == BN_CLICKED) {
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST),
SendMessage((HWND) lParam, BM_GETCHECK, 0, 0)
== BST_UNCHECKED);
}
break;
case IDC_PLSEL_ROLE_LIST:
if (HIWORD(wParam) == CBN_SELENDOK) {
/* filter out invalid options if
the selection was made */
plselAdjustLists(hWnd, LOWORD(wParam));
}
break;
case IDC_PLSEL_RACE_LIST:
if (HIWORD(wParam) == CBN_SELENDOK) {
plselAdjustLists(hWnd, LOWORD(wParam));
}
break;
case IDC_PLSEL_GENDER_LIST:
if (HIWORD(wParam) == CBN_SELENDOK) {
plselAdjustLists(hWnd, LOWORD(wParam));
}
break;
case IDC_PLSEL_ALIGN_LIST:
if (HIWORD(wParam) == CBN_SELENDOK) {
plselAdjustLists(hWnd, LOWORD(wParam));
}
break;
} }
break; break;
} }
return FALSE; return FALSE;
} }
void
setComboBoxValue(HWND hWnd, int combo_box, int value)
{
int index_max =
(int) SendDlgItemMessage(hWnd, combo_box, CB_GETCOUNT, 0, 0);
int index;
int value_to_set = LB_ERR;
for (index = 0; index < index_max; index++) {
if (SendDlgItemMessage(hWnd, combo_box, CB_GETITEMDATA,
(WPARAM) index, 0) == value) {
value_to_set = index;
break;
}
}
SendDlgItemMessage(hWnd, combo_box, CB_SETCURSEL, (WPARAM) value_to_set,
0);
}
/* initialize player selector dialog */ /* initialize player selector dialog */
void void
plselInitDialog(HWND hWnd) plselInitDialog(HWND hWnd)
{ {
struct plsel_data * data = (plsel_data_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
TCHAR wbuf[BUFSZ]; TCHAR wbuf[BUFSZ];
LVCOLUMN lvcol;
data->control_role = GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST);
data->control_race = GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST);
ZeroMemory(&lvcol, sizeof(lvcol));
lvcol.mask = LVCF_WIDTH;
lvcol.cx = GetSystemMetrics(SM_CXFULLSCREEN);
/* build role list */
ListView_InsertColumn(data->control_role, 0, &lvcol);
data->role_count = 0;
for (int i = 0; roles[i].name.m; i++) {
LVITEM lvitem;
ZeroMemory(&lvitem, sizeof(lvitem));
lvitem.mask = LVIF_STATE | LVIF_TEXT;
lvitem.iItem = i;
lvitem.iSubItem = 0;
lvitem.state = 0;
lvitem.stateMask = LVIS_FOCUSED;
if (flags.female && roles[i].name.f)
lvitem.pszText = NH_A2W(roles[i].name.f, wbuf, BUFSZ);
else
lvitem.pszText = NH_A2W(roles[i].name.m, wbuf, BUFSZ);
if (ListView_InsertItem(data->control_role, &lvitem) == -1) {
panic("cannot insert menu item");
}
data->role_count++;
}
/* build race list */
ListView_InsertColumn(data->control_race, 0, &lvcol);
data->race_count = 0;
for (int i = 0; races[i].noun; i++) {
LVITEM lvitem;
ZeroMemory(&lvitem, sizeof(lvitem));
lvitem.mask = LVIF_STATE | LVIF_TEXT;
lvitem.iItem = i;
lvitem.iSubItem = 0;
lvitem.state = 0;
lvitem.stateMask = LVIS_FOCUSED;
lvitem.pszText = NH_A2W(races[i].noun, wbuf, BUFSZ);
if (ListView_InsertItem(data->control_race, &lvitem) == -1) {
panic("cannot insert menu item");
}
data->race_count++;
}
for(int i = 0; i < ROLE_GENDERS; i++)
data->control_genders[i] = GetDlgItem(hWnd, IDC_PLSEL_GENDER_MALE + i);
for(int i = 0; i < ROLE_ALIGNS; i++)
data->control_aligns[i] = GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LAWFUL + i);
/* set gender radio button state */
for (int i = 0; i < ROLE_GENDERS; i++)
Button_Enable(data->control_genders[i], TRUE);
Button_SetCheck(data->control_genders[0], BST_CHECKED);
/* set alignment radio button state */
for (int i = 0; i < ROLE_ALIGNS; i++)
Button_Enable(data->control_aligns[i], TRUE);
Button_SetCheck(data->control_aligns[0], BST_CHECKED);
/* set player name */ /* set player name */
SetDlgItemText(hWnd, IDC_PLSEL_NAME, NH_A2W(plname, wbuf, sizeof(wbuf))); SetDlgItemText(hWnd, IDC_PLSEL_NAME, NH_A2W(plname, wbuf, sizeof(wbuf)));
/* check flags for consistency */ plselRandomize(data);
if (flags.initrole >= 0) {
if (flags.initrace >= 0
&& !validrace(flags.initrole, flags.initrace)) {
flags.initrace = ROLE_NONE;
}
if (flags.initgend >= 0
&& !validgend(flags.initrole, flags.initrace, flags.initgend)) {
flags.initgend = ROLE_NONE;
}
if (flags.initalign >= 0
&& !validalign(flags.initrole, flags.initrace, flags.initalign)) {
flags.initalign = ROLE_NONE;
}
}
/* populate select boxes */ /* populate select boxes */
plselAdjustLists(hWnd, -1); plselAdjustSelections(hWnd);
/* intialize roles list */ /* set tab order */
if (flags.initrole < 0 SetWindowPos(GetDlgItem(hWnd, IDCANCEL), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|| !ok_role(flags.initrole, ROLE_NONE, ROLE_NONE, ROLE_NONE)) { SetWindowPos(GetDlgItem(hWnd, IDC_PLSEL_RANDOM), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
CheckDlgButton(hWnd, IDC_PLSEL_ROLE_RANDOM, BST_CHECKED); SetWindowPos(GetDlgItem(hWnd, IDOK), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST), FALSE); for(int i = ROLE_GENDERS - 1; i >= 0; i--)
} else { SetWindowPos(data->control_genders[i], NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
CheckDlgButton(hWnd, IDC_PLSEL_ROLE_RANDOM, BST_UNCHECKED); for(int i = ROLE_ALIGNS - 1; i >= 0; i--)
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST), TRUE); SetWindowPos(data->control_aligns[i], NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
setComboBoxValue(hWnd, IDC_PLSEL_ROLE_LIST, flags.initrole); SetWindowPos(data->control_race, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
} SetWindowPos(data->control_role, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
/* intialize races list */
if (flags.initrace < 0
|| !ok_race(flags.initrole, flags.initrace, ROLE_NONE, ROLE_NONE)) {
CheckDlgButton(hWnd, IDC_PLSEL_RACE_RANDOM, BST_CHECKED);
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST), FALSE);
} else {
CheckDlgButton(hWnd, IDC_PLSEL_RACE_RANDOM, BST_UNCHECKED);
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST), TRUE);
setComboBoxValue(hWnd, IDC_PLSEL_RACE_LIST, flags.initrace);
}
/* intialize genders list */
if (flags.initgend < 0
|| !ok_gend(flags.initrole, flags.initrace, flags.initgend,
ROLE_NONE)) {
CheckDlgButton(hWnd, IDC_PLSEL_GENDER_RANDOM, BST_CHECKED);
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST), FALSE);
} else {
CheckDlgButton(hWnd, IDC_PLSEL_GENDER_RANDOM, BST_UNCHECKED);
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST), TRUE);
setComboBoxValue(hWnd, IDC_PLSEL_GENDER_LIST, flags.initgend);
}
/* intialize alignments list */
if (flags.initalign < 0
|| !ok_align(flags.initrole, flags.initrace, flags.initgend,
flags.initalign)) {
CheckDlgButton(hWnd, IDC_PLSEL_ALIGN_RANDOM, BST_CHECKED);
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST), FALSE);
} else {
CheckDlgButton(hWnd, IDC_PLSEL_ALIGN_RANDOM, BST_UNCHECKED);
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST), TRUE);
setComboBoxValue(hWnd, IDC_PLSEL_ALIGN_LIST, flags.initalign);
}
} }
/* adjust role/race/alignment/gender list - filter out
invalid combinations
changed_sel points to the list where selection occurred
(-1 if unknown)
*/
void void
plselAdjustLists(HWND hWnd, int changed_sel) plselAdjustSelections(HWND hWnd)
{ {
HWND control_role, control_race, control_gender, control_align; struct plsel_data * data = (plsel_data_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
int initrole, initrace, initgend, initalign;
int i;
LRESULT ind;
int valid_opt;
TCHAR wbuf[255];
/* get control handles */ if (!ok_race(flags.initrole, flags.initrace, ROLE_RANDOM, ROLE_RANDOM))
control_role = GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST); flags.initrace = pick_race(flags.initrole, ROLE_RANDOM, ROLE_RANDOM, ROLE_RANDOM);
control_race = GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST);
control_gender = GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST);
control_align = GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST);
/* get current selections */ if (!ok_gend(flags.initrole, flags.initrace, flags.initgend, ROLE_RANDOM))
ind = SendMessage(control_role, CB_GETCURSEL, 0, 0); flags.initgend = pick_gend(flags.initrole, flags.initrace, ROLE_RANDOM , ROLE_RANDOM);
initrole = (ind == LB_ERR)
? flags.initrole
: (int) SendMessage(control_role, CB_GETITEMDATA, ind, 0);
ind = SendMessage(control_race, CB_GETCURSEL, 0, 0); if (!ok_align(flags.initrole, flags.initrace, flags.initgend, flags.initalign))
initrace = (ind == LB_ERR) flags.initalign = pick_align(flags.initrole, flags.initrace, flags.initgend , ROLE_RANDOM);
? flags.initrace
: (int) SendMessage(control_race, CB_GETITEMDATA, ind, 0);
ind = SendMessage(control_gender, CB_GETCURSEL, 0, 0); ListView_RedrawItems(data->control_role, 0, data->role_count - 1);
initgend = (ind == LB_ERR) ? flags.initgend ListView_RedrawItems(data->control_race, 0, data->race_count - 1);
: (int) SendMessage(control_gender,
CB_GETITEMDATA, ind, 0);
ind = SendMessage(control_align, CB_GETCURSEL, 0, 0); /* set gender radio button state */
initalign = (ind == LB_ERR) ? flags.initalign for (int i = 0; i < ROLE_GENDERS; i++) {
: (int) SendMessage(control_align, BOOL enable = ok_gend(flags.initrole, flags.initrace, i, flags.initalign);
CB_GETITEMDATA, ind, 0); Button_Enable(data->control_genders[i], enable);
LRESULT state = Button_GetCheck(data->control_genders[i]);
/* intialize roles list */ if (state == BST_CHECKED && flags.initgend != i)
if (changed_sel == -1) { Button_SetCheck(data->control_genders[i], BST_UNCHECKED);
valid_opt = 0; if (state == BST_UNCHECKED && flags.initgend == i)
Button_SetCheck(data->control_genders[i], BST_CHECKED);
/* reset content and populate the list */
SendMessage(control_role, CB_RESETCONTENT, 0, 0);
for (i = 0; roles[i].name.m; i++) {
if (initgend >= 0 && flags.female && roles[i].name.f)
ind = SendMessage(
control_role, CB_ADDSTRING, (WPARAM) 0,
(LPARAM) NH_A2W(roles[i].name.f, wbuf, sizeof(wbuf)));
else
ind = SendMessage(
control_role, CB_ADDSTRING, (WPARAM) 0,
(LPARAM) NH_A2W(roles[i].name.m, wbuf, sizeof(wbuf)));
SendMessage(control_role, CB_SETITEMDATA, (WPARAM) ind,
(LPARAM) i);
if (i == initrole) {
SendMessage(control_role, CB_SETCURSEL, (WPARAM) ind,
(LPARAM) 0);
valid_opt = 1;
}
}
/* set selection to the previously selected role
if it is still valid */
if (!valid_opt) {
initrole = ROLE_NONE;
initrace = ROLE_NONE;
initgend = ROLE_NONE;
initalign = ROLE_NONE;
SendMessage(control_role, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
}
/* trigger change of the races list */
changed_sel = IDC_PLSEL_ROLE_LIST;
} }
/* intialize races list */ /* set alignment radio button state */
if (changed_sel == IDC_PLSEL_ROLE_LIST) { for (int i = 0; i < ROLE_ALIGNS; i++) {
valid_opt = 0; BOOL enable = ok_align(flags.initrole, flags.initrace, flags.initgend, i);
Button_Enable(data->control_aligns[i], enable);
/* reset content and populate the list */ LRESULT state = Button_GetCheck(data->control_aligns[i]);
SendMessage(control_race, CB_RESETCONTENT, 0, 0); if (state == BST_CHECKED && flags.initalign != i)
for (i = 0; races[i].noun; i++) Button_SetCheck(data->control_aligns[i], BST_UNCHECKED);
if (ok_race(initrole, i, ROLE_NONE, ROLE_NONE)) { if (state == BST_UNCHECKED && flags.initalign == i)
ind = SendMessage( Button_SetCheck(data->control_aligns[i], BST_CHECKED);
control_race, CB_ADDSTRING, (WPARAM) 0,
(LPARAM) NH_A2W(races[i].noun, wbuf, sizeof(wbuf)));
SendMessage(control_race, CB_SETITEMDATA, (WPARAM) ind,
(LPARAM) i);
if (i == initrace) {
SendMessage(control_race, CB_SETCURSEL, (WPARAM) ind,
(LPARAM) 0);
valid_opt = 1;
}
}
/* set selection to the previously selected race
if it is still valid */
if (!valid_opt) {
initrace = ROLE_NONE;
initgend = ROLE_NONE;
initalign = ROLE_NONE;
SendMessage(control_race, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
}
/* trigger change of the genders list */
changed_sel = IDC_PLSEL_RACE_LIST;
} }
/* intialize genders list */
if (changed_sel == IDC_PLSEL_RACE_LIST) {
valid_opt = 0;
/* reset content and populate the list */
SendMessage(control_gender, CB_RESETCONTENT, 0, 0);
for (i = 0; i < ROLE_GENDERS; i++)
if (ok_gend(initrole, initrace, i, ROLE_NONE)) {
ind = SendMessage(
control_gender, CB_ADDSTRING, (WPARAM) 0,
(LPARAM) NH_A2W(genders[i].adj, wbuf, sizeof(wbuf)));
SendMessage(control_gender, CB_SETITEMDATA, (WPARAM) ind,
(LPARAM) i);
if (i == initgend) {
SendMessage(control_gender, CB_SETCURSEL, (WPARAM) ind,
(LPARAM) 0);
valid_opt = 1;
}
}
/* set selection to the previously selected gender
if it is still valid */
if (!valid_opt) {
initgend = ROLE_NONE;
initalign = ROLE_NONE;
SendMessage(control_gender, CB_SETCURSEL, (WPARAM) -1,
(LPARAM) 0);
}
/* trigger change of the alignments list */
changed_sel = IDC_PLSEL_GENDER_LIST;
}
/* intialize alignments list */
if (changed_sel == IDC_PLSEL_GENDER_LIST) {
valid_opt = 0;
/* reset content and populate the list */
SendMessage(control_align, CB_RESETCONTENT, 0, 0);
for (i = 0; i < ROLE_ALIGNS; i++)
if (ok_align(initrole, initrace, initgend, i)) {
ind = SendMessage(
control_align, CB_ADDSTRING, (WPARAM) 0,
(LPARAM) NH_A2W(aligns[i].adj, wbuf, sizeof(wbuf)));
SendMessage(control_align, CB_SETITEMDATA, (WPARAM) ind,
(LPARAM) i);
if (i == initalign) {
SendMessage(control_align, CB_SETCURSEL, (WPARAM) ind,
(LPARAM) 0);
valid_opt = 1;
}
}
/* set selection to the previously selected alignment
if it is still valid */
if (!valid_opt) {
initalign = ROLE_NONE;
SendMessage(control_align, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
}
}
} }
/* player made up his mind - get final selection here */ /* player made up his mind - get final selection here */
int int
plselFinalSelection(HWND hWnd, int *selection) plselFinalSelection(HWND hWnd)
{ {
LRESULT ind; int role = flags.initrole;
int race = flags.initrace;
int gender = flags.initgend;
int alignment = flags.initalign;
UNREFERENCED_PARAMETER(selection); assert(role != ROLE_RANDOM && role != ROLE_NONE);
assert(race != ROLE_RANDOM && race != ROLE_NONE);
/* get current selections */ assert(gender != ROLE_RANDOM && gender != ROLE_NONE);
if (SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_RANDOM, BM_GETCHECK, 0, 0) assert(alignment != ROLE_RANDOM && alignment != ROLE_NONE);
== BST_CHECKED) { assert(ok_role(role, race, gender, alignment));
flags.initrole = ROLE_RANDOM; assert(ok_race(role, race, gender, alignment));
} else { assert(ok_gend(role, race, gender, alignment));
ind = assert(ok_align(role, race, gender, alignment));
SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_LIST, CB_GETCURSEL, 0, 0);
flags.initrole = return TRUE;
(ind == LB_ERR) }
? ROLE_RANDOM
: (int) SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_LIST, static boolean plselRandomize(plsel_data_t * data)
CB_GETITEMDATA, ind, 0); {
} boolean fully_specified = TRUE;
if (SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_RANDOM, BM_GETCHECK, 0, 0) // restore back to configuration settings
== BST_CHECKED) { flags.initrole = data->config_role;
flags.initrace = ROLE_RANDOM; flags.initrace = data->config_race;
} else { flags.initgend = data->config_gender;
ind = flags.initalign = data->config_alignment;
SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_LIST, CB_GETCURSEL, 0, 0);
flags.initrace = if (!flags.randomall) {
(ind == LB_ERR) if(flags.initrole == ROLE_NONE || flags.initrace == ROLE_NONE
? ROLE_RANDOM || flags.initgend == ROLE_NONE || flags.initalign == ROLE_NONE)
: (int) SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_LIST, fully_specified = FALSE;
CB_GETITEMDATA, ind, 0); }
}
if (flags.initrole == ROLE_NONE)
if (SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_RANDOM, BM_GETCHECK, 0, 0) flags.initrole = ROLE_RANDOM;
== BST_CHECKED) { if (flags.initrace == ROLE_NONE)
flags.initgend = ROLE_RANDOM; flags.initrace = ROLE_RANDOM;
} else { if (flags.initgend == ROLE_NONE)
ind = SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_LIST, CB_GETCURSEL, 0, flags.initgend = ROLE_RANDOM;
0); if (flags.initalign == ROLE_NONE)
flags.initgend = flags.initalign = ROLE_RANDOM;
(ind == LB_ERR)
? ROLE_RANDOM rigid_role_checks();
: (int) SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_LIST,
CB_GETITEMDATA, ind, 0); int role = flags.initrole;
} int race = flags.initrace;
int gender = flags.initgend;
if (SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_RANDOM, BM_GETCHECK, 0, 0) int alignment = flags.initalign;
== BST_CHECKED) {
flags.initalign = ROLE_RANDOM; assert(role != ROLE_RANDOM && role != ROLE_NONE);
} else { assert(race != ROLE_RANDOM && race != ROLE_NONE);
ind = SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_LIST, CB_GETCURSEL, 0, assert(gender != ROLE_RANDOM && gender != ROLE_NONE);
0); assert(alignment != ROLE_RANDOM && alignment != ROLE_NONE);
flags.initalign =
(ind == LB_ERR) if (!ok_role(role, race, gender, alignment)) {
? ROLE_RANDOM fully_specified = FALSE;
: (int) SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_LIST, flags.initrole = ROLE_RANDOM;
CB_GETITEMDATA, ind, 0); }
}
if (!ok_race(role, race, gender, alignment)) {
/* check the role */ fully_specified = FALSE;
if (flags.initrole == ROLE_RANDOM) { flags.initrace = ROLE_RANDOM;
flags.initrole = pick_role(flags.initrace, flags.initgend, }
flags.initalign, PICK_RANDOM);
if (flags.initrole < 0) { if (!ok_gend(role, race, gender, alignment)) {
NHMessageBox(hWnd, TEXT("Incompatible role!"), fully_specified = FALSE;
MB_ICONSTOP | MB_OK); flags.initgend = ROLE_RANDOM;
return FALSE; }
}
} if(!ok_align(role, race, gender, alignment))
{
/* Select a race, if necessary */ fully_specified = FALSE;
/* force compatibility with role */ flags.initalign = ROLE_RANDOM;
if (flags.initrace == ROLE_RANDOM }
|| !validrace(flags.initrole, flags.initrace)) {
/* pre-selected race not valid */ rigid_role_checks();
if (flags.initrace == ROLE_RANDOM) {
flags.initrace = pick_race(flags.initrole, flags.initgend, role = flags.initrole;
flags.initalign, PICK_RANDOM); race = flags.initrace;
} gender = flags.initgend;
alignment = flags.initalign;
if (flags.initrace < 0) {
NHMessageBox(hWnd, TEXT("Incompatible race!"), assert(role != ROLE_RANDOM && role != ROLE_NONE);
MB_ICONSTOP | MB_OK); assert(race != ROLE_RANDOM && race != ROLE_NONE);
return FALSE; assert(gender != ROLE_RANDOM && gender != ROLE_NONE);
} assert(alignment != ROLE_RANDOM && alignment != ROLE_NONE);
} assert(ok_role(role, race, gender, alignment));
assert(ok_race(role, race, gender, alignment));
/* Select a gender, if necessary */ assert(ok_gend(role, race, gender, alignment));
/* force compatibility with role/race, try for compatibility with assert(ok_align(role, race, gender, alignment));
* pre-selected alignment */
if (flags.initgend < 0 return fully_specified;
|| !validgend(flags.initrole, flags.initrace, flags.initgend)) { }
/* pre-selected gender not valid */
if (flags.initgend == ROLE_RANDOM) { /*-----------------------------------------------------------------------------*/
flags.initgend = pick_gend(flags.initrole, flags.initrace, BOOL
flags.initalign, PICK_RANDOM); plselDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
} {
LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) lParam;
if (flags.initgend < 0) { struct plsel_data * data = (plsel_data_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
NHMessageBox(hWnd, TEXT("Incompatible gender!"),
MB_ICONSTOP | MB_OK); /* If there are no list box items, skip this message. */
return FALSE; if (lpdis->itemID < 0)
} return FALSE;
}
HWND control = GetDlgItem(hWnd, wParam);
/* Select an alignment, if necessary */ int i = lpdis->itemID;
/* force compatibility with role/race/gender */
if (flags.initalign < 0 {
|| !validalign(flags.initrole, flags.initrace, flags.initalign)) { char buf[64];
/* pre-selected alignment not valid */ sprintf(buf, "DRAW %lx %d\n", (unsigned long)control, i);
if (flags.initalign == ROLE_RANDOM) { OutputDebugStringA(buf);
flags.initalign = pick_align(flags.initrole, flags.initrace, }
flags.initgend, PICK_RANDOM);
} else { const char * string;
NHMessageBox(hWnd, TEXT("Incompatible alignment!"),
MB_ICONSTOP | MB_OK); boolean ok = TRUE;
return FALSE; boolean selected;
}
} if (wParam == IDC_PLSEL_ROLE_LIST) {
if (flags.female && roles[i].name.f)
string = roles[i].name.f;
else
string = roles[i].name.m;
selected = (flags.initrole == i);
} else {
assert(wParam == IDC_PLSEL_RACE_LIST);
ok = ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM);
string = races[i].noun;
selected = (flags.initrace == i);
}
SetBkMode(lpdis->hDC, OPAQUE);
HBRUSH brush;
if (selected) {
brush = CreateSolidBrush(RGB(0, 0, 0));
SetTextColor(lpdis->hDC, RGB(255, 255, 255));
SetBkColor(lpdis->hDC, RGB(0, 0, 0));
} else {
brush = CreateSolidBrush(RGB(255, 255, 255));
if (!ok)
SetTextColor(lpdis->hDC, RGB(220, 0, 0));
else
SetTextColor(lpdis->hDC, RGB(0, 0, 0));
SetBkColor(lpdis->hDC, RGB(255, 255, 255));
}
FillRect(lpdis->hDC, &lpdis->rcItem, brush);
RECT rect = lpdis->rcItem;
rect.left += 5;
DrawTextA(lpdis->hDC, string, strlen(string), &rect,
DT_LEFT | DT_SINGLELINE | DT_VCENTER);
if (data->focus == control) {
if (lpdis->itemState & LVIS_FOCUSED) {
/* draw focus rect */
RECT client_rt;
GetClientRect(lpdis->hwndItem, &client_rt);
SetRect(&rect, client_rt.left, lpdis->rcItem.top,
client_rt.left + ListView_GetColumnWidth(lpdis->hwndItem, 0),
lpdis->rcItem.bottom);
DrawFocusRect(lpdis->hDC, &rect);
{
char buf[64];
sprintf(buf, "FOCUS %lx %d\n", (unsigned long)control, i);
OutputDebugStringA(buf);
}
}
}
DeleteObject(brush);
return TRUE; return TRUE;
} }
+1 -1
View File
@@ -12,6 +12,6 @@
int mswin_getlin_window(const char *question, char *result, int mswin_getlin_window(const char *question, char *result,
size_t result_size); size_t result_size);
int mswin_ext_cmd_window(int *selection); int mswin_ext_cmd_window(int *selection);
int mswin_player_selection_window(int *selection); boolean mswin_player_selection_window();
#endif /* MSWINDlgWindow_h */ #endif /* MSWINDlgWindow_h */
+44 -9
View File
@@ -245,6 +245,25 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
data = (PNHMessageWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA); data = (PNHMessageWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
switch (wParam) { switch (wParam) {
case MSNH_MSG_PUTSTR: { case MSNH_MSG_PUTSTR: {
/* Add the passed in message to the existing text. Support the
* adding of text that ends in newline. A newline in text
* will force any subsequent text that is added to be added on
* a new output line.
*
* TODO: Text can be added with newlines occurring within the text not
* just at the end. As currently implemented, this can cause
* the text to be rendered such that the text following the
* newline is rendered on a new line. This can cause a poor
* user experience when the user has set only a single text line
* for the message window. In this case, the user will not see
* any line other then the last line of text and the --MORE--
* message thus missing any text that appears before the last
* embedded newline. This does not meet the requirements of the
* message window.
* This code should be changed to do the right thing and split
* the text so that only lines that end in newlines are added to
* the stored window text.
*/
PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr) lParam; PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr) lParam;
SCROLLINFO si; SCROLLINFO si;
char *p; char *p;
@@ -271,10 +290,17 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
/* check for "--more--" */ /* check for "--more--" */
if (!data->nevermore && more_prompt_check(hWnd)) { if (!data->nevermore && more_prompt_check(hWnd)) {
int okkey = 0; int okkey = 0;
int chop; char tmptext[MAXWINDOWTEXT + 1];
// @@@ Ok respnses // @@@ Ok respnses
/* append more prompt and inticate the update */ /* save original text */
strcpy(tmptext, data->window_text[MSG_LINES - 1].text);
/* text could end in newline so strip it */
strip_newline(data->window_text[MSG_LINES - 1].text);
/* append more prompt and indicate the update */
strncat( strncat(
data->window_text[MSG_LINES - 1].text, MORE, data->window_text[MSG_LINES - 1].text, MORE,
MAXWINDOWTEXT MAXWINDOWTEXT
@@ -301,10 +327,9 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
} }
} }
/* erase the "--more--" prompt */ /* restore original text */
chop = strlen(data->window_text[MSG_LINES - 1].text) strcpy(data->window_text[MSG_LINES - 1].text, tmptext);
- strlen(MORE);
data->window_text[MSG_LINES - 1].text[chop] = '\0';
data->lines_not_seen = 0; data->lines_not_seen = 0;
} }
@@ -601,6 +626,7 @@ onPaint(HWND hWnd)
- (client_rt.bottom - ps.rcPaint.bottom) / data->yChar); - (client_rt.bottom - ps.rcPaint.bottom) / data->yChar);
y = min(ps.rcPaint.bottom, client_rt.bottom); y = min(ps.rcPaint.bottom, client_rt.bottom);
for (i = LastLine; i >= FirstLine; i--) { for (i = LastLine; i >= FirstLine; i--) {
char tmptext[MAXWINDOWTEXT + 1];
x = data->xChar * (2 - data->xPos); x = data->xChar * (2 - data->xPos);
draw_rt.left = x; draw_rt.left = x;
@@ -612,8 +638,10 @@ onPaint(HWND hWnd)
hdc, mswin_get_font(NHW_MESSAGE, data->window_text[i].attr, hdc, mswin_get_font(NHW_MESSAGE, data->window_text[i].attr,
hdc, FALSE)); hdc, FALSE));
/* convert to UNICODE */ /* convert to UNICODE stripping newline */
NH_A2W(data->window_text[i].text, wbuf, sizeof(wbuf)); strcpy(tmptext, data->window_text[i].text);
strip_newline(tmptext);
NH_A2W(tmptext, wbuf, sizeof(wbuf));
wlen = _tcslen(wbuf); wlen = _tcslen(wbuf);
setMsgTextColor(hdc, i < (MSG_LINES - data->lines_last_turn)); setMsgTextColor(hdc, i < (MSG_LINES - data->lines_last_turn));
#ifdef MSG_WRAP_TEXT #ifdef MSG_WRAP_TEXT
@@ -765,6 +793,10 @@ can_append_text(HWND hWnd, int attr, const char *text)
if (data->window_text[MSG_LINES - 1].attr != attr) if (data->window_text[MSG_LINES - 1].attr != attr)
return FALSE; return FALSE;
/* cannot append if current line ends in newline */
if (str_end_is(data->window_text[MSG_LINES - 1].text, "\n"))
return FALSE;
/* check if the maximum string langth will be exceeded */ /* check if the maximum string langth will be exceeded */
if (strlen(data->window_text[MSG_LINES - 1].text) + 2 if (strlen(data->window_text[MSG_LINES - 1].text) + 2
+ /* space characters */ + /* space characters */
@@ -772,10 +804,11 @@ can_append_text(HWND hWnd, int attr, const char *text)
>= MAXWINDOWTEXT) >= MAXWINDOWTEXT)
return FALSE; return FALSE;
/* check if the text is goinf to fin into a single line */ /* check if the text is going to fit into a single line */
strcpy(tmptext, data->window_text[MSG_LINES - 1].text); strcpy(tmptext, data->window_text[MSG_LINES - 1].text);
strcat(tmptext, " "); strcat(tmptext, " ");
strcat(tmptext, text); strcat(tmptext, text);
strip_newline(tmptext);
strcat(tmptext, MORE); strcat(tmptext, MORE);
hdc = GetDC(hWnd); hdc = GetDC(hWnd);
@@ -836,6 +869,8 @@ more_prompt_check(HWND hWnd)
hdc, FALSE)); hdc, FALSE));
strcpy(tmptext, data->window_text[MSG_LINES - i - 1].text); strcpy(tmptext, data->window_text[MSG_LINES - i - 1].text);
strip_newline(tmptext);
if (i == 0) if (i == 0)
strcat(tmptext, MORE); strcat(tmptext, MORE);
+15 -60
View File
@@ -36,13 +36,9 @@ mswin_display_splash_window(BOOL show_ver)
RECT controlrt; RECT controlrt;
HWND hWnd; HWND hWnd;
int buttop; int buttop;
int strsize = 0; strbuf_t strbuf;
int bufsize = BUFSZ;
char *buf = malloc(bufsize);
if (buf == NULL) strbuf_init(&strbuf);
panic("out of memory");
buf[0] = '\0';
hWnd = CreateDialog(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_SPLASH), hWnd = CreateDialog(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_SPLASH),
GetNHApp()->hMainWnd, NHSplashWndProc); GetNHApp()->hMainWnd, NHSplashWndProc);
@@ -87,9 +83,9 @@ mswin_display_splash_window(BOOL show_ver)
clientrt.right - 2 * SPLASH_OFFSET_X, controlrt.bottom, TRUE); clientrt.right - 2 * SPLASH_OFFSET_X, controlrt.bottom, TRUE);
/* Fill the text control */ /* Fill the text control */
Sprintf(buf, "%s\r\n%s\r\n%s\r\n%s\r\n\r\n", COPYRIGHT_BANNER_A, strbuf_reserve(&strbuf, BUFSIZ);
Sprintf(strbuf.str, "%s\n%s\n%s\n%s\n\n", COPYRIGHT_BANNER_A,
COPYRIGHT_BANNER_B, COPYRIGHT_BANNER_C, COPYRIGHT_BANNER_D); COPYRIGHT_BANNER_B, COPYRIGHT_BANNER_C, COPYRIGHT_BANNER_D);
strsize = strlen(buf);
if (show_ver) { if (show_ver) {
/* Show complete version information */ /* Show complete version information */
@@ -98,43 +94,16 @@ mswin_display_splash_window(BOOL show_ver)
int verstrsize = 0; int verstrsize = 0;
getversionstring(verbuf); getversionstring(verbuf);
verstrsize = strlen(verbuf); strbuf_append(&strbuf, verbuf);
if (verstrsize + strlen("\r\n\r\n") + 1 < BUFSZ - 1) strbuf_append(&strbuf, "\n\n");
strcat(verbuf, "\r\n\r\n");
verstrsize = strlen(verbuf);
if (strsize + verstrsize + 1 > bufsize) {
bufsize += BUFSZ;
buf = realloc(buf, bufsize);
if (buf == NULL)
panic("out of memory");
}
strcat(buf, verbuf);
strsize = strlen(buf);
/* Add compile options */ /* Add compile options */
f = dlb_fopen(OPTIONS_USED, RDTMODE); f = dlb_fopen(OPTIONS_USED, RDTMODE);
if (f) { if (f) {
char line[LLEN + 1]; char line[LLEN + 1];
while (dlb_fgets(line, LLEN, f)) { while (dlb_fgets(line, LLEN, f))
size_t len; strbuf_append(&strbuf, line);
len = strlen(line);
if (len > 0 && line[len - 1] == '\n') {
line[len - 1] = '\r';
line[len] = '\n';
line[len + 1] = '\0';
len++;
}
if (strsize + (int) len + 1 > bufsize) {
bufsize += BUFSZ;
buf = realloc(buf, bufsize);
if (buf == NULL)
panic("out of memory");
}
strcat(buf, line);
strsize += len;
}
(void) dlb_fclose(f); (void) dlb_fclose(f);
} }
} else { } else {
@@ -147,32 +116,18 @@ mswin_display_splash_window(BOOL show_ver)
if (nf != NULL) { if (nf != NULL) {
char line[LLEN + 1]; char line[LLEN + 1];
while (fgets(line, LLEN, nf)) { while (fgets(line, LLEN, nf))
size_t len; strbuf_append(&strbuf, line);
len = strlen(line);
if (len > 0 && line[len - 1] == '\n') {
line[len - 1] = '\r';
line[len] = '\n';
line[len + 1] = '\0';
len++;
}
if (strsize + (int) len + 1 > bufsize) {
bufsize += BUFSZ;
buf = realloc(buf, bufsize);
if (buf == NULL)
panic("out of memory");
}
strcat(buf, line);
strsize += len;
}
(void) fclose(nf); (void) fclose(nf);
} else { } else {
strcat(buf, "No news."); strbuf_append(&strbuf, "No news.");
} }
} }
} }
SetWindowText(GetDlgItem(hWnd, IDC_EXTRAINFO), buf);
free(buf); strbuf_nl_to_crlf(&strbuf);
SetWindowText(GetDlgItem(hWnd, IDC_EXTRAINFO), strbuf.str);
strbuf_empty(&strbuf);
ShowWindow(hWnd, SW_SHOW); ShowWindow(hWnd, SW_SHOW);
while (IsWindow(hWnd) && GetMessage(&msg, NULL, 0, 0) != 0) { while (IsWindow(hWnd) && GetMessage(&msg, NULL, 0, 0) != 0) {
+48 -13
View File
@@ -75,6 +75,8 @@ COLORREF status_fg_color = RGB(0xFF, 0xFF, 0xFF);
COLORREF message_bg_color = RGB(0, 0, 0); COLORREF message_bg_color = RGB(0, 0, 0);
COLORREF message_fg_color = RGB(0xFF, 0xFF, 0xFF); COLORREF message_fg_color = RGB(0xFF, 0xFF, 0xFF);
strbuf_t raw_print_strbuf = { 0 };
/* Interface definition, for windows.c */ /* Interface definition, for windows.c */
struct window_procs mswin_procs = { struct window_procs mswin_procs = {
"MSWIN", "MSWIN",
@@ -258,8 +260,6 @@ mswin_init_nhwindows(int *argc, char **argv)
void void
mswin_player_selection(void) mswin_player_selection(void)
{ {
int nRole;
logDebug("mswin_player_selection()\n"); logDebug("mswin_player_selection()\n");
if (iflags.wc_player_selection == VIA_DIALOG) { if (iflags.wc_player_selection == VIA_DIALOG) {
@@ -309,7 +309,7 @@ mswin_player_selection(void)
} }
} else { } else {
/* select a role */ /* select a role */
if (mswin_player_selection_window(&nRole) == IDCANCEL) { if (!mswin_player_selection_window()) {
bail(0); bail(0);
} }
} }
@@ -717,8 +717,7 @@ mswin_exit_nhwindows(const char *str)
/* Write Window settings to the registry */ /* Write Window settings to the registry */
mswin_write_reg(); mswin_write_reg();
while (max_brush)
DeleteObject(brush_table[--max_brush]);
} }
/* Prepare the window to be suspended. */ /* Prepare the window to be suspended. */
@@ -1238,6 +1237,7 @@ void
mswin_wait_synch() mswin_wait_synch()
{ {
logDebug("mswin_wait_synch()\n"); logDebug("mswin_wait_synch()\n");
mswin_raw_print_flush();
} }
/* /*
@@ -1293,6 +1293,40 @@ mswin_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph)
} }
} }
/*
* mswin_raw_print_accumulate() accumulate the given text into
* raw_print_strbuf.
*/
void
mswin_raw_print_accumulate(const char * str, boolean bold)
{
bold; // ignored for now
if (raw_print_strbuf.str != NULL) strbuf_append(&raw_print_strbuf, "\n");
strbuf_append(&raw_print_strbuf, str);
}
/*
* mswin_raw_print_flush() - display any text found in raw_print_strbuf in a
* dialog box and clear raw_print_strbuf.
*/
void
mswin_raw_print_flush()
{
if (raw_print_strbuf.str != NULL) {
int wlen = strlen(raw_print_strbuf.str) + 1;
TCHAR * wbuf = (TCHAR *) alloc(wlen * sizeof(TCHAR));
if (wbuf != NULL) {
NHMessageBox(GetNHApp()->hMainWnd,
NH_A2W(raw_print_strbuf.str, wbuf, wlen),
MB_ICONINFORMATION | MB_OK);
free(wbuf);
}
strbuf_empty(&raw_print_strbuf);
}
}
/* /*
raw_print(str) -- Print directly to a screen, or otherwise guarantee that raw_print(str) -- Print directly to a screen, or otherwise guarantee that
the user sees str. raw_print() appends a newline to str. the user sees str. raw_print() appends a newline to str.
@@ -1305,14 +1339,12 @@ raw_print(str) -- Print directly to a screen, or otherwise guarantee that
void void
mswin_raw_print(const char *str) mswin_raw_print(const char *str)
{ {
TCHAR wbuf[255];
logDebug("mswin_raw_print(%s)\n", str); logDebug("mswin_raw_print(%s)\n", str);
if (str && *str) { if (str && *str) {
extern int redirect_stdout; extern int redirect_stdout;
if (!redirect_stdout) if (!redirect_stdout)
NHMessageBox(GetNHApp()->hMainWnd, mswin_raw_print_accumulate(str, FALSE);
NH_A2W(str, wbuf, sizeof(wbuf)),
MB_ICONINFORMATION | MB_OK);
else else
fprintf(stdout, "%s", str); fprintf(stdout, "%s", str);
} }
@@ -1326,11 +1358,14 @@ possible).
void void
mswin_raw_print_bold(const char *str) mswin_raw_print_bold(const char *str)
{ {
TCHAR wbuf[255];
logDebug("mswin_raw_print_bold(%s)\n", str); logDebug("mswin_raw_print_bold(%s)\n", str);
if (str && *str) if (str && *str) {
NHMessageBox(GetNHApp()->hMainWnd, NH_A2W(str, wbuf, sizeof(wbuf)), extern int redirect_stdout;
MB_ICONINFORMATION | MB_OK); if (!redirect_stdout)
mswin_raw_print_accumulate(str, TRUE);
else
fprintf(stdout, "%s", str);
}
} }
/* /*
+145 -145
View File
@@ -2,155 +2,155 @@
// Microsoft Visual C++ generated include file. // Microsoft Visual C++ generated include file.
// Used by winhack.rc // Used by winhack.rc
// //
#define IDC_MYICON 2 #define IDC_MYICON 2
#define IDD_WINHACK_DIALOG 102 #define IDD_WINHACK_DIALOG 102
#define IDD_ABOUTBOX 103 #define IDD_ABOUTBOX 103
#define IDS_APP_TITLE 103 #define IDS_APP_TITLE 103
#define IDM_ABOUT 104 #define IDM_ABOUT 104
#define IDM_EXIT 105 #define IDM_EXIT 105
#define IDS_HELLO 106 #define IDS_HELLO 106
#define IDI_NETHACKW 107 #define IDI_NETHACKW 107
#define IDC_NETHACKW 109 #define IDC_NETHACKW 109
#define IDS_APP_TITLE_SHORT 110 #define IDS_APP_TITLE_SHORT 110
#define IDR_MAINFRAME 128 #define IDR_MAINFRAME 128
#define IDB_TILES 129 #define IDB_TILES 129
#define IDD_TEXT 130 #define IDD_TEXT 130
#define IDD_NHTEXT 130 #define IDD_NHTEXT 130
#define IDD_MENU 132 #define IDD_MENU 132
#define IDB_MENU_SEL 133 #define IDB_MENU_SEL 133
#define IDB_MENU_UNSEL 134 #define IDB_MENU_UNSEL 134
#define IDD_COMMANDS 136 #define IDD_COMMANDS 136
#define IDD_GETLIN 138 #define IDD_GETLIN 138
#define IDD_EXTCMD 139 #define IDD_EXTCMD 139
#define IDD_PLAYER_SELECTOR 141 #define IDD_PLAYER_SELECTOR 141
#define IDB_PETMARK 143 #define IDB_PETMARK 143
#define IDB_MENU_SEL_COUNT 144 #define IDB_MENU_SEL_COUNT 144
#define IDD_NHRIP 145 #define IDD_NHRIP 145
#define IDB_SPLASH 146 #define IDB_SPLASH 146
#define IDB_RIP 147 #define IDB_RIP 147
#define IDD_SPLASH 148 #define IDD_SPLASH 148
#define IDB_PILEMARK 149 #define IDB_PILEMARK 149
#define IDC_TEXT_VIEW 1000 #define IDC_TEXT_VIEW 1000
#define IDC_TEXT_CONTROL 1000 #define IDC_TEXT_CONTROL 1000
#define IDC_CMD_MOVE_NW 1001 #define IDC_CMD_MOVE_NW 1001
#define IDC_CMD_MOVE_N 1002 #define IDC_CMD_MOVE_N 1002
#define IDC_MENU_LIST 1003 #define IDC_MENU_LIST 1003
#define IDC_CMD_MOVE_NE 1003 #define IDC_CMD_MOVE_NE 1003
#define IDC_MENU_TEXT 1004 #define IDC_MENU_TEXT 1004
#define IDC_CMD_MOVE_W 1004 #define IDC_CMD_MOVE_W 1004
#define IDC_CMD_MOVE_SELF 1005 #define IDC_CMD_MOVE_SELF 1005
#define IDC_CMD_MOVE_E 1006 #define IDC_CMD_MOVE_E 1006
#define IDC_CMD_MOVE_SW 1007 #define IDC_CMD_MOVE_SW 1007
#define IDC_CMD_MOVE_S 1008 #define IDC_CMD_MOVE_S 1008
#define IDC_CMD_MOVE_SE 1009 #define IDC_CMD_MOVE_SE 1009
#define IDC_CMD_MOVE_UP 1010 #define IDC_CMD_MOVE_UP 1010
#define IDC_CMD_MOVE_DOWN 1011 #define IDC_CMD_MOVE_DOWN 1011
#define IDC_CMD_5 1012 #define IDC_CMD_5 1012
#define IDC_CMD_A 1013 #define IDC_CMD_A 1013
#define IDC_CMD_B 1014 #define IDC_CMD_B 1014
#define IDC_CMD_C 1015 #define IDC_CMD_C 1015
#define IDC_CMD_D 1016 #define IDC_CMD_D 1016
#define IDC_CMD_E 1017 #define IDC_CMD_E 1017
#define IDC_CMD_F 1018 #define IDC_CMD_F 1018
#define IDC_CMD_G 1019 #define IDC_CMD_G 1019
#define IDC_CMD_H 1020 #define IDC_CMD_H 1020
#define IDC_CMD_I 1021 #define IDC_CMD_I 1021
#define IDC_CMD_J 1022 #define IDC_CMD_J 1022
#define IDC_CMD_K 1023 #define IDC_CMD_K 1023
#define IDC_CMD_L 1024 #define IDC_CMD_L 1024
#define IDC_CMD_M 1025 #define IDC_CMD_M 1025
#define IDC_CMD_N 1026 #define IDC_CMD_N 1026
#define IDC_CMD_O 1027 #define IDC_CMD_O 1027
#define IDC_CMD_P 1028 #define IDC_CMD_P 1028
#define IDC_CMD_Q 1029 #define IDC_CMD_Q 1029
#define IDC_CMD_R 1030 #define IDC_CMD_R 1030
#define IDC_CMD_S 1031 #define IDC_CMD_S 1031
#define IDC_CMD_T 1032 #define IDC_CMD_T 1032
#define IDC_CMD_U 1033 #define IDC_CMD_U 1033
#define IDC_CMD_V 1034 #define IDC_CMD_V 1034
#define IDC_CMD_W 1035 #define IDC_CMD_W 1035
#define IDC_CMD_X 1036 #define IDC_CMD_X 1036
#define IDC_CMD_Y 1037 #define IDC_CMD_Y 1037
#define IDC_CMD_Z 1038 #define IDC_CMD_Z 1038
#define IDC_CMD_AA 1039 #define IDC_CMD_AA 1039
#define IDC_CMD_BB 1040 #define IDC_CMD_BB 1040
#define IDC_CMD_CC 1041 #define IDC_CMD_CC 1041
#define IDC_CMD_DD 1042 #define IDC_CMD_DD 1042
#define IDC_CMD_EE 1043 #define IDC_CMD_EE 1043
#define IDC_CMD_FF 1044 #define IDC_CMD_FF 1044
#define IDC_CMD_GG 1045 #define IDC_CMD_GG 1045
#define IDC_CMD_HH 1046 #define IDC_CMD_HH 1046
#define IDC_CMD_II 1047 #define IDC_CMD_II 1047
#define IDC_CMD_JJ 1048 #define IDC_CMD_JJ 1048
#define IDC_CMD_KK 1049 #define IDC_CMD_KK 1049
#define IDC_CMD_LL 1050 #define IDC_CMD_LL 1050
#define IDC_CMD_MM 1051 #define IDC_CMD_MM 1051
#define IDC_CMD_NN 1052 #define IDC_CMD_NN 1052
#define IDC_CMD_OO 1053 #define IDC_CMD_OO 1053
#define IDC_CMD_PP 1054 #define IDC_CMD_PP 1054
#define IDC_CMD_QQ 1055 #define IDC_CMD_QQ 1055
#define IDC_CMD_RR 1056 #define IDC_CMD_RR 1056
#define IDC_CMD_SS 1057 #define IDC_CMD_SS 1057
#define IDC_CMD_TT 1058 #define IDC_CMD_TT 1058
#define IDC_CMD_UU 1059 #define IDC_CMD_UU 1059
#define IDC_CMD_VV 1060 #define IDC_CMD_VV 1060
#define IDC_CMD_WW 1061 #define IDC_CMD_WW 1061
#define IDC_CMD_XX 1062 #define IDC_CMD_XX 1062
#define IDC_CMD_YY 1063 #define IDC_CMD_YY 1063
#define IDC_CMD_ZZ 1064 #define IDC_CMD_ZZ 1064
#define IDC_CMD_FIRST 1100 #define IDC_CMD_FIRST 1100
#define IDC_CMD_LAST 1300 #define IDC_CMD_LAST 1300
#define IDC_GETLIN_EDIT 1309 #define IDC_GETLIN_EDIT 1309
#define IDC_EXTCMD_LIST 1310 #define IDC_EXTCMD_LIST 1310
#define IDC_PLSEL_NAME 1314 #define IDC_PLSEL_NAME 1314
#define IDC_PLSEL_ROLE_RANDOM 1315 #define IDC_PLSEL_RANDOM 1315
#define IDC_PLSEL_RACE_RANDOM 1318 #define IDC_ABOUT_VERSION 1327
#define IDC_PLSEL_GENDER_RANDOM 1319 #define IDC_ABOUT_COPYRIGHT 1328
#define IDC_PLSEL_ALIGN_RANDOM 1320 #define IDC_EXTRAINFO 1331
#define IDC_PLSEL_ROLE_LIST 1323 #define IDC_PLSEL_ROLE_LIST 1332
#define IDC_PLSEL_RACE_LIST 1324 #define IDC_PLSEL_RACE_LIST 1333
#define IDC_PLSEL_ALIGN_LIST 1325 #define IDC_PLSEL_ALIGN_LAWFUL 1334
#define IDC_PLSEL_GENDER_LIST 1326 #define IDC_PLSEL_ALIGN_NEUTRAL 1335
#define IDC_ABOUT_VERSION 1327 #define IDC_PLSEL_ALIGN_CHAOTIC 1336
#define IDC_ABOUT_COPYRIGHT 1328 #define IDC_PLSEL_GENDER_MALE 1337
#define IDC_EXTRAINFO 1331 #define IDC_PLSEL_GENDER_FEMALE 1338
#define IDM_SAVE 32771 #define IDM_SAVE 32771
#define IDM_HELP_LONG 32772 #define IDM_HELP_LONG 32772
#define IDM_HELP_COMMANDS 32773 #define IDM_HELP_COMMANDS 32773
#define IDM_HELP_HISTORY 32774 #define IDM_HELP_HISTORY 32774
#define IDM_HELP_INFO_CHAR 32775 #define IDM_HELP_INFO_CHAR 32775
#define IDM_HELP_INFO_KEY 32776 #define IDM_HELP_INFO_KEY 32776
#define IDM_HELP_OPTIONS 32777 #define IDM_HELP_OPTIONS 32777
#define IDM_HELP_OPTIONS_LONG 32778 #define IDM_HELP_OPTIONS_LONG 32778
#define IDM_HELP_EXTCMD 32779 #define IDM_HELP_EXTCMD 32779
#define IDM_HELP_LICENSE 32780 #define IDM_HELP_LICENSE 32780
#define IDM_HELP_PORTHELP 32781 #define IDM_HELP_PORTHELP 32781
#define IDM_MAP_TILES 32782 #define IDM_MAP_TILES 32782
#define IDM_MAP_ASCII4X6 32783 #define IDM_MAP_ASCII4X6 32783
#define IDM_MAP_ASCII6X8 32784 #define IDM_MAP_ASCII6X8 32784
#define IDM_MAP_ASCII8X8 32785 #define IDM_MAP_ASCII8X8 32785
#define IDM_MAP_ASCII16X8 32786 #define IDM_MAP_ASCII16X8 32786
#define IDM_MAP_ASCII7X12 32787 #define IDM_MAP_ASCII7X12 32787
#define IDM_MAP_ASCII8X12 32788 #define IDM_MAP_ASCII8X12 32788
#define IDM_MAP_ASCII16X12 32789 #define IDM_MAP_ASCII16X12 32789
#define IDM_MAP_ASCII12X16 32790 #define IDM_MAP_ASCII12X16 32790
#define IDM_MAP_ASCII10X18 32791 #define IDM_MAP_ASCII10X18 32791
#define IDM_MAP_FIT_TO_SCREEN 32792 #define IDM_MAP_FIT_TO_SCREEN 32792
#define IDM_NHMODE 32794 #define IDM_NHMODE 32794
#define IDM_CLEARSETTINGS 32795 #define IDM_CLEARSETTINGS 32795
#define IDM_SETTING_AUTOLAYOUT 32796 #define IDM_SETTING_AUTOLAYOUT 32796
#define IDM_SETTING_LOCKWINDOWS 32797 #define IDM_SETTING_LOCKWINDOWS 32797
#define IDM_SETTING_SCREEN_TO_CLIPBOARD 32798 #define IDM_SETTING_SCREEN_TO_CLIPBOARD 32798
#define IDM_SETTING_SCREEN_TO_FILE 32799 #define IDM_SETTING_SCREEN_TO_FILE 32799
#define IDC_STATIC -1 #define IDC_STATIC -1
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 145 #define _APS_NEXT_RESOURCE_VALUE 146
#define _APS_NEXT_COMMAND_VALUE 32800 #define _APS_NEXT_COMMAND_VALUE 32800
#define _APS_NEXT_CONTROL_VALUE 1332 #define _APS_NEXT_CONTROL_VALUE 1341
#define _APS_NEXT_SYMED_VALUE 110 #define _APS_NEXT_SYMED_VALUE 110
#endif #endif
#endif #endif
+2
View File
@@ -29,6 +29,7 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <windowsx.h>
#include <commctrl.h> #include <commctrl.h>
#include <tchar.h> #include <tchar.h>
#include "hack.h" #include "hack.h"
@@ -164,6 +165,7 @@ void mswin_cliparound(int x, int y);
void mswin_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph); void mswin_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph);
void mswin_raw_print(const char *str); void mswin_raw_print(const char *str);
void mswin_raw_print_bold(const char *str); void mswin_raw_print_bold(const char *str);
void mswin_raw_print_flush();
int mswin_nhgetch(void); int mswin_nhgetch(void);
int mswin_nh_poskey(int *x, int *y, int *mod); int mswin_nh_poskey(int *x, int *y, int *mod);
void mswin_nhbell(void); void mswin_nhbell(void);
+87 -81
View File
@@ -1,4 +1,4 @@
//Microsoft Developer Studio generated resource script. // Microsoft Visual C++ generated resource script.
// //
#include "resource.h" #include "resource.h"
@@ -19,13 +19,11 @@ LANGUAGE LANG_ENGLISH,SUBLANG_ENGLISH_US
#undef APSTUDIO_READONLY_SYMBOLS #undef APSTUDIO_READONLY_SYMBOLS
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources // English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252) #pragma code_page(1252)
#endif //_WIN32
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
@@ -34,14 +32,15 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// Icon with lowest ID value placed first to ensure application icon // Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems. // remains consistent on all systems.
IDI_NETHACKW ICON DISCARDABLE "NETHACK.ICO" IDI_NETHACKW ICON "NETHACK.ICO"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
// Menu // Menu
// //
IDC_NETHACKW MENU DISCARDABLE IDC_NETHACKW MENU
BEGIN BEGIN
POPUP "&File" POPUP "&File"
BEGIN BEGIN
@@ -98,7 +97,7 @@ END
// Accelerator // Accelerator
// //
IDC_NETHACKW ACCELERATORS MOVEABLE PURE IDC_NETHACKW ACCELERATORS
BEGIN BEGIN
"?", IDM_ABOUT, ASCII, ALT "?", IDM_ABOUT, ASCII, ALT
"/", IDM_ABOUT, ASCII, ALT "/", IDM_ABOUT, ASCII, ALT
@@ -110,8 +109,8 @@ END
// Dialog // Dialog
// //
IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 230, 75 IDD_ABOUTBOX DIALOG 22, 17, 230, 75
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "About" CAPTION "About"
FONT 8, "System" FONT 8, "System"
BEGIN BEGIN
@@ -121,29 +120,27 @@ BEGIN
END END
IDD_NHTEXT DIALOGEX 0, 0, 172, 178 IDD_NHTEXT DIALOGEX 0, 0, 172, 178
STYLE WS_CHILD | WS_CLIPSIBLINGS | WS_THICKFRAME STYLE DS_SETFONT | WS_CHILD | WS_CLIPSIBLINGS | WS_THICKFRAME
EXSTYLE WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT EXSTYLE WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT
FONT 8, "MS Sans Serif", 0, 0 FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN BEGIN
EDITTEXT IDC_TEXT_CONTROL,0,0,172,160,ES_MULTILINE | EDITTEXT IDC_TEXT_CONTROL,0,0,172,160,ES_MULTILINE | ES_OEMCONVERT | ES_READONLY | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP
ES_OEMCONVERT | ES_READONLY | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,54,163,50,14,BS_FLAT | NOT WS_TABSTOP DEFPUSHBUTTON "OK",IDOK,54,163,50,14,BS_FLAT | NOT WS_TABSTOP
END END
IDD_MENU DIALOGEX 0, 0, 187, 153 IDD_MENU DIALOGEX 0, 0, 187, 153
STYLE WS_CHILD | WS_CLIPSIBLINGS | WS_THICKFRAME STYLE DS_SETFONT | WS_CHILD | WS_CLIPSIBLINGS | WS_THICKFRAME
EXSTYLE WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT EXSTYLE WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT
FONT 8, "MS Sans Serif", 0, 0 FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN BEGIN
LISTBOX IDC_MENU_LIST,10,10,170,55,LBS_SORT | NOT WS_BORDER LISTBOX IDC_MENU_LIST,10,10,170,55,LBS_SORT | NOT WS_BORDER
EDITTEXT IDC_MENU_TEXT,10,70,170,60,ES_MULTILINE | ES_OEMCONVERT | EDITTEXT IDC_MENU_TEXT,10,70,170,60,ES_MULTILINE | ES_OEMCONVERT | ES_READONLY | NOT WS_BORDER | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP
ES_READONLY | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP | NOT WS_BORDER
DEFPUSHBUTTON "OK",IDOK,7,132,50,14,BS_FLAT | NOT WS_TABSTOP DEFPUSHBUTTON "OK",IDOK,7,132,50,14,BS_FLAT | NOT WS_TABSTOP
PUSHBUTTON "Cancel",IDCANCEL,130,132,50,14,BS_FLAT | NOT WS_TABSTOP PUSHBUTTON "Cancel",IDCANCEL,130,132,50,14,BS_FLAT | NOT WS_TABSTOP
END END
IDD_GETLIN DIALOG DISCARDABLE 0, 0, 131, 29 IDD_GETLIN DIALOG 0, 0, 131, 29
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Question?" CAPTION "Question?"
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif"
BEGIN BEGIN
@@ -152,65 +149,54 @@ BEGIN
EDITTEXT IDC_GETLIN_EDIT,0,0,130,13,ES_AUTOHSCROLL EDITTEXT IDC_GETLIN_EDIT,0,0,130,13,ES_AUTOHSCROLL
END END
IDD_EXTCMD DIALOG DISCARDABLE 0, 0, 137, 117 IDD_EXTCMD DIALOG 0, 0, 137, 117
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Extended Commands" CAPTION "Extended Commands"
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif"
BEGIN BEGIN
DEFPUSHBUTTON "OK",IDOK,80,7,50,14 DEFPUSHBUTTON "OK",IDOK,80,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,80,24,50,14 PUSHBUTTON "Cancel",IDCANCEL,80,24,50,14
LISTBOX IDC_EXTCMD_LIST,7,7,65,103,LBS_NOINTEGRALHEIGHT | LISTBOX IDC_EXTCMD_LIST,7,7,65,103,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
WS_VSCROLL | WS_TABSTOP
END END
IDD_PLAYER_SELECTOR DIALOG DISCARDABLE 0, 0, 152, 169 IDD_PLAYER_SELECTOR DIALOGEX 0, 0, 225, 212
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "What are you?" CAPTION "What are you?"
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN BEGIN
DEFPUSHBUTTON "Play",IDOK,7,148,66,14 DEFPUSHBUTTON "Play",IDOK,12,192,54,14,WS_GROUP
PUSHBUTTON "Quit",IDCANCEL,79,148,66,14 PUSHBUTTON "Quit",IDCANCEL,162,192,54,14,WS_GROUP
LTEXT "Name:",IDC_STATIC,7,8,25,10 EDITTEXT IDC_PLSEL_NAME,12,12,105,12,ES_AUTOHSCROLL | ES_READONLY | WS_GROUP | NOT WS_TABSTOP
EDITTEXT IDC_PLSEL_NAME,40,7,105,12,ES_AUTOHSCROLL | ES_READONLY | CONTROL "Neutral",IDC_PLSEL_ALIGN_NEUTRAL,"Button",BS_AUTORADIOBUTTON,168,60,37,10
NOT WS_TABSTOP CONTROL "Lawful",IDC_PLSEL_ALIGN_LAWFUL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,168,48,35,10
GROUPBOX "Role",IDC_STATIC,7,21,138,30 CONTROL "Chaotic",IDC_PLSEL_ALIGN_CHAOTIC,"Button",BS_AUTORADIOBUTTON,168,72,38,10
CONTROL "Random",IDC_PLSEL_ROLE_RANDOM,"Button",BS_AUTOCHECKBOX | CONTROL "Male",IDC_PLSEL_GENDER_MALE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,168,108,30,10
WS_TABSTOP,14,34,40,10 CONTROL "Female",IDC_PLSEL_GENDER_FEMALE,"Button",BS_AUTORADIOBUTTON,168,120,38,10
COMBOBOX IDC_PLSEL_ROLE_LIST,63,33,75,50,CBS_DROPDOWNLIST | GROUPBOX "Alignment",IDC_STATIC,162,36,48,54
WS_VSCROLL | WS_TABSTOP GROUPBOX "Gender",IDC_STATIC,162,96,48,42
GROUPBOX "Race",IDC_STATIC,7,51,138,30 GROUPBOX "Role",IDC_STATIC,6,36,72,150
CONTROL "Random",IDC_PLSEL_RACE_RANDOM,"Button",BS_AUTOCHECKBOX | GROUPBOX "Race",IDC_STATIC,84,36,72,72
WS_TABSTOP,14,63,40,10 PUSHBUTTON "Random",IDC_PLSEL_RANDOM,90,192,54,14,WS_GROUP
COMBOBOX IDC_PLSEL_RACE_LIST,63,62,75,45,CBS_DROPDOWNLIST | GROUPBOX "Name",IDC_STATIC,6,0,120,30
WS_VSCROLL | WS_TABSTOP CONTROL "",IDC_PLSEL_ROLE_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_GROUP | WS_TABSTOP,12,48,60,130
GROUPBOX "Gender",IDC_STATIC,7,81,138,30 CONTROL "",IDC_PLSEL_RACE_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_GROUP | WS_TABSTOP,90,48,60,51
CONTROL "Random",IDC_PLSEL_GENDER_RANDOM,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,14,93,40,10
COMBOBOX IDC_PLSEL_GENDER_LIST,63,92,75,40,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Alignment",IDC_STATIC,7,111,138,30
CONTROL "Random",IDC_PLSEL_ALIGN_RANDOM,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,13,123,40,10
COMBOBOX IDC_PLSEL_ALIGN_LIST,63,122,75,45,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
END END
IDD_NHRIP DIALOGEX 0, 0, 281, 209 IDD_NHRIP DIALOGEX 0, 0, 281, 209
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Here lies..." CAPTION "Here lies..."
FONT 8, "MS Sans Serif", 0, 0 FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN BEGIN
DEFPUSHBUTTON "OK",IDOK,82,188,50,14 DEFPUSHBUTTON "OK",IDOK,82,188,50,14
END END
IDD_SPLASH DIALOG DISCARDABLE 0, 0, 281, 257 IDD_SPLASH DIALOG 0, 0, 281, 257
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Welcome to NetHack" CAPTION "Welcome to NetHack"
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif"
BEGIN BEGIN
DEFPUSHBUTTON "OK",IDOK,224,236,50,14 DEFPUSHBUTTON "OK",IDOK,224,236,50,14
EDITTEXT IDC_EXTRAINFO,7,176,267,52,ES_MULTILINE | ES_READONLY | EDITTEXT IDC_EXTRAINFO,7,176,267,52,ES_MULTILINE | ES_READONLY | WS_VSCROLL
WS_VSCROLL
END END
@@ -220,7 +206,7 @@ END
// TEXTINCLUDE // TEXTINCLUDE
// //
2 TEXTINCLUDE DISCARDABLE 2 TEXTINCLUDE
BEGIN BEGIN
"#if defined(__BORLANDC__)\r\n" "#if defined(__BORLANDC__)\r\n"
"LANGUAGE LANG_ENGLISH,SUBLANG_ENGLISH_US\r\n" "LANGUAGE LANG_ENGLISH,SUBLANG_ENGLISH_US\r\n"
@@ -232,13 +218,13 @@ BEGIN
"\0" "\0"
END END
3 TEXTINCLUDE DISCARDABLE 3 TEXTINCLUDE
BEGIN BEGIN
"\r\n" "\r\n"
"\0" "\0"
END END
1 TEXTINCLUDE DISCARDABLE 1 TEXTINCLUDE
BEGIN BEGIN
"resource.h\0" "resource.h\0"
END END
@@ -251,14 +237,22 @@ END
// Bitmap // Bitmap
// //
IDB_TILES BITMAP DISCARDABLE "tiles.bmp" IDB_TILES BITMAP "tiles.bmp"
IDB_MENU_SEL BITMAP DISCARDABLE "mnsel.bmp"
IDB_MENU_UNSEL BITMAP DISCARDABLE "mnunsel.bmp" IDB_MENU_SEL BITMAP "mnsel.bmp"
IDB_PETMARK BITMAP DISCARDABLE "petmark.bmp"
IDB_PILEMARK BITMAP DISCARDABLE "pilemark.bmp" IDB_MENU_UNSEL BITMAP "mnunsel.bmp"
IDB_MENU_SEL_COUNT BITMAP DISCARDABLE "mnselcnt.bmp"
IDB_RIP BITMAP DISCARDABLE "rip.bmp" IDB_PETMARK BITMAP "petmark.bmp"
IDB_SPLASH BITMAP DISCARDABLE "splash.bmp"
IDB_PILEMARK BITMAP "pilemark.bmp"
IDB_MENU_SEL_COUNT BITMAP "mnselcnt.bmp"
IDB_RIP BITMAP "rip.bmp"
IDB_SPLASH BITMAP "splash.bmp"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
@@ -266,7 +260,7 @@ IDB_SPLASH BITMAP DISCARDABLE "splash.bmp"
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE GUIDELINES DESIGNINFO
BEGIN BEGIN
IDD_NHTEXT, DIALOG IDD_NHTEXT, DIALOG
BEGIN BEGIN
@@ -297,9 +291,9 @@ BEGIN
IDD_PLAYER_SELECTOR, DIALOG IDD_PLAYER_SELECTOR, DIALOG
BEGIN BEGIN
LEFTMARGIN, 7 LEFTMARGIN, 7
RIGHTMARGIN, 145 RIGHTMARGIN, 218
TOPMARGIN, 7 TOPMARGIN, 7
BOTTOMMARGIN, 162 BOTTOMMARGIN, 205
END END
IDD_NHRIP, DIALOG IDD_NHRIP, DIALOG
@@ -342,14 +336,14 @@ BEGIN
BEGIN BEGIN
BLOCK "040904b0" BLOCK "040904b0"
BEGIN BEGIN
VALUE "FileDescription", "NetHack for Windows - Graphical Interface\0" VALUE "FileDescription", "NetHack for Windows - Graphical Interface"
VALUE "FileVersion", "3.6.1\0" VALUE "FileVersion", "3.6.1"
VALUE "InternalName", "NetHackW\0" VALUE "InternalName", "NetHackW"
VALUE "LegalCopyright", "Copyright (C) 1985 - 2017. By Stichting Mathematisch Centrum and M. Stephenson. See license for details.\0" VALUE "LegalCopyright", "Copyright (C) 1985 - 2017. By Stichting Mathematisch Centrum and M. Stephenson. See license for details."
VALUE "OriginalFilename", "NetHackW.exe\0" VALUE "OriginalFilename", "NetHackW.exe"
VALUE "PrivateBuild", "140606\0" VALUE "PrivateBuild", "140606"
VALUE "ProductName", "NetHack\0" VALUE "ProductName", "NetHack"
VALUE "ProductVersion", "3.6.1\0" VALUE "ProductVersion", "3.6.1"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@@ -358,19 +352,31 @@ BEGIN
END END
END END
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_PLAYER_SELECTOR AFX_DIALOG_LAYOUT
BEGIN
0
END
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
// String Table // String Table
// //
STRINGTABLE DISCARDABLE STRINGTABLE
BEGIN BEGIN
IDS_APP_TITLE "NetHack for Windows - Graphical Interface" IDS_APP_TITLE "NetHack for Windows - Graphical Interface"
IDC_NETHACKW "NETHACKW" IDC_NETHACKW "NETHACKW"
IDS_APP_TITLE_SHORT "NetHack for Windows" IDS_APP_TITLE_SHORT "NetHack for Windows"
END END
#endif // English (U.S.) resources #endif // English (United States) resources
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////