Merge branch 'NetHack-3.6'
This commit is contained in:
+6
-3
@@ -57,7 +57,7 @@ Spackman, Steve VanDevender, and Paul Winner, ported NetHack 3.1 to the PC.
|
|||||||
Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike Engber, David
|
Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike Engber, David
|
||||||
Hairston, Michael Hamel, Jonathan Handler, Johnny Lee, Tim Lennan, Rob Menke,
|
Hairston, Michael Hamel, Jonathan Handler, Johnny Lee, Tim Lennan, Rob Menke,
|
||||||
and Andy Swanson developed NetHack 3.1 for the Macintosh, porting it for
|
and Andy Swanson developed NetHack 3.1 for the Macintosh, porting it for
|
||||||
MPW. Building on their development, Barton House added a Think C port.
|
MPW. Building on their development, Bart House added a Think C port.
|
||||||
|
|
||||||
Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith ported NetHack 3.1
|
Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith ported NetHack 3.1
|
||||||
to the Atari. Pat Rankin, with help from Joshua Delahunty, is responsible
|
to the Atari. Pat Rankin, with help from Joshua Delahunty, is responsible
|
||||||
@@ -195,7 +195,7 @@ Unix flavors as well as maintaining the X11 interface.
|
|||||||
Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick maintained the port
|
Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick maintained the port
|
||||||
of NetHack 3.6.1 for Mac OSX.
|
of NetHack 3.6.1 for Mac OSX.
|
||||||
|
|
||||||
Michael Allison, David Cohrs, Barton House, Pasi Kallinen, Alex Kompel,
|
Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel,
|
||||||
Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the port of
|
Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the port of
|
||||||
NetHack 3.6 for Microsoft Windows.
|
NetHack 3.6 for Microsoft Windows.
|
||||||
|
|
||||||
@@ -217,6 +217,9 @@ Derek S. Ray, Alex Smith, Mike Stephenson, Janet Walz and Paul Winner.
|
|||||||
In early May 2019, another 320 bug fixes along with some enhancements and
|
In early May 2019, another 320 bug fixes along with some enhancements and
|
||||||
the adopted curses window port, were released as 3.6.2.
|
the adopted curses window port, were released as 3.6.2.
|
||||||
|
|
||||||
|
Bart House, who had contributed to the game as a porting team participant
|
||||||
|
for decades, joined the NetHack Development Team in late May 2019.
|
||||||
|
|
||||||
The official NetHack web site is maintained by Ken Lorber at
|
The official NetHack web site is maintained by Ken Lorber at
|
||||||
http://www.nethack.org/.
|
http://www.nethack.org/.
|
||||||
|
|
||||||
@@ -241,7 +244,7 @@ of these miscreants in this, the list of Dungeoneers:
|
|||||||
Andy Church Jochen Erwied Pat Rankin
|
Andy Church Jochen Erwied Pat Rankin
|
||||||
Andy Swanson John Kallen Patric Mueller
|
Andy Swanson John Kallen Patric Mueller
|
||||||
Ari Huttunen John Rupley Paul Winner
|
Ari Huttunen John Rupley Paul Winner
|
||||||
Barton House John S. Bien Pierre Martineau
|
Bart House John S. Bien Pierre Martineau
|
||||||
Benson I. Margulies Johnny Lee Ralf Brown
|
Benson I. Margulies Johnny Lee Ralf Brown
|
||||||
Bill Dyer Jon W{tte Ray Chason
|
Bill Dyer Jon W{tte Ray Chason
|
||||||
Boudewijn Waijers Jonathan Handler Richard Addison
|
Boudewijn Waijers Jonathan Handler Richard Addison
|
||||||
|
|||||||
+7
-4
@@ -24,7 +24,7 @@
|
|||||||
.ds vr "NetHack 3.7
|
.ds vr "NetHack 3.7
|
||||||
.ds f0 "\*(vr
|
.ds f0 "\*(vr
|
||||||
.ds f1
|
.ds f1
|
||||||
.ds f2 "October 27, 2019
|
.ds f2 "October 31, 2019
|
||||||
.
|
.
|
||||||
.\" A note on some special characters:
|
.\" A note on some special characters:
|
||||||
.\" \(lq = left double quote
|
.\" \(lq = left double quote
|
||||||
@@ -4911,7 +4911,7 @@ and \fBPaul Winner\fP, ported NetHack 3.1 to the PC.
|
|||||||
\fBMike Engber\fP, \fBDavid Hairston\fP, \fBMichael Hamel\fP,
|
\fBMike Engber\fP, \fBDavid Hairston\fP, \fBMichael Hamel\fP,
|
||||||
\fBJonathan Handler\fP, \fBJohnny Lee\fP, \fBTim Lennan\fP, \fBRob Menke\fP,
|
\fBJonathan Handler\fP, \fBJohnny Lee\fP, \fBTim Lennan\fP, \fBRob Menke\fP,
|
||||||
and \fBAndy Swanson\fP, developed NetHack 3.1 for the Macintosh,
|
and \fBAndy Swanson\fP, developed NetHack 3.1 for the Macintosh,
|
||||||
porting it for MPW. Building on their development, \fBBarton House\fP
|
porting it for MPW. Building on their development, \fBBart House\fP
|
||||||
added a Think C port.
|
added a Think C port.
|
||||||
.pg
|
.pg
|
||||||
\fBTimo Hakulinen\fP ported NetHack 3.1 to OS/2. \fBEric Smith\fP
|
\fBTimo Hakulinen\fP ported NetHack 3.1 to OS/2. \fBEric Smith\fP
|
||||||
@@ -5070,7 +5070,7 @@ flavors and maintained the X11 interface.
|
|||||||
\fBKen Lorber\fP, \fBHaoyang Wang\fP, \fBPat Rankin\fP, and \fBDean Luick\fP
|
\fBKen Lorber\fP, \fBHaoyang Wang\fP, \fBPat Rankin\fP, and \fBDean Luick\fP
|
||||||
maintained the port of NetHack 3.6 for Mac OSX.
|
maintained the port of NetHack 3.6 for Mac OSX.
|
||||||
.pg
|
.pg
|
||||||
\fBMichael Allison\fP, \fBDavid Cohrs\fP, \fBBarton House\fP,
|
\fBMichael Allison\fP, \fBDavid Cohrs\fP, \fBBart House\fP,
|
||||||
\fBPasi Kallinen\fP, \fBAlex Kompel\fP, \fBDion Nicolaas\fP,
|
\fBPasi Kallinen\fP, \fBAlex Kompel\fP, \fBDion Nicolaas\fP,
|
||||||
\fBDerek S. Ray\fP and \fBYitzhak Sapir\fP maintained the port of
|
\fBDerek S. Ray\fP and \fBYitzhak Sapir\fP maintained the port of
|
||||||
NetHack 3.6 for Microsoft Windows.
|
NetHack 3.6 for Microsoft Windows.
|
||||||
@@ -5095,6 +5095,9 @@ The NetHack Development Team at the time of release of 3.6.1 consisted of
|
|||||||
In early May 2019, another 320 bug fixes along with some enhancements and
|
In early May 2019, another 320 bug fixes along with some enhancements and
|
||||||
the adopted curses window port, were released as 3.6.2.
|
the adopted curses window port, were released as 3.6.2.
|
||||||
.pg
|
.pg
|
||||||
|
\fBBart House\fP, who had contributed to the game as a porting team
|
||||||
|
participant for decades, joined the NetHack Development Team in late May 2019.
|
||||||
|
.pg
|
||||||
The official NetHack web site is maintained by \fBKen Lorber\fP
|
The official NetHack web site is maintained by \fBKen Lorber\fP
|
||||||
at
|
at
|
||||||
.UR http://www.nethack.org/ .
|
.UR http://www.nethack.org/ .
|
||||||
@@ -5130,7 +5133,7 @@ Andreas Dorn Jeff Bailey Pasi Kallinen
|
|||||||
Andy Church Jochen Erwied Pat Rankin
|
Andy Church Jochen Erwied Pat Rankin
|
||||||
Andy Swanson John Kallen Patric Mueller
|
Andy Swanson John Kallen Patric Mueller
|
||||||
Ari Huttunen John Rupley Paul Winner
|
Ari Huttunen John Rupley Paul Winner
|
||||||
Barton House John S. Bien Pierre Martineau
|
Bart House John S. Bien Pierre Martineau
|
||||||
Benson I. Margulies Johnny Lee Ralf Brown
|
Benson I. Margulies Johnny Lee Ralf Brown
|
||||||
Bill Dyer Jon W{tte Ray Chason
|
Bill Dyer Jon W{tte Ray Chason
|
||||||
Boudewijn Waijers Jonathan Handler Richard Addison
|
Boudewijn Waijers Jonathan Handler Richard Addison
|
||||||
|
|||||||
+70
-67
@@ -45,7 +45,7 @@
|
|||||||
%.au
|
%.au
|
||||||
\author{Original version - Eric S. Raymond\\
|
\author{Original version - Eric S. Raymond\\
|
||||||
(Edited and expanded for 3.6 by Mike Stephenson and others)}
|
(Edited and expanded for 3.6 by Mike Stephenson and others)}
|
||||||
\date{October 22, 2019}
|
\date{October 31, 2019}
|
||||||
|
|
||||||
\maketitle
|
\maketitle
|
||||||
|
|
||||||
@@ -1130,7 +1130,7 @@ slot to another so that it has a letter which is more meaningful for you
|
|||||||
or that it will appear in a particular location when inventory listings
|
or that it will appear in a particular location when inventory listings
|
||||||
are displayed.
|
are displayed.
|
||||||
You can move to a currently empty slot, or if the destination is
|
You can move to a currently empty slot, or if the destination is
|
||||||
occupied--and won't merge--the item there will swap slots with the one
|
occupied---and won't merge---the item there will swap slots with the one
|
||||||
being moved.
|
being moved.
|
||||||
``{\tt \#adjust}'' can also be used to split a stack of objects; when
|
``{\tt \#adjust}'' can also be used to split a stack of objects; when
|
||||||
choosing the item to adjust, enter a count prior to its letter.\\
|
choosing the item to adjust, enter a count prior to its letter.\\
|
||||||
@@ -2044,9 +2044,9 @@ will result in it disappearing from your map, similarly if it is the
|
|||||||
one who moved rather than you.
|
one who moved rather than you.
|
||||||
|
|
||||||
%.pg
|
%.pg
|
||||||
However, if you encounter a monster which you can't see or sense--
|
However, if you encounter a monster which you can't see or
|
||||||
perhaps it is invisible and has just tapped you on the noggin--
|
sense---perhaps it is invisible and has just tapped you on the
|
||||||
a special ``remembered, unseen monster'' marker will be displayed at
|
noggin---a special ``remembered, unseen monster'' marker will be displayed at
|
||||||
the location where you think it is.
|
the location where you think it is.
|
||||||
That will persist until you have
|
That will persist until you have
|
||||||
proven that there is no monster there, even if the unseen monster
|
proven that there is no monster there, even if the unseen monster
|
||||||
@@ -2326,7 +2326,7 @@ But first you need to have a weapon in each hand.
|
|||||||
(Note that your two weapons are not fully equal; the one in the
|
(Note that your two weapons are not fully equal; the one in the
|
||||||
hand you normally wield with is considered primary and the other
|
hand you normally wield with is considered primary and the other
|
||||||
one is considered secondary. The most noticeable difference is
|
one is considered secondary. The most noticeable difference is
|
||||||
after you stop--or before you begin, for that matter--wielding
|
after you stop---or before you begin, for that matter---wielding
|
||||||
two weapons at once. The primary is your wielded weapon and the
|
two weapons at once. The primary is your wielded weapon and the
|
||||||
secondary is just an item in your inventory that's been designated
|
secondary is just an item in your inventory that's been designated
|
||||||
as alternate weapon.)
|
as alternate weapon.)
|
||||||
@@ -2558,7 +2558,7 @@ The commands to use rings are `{\tt P}' (put on) and `{\tt R}' (remove).
|
|||||||
%.pg
|
%.pg
|
||||||
Spellbooks are tomes of mighty magic. When studied with the `{\tt r}' (read)
|
Spellbooks are tomes of mighty magic. When studied with the `{\tt r}' (read)
|
||||||
command, they transfer to the reader the knowledge of a spell (and
|
command, they transfer to the reader the knowledge of a spell (and
|
||||||
therefore eventually become unreadable) --- unless the attempt backfires.
|
therefore eventually become unreadable)---unless the attempt backfires.
|
||||||
Reading a cursed spellbook or one with mystic runes beyond
|
Reading a cursed spellbook or one with mystic runes beyond
|
||||||
your ken can be harmful to your health!
|
your ken can be harmful to your health!
|
||||||
|
|
||||||
@@ -2701,9 +2701,9 @@ you are carrying (shopkeepers aside).
|
|||||||
Normally, if you have seen an object at a particular map location and
|
Normally, if you have seen an object at a particular map location and
|
||||||
move to another location where you can't directly see that object any
|
move to another location where you can't directly see that object any
|
||||||
more, if will continue to be displayed on your map.
|
more, if will continue to be displayed on your map.
|
||||||
That remains the case even if it is not actually there any more--
|
That remains the case even if it is not actually there any
|
||||||
perhaps a monster has picked it up or it has rotted away--
|
more---perhaps a monster has picked it up or it has rotted
|
||||||
until you can see or feel that location again.
|
away---until you can see or feel that location again.
|
||||||
One notable exception is that if the object gets covered by the
|
One notable exception is that if the object gets covered by the
|
||||||
``remembered, unseen monster'' marker.
|
``remembered, unseen monster'' marker.
|
||||||
When that marker is later removed
|
When that marker is later removed
|
||||||
@@ -3028,11 +3028,13 @@ See the ``Configuring User Sounds'' section.
|
|||||||
Define the directory that contains the sound files.
|
Define the directory that contains the sound files.
|
||||||
See the ``Configuring User Sounds'' section.
|
See the ``Configuring User Sounds'' section.
|
||||||
%.lp
|
%.lp
|
||||||
\item[\bb{SYMBOLS}
|
\item[\bb{SYMBOLS}]
|
||||||
Override one or more symbols in the symbol set used for all dungeon
|
Override one or more symbols in the symbol set used for all dungeon
|
||||||
levels except for the special rogue level.
|
levels except for the special rogue level.
|
||||||
See the ``Modifying {\it NetHack\/} Symbols'' section.
|
See the ``Modifying {\it NetHack\/} Symbols'' section.
|
||||||
%.pg
|
%.pg
|
||||||
|
|
||||||
|
%.lp ""
|
||||||
Example:
|
Example:
|
||||||
%.sd
|
%.sd
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
@@ -4378,158 +4380,158 @@ Below are the special commands you can rebind. Some of them can be bound to
|
|||||||
same keys with no problems, others are in the same ``context'', and if bound
|
same keys with no problems, others are in the same ``context'', and if bound
|
||||||
to same keys, only one of those commands will be available. Special command
|
to same keys, only one of those commands will be available. Special command
|
||||||
can only be bound to a single key.
|
can only be bound to a single key.
|
||||||
|
\elist
|
||||||
|
|
||||||
%.pg
|
%.pg
|
||||||
\blist{}
|
\blist{\itemindent 10mm \labelwidth 15mm \rightmargin 20mm}
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{count}}
|
\item[{\bb{count}}]
|
||||||
Prefix key to start a count, to repeat a command this many times.
|
Prefix key to start a count, to repeat a command this many times.
|
||||||
With {\it number\verb+_+pad\/} only. Default is `{\tt n}'.
|
With {\it number\verb+_+pad\/} only. Default is `{\tt n}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{doinv}}
|
\item[{\bb{doinv}}]
|
||||||
Show inventory. With {\it number\verb+_+pad\/} only. Default is `{\tt 0}'.
|
Show inventory. With {\it number\verb+_+pad\/} only. Default is `{\tt 0}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{fight}}
|
\item[{\bb{fight}}]
|
||||||
Prefix key to force fight a direction. Default is `{\tt F}'.
|
Prefix key to force fight a direction. Default is `{\tt F}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{fight.numpad}}
|
\item[{\bb{fight.numpad}}]
|
||||||
Prefix key to force fight a direction. With {\it number\verb+_+pad\/} only.
|
Prefix key to force fight a direction. With {\it number\verb+_+pad\/} only.
|
||||||
Default is `{\tt -}'.
|
Default is `{\tt -}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getdir.help}}
|
\item[{\bb{getdir.help}}]
|
||||||
When asked for a direction, the key to show the help. Default is `{\tt ?}'.
|
When asked for a direction, the key to show the help. Default is `{\tt ?}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getdir.self}}
|
\item[{\bb{getdir.self}}]
|
||||||
When asked for a direction, the key to target yourself. Default is `{\tt .}'.
|
When asked for a direction, the key to target yourself. Default is `{\tt .}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getdir.self2}}
|
\item[{\bb{getdir.self2}}]
|
||||||
When asked for a direction, the key to target yourself. Default is `{\tt s}'.
|
When asked for a direction, the key to target yourself. Default is `{\tt s}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.autodescribe}}
|
\item[{\bb{getpos.autodescribe}}]
|
||||||
When asked for a location, the key to toggle {\it autodescribe\/}.
|
When asked for a location, the key to toggle {\it autodescribe\/}.
|
||||||
Default is `{\tt \#}'.
|
Default is `{\tt \#}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.all.next}}
|
\item[{\bb{getpos.all.next}}]
|
||||||
When asked for a location, the key to go to next closest interesting thing.
|
When asked for a location, the key to go to next closest interesting thing.
|
||||||
Default is `{\tt a}'.
|
Default is `{\tt a}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.all.prev}}
|
\item[{\bb{getpos.all.prev}}]
|
||||||
When asked for a location, the key to go to previous closest interesting thing.
|
When asked for a location, the key to go to previous closest interesting thing.
|
||||||
Default is `{\tt A}'.
|
Default is `{\tt A}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.door.next}}
|
\item[{\bb{getpos.door.next}}]
|
||||||
When asked for a location, the key to go to next closest door or doorway.
|
When asked for a location, the key to go to next closest door or doorway.
|
||||||
Default is `{\tt d}'.
|
Default is `{\tt d}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.door.prev}}
|
\item[{\bb{getpos.door.prev}}]
|
||||||
When asked for a location, the key to go to previous closest door or doorway.
|
When asked for a location, the key to go to previous closest door or doorway.
|
||||||
Default is `{\tt D}'.
|
Default is `{\tt D}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.help}}
|
\item[{\bb{getpos.help}}]
|
||||||
When asked for a location, the key to show help. Default is `{\tt ?}'.
|
When asked for a location, the key to show help. Default is `{\tt ?}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.mon.next}}
|
\item[{\bb{getpos.mon.next}}]
|
||||||
When asked for a location, the key to go to next closest monster.
|
When asked for a location, the key to go to next closest monster.
|
||||||
Default is `{\tt m}'.
|
Default is `{\tt m}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.mon.prev}}
|
\item[{\bb{getpos.mon.prev}}]
|
||||||
When asked for a location, the key to go to previous closest monster.
|
When asked for a location, the key to go to previous closest monster.
|
||||||
Default is `{\tt M}'.
|
Default is `{\tt M}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.obj.next}}
|
\item[{\bb{getpos.obj.next}}]
|
||||||
When asked for a location, the key to go to next closest object.
|
When asked for a location, the key to go to next closest object.
|
||||||
Default is `{\tt o}'.
|
Default is `{\tt o}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.obj.prev}}
|
\item[{\bb{getpos.obj.prev}}]
|
||||||
When asked for a location, the key to go to previous closest object.
|
When asked for a location, the key to go to previous closest object.
|
||||||
Default is `{\tt O}'.
|
Default is `{\tt O}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.menu}}
|
\item[{\bb{getpos.menu}}]
|
||||||
When asked for a location, and using one of the next or previous keys to
|
When asked for a location, and using one of the next or previous keys to
|
||||||
cycle through targets, toggle showing a menu instead. Default is `{\tt !}'.
|
cycle through targets, toggle showing a menu instead. Default is `{\tt !}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.moveskip}}
|
\item[{\bb{getpos.moveskip}}]
|
||||||
When asked for a location, and using the shifted movement keys or
|
When asked for a location, and using the shifted movement keys or
|
||||||
meta-digit keys to fast-move around, move by skipping the same glyphs
|
meta-digit keys to fast-move around, move by skipping the same glyphs
|
||||||
instead of by 8 units.
|
instead of by 8 units.
|
||||||
Default is `{\tt *}'.
|
Default is `{\tt *}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.filter}}
|
\item[{\bb{getpos.filter}}]
|
||||||
When asked for a location, change the filtering mode when using one of
|
When asked for a location, change the filtering mode when using one of
|
||||||
the next or previous keys to cycle through targets. Toggles between no
|
the next or previous keys to cycle through targets. Toggles between no
|
||||||
filtering, in view only, and in the same area only. Default is `{\tt "}'.
|
filtering, in view only, and in the same area only. Default is `{\tt "}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.pick}}
|
\item[{\bb{getpos.pick}}]
|
||||||
When asked for a location, the key to choose the location, and possibly
|
When asked for a location, the key to choose the location, and possibly
|
||||||
ask for more info. Default is `{\tt .}'.
|
ask for more info. Default is `{\tt .}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.pick.once}}
|
\item[{\bb{getpos.pick.once}}]
|
||||||
When asked for a location, the key to choose the location, and skip
|
When asked for a location, the key to choose the location, and skip
|
||||||
asking for more info. Default is `{\tt ,}'.
|
asking for more info. Default is `{\tt ,}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.pick.quick}}
|
\item[{\bb{getpos.pick.quick}}]
|
||||||
When asked for a location, the key to choose the location, skip asking
|
When asked for a location, the key to choose the location, skip asking
|
||||||
for more info, and exit the location asking loop. Default is `{\tt ;}'.
|
for more info, and exit the location asking loop. Default is `{\tt ;}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.pick.verbose}}
|
\item[{\bb{getpos.pick.verbose}}]
|
||||||
When asked for a location, the key to choose the location, and show more
|
When asked for a location, the key to choose the location, and show more
|
||||||
info without asking. Default is `{\tt :}'.
|
info without asking. Default is `{\tt :}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.self}}
|
\item[{\bb{getpos.self}}]
|
||||||
When asked for a location, the key to go to your location.
|
When asked for a location, the key to go to your location.
|
||||||
Default is `{\tt @}'.
|
Default is `{\tt @}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.unexplored.next}}
|
\item[{\bb{getpos.unexplored.next}}]
|
||||||
When asked for a location, the key to go to next closest unexplored location.
|
When asked for a location, the key to go to next closest unexplored location.
|
||||||
Default is `{\tt x}'.
|
Default is `{\tt x}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.unexplored.prev}}
|
\item[{\bb{getpos.unexplored.prev}}]
|
||||||
When asked for a location, the key to go to previous closest unexplored
|
When asked for a location, the key to go to previous closest unexplored
|
||||||
location. Default is `{\tt X}'.
|
location. Default is `{\tt X}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.valid}}
|
\item[{\bb{getpos.valid}}]
|
||||||
When asked for a location, the key to go to show valid target locations.
|
When asked for a location, the key to go to show valid target locations.
|
||||||
Default is `{\tt \$}'.
|
Default is `{\tt \$}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.valid.next}}
|
\item[{\bb{getpos.valid.next}}]
|
||||||
When asked for a location, the key to go to next closest valid location.
|
When asked for a location, the key to go to next closest valid location.
|
||||||
Default is `{\tt z}'.
|
Default is `{\tt z}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{getpos.valid.prev}}
|
\item[{\bb{getpos.valid.prev}}]
|
||||||
When asked for a location, the key to go to previous closest valid location.
|
When asked for a location, the key to go to previous closest valid location.
|
||||||
Default is `{\tt Z}'.
|
Default is `{\tt Z}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{nopickup}}
|
\item[{\bb{nopickup}}]
|
||||||
Prefix key to move without picking up items. Default is `{\tt m}'.
|
Prefix key to move without picking up items. Default is `{\tt m}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{redraw}}
|
\item[{\bb{redraw}}]
|
||||||
Key to redraw the screen. Default is `{\tt \^{}R}'.
|
Key to redraw the screen. Default is `{\tt \^{}R}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{redraw.numpad}}
|
\item[{\bb{redraw.numpad}}]
|
||||||
Key to redraw the screen. With {\it number\verb+_+pad\/} only.
|
Key to redraw the screen. With {\it number\verb+_+pad\/} only.
|
||||||
Default is `{\tt \^{}L}'.
|
Default is `{\tt \^{}L}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{repeat}}
|
\item[{\bb{repeat}}]
|
||||||
Key to repeat previous command. Default is `{\tt \^{}A}'.
|
Key to repeat previous command. Default is `{\tt \^{}A}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{reqmenu}}
|
\item[{\bb{reqmenu}}]
|
||||||
Prefix key to request menu from some commands. Default is `{\tt m}'.
|
Prefix key to request menu from some commands. Default is `{\tt m}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{run}}
|
\item[{\bb{run}}]
|
||||||
Prefix key to run towards a direction. Default is `{\tt G}'.
|
Prefix key to run towards a direction. Default is `{\tt G}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{run.nopickup}}
|
\item[{\bb{run.nopickup}}]
|
||||||
Prefix key to run towards a direction without picking up items on the way.
|
Prefix key to run towards a direction without picking up items on the way.
|
||||||
Default is `{\tt M}'.
|
Default is `{\tt M}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{run.numpad}}
|
\item[{\bb{run.numpad}}]
|
||||||
Prefix key to run towards a direction. With {\it number\verb+_+pad\/} only.
|
Prefix key to run towards a direction. With {\it number\verb+_+pad\/} only.
|
||||||
Default is `{\tt 5}'.
|
Default is `{\tt 5}'.
|
||||||
%.lp
|
%.lp
|
||||||
\item{\bb{rush}}
|
\item[{\bb{rush}}]
|
||||||
Prefix key to rush towards a direction. Default is `{\tt g}'.
|
Prefix key to rush towards a direction. Default is `{\tt g}'.
|
||||||
\elist
|
\elist
|
||||||
\elist
|
|
||||||
|
|
||||||
|
|
||||||
%.hn 2
|
%.hn 2
|
||||||
@@ -4733,6 +4735,8 @@ combination with any of the other attributes.
|
|||||||
|
|
||||||
To specify both a color and an attribute, use `\&' to combine them.
|
To specify both a color and an attribute, use `\&' to combine them.
|
||||||
To specify multiple attributes, use `+' to combine those.
|
To specify multiple attributes, use `+' to combine those.
|
||||||
|
|
||||||
|
%.lp ""
|
||||||
For example: {\tt magenta\&inverse+dim}.
|
For example: {\tt magenta\&inverse+dim}.
|
||||||
|
|
||||||
Note that the display may substitute or ignore particular attributes
|
Note that the display may substitute or ignore particular attributes
|
||||||
@@ -4785,23 +4789,19 @@ percentage or absolute number threshold, or text to match against.
|
|||||||
|
|
||||||
\blist{}
|
\blist{}
|
||||||
%.lp "*"
|
%.lp "*"
|
||||||
\item{\bb{}}
|
\item[{\tt always}] will set the default attributes for that field.
|
||||||
``{\tt always}'' will set the default attributes for that field.
|
|
||||||
%.lp "*"
|
%.lp "*"
|
||||||
\item{\bb{}}
|
\item[{\tt up} and ``{\tt down}''] set the field attributes for when the field
|
||||||
``{\tt up}'' and ``{\tt down}'' set the field attributes for when the field
|
|
||||||
value changes upwards or downwards. This attribute times out after
|
value changes upwards or downwards. This attribute times out after
|
||||||
{\tt statushilites} turns.
|
{\tt statushilites} turns.
|
||||||
%.lp "*"
|
%.lp "*"
|
||||||
\item{\bb{}}
|
\item[{\tt changed}] sets the field attribute for when the field value
|
||||||
``{\tt changed}'' sets the field attribute for when the field value
|
|
||||||
changes. This attribute times out after {\tt statushilites} turns.
|
changes. This attribute times out after {\tt statushilites} turns.
|
||||||
(If a field has both a ``changed'' rule and an ``up'' or ``down''
|
(If a field has both a ``changed'' rule and an ``up'' or ``down''
|
||||||
rule which matches a change in the field's value,
|
rule which matches a change in the field's value,
|
||||||
the ``up'' or ``down'' one takes precedence.)
|
the ``up'' or ``down'' one takes precedence.)
|
||||||
%.lp "*"
|
%.lp "*"
|
||||||
\item{\bb{}}
|
\item[{\tt percentage}] sets the field attribute when the field value
|
||||||
percentage sets the field attribute when the field value
|
|
||||||
matches the percentage.
|
matches the percentage.
|
||||||
It is specified as a number between 0 and 100, followed by `{\tt \%}'
|
It is specified as a number between 0 and 100, followed by `{\tt \%}'
|
||||||
(percent sign).
|
(percent sign).
|
||||||
@@ -4829,8 +4829,7 @@ exactly 1 experience point short of the next level.
|
|||||||
% percentage will remain at 0\% no matter have many additional experience
|
% percentage will remain at 0\% no matter have many additional experience
|
||||||
% points you earn.)
|
% points you earn.)
|
||||||
%.lp "*"
|
%.lp "*"
|
||||||
\item{\bb{}}
|
\item[{\tt absolute}] value sets the attribute when the field value
|
||||||
absolute value sets the attribute when the field value
|
|
||||||
matches that number.
|
matches that number.
|
||||||
The number must be 0 or higher, except for ``{\it armor-class\/} which
|
The number must be 0 or higher, except for ``{\it armor-class\/} which
|
||||||
allows negative values, and may optionally be preceded by `{\tt =}'.
|
allows negative values, and may optionally be preceded by `{\tt =}'.
|
||||||
@@ -4839,8 +4838,7 @@ it also matches when value is below or above.
|
|||||||
If the prefix is `{\tt <}' or `{\tt >}', only match when strictly
|
If the prefix is `{\tt <}' or `{\tt >}', only match when strictly
|
||||||
above or below.
|
above or below.
|
||||||
%.lp "*"
|
%.lp "*"
|
||||||
\item{\bb{}}
|
\item[{\tt text}] match sets the attribute when the field value matches the text.
|
||||||
text match sets the attribute when the field value matches the text.
|
|
||||||
Text matches can only be used for ``{\it alignment\/}'',
|
Text matches can only be used for ``{\it alignment\/}'',
|
||||||
``{\it carrying-capacity\/}'', ``{\it hunger\/}'', ``{\it dungeon-level\/}'',
|
``{\it carrying-capacity\/}'', ``{\it hunger\/}'', ``{\it dungeon-level\/}'',
|
||||||
and ``{\it title\/}''.
|
and ``{\it title\/}''.
|
||||||
@@ -5469,7 +5467,7 @@ with help from {\it Ross Brown}, {\it Mike Engber}, {\it David Hairston},
|
|||||||
{\it Michael Hamel}, {\it Jonathan Handler}, {\it Johnny Lee},
|
{\it Michael Hamel}, {\it Jonathan Handler}, {\it Johnny Lee},
|
||||||
{\it Tim Lennan}, {\it Rob Menke}, and {\it Andy Swanson},
|
{\it Tim Lennan}, {\it Rob Menke}, and {\it Andy Swanson},
|
||||||
developed {\it NetHack\/} 3.1 for the Macintosh, porting it for MPW.
|
developed {\it NetHack\/} 3.1 for the Macintosh, porting it for MPW.
|
||||||
Building on their development, {\it Barton House} added a Think C port.
|
Building on their development, {\it Bart House} added a Think C port.
|
||||||
|
|
||||||
%.pg
|
%.pg
|
||||||
\medskip
|
\medskip
|
||||||
@@ -5682,7 +5680,7 @@ maintained the port of {\it NetHack\/} 3.6 for Mac OSX.
|
|||||||
|
|
||||||
%.pg
|
%.pg
|
||||||
\medskip
|
\medskip
|
||||||
{\it Michael Allison}, {\it David Cohrs}, {\it Barton House},
|
{\it Michael Allison}, {\it David Cohrs}, {\it Bart House},
|
||||||
{\it Pasi Kallinen}, {\it Alex Kompel}, {\it Dion Nicolaas},
|
{\it Pasi Kallinen}, {\it Alex Kompel}, {\it Dion Nicolaas},
|
||||||
{\it Derek S. Ray} and {\it Yitzhak Sapir}
|
{\it Derek S. Ray} and {\it Yitzhak Sapir}
|
||||||
maintained the port of {\it NetHack\/} 3.6 for Microsoft Windows.
|
maintained the port of {\it NetHack\/} 3.6 for Microsoft Windows.
|
||||||
@@ -5716,6 +5714,11 @@ time of release of 3.6.1 consisted of
|
|||||||
In early May 2019, another 320 bug fixes along with some enhancements and
|
In early May 2019, another 320 bug fixes along with some enhancements and
|
||||||
the adopted curses window port, were released as 3.6.2.
|
the adopted curses window port, were released as 3.6.2.
|
||||||
|
|
||||||
|
%.pg
|
||||||
|
\medskip
|
||||||
|
{\it Bart House}, who had contributed to the game as a porting team participant
|
||||||
|
for decades, joined the {\it NetHack Development Team} in late May 2019.
|
||||||
|
|
||||||
%.pg
|
%.pg
|
||||||
\medskip
|
\medskip
|
||||||
\nd The official {\it NetHack\/} web site is maintained by {\it Ken Lorber} at
|
\nd The official {\it NetHack\/} web site is maintained by {\it Ken Lorber} at
|
||||||
@@ -5757,7 +5760,7 @@ Andreas Dorn & Jeff Bailey & Pasi Kallinen\\
|
|||||||
Andy Church & Jochen Erwied & Pat Rankin\\
|
Andy Church & Jochen Erwied & Pat Rankin\\
|
||||||
Andy Swanson & John Kallen & Patric Mueller\\
|
Andy Swanson & John Kallen & Patric Mueller\\
|
||||||
Ari Huttunen & John Rupley & Paul Winner\\
|
Ari Huttunen & John Rupley & Paul Winner\\
|
||||||
Barton House & John S. Bien & Pierre Martineau\\
|
Bart House & John S. Bien & Pierre Martineau\\
|
||||||
Benson I. Margulies & Johnny Lee & Ralf Brown\\
|
Benson I. Margulies & Johnny Lee & Ralf Brown\\
|
||||||
Bill Dyer & Jon W\{tte & Ray Chason\\
|
Bill Dyer & Jon W\{tte & Ray Chason\\
|
||||||
Boudewijn Waijers & Jonathan Handler & Richard Addison\\
|
Boudewijn Waijers & Jonathan Handler & Richard Addison\\
|
||||||
|
|||||||
@@ -21,15 +21,17 @@ extern LONG GetCurrentPackageFullName(UINT32 *packageFullNameLength,
|
|||||||
PWSTR packageFullName);
|
PWSTR packageFullName);
|
||||||
extern HRESULT SHGetKnownFolderPath(REFKNOWNFOLDERID rfid,
|
extern HRESULT SHGetKnownFolderPath(REFKNOWNFOLDERID rfid,
|
||||||
DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath);
|
DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath);
|
||||||
|
#ifndef DEFINE_KNOWN_FOLDER
|
||||||
#ifdef INITGUID
|
#ifdef INITGUID
|
||||||
#define DEFINE_KNOWN_FOLDER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID DECLSPEC_SELECTANY name = { l, w1, w2,{ b1, b2, b3, b4, b5, b6, b7, b8 } }
|
#define DEFINE_KNOWN_FOLDER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID DECLSPEC_SELECTANY name = { l, w1, w2,{ b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||||
#else
|
#else
|
||||||
#define DEFINE_KNOWN_FOLDER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID name
|
#define DEFINE_KNOWN_FOLDER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID name
|
||||||
#endif
|
#endif /* INITGUID */
|
||||||
|
#endif /* DEFINE_KNOWN_FOLDER */
|
||||||
DEFINE_KNOWN_FOLDER (FOLDERID_ProgramData, 0x62ab5d82, 0xfdc1, 0x4dc3, 0xa9, 0xdd, 0x07, 0x0d, 0x1d, 0x49, 0x5d, 0x97);
|
DEFINE_KNOWN_FOLDER (FOLDERID_ProgramData, 0x62ab5d82, 0xfdc1, 0x4dc3, 0xa9, 0xdd, 0x07, 0x0d, 0x1d, 0x49, 0x5d, 0x97);
|
||||||
DEFINE_KNOWN_FOLDER (FOLDERID_LocalAppData, 0xf1b32785, 0x6fba, 0x4fcf, 0x9d, 0x55, 0x7b, 0x8e, 0x7f, 0x15, 0x70, 0x91);
|
DEFINE_KNOWN_FOLDER (FOLDERID_LocalAppData, 0xf1b32785, 0x6fba, 0x4fcf, 0x9d, 0x55, 0x7b, 0x8e, 0x7f, 0x15, 0x70, 0x91);
|
||||||
DEFINE_KNOWN_FOLDER (FOLDERID_Profile, 0x5e6c858f, 0x0e22, 0x4760, 0x9a, 0xfe, 0xea, 0x33, 0x17, 0xb6, 0x71, 0x73);
|
DEFINE_KNOWN_FOLDER (FOLDERID_Profile, 0x5e6c858f, 0x0e22, 0x4760, 0x9a, 0xfe, 0xea, 0x33, 0x17, 0xb6, 0x71, 0x73);
|
||||||
#endif
|
#endif /* __MINGW32__ */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#include "wintty.h"
|
#include "wintty.h"
|
||||||
|
|||||||
@@ -172,12 +172,12 @@ BEGIN
|
|||||||
CONTROL "Chaotic",IDC_PLSEL_ALIGN_CHAOTIC,"Button",BS_AUTORADIOBUTTON,168,72,38,10
|
CONTROL "Chaotic",IDC_PLSEL_ALIGN_CHAOTIC,"Button",BS_AUTORADIOBUTTON,168,72,38,10
|
||||||
CONTROL "Male",IDC_PLSEL_GENDER_MALE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,168,108,30,10
|
CONTROL "Male",IDC_PLSEL_GENDER_MALE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,168,108,30,10
|
||||||
CONTROL "Female",IDC_PLSEL_GENDER_FEMALE,"Button",BS_AUTORADIOBUTTON,168,120,38,10
|
CONTROL "Female",IDC_PLSEL_GENDER_FEMALE,"Button",BS_AUTORADIOBUTTON,168,120,38,10
|
||||||
GROUPBOX "Alignment",IDC_STATIC,162,36,48,54
|
GROUPBOX "Alignment",IDC_PLSEL_ALIGNMENT_GROUP,162,36,48,54
|
||||||
GROUPBOX "Gender",IDC_STATIC,162,96,48,42
|
GROUPBOX "Gender",IDC_PLSEL_GENDER_GROUP,162,96,48,42
|
||||||
GROUPBOX "Role",IDC_STATIC,6,36,72,150
|
GROUPBOX "Role",IDC_PLSEL_ROLE_GROUP,6,36,72,150
|
||||||
GROUPBOX "Race",IDC_STATIC,84,36,72,72
|
GROUPBOX "Race",IDC_PLSEL_RACE_GROUP,84,36,72,72
|
||||||
PUSHBUTTON "Random",IDC_PLSEL_RANDOM,90,192,54,14,WS_GROUP
|
PUSHBUTTON "Random",IDC_PLSEL_RANDOM,90,192,54,14,WS_GROUP
|
||||||
GROUPBOX "Name",IDC_STATIC,6,0,120,30
|
GROUPBOX "Name",IDC_PLSEL_NAME_GROUP,6,0,120,30
|
||||||
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
|
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
|
||||||
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 "",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
|
||||||
END
|
END
|
||||||
|
|||||||
+395
-146
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
/* various dialog boxes are defined here */
|
/* various dialog boxes are defined here */
|
||||||
|
|
||||||
|
#include "win10.h"
|
||||||
#include "winMS.h"
|
#include "winMS.h"
|
||||||
#include "hack.h"
|
#include "hack.h"
|
||||||
#include "func_tab.h"
|
#include "func_tab.h"
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------*/
|
/*---------------------------------------------------------------*/
|
||||||
/* data for getlin dialog */
|
/* data for getlin dialog */
|
||||||
struct getlin_data {
|
struct getlin_data {
|
||||||
@@ -276,22 +278,68 @@ ExtCmdDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
/*---------------------------------------------------------------*/
|
/*---------------------------------------------------------------*/
|
||||||
/* player selector dialog */
|
/* player selector dialog */
|
||||||
|
|
||||||
|
/* NOTE: this enumeration is in control tab order */
|
||||||
|
enum player_selector_control {
|
||||||
|
psc_name_group,
|
||||||
|
psc_role_group,
|
||||||
|
psc_race_group,
|
||||||
|
psc_alignment_group,
|
||||||
|
psc_gender_group,
|
||||||
|
psc_name_box,
|
||||||
|
psc_role_list,
|
||||||
|
psc_race_list,
|
||||||
|
psc_lawful_button,
|
||||||
|
psc_neutral_button,
|
||||||
|
psc_chaotic_button,
|
||||||
|
psc_male_button,
|
||||||
|
psc_female_button,
|
||||||
|
psc_play_button,
|
||||||
|
psc_random_button,
|
||||||
|
psc_quit_button,
|
||||||
|
psc_control_count
|
||||||
|
};
|
||||||
|
|
||||||
|
static const s_psc_id[psc_control_count] = {
|
||||||
|
IDC_PLSEL_NAME_GROUP,
|
||||||
|
IDC_PLSEL_ROLE_GROUP,
|
||||||
|
IDC_PLSEL_RACE_GROUP,
|
||||||
|
IDC_PLSEL_ALIGNMENT_GROUP,
|
||||||
|
IDC_PLSEL_GENDER_GROUP,
|
||||||
|
IDC_PLSEL_NAME,
|
||||||
|
IDC_PLSEL_ROLE_LIST,
|
||||||
|
IDC_PLSEL_RACE_LIST,
|
||||||
|
IDC_PLSEL_ALIGN_LAWFUL,
|
||||||
|
IDC_PLSEL_ALIGN_NEUTRAL,
|
||||||
|
IDC_PLSEL_ALIGN_CHAOTIC,
|
||||||
|
IDC_PLSEL_GENDER_MALE,
|
||||||
|
IDC_PLSEL_GENDER_FEMALE,
|
||||||
|
IDOK,
|
||||||
|
IDC_PLSEL_RANDOM,
|
||||||
|
IDCANCEL
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int id;
|
||||||
|
POINT pos;
|
||||||
|
SIZE size;
|
||||||
|
HWND hWnd;
|
||||||
|
} control_t;
|
||||||
|
|
||||||
typedef struct plsel_data {
|
typedef struct plsel_data {
|
||||||
|
HWND dialog;
|
||||||
|
HWND focus;
|
||||||
|
control_t controls[psc_control_count];
|
||||||
|
SIZE client_size;
|
||||||
int config_race;
|
int config_race;
|
||||||
int config_role;
|
int config_role;
|
||||||
int config_gender;
|
int config_gender;
|
||||||
int config_alignment;
|
int config_alignment;
|
||||||
HWND control_role;
|
|
||||||
HWND control_race;
|
|
||||||
HWND control_genders[ROLE_GENDERS];
|
|
||||||
HWND control_aligns[ROLE_ALIGNS];
|
|
||||||
int role_count;
|
int role_count;
|
||||||
int race_count;
|
int race_count;
|
||||||
HWND focus;
|
|
||||||
} plsel_data_t;
|
} 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 plselAdjustSelections(HWND hWnd);
|
static void plselAdjustSelections(HWND hWnd);
|
||||||
static boolean plselRandomize(plsel_data_t * data);
|
static boolean plselRandomize(plsel_data_t * data);
|
||||||
static BOOL plselDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
static BOOL plselDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||||
@@ -322,38 +370,314 @@ mswin_player_selection_window()
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
list_view_height(HWND hWnd, int count)
|
||||||
|
{
|
||||||
|
return (ListView_ApproximateViewRect(hWnd, -1, -1, count)) >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate the size and position of the controls taking into account
|
||||||
|
the per-monitor DPI expressed as a scaling factor on sizes at 96 DPI */
|
||||||
|
void
|
||||||
|
calculate_player_selector_layout(plsel_data_t * data)
|
||||||
|
{
|
||||||
|
MonitorInfo monitorInfo;
|
||||||
|
win10_monitor_info(data->dialog, &monitorInfo);
|
||||||
|
|
||||||
|
double scale = monitorInfo.scale;
|
||||||
|
|
||||||
|
/* Note these hard coded sizes are in 96DPI pixels and must be
|
||||||
|
scaled by the per-monitor DPI scaling factor */
|
||||||
|
int list_width = (int) (120 * scale);
|
||||||
|
int group_border = (int) (16 * scale);
|
||||||
|
int client_border = (int) (16 * scale);
|
||||||
|
int group_spacing = (int) (16 * scale);
|
||||||
|
int button_width = (int) (80 * scale);
|
||||||
|
int button_height = (int) (28 * scale);
|
||||||
|
|
||||||
|
/* set control sizes */
|
||||||
|
control_t * name_box = &data->controls[psc_name_box];
|
||||||
|
name_box->size.cx = (int) (280 * scale);
|
||||||
|
name_box->size.cy = (int) (24 * scale);
|
||||||
|
|
||||||
|
control_t * role_list = &data->controls[psc_role_list];
|
||||||
|
/* NOTE: we dont' scale the list view reported height as it appears these
|
||||||
|
values are the actual size the control will be drawn at using the
|
||||||
|
existing DPI value */
|
||||||
|
role_list->size.cy = list_view_height(role_list->hWnd, data->role_count);
|
||||||
|
role_list->size.cx = list_width;
|
||||||
|
|
||||||
|
control_t * race_list = &data->controls[psc_race_list];
|
||||||
|
race_list->size.cy = list_view_height(race_list->hWnd, data->race_count);
|
||||||
|
race_list->size.cx = list_width;
|
||||||
|
|
||||||
|
for(int i = psc_lawful_button; i <= psc_quit_button; i++) {
|
||||||
|
data->controls[i].size.cx = button_width;
|
||||||
|
data->controls[i].size.cy = button_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
control_t * group_control = &data->controls[psc_name_group + i];
|
||||||
|
control_t * inner_control = &data->controls[psc_name_box + i];
|
||||||
|
group_control->size.cx = inner_control->size.cx + (2 * group_border);
|
||||||
|
group_control->size.cy = inner_control->size.cy + (2 * group_border);
|
||||||
|
}
|
||||||
|
|
||||||
|
control_t * alignment_group = &data->controls[psc_alignment_group];
|
||||||
|
alignment_group->size.cx = button_width + (2 * group_border);
|
||||||
|
alignment_group->size.cy = (3 * button_height) + (2 * group_border);
|
||||||
|
|
||||||
|
control_t * gender_group = &data->controls[psc_gender_group];
|
||||||
|
gender_group->size.cx = button_width + (2 * group_border);
|
||||||
|
gender_group->size.cy = (2 * button_height) + (2 * group_border);
|
||||||
|
|
||||||
|
/* set control positions */
|
||||||
|
control_t * name_group = &data->controls[psc_name_group];
|
||||||
|
name_group->pos.x = client_border;
|
||||||
|
name_group->pos.y = client_border;
|
||||||
|
|
||||||
|
control_t * role_group = &data->controls[psc_role_group];
|
||||||
|
role_group->pos.x = client_border;
|
||||||
|
role_group->pos.y = name_group->pos.y + name_group->size.cy + group_spacing;
|
||||||
|
|
||||||
|
control_t * race_group = &data->controls[psc_race_group];
|
||||||
|
race_group->pos.x = role_group->pos.x + role_group->size.cx + group_spacing;
|
||||||
|
race_group->pos.y = role_group->pos.y;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
control_t * group_control = &data->controls[psc_name_group + i];
|
||||||
|
control_t * inner_control = &data->controls[psc_name_box + i];
|
||||||
|
inner_control->pos.x = group_control->pos.x + group_border;
|
||||||
|
inner_control->pos.y = group_control->pos.y + group_border;
|
||||||
|
}
|
||||||
|
|
||||||
|
alignment_group->pos.x = race_group->pos.x + race_group->size.cx + group_spacing;
|
||||||
|
alignment_group->pos.y = race_group->pos.y;
|
||||||
|
|
||||||
|
for(int i = psc_lawful_button; i <= psc_chaotic_button; i++) {
|
||||||
|
data->controls[i].pos.x = alignment_group->pos.x + group_border;
|
||||||
|
data->controls[i].pos.y = alignment_group->pos.y + group_border +
|
||||||
|
((i -psc_lawful_button) * button_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
gender_group->pos.x = alignment_group->pos.x;
|
||||||
|
gender_group->pos.y = alignment_group->pos.y + alignment_group->size.cy + group_spacing;
|
||||||
|
|
||||||
|
for(int i = psc_male_button; i <= psc_female_button; i++) {
|
||||||
|
data->controls[i].pos.x = gender_group->pos.x + group_border;
|
||||||
|
data->controls[i].pos.y = gender_group->pos.y + group_border +
|
||||||
|
((i - psc_male_button) * button_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
int group_bottom = role_group->pos.y + role_group->size.cy;
|
||||||
|
if (group_bottom < race_group->pos.y + race_group->size.cy)
|
||||||
|
group_bottom = race_group->pos.y + race_group->size.cy;
|
||||||
|
if (group_bottom < gender_group->pos.y + gender_group->size.cy)
|
||||||
|
group_bottom = gender_group->pos.y + gender_group->size.cy;
|
||||||
|
|
||||||
|
control_t * play_button = &data->controls[psc_play_button];
|
||||||
|
play_button->pos.y = group_bottom + group_spacing;
|
||||||
|
play_button->pos.x = role_group->pos.x;
|
||||||
|
|
||||||
|
control_t * random_button = &data->controls[psc_random_button];
|
||||||
|
random_button->pos.y = play_button->pos.y;
|
||||||
|
random_button->pos.x = race_list->pos.x;
|
||||||
|
|
||||||
|
control_t * quit_button = &data->controls[psc_quit_button];
|
||||||
|
quit_button->pos.y = play_button->pos.y;
|
||||||
|
quit_button->pos.x = data->controls[psc_female_button].pos.x;
|
||||||
|
|
||||||
|
data->client_size.cx = alignment_group->pos.x + alignment_group->size.cx;
|
||||||
|
data->client_size.cy = quit_button->pos.y + quit_button->size.cy;
|
||||||
|
data->client_size.cx += client_border;
|
||||||
|
data->client_size.cy += client_border;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
get_rect_size(RECT * rect, SIZE * size)
|
||||||
|
{
|
||||||
|
size->cx = rect->right - rect->left + 1;
|
||||||
|
size->cy = rect->bottom - rect->top + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* center given dialog in the main window */
|
||||||
|
void
|
||||||
|
center_dialog(HWND dialog)
|
||||||
|
{
|
||||||
|
RECT main_rect;
|
||||||
|
SIZE main_size;
|
||||||
|
RECT dialog_rect;
|
||||||
|
SIZE dialog_size;
|
||||||
|
POINT pos;
|
||||||
|
|
||||||
|
GetWindowRect(GetNHApp()->hMainWnd, &main_rect);
|
||||||
|
get_rect_size(&main_rect, &main_size);
|
||||||
|
|
||||||
|
GetWindowRect(dialog, &dialog_rect);
|
||||||
|
get_rect_size(&dialog_rect, &dialog_size);
|
||||||
|
|
||||||
|
pos.x = main_rect.left + (main_size.cx - dialog_size.cx) / 2;
|
||||||
|
pos.y = main_rect.top + (main_size.cy - dialog_size.cy) / 2;
|
||||||
|
|
||||||
|
MoveWindow(dialog, pos.x, pos.y, dialog_size.cx, dialog_size.cy,
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* size the dialog such that it has the given client rect size */
|
||||||
|
void
|
||||||
|
size_dialog(HWND dialog, SIZE new_client_size)
|
||||||
|
{
|
||||||
|
RECT dialog_rect;
|
||||||
|
SIZE dialog_size;
|
||||||
|
RECT client_rect;
|
||||||
|
SIZE client_size;
|
||||||
|
|
||||||
|
GetWindowRect(dialog, &dialog_rect);
|
||||||
|
get_rect_size(&dialog_rect, &dialog_size);
|
||||||
|
|
||||||
|
GetClientRect(dialog, &client_rect);
|
||||||
|
get_rect_size(&client_rect, &client_size);
|
||||||
|
|
||||||
|
dialog_size.cx += new_client_size.cx - client_size.cx;
|
||||||
|
dialog_size.cy += new_client_size.cy - client_size.cy;
|
||||||
|
|
||||||
|
MoveWindow(dialog, dialog_rect.left, dialog_rect.top,
|
||||||
|
dialog_size.cx, dialog_size.cy, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* helper routine to move all controls according to there position
|
||||||
|
and size information */
|
||||||
|
void
|
||||||
|
move_controls(control_t * controls, int count)
|
||||||
|
{
|
||||||
|
control_t * control = controls;
|
||||||
|
while(count-- > 0) {
|
||||||
|
MoveWindow(control->hWnd, control->pos.x, control->pos.y,
|
||||||
|
control->size.cx, control->size.cy, TRUE);
|
||||||
|
control++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* adjust the size and positions of all controls in the player
|
||||||
|
selection dialog taking into account the per-monitor DPI. */
|
||||||
|
void
|
||||||
|
do_player_selector_layout(plsel_data_t * data)
|
||||||
|
{
|
||||||
|
calculate_player_selector_layout(data);
|
||||||
|
move_controls(data->controls, psc_control_count);
|
||||||
|
size_dialog(data->dialog, data->client_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize player selector dialog */
|
||||||
|
void
|
||||||
|
plselInitDialog(struct plsel_data * data)
|
||||||
|
{
|
||||||
|
TCHAR wbuf[BUFSZ];
|
||||||
|
LVCOLUMN lvcol;
|
||||||
|
|
||||||
|
SetWindowLongPtr(data->dialog, GWLP_USERDATA, (LONG_PTR) data);
|
||||||
|
|
||||||
|
for(int i = 0; i < psc_control_count; i++) {
|
||||||
|
data->controls[i].id = s_psc_id[i];
|
||||||
|
data->controls[i].hWnd = GetDlgItem(data->dialog, s_psc_id[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
control_t * role_list = &data->controls[psc_role_list];
|
||||||
|
|
||||||
|
ZeroMemory(&lvcol, sizeof(lvcol));
|
||||||
|
lvcol.mask = LVCF_WIDTH;
|
||||||
|
lvcol.cx = 1024;
|
||||||
|
|
||||||
|
/* build role list */
|
||||||
|
ListView_InsertColumn(role_list->hWnd, 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(role_list->hWnd, &lvitem) == -1) {
|
||||||
|
panic("cannot insert menu item");
|
||||||
|
}
|
||||||
|
data->role_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build race list */
|
||||||
|
control_t * race_list = &data->controls[psc_race_list];
|
||||||
|
ListView_InsertColumn(race_list->hWnd, 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(race_list->hWnd, &lvitem) == -1) {
|
||||||
|
panic("cannot insert menu item");
|
||||||
|
}
|
||||||
|
data->race_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set gender radio button state */
|
||||||
|
control_t * gender_buttons = &data->controls[psc_male_button];
|
||||||
|
for (int i = 0; i < ROLE_GENDERS; i++)
|
||||||
|
Button_Enable(gender_buttons[i].hWnd, TRUE);
|
||||||
|
|
||||||
|
Button_SetCheck(data->controls[psc_male_button].hWnd, BST_CHECKED);
|
||||||
|
|
||||||
|
/* set alignment radio button state */
|
||||||
|
control_t * alignment_buttons = &data->controls[psc_lawful_button];
|
||||||
|
for (int i = 0; i < ROLE_ALIGNS; i++)
|
||||||
|
Button_Enable(alignment_buttons[i].hWnd, TRUE);
|
||||||
|
|
||||||
|
Button_SetCheck(data->controls[psc_lawful_button].hWnd, BST_CHECKED);
|
||||||
|
|
||||||
|
/* set player name */
|
||||||
|
control_t * name_box = &data->controls[psc_name_box];
|
||||||
|
SetDlgItemText(data->dialog, name_box->id, NH_A2W(g.plname, wbuf, sizeof(wbuf)));
|
||||||
|
|
||||||
|
plselRandomize(data);
|
||||||
|
|
||||||
|
/* populate select boxes */
|
||||||
|
plselAdjustSelections(data->dialog);
|
||||||
|
|
||||||
|
/* set tab order */
|
||||||
|
control_t * control = &data->controls[psc_quit_button];
|
||||||
|
for(int i = psc_quit_button; i >= psc_name_box; i--, control++)
|
||||||
|
SetWindowPos(control->hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||||
|
|
||||||
|
do_player_selector_layout(data);
|
||||||
|
|
||||||
|
center_dialog(data->dialog);
|
||||||
|
}
|
||||||
|
|
||||||
INT_PTR CALLBACK
|
INT_PTR CALLBACK
|
||||||
PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
struct plsel_data *data;
|
plsel_data_t *data;
|
||||||
RECT main_rt, dlg_rt;
|
|
||||||
SIZE dlg_sz;
|
|
||||||
|
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
data = (struct plsel_data *) lParam;
|
|
||||||
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data);
|
|
||||||
|
|
||||||
/* center dialog in the main window */
|
data = (plsel_data_t *) lParam;
|
||||||
GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
|
data->dialog = hWnd;
|
||||||
GetWindowRect(hWnd, &dlg_rt);
|
|
||||||
dlg_sz.cx = dlg_rt.right - dlg_rt.left;
|
|
||||||
dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
|
|
||||||
|
|
||||||
dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
|
plselInitDialog(data);
|
||||||
dlg_rt.right = dlg_rt.left + dlg_sz.cx;
|
|
||||||
dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
|
|
||||||
dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
|
|
||||||
MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
|
|
||||||
(main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
|
|
||||||
dlg_sz.cy, TRUE);
|
|
||||||
|
|
||||||
/* init dialog */
|
|
||||||
plselInitDialog(hWnd);
|
|
||||||
|
|
||||||
/* tell windows to set the focus */
|
/* tell windows to set the focus */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_DRAWITEM:
|
case WM_DRAWITEM:
|
||||||
if (wParam == IDC_PLSEL_ROLE_LIST || wParam == IDC_PLSEL_RACE_LIST)
|
if (wParam == IDC_PLSEL_ROLE_LIST || wParam == IDC_PLSEL_RACE_LIST)
|
||||||
@@ -367,20 +691,23 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
data = (struct plsel_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
data = (struct plsel_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||||
|
|
||||||
|
control_t * role_control = &data->controls[psc_role_list];
|
||||||
|
control_t * race_control = &data->controls[psc_race_list];
|
||||||
|
|
||||||
switch (nmhdr->code) {
|
switch (nmhdr->code) {
|
||||||
case LVN_KEYDOWN:
|
case LVN_KEYDOWN:
|
||||||
{
|
{
|
||||||
LPNMLVKEYDOWN lpnmkeydown = (LPNMLVKEYDOWN) lParam;
|
LPNMLVKEYDOWN lpnmkeydown = (LPNMLVKEYDOWN) lParam;
|
||||||
|
|
||||||
if (lpnmkeydown->wVKey == ' ') {
|
if (lpnmkeydown->wVKey == ' ') {
|
||||||
if (control == data->control_role) {
|
if (control == role_control->hWnd) {
|
||||||
int i = ListView_GetNextItem(data->control_role, -1, LVNI_FOCUSED);
|
int i = ListView_GetNextItem(control, -1, LVNI_FOCUSED);
|
||||||
assert(i == -1 || ListView_GetNextItem(data->control_role, i, LVNI_FOCUSED) == -1);
|
assert(i == -1 || ListView_GetNextItem(control, i, LVNI_FOCUSED) == -1);
|
||||||
flags.initrole = i;
|
flags.initrole = i;
|
||||||
plselAdjustSelections(hWnd);
|
plselAdjustSelections(hWnd);
|
||||||
} else if (control == data->control_race) {
|
} else if (control == race_control->hWnd) {
|
||||||
int i = ListView_GetNextItem(data->control_race, -1, LVNI_FOCUSED);
|
int i = ListView_GetNextItem(control, -1, LVNI_FOCUSED);
|
||||||
assert(i == -1 || ListView_GetNextItem(data->control_race, i, LVNI_FOCUSED) == -1);
|
assert(i == -1 || ListView_GetNextItem(control, i, LVNI_FOCUSED) == -1);
|
||||||
if (ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM)) {
|
if (ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM)) {
|
||||||
flags.initrace = i;
|
flags.initrace = i;
|
||||||
plselAdjustSelections(hWnd);
|
plselAdjustSelections(hWnd);
|
||||||
@@ -395,10 +722,10 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
int i = lpnmitem->iItem;
|
int i = lpnmitem->iItem;
|
||||||
if (i == -1)
|
if (i == -1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (control == data->control_role) {
|
if (control == role_control->hWnd) {
|
||||||
flags.initrole = i;
|
flags.initrole = i;
|
||||||
plselAdjustSelections(hWnd);
|
plselAdjustSelections(hWnd);
|
||||||
} else if(control == data->control_race) {
|
} else if(control == race_control->hWnd) {
|
||||||
if (ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM)) {
|
if (ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM)) {
|
||||||
flags.initrace = i;
|
flags.initrace = i;
|
||||||
plselAdjustSelections(hWnd);
|
plselAdjustSelections(hWnd);
|
||||||
@@ -408,12 +735,12 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
break;
|
break;
|
||||||
case NM_KILLFOCUS:
|
case NM_KILLFOCUS:
|
||||||
{
|
{
|
||||||
if (data->focus == data->control_race) {
|
if (data->focus == race_control->hWnd) {
|
||||||
data->focus = NULL;
|
data->focus = NULL;
|
||||||
ListView_RedrawItems(data->control_race, 0, data->race_count - 1);
|
ListView_RedrawItems(race_control->hWnd, 0, data->race_count - 1);
|
||||||
} else if (data->focus == data->control_role) {
|
} else if (data->focus == role_control->hWnd) {
|
||||||
data->focus = NULL;
|
data->focus = NULL;
|
||||||
ListView_RedrawItems(data->control_role, 0, data->role_count - 1);
|
ListView_RedrawItems(role_control->hWnd, 0, data->role_count - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -421,11 +748,11 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
{
|
{
|
||||||
data->focus = control;
|
data->focus = control;
|
||||||
|
|
||||||
if (control == data->control_race) {
|
if (control == race_control->hWnd) {
|
||||||
data->focus = data->control_race;
|
data->focus = control;
|
||||||
plselAdjustSelections(hWnd);
|
plselAdjustSelections(hWnd);
|
||||||
} else if (control == data->control_role) {
|
} else if (control == role_control->hWnd) {
|
||||||
data->focus = data->control_role;
|
data->focus = control;
|
||||||
plselAdjustSelections(hWnd);
|
plselAdjustSelections(hWnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -478,109 +805,29 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_DPICHANGED:
|
||||||
|
{
|
||||||
|
data = (struct plsel_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||||
|
|
||||||
|
do_player_selector_layout(data);
|
||||||
|
|
||||||
|
InvalidateRect(hWnd, NULL, TRUE);
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize player selector dialog */
|
|
||||||
void
|
|
||||||
plselInitDialog(HWND hWnd)
|
|
||||||
{
|
|
||||||
struct plsel_data * data = (plsel_data_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
|
||||||
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 */
|
|
||||||
SetDlgItemText(hWnd, IDC_PLSEL_NAME, NH_A2W(g.plname, wbuf, sizeof(wbuf)));
|
|
||||||
|
|
||||||
plselRandomize(data);
|
|
||||||
|
|
||||||
/* populate select boxes */
|
|
||||||
plselAdjustSelections(hWnd);
|
|
||||||
|
|
||||||
/* set tab order */
|
|
||||||
SetWindowPos(GetDlgItem(hWnd, IDCANCEL), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
||||||
SetWindowPos(GetDlgItem(hWnd, IDC_PLSEL_RANDOM), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
||||||
SetWindowPos(GetDlgItem(hWnd, IDOK), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
||||||
for(int i = ROLE_GENDERS - 1; i >= 0; i--)
|
|
||||||
SetWindowPos(data->control_genders[i], NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
||||||
for(int i = ROLE_ALIGNS - 1; i >= 0; i--)
|
|
||||||
SetWindowPos(data->control_aligns[i], NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
plselAdjustSelections(HWND hWnd)
|
plselAdjustSelections(HWND hWnd)
|
||||||
{
|
{
|
||||||
struct plsel_data * data = (plsel_data_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
struct plsel_data * data = (plsel_data_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||||
|
|
||||||
|
control_t * role_control = &data->controls[psc_role_list];
|
||||||
|
control_t * race_control = &data->controls[psc_race_list];
|
||||||
|
|
||||||
if (!ok_race(flags.initrole, flags.initrace, ROLE_RANDOM, ROLE_RANDOM))
|
if (!ok_race(flags.initrole, flags.initrace, ROLE_RANDOM, ROLE_RANDOM))
|
||||||
flags.initrace = pick_race(flags.initrole, ROLE_RANDOM, ROLE_RANDOM, ROLE_RANDOM);
|
flags.initrace = pick_race(flags.initrole, ROLE_RANDOM, ROLE_RANDOM, ROLE_RANDOM);
|
||||||
|
|
||||||
@@ -590,29 +837,31 @@ plselAdjustSelections(HWND hWnd)
|
|||||||
if (!ok_align(flags.initrole, flags.initrace, flags.initgend, flags.initalign))
|
if (!ok_align(flags.initrole, flags.initrace, flags.initgend, flags.initalign))
|
||||||
flags.initalign = pick_align(flags.initrole, flags.initrace, flags.initgend , ROLE_RANDOM);
|
flags.initalign = pick_align(flags.initrole, flags.initrace, flags.initgend , ROLE_RANDOM);
|
||||||
|
|
||||||
ListView_RedrawItems(data->control_role, 0, data->role_count - 1);
|
ListView_RedrawItems(role_control->hWnd, 0, data->role_count - 1);
|
||||||
ListView_RedrawItems(data->control_race, 0, data->race_count - 1);
|
ListView_RedrawItems(race_control->hWnd, 0, data->race_count - 1);
|
||||||
|
|
||||||
/* set gender radio button state */
|
/* set gender radio button state */
|
||||||
for (int i = 0; i < ROLE_GENDERS; i++) {
|
for (int i = 0; i < ROLE_GENDERS; i++) {
|
||||||
|
HWND button = data->controls[psc_male_button+i].hWnd;
|
||||||
BOOL enable = ok_gend(flags.initrole, flags.initrace, i, flags.initalign);
|
BOOL enable = ok_gend(flags.initrole, flags.initrace, i, flags.initalign);
|
||||||
Button_Enable(data->control_genders[i], enable);
|
Button_Enable(button, enable);
|
||||||
LRESULT state = Button_GetCheck(data->control_genders[i]);
|
LRESULT state = Button_GetCheck(button);
|
||||||
if (state == BST_CHECKED && flags.initgend != i)
|
if (state == BST_CHECKED && flags.initgend != i)
|
||||||
Button_SetCheck(data->control_genders[i], BST_UNCHECKED);
|
Button_SetCheck(button, BST_UNCHECKED);
|
||||||
if (state == BST_UNCHECKED && flags.initgend == i)
|
if (state == BST_UNCHECKED && flags.initgend == i)
|
||||||
Button_SetCheck(data->control_genders[i], BST_CHECKED);
|
Button_SetCheck(button, BST_CHECKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set alignment radio button state */
|
/* set alignment radio button state */
|
||||||
for (int i = 0; i < ROLE_ALIGNS; i++) {
|
for (int i = 0; i < ROLE_ALIGNS; i++) {
|
||||||
|
HWND button = data->controls[psc_lawful_button+i].hWnd;
|
||||||
BOOL enable = ok_align(flags.initrole, flags.initrace, flags.initgend, i);
|
BOOL enable = ok_align(flags.initrole, flags.initrace, flags.initgend, i);
|
||||||
Button_Enable(data->control_aligns[i], enable);
|
Button_Enable(button, enable);
|
||||||
LRESULT state = Button_GetCheck(data->control_aligns[i]);
|
LRESULT state = Button_GetCheck(button);
|
||||||
if (state == BST_CHECKED && flags.initalign != i)
|
if (state == BST_CHECKED && flags.initalign != i)
|
||||||
Button_SetCheck(data->control_aligns[i], BST_UNCHECKED);
|
Button_SetCheck(button, BST_UNCHECKED);
|
||||||
if (state == BST_UNCHECKED && flags.initalign == i)
|
if (state == BST_UNCHECKED && flags.initalign == i)
|
||||||
Button_SetCheck(data->control_aligns[i], BST_CHECKED);
|
Button_SetCheck(button, BST_CHECKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
//{{NO_DEPENDENCIES}}
|
||||||
// Microsoft Visual C++ generated include file.
|
// Microsoft Visual C++ generated include file.
|
||||||
// Used by winhack.rc
|
// Used by NetHackW.rc
|
||||||
//
|
//
|
||||||
#define IDC_MYICON 2
|
#define IDC_MYICON 2
|
||||||
#define IDD_WINHACK_DIALOG 102
|
#define IDD_WINHACK_DIALOG 102
|
||||||
@@ -114,6 +114,11 @@
|
|||||||
#define IDC_PLSEL_ALIGN_CHAOTIC 1336
|
#define IDC_PLSEL_ALIGN_CHAOTIC 1336
|
||||||
#define IDC_PLSEL_GENDER_MALE 1337
|
#define IDC_PLSEL_GENDER_MALE 1337
|
||||||
#define IDC_PLSEL_GENDER_FEMALE 1338
|
#define IDC_PLSEL_GENDER_FEMALE 1338
|
||||||
|
#define IDC_PLSEL_NAME_GROUP 1339
|
||||||
|
#define IDC_PLSEL_ROLE_GROUP 1340
|
||||||
|
#define IDC_PLSEL_RACE_GROUP 1341
|
||||||
|
#define IDC_PLSEL_ALIGNMENT_GROUP 1342
|
||||||
|
#define IDC_PLSEL_GENDER_GROUP 1343
|
||||||
#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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp rescap">
|
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp rescap">
|
||||||
<Identity Name="30485NetHackDevTeam.NetHack3.6" Publisher="CN=8BDC628A-FAAA-4EBA-8B5B-EB61BA93BA1F" Version="363.0.19.0" />
|
<Identity Name="30485NetHackDevTeam.NetHack3.6" Publisher="CN=8BDC628A-FAAA-4EBA-8B5B-EB61BA93BA1F" Version="363.0.20.0" />
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>NetHack 3.6</DisplayName>
|
<DisplayName>NetHack 3.6</DisplayName>
|
||||||
<PublisherDisplayName>NetHack DevTeam</PublisherDisplayName>
|
<PublisherDisplayName>NetHack DevTeam</PublisherDisplayName>
|
||||||
|
|||||||
@@ -206,6 +206,18 @@
|
|||||||
<ClInclude Include="$(WinWin32Dir)mhstatus.h" />
|
<ClInclude Include="$(WinWin32Dir)mhstatus.h" />
|
||||||
<ClInclude Include="$(WinWin32Dir)mhtext.h" />
|
<ClInclude Include="$(WinWin32Dir)mhtext.h" />
|
||||||
<ClInclude Include="$(WinWin32Dir)winMS.h" />
|
<ClInclude Include="$(WinWin32Dir)winMS.h" />
|
||||||
|
<ClInclude Include="..\resource.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="..\mnsel.bmp" />
|
||||||
|
<Image Include="..\mnselcnt.bmp" />
|
||||||
|
<Image Include="..\mnunsel.bmp" />
|
||||||
|
<Image Include="..\NETHACK.ICO" />
|
||||||
|
<Image Include="..\petmark.bmp" />
|
||||||
|
<Image Include="..\pilemark.bmp" />
|
||||||
|
<Image Include="..\rip.bmp" />
|
||||||
|
<Image Include="..\splash.bmp" />
|
||||||
|
<Image Include="..\tiles.bmp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
@@ -217,4 +229,4 @@
|
|||||||
<Target Name="AfterRebuild">
|
<Target Name="AfterRebuild">
|
||||||
<MSBuild Projects="afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" />
|
<MSBuild Projects="afternethack.proj" Targets="Build" Properties="Configuration=$(Configuration)" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user