Pull request from argrath nearly a year ago: an 'if' and corresponding
'else' have the same code so there's no point in testing for if/else.
I'm still not convinced that simply removing the if/else is the right
fix here but nothing else is going on. I've put part of the removed
code back inside '#if 0' in case it needs to be resurrected someday.
Closes#628
(user-side decisions really, but as it stands right now
user-side decisions/options are made and processed by the core)
add a parameter to add_menu so color can be passed
There are no longer distinct gendered versions of monsters, so femalenum
is unused (i.e. set to NON_PM) for all roles and races. Take a pass at
removing all uses of/references to femalenum, and rename 'malenum' to
'mnum' since it no longer has any particular association with
gender or sex.
further adjustments to the window port interface to pass a pointer
to a glyph_info struct which describes not just the glyph number
itself, but also the ttychar, the color, the glyphflags, and the
symset index.
This affects two existing window port calls that get passed glyphs
and does the parameter consistently for both of them using the
glyph_info struct pointer:
print_glyph()
add_menu().
The recently added glyphmod parameter is now unnecessary and has been
removed.
add MALE, FEMALE, and gender-neutral names for individual monster species
to the mons array. The gender-neutral name (NEUTRAL) is mandatory, the
MALE and FEMALE versions are not.
replace code uses of the mname field of permonst with one of the three
potentially-available gender-specific names.
consolidate some separate mons entries that differed only by species into a
single mons entry (caveman, cavewoman and priest,priestess etc.)
consolidate several "* lord" and "* queen/* king" monst entries into
their single species, and allow both genders on some where it makes some
sense (there is probably more work and cleanup to come out of this at some
point, and the chosen gender-neutral name variations are not cast in stone
if someone has better suggestions).
related function or macro additions:
pmname(pm, gender) to get the gender variation of the permonst name. It
guards against monsters that haven't got anything except NEUTRAL naming
and falls back to the NEUTRAL version if FEMALE and MALE versions are
missing.
Ugender to obtain the current hero gender.
Mgender(mtmp) to obtain the gender of a monster
While the code can safely refer directly to pmnames[NEUTRAL] safely in the
code because it always exists, the other two (pmnames[MALE] and
pmnames[FEMALE] may not exist so use:
pmname(ptr, gidx)
where -ptr is a permonst *
-gidx is an index into the pmnames array field of the
permonst struct
pmname() checks for a valid index and checks for null-pointers for
pmnames[MALE] and pmnames[FEMALE], and will fall back to pmnames[NEUTRAL] if
the pointer requested if the requested variation is unavailable, or if the
gidx is out-of-range.
Allow code to specify makemon flags to request female or male (via MM_MALE
and MM_FEMALE flags respectively)to makedefs, since the species alone doesn't
distinguish male/female anymore. Specifying MM_MALE or MM_FEMALE won't
override the pm M2_MALE and M2_FEMALE flags on a mons[] entry.
male and female tiles have been added to win/share/monsters.txt.
The majority are duplicated placeholders except for those that were
separate mons entries before. Perhaps someone will contribute artwork in the
future to make the male and female variations visually distinguishable.
tilemapping via has the MALE tile indexes in the glyph2tile[]
array produced at build time. If a window port has information that the
FEMALE tile is required, it just has to increment the index returned
from the glyph2tile[] array by 1.
statues already preserved gender of the monster through STATUE_FEMALE
and STATUE_MALE, so ensure that pmnames takes that into consideration.
I expect some refinement will be required after broad play-testing puts it to
the test.
consolidate caveman,cavewoman and priest,priestess monst.c entries etc
This commit will require a bump of editlevel in patchlevel.h because it alters
the index numbers of the monsters due to the consolidation of some. Those
index numbers are saved in some other structures, even though the mons[] array
itself is not part of the savefile.
Window Port Interface Change
Also add a parameter to print_glyph to convey additional information beyond
the glyph to the window ports. Every single window port was calling back to
mapglyph for the information anyway, so just included it in the interface and
produce the information right in the display core.
The mapglyph() function uses will be eliminated, although there are still some
in the code yet to be dealt with.
win32, tty, x11, Qt, msdos window ports have all had adjustments done to
utilize the new parameter instead of calling mapglyph, but some of those
window ports have not been thoroughly tested since the changes.
Interface change additional info:
print_glyph(window, x, y, glyph, bkglyph, *glyphmod)
-- Print the glyph at (x,y) on the given window. Glyphs are
integers at the interface, mapped to whatever the window-
port wants (symbol, font, color, attributes, ...there's
a 1-1 map between glyphs and distinct things on the map).
-- bkglyph is a background glyph for potential use by some
graphical or tiled environments to allow the depiction
to fall against a background consistent with the grid
around x,y. If bkglyph is NO_GLYPH, then the parameter
should be ignored (do nothing with it).
-- glyphmod provides extended information about the glyph
that window ports can use to enhance the display in
various ways.
unsigned int glyphmod[NUM_GLYPHMOD]
where:
glyphmod[GM_TTYCHAR] is the text characters associated
with the original NetHack display.
glyphmod[GM_FLAGS] are the special flags that denote
additional information that window
ports can use.
glyphmod[GM_COLOR] is the text character
color associated with the original
NetHack display.
Support for including the glyphmod info in the display glyph buffer
alongside the glyph itself was added and is the default operation.
That can be turned off by defining UNBUFFERED_GLYPHMOD at compile time.
With UNBUFFERED_GLYPHMOD operation, a call will be placed to map_glyphmod()
immediately prior to every print_glyph() call.
Fix for $USER, $LOGNAME, getlogin() values that have dashes in them:
keep dash and whatever follows as part of the name instead of stripping
it off for role/race/gender/alignment.
Before:
% USER=test-bar-fem ./nethack
|Shall I pick your female Barbarian's race and alignment for you?
and character ended up named 'test'.
After:
% USER=test-bar-fem ./nethack
|Shall I pick character's race, role, gender and alignment for you?
and character ends up named 'test-bar-fem'. However,
% ./nethack -u test-bar-fem
still behaves like the 'before' case.
|Shall I pick your female Barbarian's race and alignment for you?
Dash handling is only changed when the dash comes from user name (or
from envionment overriding user name), not from direct player input
or run-time config file.
Role selection is insanely complex. I had to use a debugger to force
the relevant routine to be executed.
The analysis was correct: it could use rn2(14) to pick a role (valid
values 0 through 12) and randomly getting 13 would lead to a crash.
The terminating element of roles[] passes all the ok_role(), ok_race(),
etc tests. Explicitly exclude that element when collecting the roles
to choose from.
pick_role() had a 5 year old copy+paste error where a pair of lines
were cloned multiple times but one of the resulting lines didn't get
the intended revision, preventing OPTIONS=align:!chaotic or !neutral
or !lawful from working as intended when letting the game choose role
randomly. The bad line should have been calling ok_align() but that
routine turned out to have a bug too.
Fixing those lead to other less obvious problems with role selection,
particularly the tty menu version for picking manually. Roles and/or
races which should have been excluded by partial specification weren't
always kept out. Also, if any filtering was specified, trying to
disable all filters (via choosing 'reset filtering' and de-selecting
everything in the menu) was a no-op. Once any filtering was in place
you had to leave at least one role or race or gender or alignment
flagged as not acceptable in order to change any of the filtering.
When that was fixed and it was possible to turn off all filtering,
there was no way to turn it back on because the menu choice to reset
the filters wasn't offered unless there was some filtering in place
(that was intentional but turned out not to be a good idea).
I checked curses and X11; they both offer less versatile selection
capability that don't seem to need the tty-specific fixes.
Assume a degenerate RNG that always returns the same number.
With these fixes, the game starts and is almost playable.
There are still some places that will go into infinite loop, eg.
the mines level generation.
groundwork only - window port interface change
This changes the last parameter for add_menu() from a boolean
to an unsigned int, to allow additional itemflags in future
beyond just the "preselected" that the original boolean offered.
There shouldn't be any functionality changes with this groundwork-only
change, and if there are it is unintentional and should be reported.
Developed for 3.6 but deferred to 3.7. Most of the testing was with
the earlier incarnation.
Report was that pronouns were accurate for the underlying monsters
when hallucination was describing something random, and also that the
gender prefix flag from bogusmon.txt wasn't being used. The latter
is still the case, but pronouns are now chosen at random while under
the influence of hallucination. One of the choices is plural and an
attempt is made to make the monster name and verb fit that usage.
|The homunculus picks up a wand of speed monster.
|The large cats zap themselves with a wand of speed monster!
|The blue dragon is suddenly moving faster.
There is no attempt to match gender for the singular cases; you might
get
|The succubus zaps himself [...]
or
|The incubus zaps herself [...]
With 3.7+ aspirations of improving savefile interoperability between 32-bit
and 64-bit builds, as well as between platforms, it is better to not have
the underlying struct/array content be conditional.
This splits off some of the MAIL code into MAIL_STRUCTURES code. In theory,
since MAIL_STRUCTURES is unconditionally included, the macro could
just go away and leave that code unconditional, but this commit doesn't
go that far.
The new code provoked several warnings; this fixes one of them.
Moving the declaration of 'rolecount' would have been sufficient,
but I've gone another way.
Take a first step towards making the mons[] array be readonly.
The only other place that updates it is when changing succubus and
incubus AD_SSEX attacks to AD_SEDU ones and that can be handled
via existing getmattk(), but so far has proven to be trickier than
anticipated.
Back out '#include "date.h"' so that cursinit.c won't be recompiled
every time any other file(s) need to be compiled. It doesn't need
patchlevel.h either. There is already a straightforward way to fetch
the copyright banner lines from version.c.
The splash screen (ascii art spelling "NetHack" preceding the normal
copyright lines) was invisible when showing white text on white-ish
background. Make it honor !guicolor.
"Shall I pick a character's role, race, gender and alignment for you?
[ynaq] (y) " was too wide to accept the answer on the same line on
an 80-column display so "(y) " was placed on the second line. That's
constructed in the core; change the construction to omit " a" when
using "character" rather than a role name. (tty shortens it by omitting
the default " (y)"; with " a" gone, it could revert to normal prompt.)
Also a bit of lint cleanup and some reformatting of cursinit.c....
Clean up quite a bit of minor things found with simple grep patterns:
operator at end of continued line instead of beginning of continuation
(and a few comments which produced false matches, so that they won't
do so next time), trailing spaces (only one or two of those), tabs (a
dozen or so of those), several casts which didn't have a space between
the type and the expression (I wasn't systematic about finding these).
I think the only code change was in the function for the help command.
Due to the new player selection dialog I did, it was possible
to rename your character - but this didn't rename the lock files
and tried to load a save from the wrong name.
This is a bit of a hack, but seems to work and didn't seem to
cause problems for the tty.
For OPTIONS=role:Valk,race:!human,align:!lawful (where first+second
contradicts third or vice versa), you'd get
Shall I pick your Dwarven Valkyrie's for you?
where the what-to-pick field names are empty. Now, align:!lawful
gets overridden, producing
Shall I pick your Dwarven Valkyrie's alignment for you?
and then you'll end up lawful regardless of whether you answer yes
or no. That may be suboptimal but does emphasize that the original
alignment constraint couldn't be honored. (Things just fell out
that way and I haven't tried to make it behave any other way.)
While testing the fix, I noticed that OPTIONS=role:Valk,race:random
prompted
Shall I pick your Valkyrie's race and alignment for you?
instead of honoring 'race:random' without asking, so I've tried to
fix that too.
Role selection has become insanely complex, so one or the other of
these fixes has probably broken some other permuation of partial
specification. Both of the changes here have been done in the core
without touching any interface-specific role selection code.
Report states that using OSX Xcode IDE results in use of 'clang
Modules', whatever those are, and role.c's 'filter' struct ends up
conflicting with a function declared by <curses.h> (or possibly
<ncurses.h> since one includes the other). src/role.c does not
include <curses.h>, so this smacks of the problems caused by using
precompiled headers on pre-OSX Mac.
Instead of trying to import nethack into Xcode, I temporarily
inserted '#include <curses.h>' at the end of unixconf.h. gcc did
complain about 'filter' in role.c (but not in invent.c, despite
-Wshadow), and then complained about termcap.c using TRUE when it
wasn't defined (after in had been #undef'd, where there's a comment
stating that it won't be used in the rest of that file), and also
complained about static function winch() in wintty.c conflicting
with external winch() in curses.
This renames 'filter' and 'winch()' to things that won't conflict.
Also, our winch() is a signal handler but had the wrong signature
for one. And the troublesome use of TRUE was in code that was
supposed to be dealing with int rather than boolean.
Instead of just using 'random' as the default choice if the user hits
<return> when picking role, race, gender, or alignment, flag it as
pre-selected in the menu so that it can be seen to be the default.
Someday somebody is going to have to fix up the interaction between
PICK_ONE menu and pre-selected choice....
Like the just fixed naming for discoveries list, there are several
other add_menu() calls which specify <space> instead of 0 as a useless
selector on separator lines. These others are all for role selection,
where menus don't get big enough to need next-page.
I don't know what I was thinking at the time, although it must have
seemed like a good idea for some reason....
Change "Shall I pick your priest/priestess' race, gender, ..." prompt
to "... priest/priestess's ...".
Unfortunately that makes it long enough to push the cursor onto the
next line for basic 80 column display. If caveman/cavewoman's wasn't
already longer I think I would have left the clumsier phrasing/spelling.
Honor things like OPTIONS:role=!tourist and NETHACKOPTIONS='race=!orc'
when performing interactive role selection. I don't think it was
completely correct when players let the program choose, but it must
have been close enough because we haven't gotten any complaints.
The post-3.4.3 interactive selection was ignoring options-base filtering
entirely and did get complaints for the pre-beta.
Role selection has a ton of code which bloats the program without doing
anything useful for actual game play. It ought to be split off into a
separate front end.
I'll push a formatting guide at some point. There may still be
outstanding changes, but please feel free to resolve those as you arrive
a them.
To the best of my knowledge, there is no changes to the actual code
content, but the formatter does have the occasional bug. If you run into
an issue, please fix it!