Commit Graph

403 Commits

Author SHA1 Message Date
nhmall
de79240dea some comment spelling fixes 2023-03-16 22:27:01 -04:00
nhmall
288cc01f3a Merge branch 'naming-overflow-fix2' into NetHack-3.7 2023-02-16 18:52:47 -05:00
Pasi Kallinen
7401b44fa1 Walls of lava
Add "walls of lava", basically lava which blocks vision and
require a bit more than just levitation or flight to move through.

No levels use this yet, as testing isn't thorough enough.
2023-02-06 19:23:42 +02:00
Pasi Kallinen
d3430bed9f Prevent certain items from random erosion
Prevent wished for items (unless specified), artifacts,
armor and weapons of NPC heroes, and ammo from Longbow of Diana
being generated eroded.
2023-02-05 16:46:54 +02:00
Pasi Kallinen
e1b01a5d7c Fix segfault when farlooking monster under generic object
A detected cave spider was hiding under a generic spellbook object;
farlooking at it produced a segfault.  OBJ_NAME is null for the generic
objects, so don't try to strcmp it.
2023-02-04 17:48:57 +02:00
PatR
b9bbf0205b Pending 3.7 edition of the naming overflow patch.
Like the 3.6.7 one, the original pieces have been combined into one
commit.  But it is separate from the one added to that version.
2023-01-28 13:02:46 -08:00
PatR
8952ea9bb5 add Japanese item names to discoveries list
When playing as a Samurai, add things like "osaku" to the discoveries
list even though they don't have separate descriptions to be used
when not yet discovered.  Non-magic ones are pre-discovered and
players can now use the '\' command to figure out what things like
"tanko" mean without resorting to '/?'.

"wooden harp" has been getting changed to "koto (harp)"; make that be
| koto [wooden harp] (koto)
"magic harp" has been staying as "magic harp (harp)"; add it to the
list of Japanese item names.  Since it's magic it isn't pre-discovered.
Once discovered it becomes
| magic koto [magic harp] (koto)

Those two needed special case handling, none of the other items did
aside from forcing them to be discoverable when lacking descriptions.
The discoveries list now has things like
| wakizashi [short sword]
| naginata [glaive] (single-edged polearm)
| gunyoki [food ration]
if--and only if--the hero is a Samurai.
2023-01-18 22:00:57 -08:00
PatR
97a90de172 another static analyzer bit - Japanese_item_name()
The analyzer complained that the second call to Japanese_item_name()
might return Null after the first one didn't.
|    if (Role_if(PM_SAMURAI) && Japanese_item_name(otyp))
|        actualnm = Japanese_item_name(otyp);
even though the code involved is self-contained and deterministic.
Then later in obj_typename() 'actualnm' gets passed to strcat() or
strcpy() where Null isn't acceptable.

Could probably fix that by caching and reusing the first return value:
|    if (Role_if(PM_SAMURAI) && (jname = Japanese_item_name(otyp)) != 0)
|        actualnm = jname;
but I went a different route, revising that routine to take a second
argument:
|    if (Role_if(PM_SAMURAI))
|        actualnm = Japanese_item_name(otyp, actualnm);
It now passes back 'actualnm' instead of Null when no substitution
takes place.

The recent introduction of generic objects without names meant that
'actualnm' could actually be Null, but generic objects only occur
for map glyphs and only when dknown is 0, so the actual-name field
shouldn't ever be get used for them.  Give actualnm a fallback value
just in case.

Wishing is a place that loops over all of objects[] so have it skip
the generic objects.  They're all flagged no-wish so weren't being
chosen, but explicitly skipping them makes the intention clear.
2023-01-13 23:41:23 -08:00
nhmall
ba5356603a yn()
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.
2023-01-12 16:04:40 -05:00
PatR
ddd358aa03 miscellaneous objects[] macros
Replace FIRST_GEM and LAST_GEM with FIRST_REAL_GEM, LAST_REAL_GEM,
FIRST_GLASS_GEM, and LAST_GLASS_GEM and define those along with
objects[] rather than separately.  Do the latter for FIRST_AMULET
and LAST_AMULET too.  Also new FIRST_SPELL and LAST_SPELL used to
compute MAXSPELLS.  (That value looks wrong to me, but this defines
it with the same value as before.  If it gets fixed, EDITLEVEL will
need to be incremented.)

This started as just proof of concept that extra information could
be collected as objects[] gets initialized at compile time.
2022-12-28 01:50:24 -08:00
PatR
daeec9291c refine PR #946 - named armor
Move the new stuff from PR #946 out of xname() into new routine
armor_simple_name().

Noticed while testing:  tweak 'call object type' so that it doesn't
list instances of pre-discovered armor as likely candidates since
assigning a name to such wasn't showing up in the discoveries list.

Add "silver shield" as wishing synonym for "polished silver shield".
2022-12-14 07:37:04 -08:00
Michael Meyer
eff2cba10d Use foo_simple_name for armor types in xname
This will distinguish between a hat and a helmet, shoes and boots, etc,
so that a "conical hat" doesn't turn into a "helmet called dunce" after
type-naming it, and so on.  Instead, more specific names will be used
for the base type, consistent with the terms used in various messages
(so "a hat called dunce").

Some of these don't seem like necessary distinctions to make, and some
of them probably don't make a difference at all (e.g. gloves vs
gauntlets, since "gauntlets" only shows up once you've IDed the item so
the user-assigned typename isn't visible), but it probably makes sense
to be consistent in using these functions if it's done for any armor
type.
2022-12-14 05:49:05 -08:00
nhmall
02a48aa8cf split g into multiple structures
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
     ^ ^
2022-11-29 21:53:21 -05:00
PatR
223818ff41 github issue #934 - hearing unseem mon read scroll
Issue reported by Melon2007:  when non-deaf hero heard an unseen
monster read a scroll, the monster's type was identified accurately
(unless distorted by hallucination).  That was intentional but it
doesn't seem plausible for the hero's hearing to be that acute.
Change it to report the monster type accurately if not hallucinating
and monster is the same species as the hero (as the current form if
hero is poly'd), otherwise report it as "someone" when it's humanoid,
otherwise as "something".

Also, if the monster is heard at a spot that would be visible if
hero could see, draw a "remembered, unseen monster" glyph there.

Fixes #934
2022-11-28 01:44:19 -08:00
nhmall
cf897d9293 prefix some macro names 2022-11-03 16:50:25 -04:00
nhmall
99a93fe50b some C99 changes
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() */
2022-10-29 10:54:25 -04:00
PatR
8509951291 rename "huge chunk of meat" to "enormous meatball"
Pull request #607 by Vivit-R proposed renaming "huge chunk of meat"
to "giant meatball" to better reflect the similarity to meatball.
But an object name that contains a monster name prefix requires extra
work in the wishing code.  I considered "huge meatball" which retains
more of the original name but decided to go with "enormous meatball"
becaues it seems more evocative.

Supersedes #607
Closes #607
2022-09-27 13:32:51 -07:00
PatR
aa8f73c890 empty horn of plenty
Format a horn of plenty whose charge count is unknown but is known to
be empty as "empty horn of plenty" like is done for real containers.

This was too easy; I must have missed something....
2022-09-15 14:14:12 -07:00
Pasi Kallinen
601dba5279 Make glorkums emit impossible 2022-09-04 17:43:06 +03:00
Patric Mueller
14007e9483 lit candles generated by wishing could have wrong light radius
begin_burn() was called before the quantity of wished lit candles was
restricted which meant that the light source radius could depend on a
larger quantity than the final object actually had.
2022-08-26 21:54:56 +02:00
PatR
32636099ce wizmgender fix
The 'wizmgender' option is flagged as 'wizonly' in optlist.h but that
doesn't prevent it from being set in NETHACKOPTIONS or .nethackrc.
Apply the fix from entrez to only honor it when running in wizard
mode.
2022-07-14 16:29:08 -07:00
Michael Meyer
1ee9e6ae3d wizmgender: include corpstat gender in object name
Add another use to wizmgender: when it is enabled, include the gender
specified in corpstat flags in the name of a statue, corpse, or
figurine, since it can influence various things but otherwise remains
invisible (for monsters without gendered names).  A little while ago
lichen corpses weren't stacking because, despite being a neuter monster,
the corpses they produced were being flagged as female or male; this
could be useful for debugging issues along those lines.
2022-07-03 16:34:29 -07:00
nhmall
3004cf2d34 be more consistent with coordinates 2022-07-02 09:10:03 -04: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
PatR
d1d0f1103c artifact name formatting bit
All the quest artifacts are named "The <something> of <someone>".
Change xname() to force "the" instead of "The" when that occurs in
the middle of "a skeleton key named The Master Key of Thievery" or
"a pair of lenses named The Eyes of the Overworld".

This change isn't applied to user-assigned names; they're used as-is.
2022-06-06 16:15:07 -07:00
Michael Meyer
092e8c37fd Fix: wished-for doors in wizmode always vertical
Wishing for a door is intended to retain the existing 'horizontal' value
of the surrounding wall or door (see comment in the wizterrainwish
'door' case).  However, the field was being reset by mistake, causing
all door wishes to create vertical doors.  Preserve it as intended.
2022-06-03 15:17:03 -04:00
PatR
cc2332946e fix #K3608 - glob quantity
Wishing for "N <size> globs [of pudding type]" produces 1 glob
starting at <size> and then multiples weight by N (so possibly
increasing <size>).  When not it wizard mode, N can be replaced by
a random amount to prevent the total weight from being huge.  When
N was less than 6, it was possible for that random amount to be
larger than what the player asked for.

Change the way the random amount is calculated so that it won't
ever be larger than what player specified.  Also for wizard mode
prompt whether to make the substitution so that the player can
choose to abide by the limit or to obtain a huge glob for whatever
testing is being conducted.
2022-06-02 13:02:45 -07:00
nhmall
7b506c715c Merge branch 'NetHack-3.7' of https://rodney.nethack.org:20040/git/NHsource into NetHack-3.7 2022-05-21 21:22:42 -04:00
nhmall
68d7ef440f follow-up (from entrez) 2022-05-21 21:22:20 -04:00
PatR
15882c5bee wizard mode wishing bit
I meant to wish for a "wand of cold" and accidentally typed "wand of
ice".  Instead of being told that there's no such thing or receiving
a random wand, the spot I was standing on was changed to ice.

Only check for a terrain-change wish if an object class hasn't been
stripped from the wish text.
2022-05-21 15:19:48 -07:00
nhmall
35b56fb94b incorporate the later force push on pr767 2022-05-20 19:45:07 -04:00
Michael Meyer
0c0262eab0 Handle -eaux plurals in makeplural/makesingular
I noticed a comment about -eau pluralizing as -eaux, e.g. "gateau" ->
"gateaux", was not consistent with the actual output of makeplural.
Same thing with "VAX" -> "VAXen" in the line below it; they're very old
comments, so maybe they were originally meant to point out some plurals
makeplural got wrong?  Since they predate the addition of "oxen" and
"geese" to one_off[] (and the array itself), it seems like the other
special cases mentioned in the comments would also have been wrong at
the time they were written.

Address this horrifying pastry-related oversight by adding handling for
'-eaux' plurals to makeplural, with an exception for 'bureau' (plural
'bureaus'; according to the dictionary, 'bureaux' is an acceptable
variant but 'bureaus' is more common, at least in American English).
There's also an exception for 'Bordeaux' (as in a bottle of the wine),
since the singular and plural are the same.

A bit surprised this wasn't already in there, since 'gateau' is a real
food item and seems like a much more likely fruit name than some of the
inedible items makeplural has special rules for.

Also add " au " to compounds[] in singplur_compound, so that 'gateau au
chocolat' will pluralize correctly to 'gateaux au chocolat'.  Without
that change, the result is 'gateau au chocolats'.
2022-05-20 17:37:02 -04:00
PatR
9f1b738d1d recharging
Make "recharging" and "scroll of recharging" be aliases for "scroll
of charging" when wishing.

I thought this had been put in place years ago.
2022-05-11 22:11:42 -07:00
PatR
a31dd26d8a minor trapped container changes
When probing a trapped container, report that it is trapped.
Done with a one-line message in the zap code and also in the title
of the contents display if it isn't empty.

For wizard mode wishing, if both "trapped" and "broken" are specified,
produce an untrapped container with a broken lock.

Also for wizard mode wishing, ignore "trapped" if player wishes for
"trapped secret door".
2022-05-06 13:27:11 -07:00
PatR
ea15bc05ec formatting attached ball and chain
When punished, the ball gets formatted as
| heavy iron ball (chained to you)
but the chain was just "iron chain".  Since iron golems leave some
of those behind, doname() shouldn't just assume that you know which
chain is locked to your leg.  Change the formatting for uchain to
| iron chain (attached to you)
2022-04-09 11:45:43 -07:00
PatR
d52e6732a8 fix github issue #722 - unique monster's corpse
Issue #722 posted by copperwater and commented on by Entrez:  both
shk_your() and the() inserted "the" in front of a unique monster's
corpse, yielding "the Lord Surtur's corpse glows iridescently" and
"the Lord Surtur's corpse drops to the floor."

Teach both of those routines to skip "the" when used for monsters
with personal names.  It now omits "the" for "Medusa's corpse" but
still gives "the Oracle's corpse".

shk_your() operates on an object and can deal explicitly with corpses
of named monsters.  the() operates on text and has to guess whether
it is being used in a similar situation.  Right now the guess is just
"is there an apostrophe present?" and might need further refinement.

Fixes #722
2022-04-09 10:15:34 -07:00
PatR
81a4c2ed4c aligned cleric corpse
I was looking into "The Lord Surtur's corpse" and got side-tracked by
something else:  move a priest hack for avoiding "aligned" in a corpse
description from corpse_xname() to obj_pmname().  The old variation
always picked "priest corpse" over "priestess corpse".  The new one
will use either one of those if the corpse is flagged as such, or use
"cleric corpse" (avoiding "aligned cleric corpse") if it's flagged as
random.
2022-04-08 00:35:13 -07:00
PatR
eea362249c wishing for artifacts
Use 'fuzzymatch(,," -",)' when checking whether the name specified
in a player's wish text matches an artifact name so that extra or
omitted spaces and dashes are ignored.  Wishing for "firebrand" will
yield "Fire Brand" and "demon bane" will yield "Demonbane".
2022-04-02 00:28:48 -07:00
PatR
b1f8c3d5c1 wishing for flint
Allow wishes for quantity up to 20 to be granted when asking for
flint.  Like rocks, flints are mainly useful as sling ammo.

Also, remove the hardcoded assumption that globs weigh 20 when wish
handling computes glob weight based on user-specified count and/or
relative size.
2022-04-01 10:53:19 -07:00
PatR
b0067493c9 fix #K3564 - obj sanity failure: N globs for N>1
Using #name and picking an item on the floor to be assigned a type
name allowed any of the four types of globs to be named.  After
that, wishing for those by the assigned name bypassed the code that
forced the quantity to stay at 1.  Asking for "3 foo" could then
produce "3 small globs of gray ooze" which fails obj_sanity() and
issues an impossible warning (which the fuzzer escalates to panic).

The "getobj refactor" patch changed the return value of call_ok().
When it gets used to check whether an object on the floor could have
a type name assigned (rather than as a getobj() callback), the test
that should have rejected the naming attempt accepted it instead.

Update the wishing code to handle globs differently:  you can still
specify the relative size via small, medium, large, or very large,
but now you can specify a count either instead or in addition.  A
count of more than 1 is used to multiply the created glob's weight,
although it's less likely to be honored as-is when the size is bigger
than small.  Quantity is always forced to 1, at a different place in
readobjnam() than previously.
2022-03-30 14:11:29 -07:00
nhkeni
b5c5496d17 Replace streq() with str_start_is(), which actually has the intended semantics.
Contributed by Michael Meyer.
2022-03-18 20:33:13 -04: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
nhkeni
7f484815e5 Add streq() and start finding places it fixes warnings.
Some type fixes from Michael Allison.
2022-03-16 18:50:17 -04:00
PatR
77dc522a62 artifact tracking 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.
2022-03-12 17:25:54 -08:00
PatR
809232914e more artifact tracking
Move some code that was used to decide whether to call distant_name
or doname into distant_name so that the places which were doing that
don't need to anymore and fewer places can care about whether an
artifact is being found.  There were two or three instances of
distant_name maybe being called, based on distance from hero, and
yesterday's artifact livelog change added two or three more and made
all of them override the distance limit for artifacts.

After that change to distant_name, make sure that conditional calls
to it become unconditional--just not displayed for the cases where
!flags.verbose had been excluding them.  That way distant_name can
decide whether an item is up close and arrange for xname to find it
if it as an artifact.

Also, implement an old TODO.  Wearing the Eyes of the Overworld
extends the distance that an item can be from the hero and still be
considered near anough to be seen "up close" when monsters pick it
up or drop it.  The explicit cases were using distu(x,y) <= 5, the
distance of a knight's jump.  Each quadrant around the hero is a 2x2
square with the diagonal corner chopped off.  The replacement code in
distant_name calculates a value of 6, which is functionally equivalent
since the next value of interest beyond 5 is 8.  Wearing the Eyes
(deduced by having Xray vision) extends that threshold an extra step
in addition to overriding blindness and seeing through walls:  15,
a 3x3 square in each quadrant, still with the far diagonal corner (16)
treated as out of range.
2022-03-07 13:21:17 -08:00
PatR
f65e652e2e livelog event for finding artifacts
Log artifacts found on the floor, or carried by monsters if hero sees
those monsters do something with them.  Shown to player via #chronicle
and included in dumplog.

For most cases, finding is based on having the artifact object be
formatted for display.  So walking across one won't notice it if pile
size inhibits showing items at its location, even if the artifact is
on top.  Taking stuff out of a container won't notice an artifact if a
subset of the contents chosen by class or BUCX filter doesn't include
it unless player has used ':' to look inside.  Seeing an artifact be
picked up by a monster (even if the monster itself is unseen) or being
dropped (possibly upon death) will find an artifact even if beyond the
normal range of having it be treated as seen up close.  Random treasure
drop items are excluded since they are placed directly on the floor
rather than going into a dying monster's inventory and then dropped
with its other stuff.
2022-03-07 03:33:01 -08:00
PatR
d37fa4138a found_artifact() groundwork
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.
2022-03-07 02:06:55 -08:00
PatR
90fc7402b8 livelog event for crowning gift
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.
2022-03-05 15:14:18 -08:00
Pasi Kallinen
1cc79b7156 Wizard-mode wishing for (melting) ice 2022-02-25 16:42:08 +02:00