Redo the recent artifact creation stuff by replacing several nearly
identical routines with one more general one. Also adds a tracking
bit for one or two more creation methods. That changed artiexist[]
from an array of structs holding 8 or less bits to one holding 9, so
bump EDITLEVEL in case the total size changed.
Since the struct used for elements of artiexist[] has a lot of unused
bits, add some new ones to extend it to indicate how artifacts have
been created. It had
| .exists (has been created) and
| .found (hero is aware that it has been created)
introduce
| .gift (divine gift),
| .wish (player wish),
| .named (naming elven weapon Sting or Orcrist)
| .viadip (made Excalibur by dipping long sword into fountain)
| .rndm (randomly created), and
| .bones (from bones file--how it got created in earlier game isn't
tracked). The first four are implemented, fifth and sixth aren't.
Some of the feedback when receiving an artifact or spellbook has been
revised.
When artiexist[] was changed from an array of booleans to an array of
structs a couple of days ago, EDITLEVEL should have been incremented
but I overlooked that at the time. This commit does so now.
The change to report which item was acquired in the logged event for
Sokoban completion changed the context struct so changed the contents
of save files but neglected to update EDITLEVEL to reject old save
files. Do so now.
In the name of accessibility: Prevent moving into dangerous liquids.
Now with themed rooms, water and lava are more common, and it's
unreasonable to expect blind players to check every step for those.
With paranoid:swim, just prevent normal walking into those liquids,
unless you prefix the movement with 'm', or if the liquid would not
harm you.
Doesn't completely prevent an accidental dunking - for example
if the hero is impaired or couldn't see the liquid.
This comes from xNetHack by copperwater <aosdict@gmail.com>
with some changes to the code.
The livelog message for losing a level had an off-by-1 error, showing
the level the hero ended up at rather than the level that was lost.
There was a message for regaining a previously lost level when rank
title stayed the same but no such message if the title changed (the
achievement of gaining a particular title only occurs once).
Say "regained" rather than "gained" when gaining a previously lost
level. (Blessed potions of full healing regain levels but can also
reduce u.ulevelmax so a different way to remember peak experience
level has been added.)
Report level change due to polymorphing into new man/woman/elf/&c.
I hadn't realized that that hasn't been recording achievement for new
rank when applicable and decided to leave things that way.
Report gender change when putting on an amulet of change or becoming
a new man/&c unless hero is polymorphed at the time or experience
level is also changing.
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.
'moves' is actually turns and there hasn't been any straightforward
way to track actual hero moves. Add hero_seq for that. It isn't a
counter but is distinct each time the hero makes a move. I wanted
it for curses ^P support but so far use it for checking stethoscope
usage and for shopkeeper behavior when items in a shop are broken by
the hero.
Increment EDITLEVEL due to change in save file contents.
Keep track of the highest value that u.uhpmax and u.uenmax have
attained, in new u.uhppeak and u.uenpeak. They aren't used for
anything yet. u.mhmax (max HP while polymorphed) isn't interesting
enough to track.
Not save and bones compatible so increments EDITLEVEL.
Globs never rotted away but did become tainted after a relatively
short while, which seemed like a contradiction. Change them to never
be tainted but shrink by 1 unit of weight approximately every 25
turns. An ordinary glob (one that hasn't combined with any others)
starts out weighing 20 units, so it takes about 500 turns to vanish.
That's roughly twice as long as a corpse takes to rot away.
Shrinking globs give feedback when in hero's invent or in a container
in hero's inventory, but rarely (when going from an exact multiple
of 20 weight units; that is, from integral number of N globs to
N-1 + 19/20, or if weight reduction triggers an encumbrance change).
When a glob goes away completely, there is feedback for those two
circumstances and also for seeing the glob vanish from the floor.
I haven't touched how much nutrition eating a glob confers. I have
changed formatting of glob names to use "small", "medium", "large",
"very large" instead of "small", [no adjective], "large", &c. You
still need to have at least five globs coalesced together for the
adjective to become "medium", same amount as before.
I don't think EDITLEVEL needs to be modified but have incremented it
anyway to play things safe.
Reported by eakaye. Selection of equipment when creating a soldier
or watchperson can pick a polearm, but random selection among those
had a chance to choose dwarvish mattock which doesn't use polearms
skill and isn't appropriate for a human soldier or watchperson.
Not mentioned, but lance was in the same boat.
Change the selection to only pick something which uses polearms
skill, then make that moot by moving lance and dwarvish mattock out
of the midst of the polearms so that they're no longer candidates
for special case rejection.
A couple of other things which might have had a similar issue were
already ok. Giving a polearm when creating a troll selects between
a few choices rather than among all the polearms. And wishing for
"polearm" only considers items which use polearms skill.
While changing objects.h to reorder the two non-polearms, I removed
a bunch of tabs that were present in the scroll definitions.
EDITLEVEL is incremented due to objects[] reordering, so existing
save and bones files will be invalidated.
Fixes#623
triggering an impossible warning about "wall_angle: unknown" due
to the known conflict between door state and wall info which both
overlay the flags field for map locations.
Reported and diagnosed by vultur-cadens: if a shop's wall was dug
open, followed by use of locking magic to plug the gap with a door,
and then unlocking that door, the D_CLOSED door flag was left as
invalid wall_info when shop damage was repaired. Map re-display
complained. Leaving the door locked or opening it after unlocking
did not result in any complaint because the values for those door
states do not conflict with wall angle values.
The problem was reproducible and is now fixed by adding an extra
field to the shop damage structure. A similar change has been
made to the vault guard's 'fake corridor' structure but I have no
test case for that so don't know whether it makes any difference.
At least it doesn't seem to have broken anything.
Existing save and bones files are invalidated by the fixes.
Fixes#606
When using a menu to drop or put in items into a container,
allow putting in the item (or items) you picked up previously,
by selecting the 'P' entry from the item class menu
Inspired by the itemcat patch by Stanislav Traykov.
Invalidates saves and bones.
Save files from before the 'disambiguate WHACK' patch were not
necessarily compatible with ones after it, leading to potential
restore problems.
Comments in objclass.h (from before the patch) suggested that
inappropriate assumptions were being made about field layout.
This deliberately introduces new incompatibility and increments
EDITLEVEL to caused earlier save and bones files to be thrown
away.
Fixes#587
This evolves and hopefully eases the game-build requirements by
removing game-compile dependencies on any header files generated
by the makedefs utility, including:
date.h dependency and its inclusion is removed and comparable functionality
is produced at runtime via new file src/date.c.
pm.h dependency and its inclusion is removed and comparable functionality is
produced by moving the monster definitions from monst.c into new header
file called monsters.h and altering them slightly. The former pm.h header
file #define PM_ values are now replaced with appropriate emitted enum
entries during the compiler preprocessing.
onames.h dependency and its inclusion is removed and comparable functionality
is produced by moving the object definitions from objects.c into new header
file called objects.h and altering them slightly. The former onames.h header
file #define values are now replaced with appropriate emitted enum entries
during the compiler preprocessing.
artilist.h has been slightly altered, and the former onames.h artifact-related
header file #define ART_ values are now replaced with appropriate emitted enum
entries during the compiler preprocessing.
makedefs can still produce date.h (makedefs -v), pm.h (makedefs -p), and
onames.h (makedefs -o) for reference purposes. They won't be used during
the compiler.
The other uses for makedefs remain. They are used to prepare external
file content that the game utilizes, not prerequisite code for the
compile:
makedefs -d (database)
makedefs -r (rumors)
makedefs -h (oracles)
makedefs -s (epitaphs, engravings, bogusmons)
date.c
Pull the code for date/time stamping from mdlib.c into date.c.
Set date.o to be dependent on source files, header files, and .o files
so that date.o is rebuilt from date.c when any of those changes, thus
ensuring an accurate date/time stamp. It also includes git sha
functionality formerly done by makedefs writing #define directives
into include/date.h. For unix it passes the git info on
the compile line for date.c (via sys/unix/hints/linux.2020, macOS.2020)
nethack --dumpenums (optional, but on by default)
Allow developer to obtain some internal enum values from NetHack
without having to resort to an external utility such as
makedefs.
Uncomment #define NODUMPENUMS in config.h to disable this.
The updates to sys/windows/Makefile.gcc have not been tested yet.
Add two new monsters and two new objects:
gold dragon
baby gold dragon
gold dragon scale mail
set of gold dragon scales
A couple of variants seem to have added these already, but this came
off my ancient list of monsters to add and was done from scratch.
It's a clone of silver dragon, but instead of having reflection and
breathing cold, a gold dragon emits light and breathes fire; because
of the latter it can be seen with infravision like a red dragon.
Adult gold dragons are lawful as in the AD&D Monster Manual rather
than chaotic as the wiki pages show for the variant versions.
Worn gold dragon scales operate similar to wielded Sunsword: when
blessed, radius is 3 (same as a lamp), if uncursed, radius is 2, and
if cursed, radius is 1 (but functions as 2 when worn by the hero,
otherwise there would be no tangible effect). Gold dragon scale mail
gets an extra +1, making blessed gold DSM have a bigger radius than
lamps. Embedded scales have radius 1 regardless of BUC state; light
for that case comes from the gold dragon monster form the hero is in.
When not worn, gold scales and scale-mail don't emit any light.
The tiles use a mix of yellow (for gold) and red. The two object
tiles seem reasonable variations of the corresponding silver dragon
ones. The two monster tiles definitely need work since the silver
ones were mostly cyan and changing that to red did not produce very
good result; subsequent attempt at a mixture was haphazard at best.
Allow killing your quest leader, just to make games winnable if you
converted before doing the quest.
Boost the quest leaders and give them some equipment. King Arthur
gets Excalibur. Killing quest leader gives really bad luck and
makes your god angry at you, and killing quest guardians gives
smaller penalties.
This is based on both the EvilHack implementation by
k21971 <keith.simpson1971@gmail.com>, and xNetHack
implementation by copperwater <aosdict@gmail.com>.
If monsters see you resist something, generally elemental or magical
attack, or if they see you reflect an attack, they learn that and
will adjust their attack accordingly.
Originally from SporkHack, but this version comes via EvilHack with
some minor changes.
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.
The pull request changed \ and ` output to unconditionally show
discoveries in alphabetical order. That's nearly useless except
when looking at prediscovered weapons and armor that fighter
types start out knowing.
This allows the player to choose sorting order via the new
'sortdiscoveries' option. In addition to setting it via
config file or 'O', it can be set via 'm' prefix for \ and `.
Choices are:
o - sort by class, by order of discovery in class (default);
s - sort by 'sortloot' classification which groups sub-class
items (so all helmets before any other armor, then all
gloves, then boots, and so on); within each sub-class, or
whole class for classes which don't subdivide so usefully,
partly-discovered types (where a name has been assigned)
come before fully ID'd types;
c - sort by class, alphabetically within class;
a - sort alphabetically across all classes.
Turned out to be a large amount of work for fairly little gain,
although I suspect that 'sortdiscoveries:s' will eventually be
more popular than the default.
Invalidates existing save files so that current sort setting can
persist across save/restore cycles.
Closes#334
If we ever want huge maps with COLNO or ROWNO larger than signed char,
this will at least allow the game to compile and start when typedef'ing
xchar to int. Trying to use huge maps exposes more bugs.
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.
Track sokoban cheating (taking actions that incur a luck penalty).
The pull request only reported the number of times (possibly zero)
that the player broke nethack's sokoban rules when reporting the
"you obtained the Sokoban prize" achievement, which is when the
count is most meaningful, but this implements it as a full-fledged
conduct instead. This way the #conduct command can be used after
"creative nethacking" to check immediately whether an action has
violated the Sokoban rules so a player willing to put in a bit of
effort can eventually learn which actions have a negative impact.
The new conduct is only shown during games where the character has
entered the Sokoban branch, but once that has happened it gets shown
no matter the location at the time of #conduct or end of game.
Most of this wasn't in the pull request: expanding the Guidebook to
give more information about sokoban and its conduct.
Bump EDITLEVEL to invalidate to-be-3.7 save files because u.uconduct
has been extended.
Fixes#355
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.
Replace the octagonal amulet placeholder for the two new tiles.
Give the "cubical amulet" a hint of being cube shaped and rename
"pentagonal amulet" to "perforated amulet" because it's easier to
draw that way.
Bump EDITLEVEL now for the extra objects and monsters because I
forgot to do so earlier.
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.
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.
Introduce eight achievements that can be attained by more players.
Entered Gnomish Mines - self explanatory
Entered Mine Town - the town portion, not just the level
Entered a shop - any tended shop on any level
Entered a temple - likewise for temple
Consulted the Oracle - bought at least one major or minor oracle
Read a Discworld Novel - read at least one passage
Entered Sokoban - like mines
Entered the Big Room - not always possible since not always present
The novel and bigroom ones aren't always achieveable since novels are
only guaranteed if a book or scroll shop gets created and bigroom is
only guaranteed in wizard mode. No one ever claimed that every
possible achievement can be attained in a single game. (If one for
entering the Fort Ludios level--or perhaps entering the Fort itself--
eventually gets add, that won't be possible in every game either.)
The mine town one probably needs some tweaking. Two of the town's
seven variants have no town boundary (despite a rectangular area of
pre-defined map) and at present simply arriving on either of those
levels is enough to be credited with the entered-town achievement.
Bump EDITLEVEL because u.uachieved[] has increased in size. This
time it has been expanded to the maximum that xlogfile's bitmask of
achievements can handle, enough for up to 9 more achievements without
another EDITLEVEL increment.
Instead of an assortment of bits, assign numeric indices to the
potential achievements and keep an array of those in the order they
were attained. So disclosure might show the same subset occurring
differently in different games depending on the player's actions.
The encoded field in xlogfile doesn't care about that and remains
the same.
Modifies 'struct u', so EDITLEVEL has been incremented and existing
save files are invalidated.