The submenu of 'm O' for recently added option 'perminv_mode' didn't
have color 0 changed to NO_COLOR. On tty the entries came out blue,
on X11 they were nearly invisible. Qt and curses didn't seem to care.
I checked all the add_menu() calls in src/*.c and managed to refrain
from the impulse to reformat, mostly.
Instead of just accepting an attribute, it's now possible to
use a color, or both color and attribute, for example:
OPTIONS=menu_headings:inverse
OPTIONS=menu_headings:red
OPTIONS=menu_headings:red&underline
Default is still just inverse.
This lets the player change the menu heading color without
needing to use menu colors for them.
Also makes it so the core uses NO_COLOR instead of 0, for all
the menu lines which don't have any prefedefined color.
Tested for tty, curses, x11, qt, and win32
Confusion between 'o_status_cond' and 'pfx_cond_'. Still confusing
but I think now working as intended and expected.
If any cond_xyz option has been loaded from the RC file or changed via
'm O', #saveoptions still saves the full set rather than just the ones
that are different from their default value.
Gold on status line can be truncated, so testing the display value
might miss up/down/changed highlights. I don't think that it actually
matters since a hero cannot pick up enough gold to reach the 999999
truncation threshold.
Normal amounts still seem to highlight correctly after this.
The hitpoints and power/energy status values (and corresponding
maxima) shown on the screen are capped at 9999 to control status line
width. The actual values can be bigger than that. Highlights based
on percentages were doing their calculations on the potentially
truncated values rather than on the actual ones.
Add another field to the blstat[] structure, populate it for BL_HP,
BL_HPMAX, BL_ENE, and BL_EXEMAX and switch to it for their percentage
calculations.
Doesn't seem to break highlighting of 'normal' range values but hasn't
been tested for extreme ones.
The options menu for status hilites wouldn't work as intended if the
entries in the initblstats[] array were changed to not be in BL_xyz
order. (No effect on current behavior since they are in that order.)
If there was a status_hilite rule for hitpoints:up, it got used for
both up and down changes. If there was one for hitpoints:down, it got
ignored even if there was no 'up' rule. The flag for which direction
the value changed was always positive even when the value went down.
I'm reasonably sure that at some point HP up/down worked correctly.
This problem was present in 3.6.4; I didn't go back any farther.
If status field 'hitpoints' has rules for both 'criticalhp' and 'up'
or 'down' or 'changed', make critical-hp take precedence. Otherwise
critical-hp might never be seen because of the value changing every
move (if hero has regeneration attribute). Normally up/down/changed
take precedence over other types of highlighting.
Something is messed up with up/down/changed HP though. I'm seeing
the 'up' highlight when it goes either up or down and not seeing the
'down' highlight at all. 'up' and 'down' for gold work as expected.
This allows players to specify a highlight for critically low HP in
the config file, for example:
OPTIONS=hilite_status:hitpoints/criticalhp/purple&inverse
This will cause the hitpoints field to be highlighted when HP is low
enough to be considered a major trouble. The new "criticalhp" setting
only applies to the hitpoints field.
Since the critical HP threshold changes with level (and most of the
fractions are not integer percents) it was impossible to set
highlights to match the critical HP threshold using percentage
settings.
Replace tests against tutorial_dnum with 'In_tutorial()' predicate.
Give a message when entering the tutorial (via level change mechanism).
Likewise, give a message when resuming regular play.
If player uses #quit or ^C in the tutorial, ask whether to cut the
tutorial short and resume regular play; skip "Really quit?" if the
answer is yes. Behavior is a bit odd for ^C + yes; it just sits there
until player types something.
Reported by Noisytoot: going from level tut-1 to tut-2 returned the
hero's starting equipment too soon, and exiting the tutorial from
tut-2 let the hero keep any equipment acquired within the tutorial.
Entering and leaving the tutorial was being handled by lua code in
the level description of tut-1 and adding a second level messed that
up. I didn't see any way of handing that with level-specific lua
code so I made it become the core's responsibility. gotolevel()
knows when the hero is moving from one dungeon branch to another so
it can recognize entry to or exit from the tutorial easily.
While fixing this, prevent #invoke of the Eye of the Aethiopica from
offering the tutorial as a candidate destination (was feasible if it
had been entered at start of game).
Not fixed: levels visited in the tutorial become part of #overview.
Show location as "Tutorial:1" instead of "Dlvl:1" on status lines.
Only tested with tty; some interfaces handle location themselves and
may need their own fixup for this.
Fixes#1046
The consolidation of global variables from scattered source
files into decl.c and declared in decl.h was begun in 3.7.0.
Their placement in common files was done for centralized
initialization and potential re-initialization during a
"play again" scenario.
It wasn't really necessary for all of them to be housed in a
single huge structure to meet the "play again" requirement,
and the single huge structure has been a little unwieldy when
it comes to maintenance.
Following this commit, instead of one single extremely large structure
named 'g' to house all of the relocated global variables, they
are distributed into several ga through gz.
To make things easy for the developer, each variable is placed
into the struct corresponding to the starting letter of the variable.
That way, no lookup is required in order to know which struct houses
a particular variable, it is a simple match to the starting letter
for all the centralized global variables.
A global variable named 'amulets', would be found in ga.
ga.amulets
^ ^
A global varable named 'move', would be found in gm.
gm.moves
^ ^
A global variable named 'val_for_n_or_more' would be found in gv.
gv.val_for_n_or_more
^ ^
A global variable named 'youmonst' would be found in gy.
gy.youmonst
^ ^
Option parsing rejected
|OPTIONS=!cond_X
for all valid X.
Using the menu to unselect all condition options treated that as not
having made any choice and didn't make any changes. That would be
reasonable if nothing was preselected, but things are so unselecting
all of them is a choice. (A bizarre one, but still should be viable.)
Mostly this deals with including cond_X options when #saveoptions is
used to write a new RC file. It now produces something like
|OPTIONS=!cond_barehanded,cond_blind,!cond_busy,cond_conf,!cond_deaf,\
| cond_iron,cond_fly,cond_foodPois,!cond_glowhands,cond_grab,\
| cond_hallucinat,!cond_held,!cond_ice,cond_lava,cond_levitate,\
| !cond_paralyzed,cond_ride,!cond_sleep,cond_slime,!cond_slip,\
| cond_stone,cond_strngl,cond_stun,!cond_submerged,cond_termIll,\
| !cond_tethered,!cond_trap,!cond_unconscious,!cond_woundedlegs,\
| !cond_holding
after the last alphabetical option and before the bound keys, menu
colors, and others which aren't simple OPTIONS=X settings. This only
happens if there is already one or more OPTIONS=cond_X entries in the
old file when it was read or if 'mO' gets used to make any changes.
Not fixed: after my RC had something similar to the above and before
I changed status conditions to accept negation, I was getting several
"the cond_ option may not both have a value and be negated" messages
written to stdout instead of the config file error handler. So they
vanished when the screen was initialized without providing a --More--
prompt to acknowledge that they have been seen.
Instead of using index() macro defined to strchr, use C99 strchr.
Instead of using rindex() macro defined to strrchr, use C99 strrchr.
If you want to try building on a platform that doesn't offer those
two functions, these are available:
define NOT_C99 /* to make some non-C99 code available */
define NEED_INDEX /* to define a macro for index() */
define NEED_RINDX /* to define a macro for rindex() */
The definition of enc_stat[] got changed by a pull request nearly a
year ago ('const char *enc_stat[]' -> 'const char *const enc_stat[]')
but the separate declarations for it weren't changed to match.
Make the same change for hu_stat[]. Not sure why the pull request
didn't include it since the old declaration and the usage are same.
The curses one is in code that isn't used.
Add a #saveoptions extended command, to allow saving configuration
settings from within the game. This is still highly experimental,
and gives plenty of warnings before asking to overwrite the file.
Lack of option saving is one of the biggest complaints new players
have, so this should help with it. More experienced players with
highly customized config file should not use this feature, as it
completely rewrites the file, removing all comments and non-config
lines.
Not related to changes to 'O' but noticed because of those. The menu
for selecting which status conditions to include on the status line
starts with a special entry for sorting that shouldn't be selected by
the select all and toggle all actions.
(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
release_hold() checked for (Upolyd && sticks(g.youmonst.data)) before
checking for (u.uswallow) and it could set u.ustuck to Null while
u.uswallow remained set to 1. dmove_core() was accessing u.ustuck->mx
and u.ustuck->my after that, resulting in a crash.
This fixes that particular case but there might be others that also
assume sticky poly'd hero should be handled before swallowed hero.
Being swallowed/engulfed needs to be handled first.
Noticed earlier when testing the status_hilite_menu_fld() changes:
if you enter a duplicate rule (with different highlighting), it didn't
replace the previous one and the old rule continued to be used.
This still doesn't do replacement, but by adding the new rule at the
end of the list of rules for the specified field instead of inserting
it at the beginning, the new rule gets used.
Pull request #740 by argrath removes some redundant code. Instead
of adopting that, this rewrites the section of code in question.
The menu involved allows the user to select both "delete hilites"
and "add new hilite" but if both are selected it would only do
deletion. It also falsely claimed to have done something if delete
was chosen but no highlights were selected to be deleted. And it
only added one new highlight for the specified field when adding.
This supports both add and delete on the same menu invocation, for
addition it keeps adding until no new highlight is specified, and
has caller do the highlight updating if any changes are made.
Supersedes #740
Fix up the level descriptions used when logging an "entered new level"
event. Most of the change is for adding an extra argument to calls
to describe_level(). The curses portion is in a big chunk of old code
suppressed by #if 0.
I didn't notice that the level entry events are classified as LL_DEBUG
until all the work was done. This promotes the entry events for the
four Plane of <Element> levels from debug events to major ones instead.
It doesn't do that for the Astral Plane because the entered-the-Astral-
Plane achievement already produces a major event for that. Most other
key level entry events are in a similar situation--or will become that
way once another set of achievements eventually gets added--so there
aren't any other event classification promotions.
If you want to declare a pointer which the address pointed to is constant,
you should declare it as like `static const char *const var = "...";`.
This commit supplies missing `const` and prevents some programming
error in the future.
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.
Indent all labels one space. Having uniform placement makes spotting
them much easier. (Having no indent at all would impact the change
bars of 'git diff'. Those display the last unindented line--which
doesn't start with punctuation--occuring before each band of changes,
so usually the name of the function being changed now that we no
longer have unindented K&R-style function argument declarations.)
While in there, shorten or split various wide lines and replace a few
tabs with spaces.
Get rid of the last reference to 'g.restoring' (which managed to
unintentionally survive the change to 'g.program_state.restoring').
Also have suppress_map_output() check 'g.program_state.saving' and
switch the couple of checks against that flag to use the function.
triggered by Grayswandir's hallucination resistance. If the game
is saved while hero is hallucinating but having that be suppressed
by wielding Grayswandir, is riding, and the steed is on an object,
then during restore the hero's location will be updated because
of the presence of the object but the attempt to display the hero
there is made before u.usteed has been restored and fails.
For extended monster detection, show the number of turns remaining
during enlightenment (wizard mode only). The value is also
available via #timeout but various enlightenment entries already do
something like this.
For confuse monster, show the number of hits left for glowing hands
(again, wizard mode only).
And for the latter, the 3.7 conditional status condition set up was
storing u.umconf, an unsigned int, into contests[bl_glowhands].test,
a boolean, so would yield the wrong value if glowing hands managed
to become high enough to be a multiple of 256 (assumes 8-bit char
for boolean).