Commit Graph

192 Commits

Author SHA1 Message Date
Michael Meyer
f8ec9dc32e Fix: antigravity trap doors
Trap doors saved their destinations as an absolute level, rather than a
relative one, so if you loaded bones from a special level their
destinations would reflect the dungeon layout from the bones player's
game.  For example, die on the Oracle level, on dlvl5, with a trap door
that goes to dlvl6.  Another player gets those bones on their Oracle
level, which is dlvl8... the trap door would still go to dlvl6.  Pretty
amazing trap door -- something you might see in a funhouse!

Include relative rather than absolute destinations in save and bones
files, much like stairs do, to avoid this problem.

I bumped EDITLEVEL because although this won't break save files in an
obvious way, it will interpret the (absolute) destinations in existing
save and bones files as relative, leading to some crazy long falls. :)
2022-09-22 11:36:47 +03:00
Pasi Kallinen
a733004912 Remove the per dungeon level door limit
Number of doors in a room-and-corridor style level was fixed
at 120; now the doors-array is dynamically allocated when needed.

Breaks saves and bones.
2022-09-09 19:40:45 +03:00
nhmall
c548fff9e4 some spelling corrections
The pull request included some changes that were neither accidental nor
unintentional, so only a subset of the changes from pull request #869
submitted by klorpa were manually applied.

behaviour  -> behavior
speach     -> speech
knowlege   -> knowledge
incrments  -> increments
stethscope -> stethoscope
staiway    -> stairway
arifact    -> artifact
extracing  -> extracting

The uses of "iff" were left alone.

Close #869
2022-09-08 10:54:11 -04:00
PatR
336ecf34c3 docrt()
Replace a few more instances of calling user command doredraw()
when docrt() is meant.
2022-08-23 00:45:30 -07:00
PatR
be0def37c1 u.uswallow
Make sure u.uswallow is cleared when u.ustuck gets set to Null so
that they won't be out of sync with each other.  Having u.uswallow
be non-zero does imply that u.ustuck is non-Null.

Running #panic while swallowed didn't produce any anomalies for me,
either before or after this change.
2022-08-15 10:53:50 -07:00
Pasi Kallinen
45613ea771 Experimental #saveoptions command
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.
2022-08-05 10:33:55 +03:00
Michael Meyer
cc46da90e0 Fix #812: recovered stair dlevel
Stair dlevels weren't being restored with the correct values when
recovered after the game crashed, apparently because they weren't being
reset back to their 'absolute' level from a 'relative' level.  I'm not
totally sure of why this affected only recovered games (maybe that's the
only time when the 'relative' stair values are used?) but this fix seems
to work.

Fixes #812
2022-07-17 16:12:39 -07:00
nhmall
30b557f7d5 change xchar to other typedefs
One of the drivers of this change was that screen coordinates require a
type that can hold values greater than 127. Parameters to the window
port routines require a large type in order to be able to have values
a fair bit larger than COLNO and ROWNO passed to them, particularly for
their use to the right of the map window.

This splits the uses of xchar into 3 different situations, and adjusts
their type and size:

                        xchar
                          |
               -----------------------
               |          |          |
            coordxy     xint16     xint8

coordxy: Actual x or y coordinates for various things (moved to 16-bits).

xint16:  Same data size as coordxy, but for non-coordinate use (16-bits).

xint8:   There are only a few use cases initially, where it was very
         plain to see that the variable could remain as 8-bits, rather
         than be bumped to 16-bits.  There are probably more such cases
         that could be changed after additional review.

Note: This first changed all xchar variables to coordxy. Some were
reviewed and got changed to xint16 or xint8 when it became apparent that
their usage was not for coordinates.

This increments EDITLEVEL in patchlevel.h
2022-06-30 23:48:18 -04:00
nhmall
e2b77e51ad Revert "follow-up 4"
This reverts commit 9e38fb661d.
2022-06-30 22:36:21 -04:00
nhmall
9e38fb661d follow-up 4 2022-06-30 13:43:44 -04:00
nhmall
a518d82c54 no quotes in WINDOWPORT macro invocation 2022-06-29 22:13:28 -04:00
PatR
542ab25da1 saving/freeing ball and chain
Reported by entrez:  fix memory being accessed after having been
freed by trying to keep ball&chain data up to date when they're
processed by the save code.  This fix is a little more elaborate
than this suggested one.  I'm crossing my fingers on this one....
2022-06-11 00:08:17 -07:00
PatR
140077b163 avoid new "where are we?" panic
savelev() gets run to clean up memory even if the player quits before
level 1 is created, and a change made yesterday panicked if it couldn't
figure out what level the hero is on.  Caught by entrez, again....

If not actually writing a level's file, don't panic if both u.uz and
g.uz_save are 0.  Having one of those be non-zero is only essential
when the level being processed is the Plane of Water or Plane of Air.
2022-04-29 23:00:51 -07:00
PatR
5d56da3d32 bubble/cloud save/restore overhaul
The air bubbles on the Plane of Water and the clouds on the Plane of
Air were being saved and restored as part of the current level's state
(which is the 'u' struct and invent and such) rather than with the
current level itself.  That was ok for normal play, but for wizard
mode's ^V allowing you to return to a previously visited endgame level
after moving to a different one it meant a new set of bubbles for
Water and new set of clouds for Air.  Even that was ok since it only
applied to wizard mode, but using #wizmakemap to recreate Water or Air
while you were on it added a new set of bubbles or clouds to the
existing ones.  If repeated, eventually there wouldn't be much water
or air left.

Instead of just adding a hack to #wizmakemap, change save/restore to
keep the bubbles/clouds with the level rather than with the state.
That wasn't trivial and now I know why the old odd arrangement was
chosen.  Saving hides u.uz by zeroing it out for levels that the hero
isn't on and it is zero during restore so simple checks for whether a
given level is water or air won't work.

This also adds another non-file/non-debugpline() use of DEBUGFILES:
 DEBUGFILES=seethru nethack -D
will make water and clouds be transparent instead of opaque.  It also
makes fumaroles and other light-blocking gas clouds be transparent
which wasn't really intended, but avoiding it would be extra work that
doesn't accomplish much.

Increments EDITLEVEL for the third time this week....
2022-04-29 12:44:26 -07:00
nhkeni
1151d54500 Add and use Strlen(), like strlen() but panics on unreasonably long strings. 2022-03-16 21:42:00 -04:00
nhkeni
ff1289e828 Add Strlen(), a strlen(3) that panics if string is stupid long and returns unsigned.
First batch of changes to use it to suppress warnings.
2022-03-16 21:34:21 -04:00
PatR
ca97f4f3dd more thrown object cleanup
Handle thrown or kicked object that's in transit for hangup save and
panic save in addition to normal end of game.  Affects ball and chain
placement too, if they've been temporarily taken off the map.
2022-02-25 07:10:30 -08:00
PatR
3ea4b00879 memory management
MONITOR_HEAP+heaputil pointed out some unreleased memory.  The livelog
stuff wasn't being freed.  Not surpringly the data used for collecting
and formatting build-options that just got changed from strdup() to
dupstr() wasn't being freed.  And a couple of date/version bits.
2022-02-10 12:14:27 -08:00
nhmall
478daa0002 Merge branch 'argrath' into NetHack-3.7 2022-02-09 16:09:37 -05:00
Pasi Kallinen
1e90f89203 Chronicle of major events, and livelog
Log game events, such as entering a new dungeon level, breaking
a conduct, or killing a unique monster, in a new "Major events"
chronicle. The entries record the turn when the event happened.
The log can be viewed with #chronicle -command, and the entries
also show up in the end-of-game dump, if that is available.

This feature is on by default, but can be disabled by
defining NO_CHRONICLE compile-time option.

This also contains "live logging", writing the events as they
happen into a single livelog-file. This is mostly useful for
public servers. The livelog is off by default, and must be
compiled in with LIVELOG, and then turned on in sysconf.

Mostly this a version of livelogging from the Hardfought server,
with some changes.
2022-02-09 22:49:25 +02:00
SHIRAKATA Kentaro
128966bfe1 move null-check on savelev()
Move null-check of nhfp before its first use.
2022-02-10 01:25:13 +09:00
nhmall
560b74fabc remove some dev code
Closes #648
2022-01-10 14:18:12 -05:00
Pasi Kallinen
e5ee580961 Allocate rects dynamically
... instead of hard-coding them to 50. New allocated value is
(COLNO*ROWNO)/30, which is slightly higher (56), and that formula
seems to work for hypothetical larger maps too.
2022-01-05 17:35:33 +02:00
Pasi Kallinen
d53cd28d46 Make extended commands return defined flags
Instead of returning 0 or 1, we'll now use ECMD_OK or ECMD_TURN.
These have the same meaning as the hardcoded numbers; ECMD_TURN
means the command uses a turn.

In future, could add eg. a flag denoting "user cancelled command"
or "command failed", and should clear eg. the cmdq.

Mostly this was simply replacing return values with the defines
in the extended commands, so hopefully I didn't break anything.
2021-12-30 19:16:33 +02:00
PatR
b2d4b77d3a fix pull request #636 - the("Capitalized Monster")
Function the() wasn't supposed to be used for monsters because many
of the ones with capitalized names confuse it, but over time multiple
instances of the(mon_nam()) have crept into the code.  Instead of
ripping those out, modify the() to handle that situation better.

Pull request #636 by entrez dealt with this with one extra line of
code, but could end up scanning all the names in mons[] repeatedly
if the("Capitalized string") gets called a lot.  This uses a similar
one line fix but calls a whole new routine that scans through mons[]
once collecting all the relevant special case names.  As a bonus,
it does the same for hallucinatory monster names which name_to_mon()
couldn't handle.

Fixes #626
2021-11-24 00:24:56 -08:00
nhmall
39713783d1 some trailing whitespace in src, include 2021-10-16 12:12:21 -04:00
copperwater
f855fb5e45 Remove g.monstermoves
It's redundant with g.moves, so there is no more need for it.

Way, way back, it looks like g.moves and g.monstermoves can and did
desync, where g.moves would track the amount of moves the player had
gotten (and would therefore increase faster if the player were hasted)
and g.monstermoves would track the amount of monster move cycles, aka
turns. But this has not been the case for a long time, and they both
increment together in the same location in allmain.c. There are no
longer any cases where they will not be the same value.

This is a save-breaking change because it changes struct
instance_globals, but I have not updated the editlevel in this commit.
2021-08-28 16:22:38 -07:00
PatR
b1f3d1f864 elapsed time handling
The code has been assuming that time_t is some number of seconds.
That's valid for traditional Unix systems and for Posix compliant
systems but is not something guaranteed by the C standard.  (We ran
into a long time ago when trying out an alternate way to calculate
phase of moon.  That code made a similar assumption and broke one
of the ports.)

'ubirthday' also warrants being re-done but I've run out of energy.
2021-08-25 14:14:23 -07:00
Pasi Kallinen
7f39d53ad3 Lua: improve level testing
Add des.finalize_level() used for testing in conjunction with
des.reset_level().
Add nhc.DLB to return 0 or 1 if DLB was defined at compile-time.
Change the test_lev.lua to give more informative messages instead of
just lua error when required file doesn't exist.
Add bigrm-11 to the level tests.
2021-07-24 10:49:06 +03:00
Pasi Kallinen
491adc6a69 Mark some extended commands as no-fuzzer
... instead of checking the fuzzer being on in the commands themselves.
2021-07-08 11:35:43 +03:00
Pasi Kallinen
c019968997 Clear all room data
Restoring a level cleared residence pointer from those subrooms
which were in the restored level, but if the previous level had
more subrooms, those pointers weren't cleared.
This caused weird problems when a shopkeeper data was looked
up based on the subroom number.

Just to be safe, clear all the room data when freeing the level.
2021-06-26 15:10:43 +03:00
nhmall
f963c5aca7 switch source tree from k&r to c99 2021-01-26 21:06:16 -05:00
nhmall
0c3b9642e4 pmnames mons gender naming plus a window port interface change
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.
2020-12-26 11:23:23 -05:00
nhmall
f543763695 stairway save/restore bit
The logic surrounding stairway saves and restores should not be within
a block reserved for deliminating external file structure.
2020-12-03 10:05:31 -05:00
Pasi Kallinen
cf88808285 Fix stairs on oracle level bones
Recent change to the stairs structure now lets each stair keep
the destination level number and dungeon where the stairs go to.

When a level that can be on different depth (such as the Oracle)
became a bones level, and it was loaded in another game at different
depth, the stairs were still pointing to the old level number.

Save it as relative to the current level instead of absolute.
2020-12-03 16:38:20 +02:00
PatR
5e570b181f saving followup
If attempting to checkpoint when changing levels discovered that
the alock.0 or 123wizard.0 file was missing and the game was
running in wizard mode, play continued after reporting trickery
but screen updating was left disabled.  An early return in
savegamestateinlock() wasn't resetting the program_state.saving
flag to revert to normal screen updates.

I added a few return statements at the ends of void routines,
where they're optional, because it makes searching for early
returns easier.  (Without these then when no early return is
present between current point and end of routine, the search
would move past the routine looking for 'return' later in the
file.)

save_stairs() was placed in between saveobj() and saveobjchn()
so I've moved it.  (Has no effect on the recently reported stair
anomalies.)  It was also accumulating the total stairway data
size in 'len' and never using that for anything, so I got rid
of it.  (Ditto about anomalies.)
2020-12-02 14:49:09 -08:00
PatR
4d6a140d34 saving vs ball&chain
I started activating new program_state.saving and discovered that
saving of ball and chain could access freed memory.  The change
for the former and fix for the latter are mixed together here (but
easily distinguishable).

The saving flag inhibits status updating and perm_invent updating,
also map updating that goes through flush_screen().  That should
fix the exception triggered after an impossible warning was issued
during a save operation.  impossible() goes through pline() which
tries to bring the screen up to date before issuing a message.
During save, data for that update can be in an inconsistent state.

The code to save ball and/or chain when not on floor or in invent
(I think swallowed is the only expected case) was examining the
memory pointed to by uball and uchain even if saving the level had
just freed floor objects and saving invent had just freed carried
objects.  So for the usual cases, stale pointer values for uball
and uchain would be present and checking their obj->where field
was not reliable.
2020-12-02 06:29:58 -08:00
Pasi Kallinen
6ec55a3624 Rework stairs structure
Use a linked list to store stair and ladder information, instead
of having fixed up/down stairs/ladders and a single "special" (branch)
stair.

Breaks saves and bones.

Adds information to migrating objects and monsters for the dungeon
and level where they are migrating from.
2020-11-13 20:27:17 +02:00
Adam Powers
03e9eb6dd6 fix NO_SIGNAL 2020-10-19 13:21:07 -07:00
nhmall
ac9ba38449 file header bump from "NetHack 3.6" to "NetHack 3.7" 2020-08-03 22:07:36 -04:00
nhmall
5a437b336a remove SYSFLAGS and MFLOPPY code
A check into github issue 364 confirmed that
ba6edbe5dc
had incorrectly updated the bwrite sizeof entry for sysflags.

The SYSFLAGS and MFLOPPY code is all in the outdated part of the tree, so just
remove it rather than re-correct it.

Closes #364
Closes #207
2020-07-05 08:50:13 -04:00
PatR
298331fe04 improved regexp handling
If regex_compile() fails, free the regexp before doing anything else
in case failure reason is "out of memory".  Feedback to the user is
highly likely to panic or crash after memory runs out; this should
let the regex failure message be issued and the game continue.

User sound regular expressions were never freed.  This frees them
when FREE_ALL_MEMORY is enabled.
2020-05-23 12:51:01 -07:00
PatR
a51e44e532 move lua context out of dungeons[]
and out of save files so restore doesn't need to clear stale data.
Behavior should be the same as before, except that when entering
the endgame branch and discarding the main dungeon and its other
branches, lua theme context is now discarded for those too.
2020-05-05 18:06:00 -07:00
PatR
e63fed627c obj->oextra->{omid,olong}
Change obj->oextra->omid from a usually-Null pointer field in
oextra to a simple 'unsigned' that doesn't need any allocation
beyond obj->oextra itself.  Value 0 means that it is not in use;
it is used to hold a monst.m_id and those are always non-zero.

Delete unused obj->oextra->olong.  'olong' used to be the last
field in struct obj, put there to force alignment of anything
which followed it back when obj structures were over-allocated to
append extra information.  It had a comment about being used for
temporary gold but whatever that was, temporary gold was gone long
before obj->oextra got introduced.

Bump EDITLEVEL since this invalidates existing 3.7 save files.

Remove a bunch of tabs from obj.h and save.c.
2020-04-24 09:29:52 -07:00
Pasi Kallinen
9b74ea0b22 Shaped and themed rooms
Allows creating shaped or themed rooms for the Dungeons of Doom
via lua script.

Invalidates bones and saves.

Makefiles updated for unix/linux by adding themerms.lua, but other
OSes need to have that added.
2020-04-18 19:55:09 +03:00
PatR
a2338e92aa groundwork: u.uinwater manipulation
Toggle u.uinwater on or off in just one place.
2020-04-03 01:04:27 -07:00
PatR
3981e3e6e5 controlling u.ustuck
Setting or clearing u.ustuck now requires that context.botl be set,
so make a new routine to take care of both instead of manipulating
that pointer directly.
2020-02-16 13:04:12 -08:00
nhmall
a213811975 stone/unexplored glyph follow-up
typo
2020-02-13 17:37:55 -05:00
nhmall
d37fa196b2 make a distinction between rock and unexplored area
This adds a pair of new glyphs: GLYPH_UNEXPLORED and GLYPH_NOTHING

GLYPH_UNEXPLORED is meant to be the glyph for areas of the map that
haven't been explored yet.

GLYPH_NOTHING is a glyph that represents that which cannot be seen,
for instance the dark part of a room when the dark_room option is
not set.  Since the symbol for stone can now be overridden to
a players choice, it no longer made sense using S_stone for the
dark areas of the room with dark_room off. This allows the same
intended result even if S_stone symbol is mapped to something visible.

GLYPH_UNEXPLORED is what areas of the map get initialized to now
instead of STONE.

This adds a pair of new symbols: S_unexplored and S_nothing.

S_nothing is meant to be left as an unseen character (space) in
order to achieve the intended effect on the display.

S_unexplored is the symbol that is mapped to GLYPH_UNEXPLORED, and
is a distinct symbol from S_stone, even if they are set to the same
character. They don't have to be set to the same character.

Hopefully there are minimal bugs, but it is a deviation from a
fairly long-standing approach so there could be some unintended
glitches that will need repair.
2020-02-08 00:48:03 -05:00
nhmall
1dfab5fe11 remove an argument that is no longer necessary from a few functions
Passing a boolean 'ghostly' argument to some functions that are also passed
an NHFILE * is unnecessary now.
2020-02-02 22:54:44 -05:00