Insert the calls to trigger a number of potential soundeffects
into the core.
If no additional soundlib support is integrated into the
build, then the Soundeffect macro (sndprocs.h) expands to nothing:
[#define Soundeffect(seid, vol)
]
If, however, at least one additional soundlib support is integrated
into the build, then the Soundeffect macro gets defined as this
in sndprocs.h:
[#define Soundeffect(seid, vol) \
do { \
if (!Deaf && soundprocs.sound_soundeffect \
&& ((soundprocs.sndcap & SNDCAP_SOUNDEFFECTS) != 0)) \
(*soundprocs.sound_soundeffect)(emptystr, (seid), (vol)); \
} while(0)
]
That macro definition checks for the hero not being Deaf; it checks
to ensure that the active soundlib interface has a non-null
sound_soundeffect() function pointer; and it checks to ensure
that the active soundlib interface has declared that it supports
soundeffects by setting the SNDCAP_SOUNDEFFECTS bit in its sndcap
entry. That just means that the interface routines are prepared to
accept and deal with the calls from the core, whether or not it
actually produces the desired soundeffect.
A number of C compiler suites have a math.h library that includes a yn()
function name that conflicts with NetHack's yn() macro:
"The y0(), y1(), and yn() functions are Bessel functions of the second kind,
for orders 0, 1, and n, respectively. The argument x must be positive. The
argument n should be greater than or equal to zero. If n is less than zero,
there will be a negative exponent in the result."
At one point, isaac64.h included math.h, although that has since been removed.
Some libraries used in NetHack (Qt for one) do include math.h and that required
build work-arounds to avoid the conflict.
Rename the NetHack macro from yn() to y_n() and avoid the math.h conflict
altogether, eliminating the need for that particular work-around.
Pull request from Vivit-R was to change feedback when offering on a
neutral altar from "your sacrifice is consumed in a cloud of smoke"
to "... in a puff of smoke". There were multiple comments, some
agreeing and some disagreeing but no better alternatives offered.
I'm ambivalent to whether any alteration was needed, but think "puff"
sounds rather passive. I looked at a lot of synonyms and considered
"veil of smoke" and "haze of smoke" and even "puff of vapor", but
finally settled on "plume of smoke". It isn't something that appears
and is gone in an instant like the lawful flash of light and chaotic
burst of flame, but I think it is more interesting than cloud or puff.
The PR's commit hasn't been used since 100% of its content is being
superseded.
Closes#609
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
^ ^
If paranoid_confirm settings include praying, don't put the answer
to "are you sure you want to pray?" into the do-again buffer where ^A
would use it to ignore confirmation if prayer is repeated. And for
wizard mode, when confirmation is 'y' then the answer to "force the
gods to be pleased?" has to be suppressed from the do-again buffer too
or it would be used by subsequent ^A to answer "are you sure?".
This is basically a band-aid just for #pray. There are probably other
confirmations that should be suppressed from do-again instead of being
reusable. The rest of the paranoid_confirm ones should be ok because
they require "yes" and that doesn't end up in the do-again buffer, but
there are bound to be other confirmations that shouldn't automatically
be re-used during repetition.
Short for distu(mtmp->mx, mtmp->my) (i.e. the distance between the hero
and the specified monster), which is a very common use of distu(). The
idea is that this would be a convenient shorthand for it; I actually
thought it (or something very similar) existed already, but couldn't
find it when I tried to use it earlier. Based on the number of uses of
fully-spelled-out 'distu(mtmp->mx, mtmp->my)' replaced in this commit
I'm guessing I just imagined it.
Wizard-mode command to cast any spell without checks that would
prevent casting, and with no energy use.
Mainly to allow the fuzzer to exercise the spell code paths.
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
High altars and normal temple altars had identical altarmasks, so
there was no way to distinguish between the two based on the altarmask
alone. Instead, anywhere it was necessary to determine whether an altar
was a high altar included a check whether the hero was currently the
Astral Plane or Moloch's Sanctum, and assumed any temple altar was the
high altar.
Since there's an extra, unused bit in altarmask anyway, use it to
explicitly mark high altars -- the lua level files already distinguish
between normal temple altars and so-called 'sanctum' altars anyway, so
rather than throwing away this distinction when generating the level,
keep it in the altarmask and use it in place of various u.uz checks.
I think this would require incrementing EDITLEVEL again...
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.
This should have been broken up into multiple pieces but they're
all lumped together. I did ultimately throw away a fourth change.
Implement artiexist[].bones and artiexist[].rndm artifact creation
tracking bits that were added recently. Doesn't need to increment
EDITLEVEL this time.
Add a new wizard mode feature: if you use `a to show discovered
artifacts, it will prompt about whether to show the tracking bits
for all artifacts instead. If not using menustyle traditional,
you need at least one artifact to have been discovered in order to
have 'a' choice available when selecting what class of discovered
objects to show for the '`' command.
artifact_gift(), aritfact_wish(), and so forth return a value that
none of the existing callers use, so cast their calls to (void).
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.
Remove the conduct-specific aspect of receiving spells as prayer boon.
Anyone now has a 25% chance of having the spell directly implanted
into their head, not just characters who have maintained illiterate
conduct. It can now also restore a forgotten spell or refresh one
that is nearly forgotten. It still tries to choose a spell which
isn't already known (new: or was known but has been forgotten) but if
it picks one that is known and doesn't need refreshing, a redundant
book will be given, same as the behavior in earlier versions.
The chance for receiving a blank spellbook is higher when that item
is undiscovered. When given as a prayer reward, make it become
discovered even if hero doesn't read it so that it will be less likely
to be given again. There's a 1% chance for that auto-discovery to
happen with other bestowed books. Unlike blank boots, having the book
be discovered doesn't lessen their chance of being repeat gifts.
Minor bug fix: for a spell implanted from scratch, the book remains
unknown. That's ok; it's actually more interesting than discovering
a book you haven't seen yet. But after acquiring and reading the book
you could get "you know <spell> quite well already" and the book would
stay undiscovered even though you were just told what spell it's for.
Lay groundwork for generating a log event when finding an artifact
on the floor or carried by a monster. This part should not produce
any change in behavior.
Move g.artidisco[] and g.artiexist[] out of the instance_globals
struct back to local within artifact.c. They are both initialized
at the start of a game (and only used in that file) so don't need
to be part of any bulk reinitialization if restart-instead-of-exit
ever gets implemented.
Convert artiexist[] from an array of booleans to an array of structs
containing a pair of bitfields. artiexist[].exists is a direct
replacement for the boolean; artiexist[].found is new but not put to
any significant use yet. If will be used to suppress the future
found-an-artifact event for cases where a more specific event (like
crowning or divine gift as #offer reward) is already produced.
Remove g.via_naming altogether and add an extra argument to oname()
calls to replace it.
Add an extra argument to artifact_exists() calls.
There is an event for being crowned "Hand of Elebereth" and so forth
and an event for being given an artifact (any, not just the first) as
reward for #offer, but there wasn't one for the item usually given
along with being crowned.
Now there is. It's not something that an observer (of the events
being logged) can deduce since sometimes an alternative is given
(wizard and monk) and other times nothing is given (artifact already
exists or lawful character isn't wielding non-artifact long sword).
I flagged the spellbook given to a wizard or a monk as
'divinegift | artifact | spoiler'. 'artifact' since even though it
isn't actually an artifact, it is standing in the place for one. And
'spoiler', to hide from #chronicle, in case the hero doesn't know the
spellbook yet.
Make gods avoid giving blank spellbooks as gifts, if you're
illiterate. But if you do get a blank spellbook as a gift,
don't force-learn that non-existent spell.
Use up the last available bit for achievements:
"You learned the tune to open and close the castle's drawbridge."
(More can still be added but xlogfile will need another field to
track a second set of 31 in order to keep its achievement bitmask(s)
within portable size.)
As achievements go, it's not very exciting, but players who normally
destroy the drawbridge have to choose whether to earn an achievement
first since once it's gone, there's no way to find out the tune
(either via prayer reward or successful Mastermind). I'm guessing
that most will probably decide to ignore this achievement since it
has no effect on the outcome of the game. However, that might not
be true for future tournament play.
There's no need to bump EDITLEVEL for this; room for recording one
additional achievement is already allocated.
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.
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.
Always give a message when creating a detected monster
during gameplay (as opposed to during level creation).
To prevent the message, use the MM_NOMSG flag for makemon.
Most places already handled their own messaging, but there
were some, such as bag of tricks, create monster magic
and random monsters created during gameplay that didn't.
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.
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.
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.
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.
This is a security fix, intended to avoid a DoS attack (that has
been used in practice against public servers) in which a situation
is created in which the same short loop of commands can be run
over and over indefinitely; this causes a lot of CPU usage on the
public server as it simulates the game turns, and requires hardly
any network or CPU usage for an attacker.
Once the turn counter goes above 100000, the average prayer timeout
increases by 1 for every additional 100 turns spent. Thus, even
with a ring of slow digestion, nutrition prayers will no longer
be possible after turn 2 million or so. This is unlikely to have
any noticeable effect on any strategy that does not rely heavily
on prayer for nutrition; even in an implausible 200000-turn game,
prayer timeout will only be increased by 1000 or so, which should
be easily manageable for a character that powerful.
Same race corpses, deceased pet corpses, wraith corpses, and unicorn
corpses could be sacrificed even when otherwise too old. This
prevents that for wraith and unicorn corpses but leaves the same
race and dead pet cases as is. I'm not sure that this is the right
way to resolve things but at least has the virute of being simple.
This also lets chaotics get the trivial bonus for sacrificing a
wraith corpse even though alignment matches. Alignment doesn't
matter for anything else (except unicorns) and giving up a wraith
corpse that isn't too old to eat is a tangible sacrifice. Unless
the hero is vegetarian (or the supersets vegan and foodless) since
giving up a corpse that won't be eaten isn't worthy of a bonus.
(It will still retain regular sacrifice value in that situation.)
Fixes#304
From a reddit thread, praying on the altar in orctown behaved like an
ordinary prayer directed at Moloch rather than being an exceptional
event. Make it always be rejected. The penalty is very trivial.
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.
Recently added "you hear an invisible choir chant in Latin ..." is
jarring. Unfortunately, something like "in an archaic language" would
make the message too long so just take out "in Latin".
Also a few reformatting bits for pray.c.