'unsigned long' isn't big enough to hold a pointer in my configuration,
and the old "only micros are sure to support %p format" is long out of
date. Just assume that everyone has %p these days, and provide a hook
to avoid it for anyone who doesn't. (Opt-out instead of opt-in.)
'heaputil' is producing a lot of complaints. This fixes one of them,
about freeing memory that was never allocated. In this case, it's
when removing an overview annotation for a level. The annotation
is using dupstr_n() and not being recorded due to dupstr_n() being
placed after MONITOR_HEAP undefines the macro that overrides alloc().
There's only one use of dupstr_n(), and its length checking isn't
needed there, so just switch to dupstr() and comment out the
implementation of dupstr_n(). I left the prototype in extern.h;
that's harmless.
If dupstr_n() needs to be resurrected, a second MONITOR_HEAP-aware
version should be implemented, with corresponding macro to choose
which one to use.
Warning about missing parantheses when mixing '+' and '?:'. It didn't
cause 'make' to quit but resulted in incorrect score-in-progress values
eing generated.
Provide a way to bypass a debugger when initiating fuzzing.
nethack -D --debug:fuzzer # run fuzzer in wizard mode
nethack --debug:fuzzer # run it in normal mode
nethack [-D] -@ --debug:fuzzer # skip role/race/&c selection
This is the first of several savefile-related changes to
follow later. This one is groundwork for those later changes.
Remove internal compression schemes (RLECOMP and ZEROCOMP)
and discard the savefile_info struct that was primarily used to
convey which internal compression schemes had been in use.
Relocate some struct definitions into appropriate header files
for use by code to come in later changes.
Remove the two struct size-related fields from version_info and
from the nmakedefs_s. Instead, include a series of bytes near the
beginning of the savefile, representing the size of each
struct or base data type that impacts the historical savefile
content. Those are referred to as the "critical bytes".
(Related note: the "you" struct required two bytes, low and high,
due to its size).
Compare those critical bytes in a savefile against the NetHack
build that is reading the savefile. This allows mismatch detection
early in the savefile-reading process, and a clean exit, rather than
proceeding to read nonsensical values from the file. Include some
feedback on what the first mismatch was when encountering
one.
For arrays stored in the savefile, use loop-logic in the core
to write/read the array elements one at a time, rather than in
a single blob. This will be required for changes to follow later.
(impacts artiexist[], artidisco[], svd.dungeons[], svl.level_info[],
svl.level.locations[][], msrooms[] field of mapseen, svb.bases[],
svb.disco[] objects[], svm.mvitals[], svs.spl_book[], svd.doors[],
go.oracle_loc[], utrack[], wgrowtime[])
This also adds data model to the long version information.
This invalidates existing save and bones files due to the changes in
the information at the start of the file.
When I reworked amnesia to not forget levels or objects, I removed
the forgetting from the mind flayer attacks. I intended to add
something to replace it, but forgot ...
Issue reported by elunna: when a room gets converted into a theme
room with fill type Garden, its walls are changed to trees but any
secret doors in those walls are still displayed as regular walls.
This adds a new D_ARBOREAL flag for secret doors, used to force them
to be displayed as a tree instead of a wall.
Fixes#1309
Grimtooth is now permanently poisoned, protects the wielder from
poison, and can be invoked to throw poison.
Permapoison code comes from xNetHack by copperwater <aosdict@gmail.com>.
Pull request from copperwater: reorganize the theme rooms data so
that a room or a fill can be chosen by name, and when in wizard mode,
consult environment variables THEMERM and THEMERMFILL during level
creation to provide control over which theme rooms/room fills to
generate.
I reverted a commit that did a bunch of reformatting to themerms.lua
because to caused substantial merge conflicts. I will redo at least
part of it.
Closes#1384
The themed room code previously assumed that on any given level, at
least one room or fill would resolve as OK to generate there. However,
that's not a great assumption to make, and if it happened to be broken,
the first themed room or fill would arbitrarily be executed, even though
it wasn't eligible. Fix that by setting the initial pick to nil, and
raising an impossible if it's still nil after trying to choose a random
room.
A common pain point I encounter when working on themed rooms is making
specific rooms generate. The only ways to do this were mass commenting
out the rooms not being tested, or hacking in different room frequency
values (even more annoying when testing a fill, not a room, or testing
pure-function rooms/fills that have no frequency).
This change solves that problem by allowing a wizard-mode user to define
THEMERM or THEMERMFILL environment variables to make specific rooms or
fills generate.
The first part of this change is converting all themed rooms and fills
that were plain functions into tables, and converting their comment
names into actual names in those tables. The names are not intended to
be shown during gameplay, but instead serve as values that THEMERM or
THEMERMFILL can be matched to to generate those rooms. It's no longer
possible to have a function themeroom; this will raise an impossible.
As far as I'm concerned, this is a good change because it allows some
code simplification of themerooms_generate and makes it easier to add
difficulty or eligibility parameters to rooms.
The second part of this change is adding a new nh.debug_themerm function
to make the environment variable values accessible to themerms.lua. I
looked for an existing way to do this but didn't see one (nh.variable
is the closest but appears to be for variables that get saved).
The final part is inserting behavior into the actual themeroom
generation code that changes how they generate when either a room or a
fill is set. I don't think it's safe to generate every single room with
the requested type or fill - that might lead to cases where the stairs
or a magic portal cannot generate. So it creates ordinary rooms half of
the time, which still results in plenty of themed rooms on levels.
Another thing to note is that any themed room using filler_region will
still only pick a fill 30% of the time. If one specifies both a fill and
a room that uses filler_region, many of those rooms will appear without
a themed fill.