Commit Graph

437 Commits

Author SHA1 Message Date
Pasi Kallinen
9d97835686 Minor wishing alias improvement
Previously when wishing for "ring of protection from shape shifters",
you got a random ring instead of the protection from shape changers,
because the string matching alias was "protection from shape shifters"
without the object class.  Now, we'll check if the wish matched any
object class, but not existing object or alias, and try matching
the aliases again, but only those of the already matching obj class.

Add an alias for the ring of increase accuracy: "ring of accuracy",
and tests for it.
2024-03-16 16:59:58 +02:00
nhkeni
9c0ed8ae63 NOSTATICFN for src/* 2024-03-14 17:41:51 -04:00
RainRat
a3658f85ac fix typos 2024-02-28 20:15:56 -08:00
nhmall
0a985459f0 make style consistent for function ptr arguments 2024-02-19 17:21:04 -05:00
nhmall
688ac6ffbe remove register from variable declarations 2024-02-19 16:30:07 -05:00
PatR
576dd10bdd fix #K4088 and #K4089 - ring formatting
+/-N for charged rings with known enchantment was clobbering the
BUC formatting that had occurred earlier.  #K4088 thought it was a
problem with the implicit_cursed option; followup #K4089 from same
user correctly pointed out that the problem was present for any BUC
state.

This is the same line of code that inadvertently omitted the space
between +/-N and "ring of <type>".  That was fixed by commit
1a2b2a8cae a couple of days ago.

While in doname(), fix a potential issue calling corpse_xname().
That assigns a new value to gx.xnamep, clobbering the value that
doname() relied on when it was first called (but doesn't look at
again, so doesn't matter now but could conceivably in the future).
2024-01-24 00:37:09 -08:00
PatR
5d90499148 doname bounds checking bits
When ready to return, check for overlooked overflow (shouldn't happen)
and panic, or report the first excessively long but not overflown
description to paniclog, similar to xname.

Make ConcUpdate() more robust by not needing bp_eos to be previously
set.  Less efficient but I think that boat has left the barn?  :=}

Fix a comment typo.
2024-01-21 17:43:55 -08:00
PatR
9e640fb14e gcc warning fix
Avoid two new warnings in xname_flags() about strncpy() not supplying
a terminating '\0'.  That's exactly why strncpy() was being used.

The gcc manual lists -Wno-stringop-truncation to suppress the warning
but not -Wstringup-truncation to voluntarily enable it, so the pragma
stuff in warnings.h probably won't work for this.  Just switch from
strncpy() to memcpy() instead even though it seems like obfuscation.
2024-01-21 11:01:45 -08:00
PatR
1a2b2a8cae object formatting fix for charged rings
The bounds checking code for object formatting had a typo that left
out the space between +N and <ring of type>.
2024-01-21 07:58:25 -08:00
PatR
7b1ec30d0d bounds checking by doname() and xname()
Try harder to prevent buffer overflow when formatting objects.
I don't have any test cases where overflow has been happening so
don't really know whether this works reliably.  And it doesn't try
to check prefix construction by doname().  [Yet?]
2024-01-20 17:53:44 -08:00
nhmall
25a8c258e6 replace x >= LOW_PM with ismnum(x) shorthand macro 2024-01-11 14:01:10 -05:00
nhmall
4e19221e55 variable 'display' causes shadow variable warnings in X11 build
display.botl      -> disp.botl
display.botlx     -> disp.botlx
display.time_botl -> disp.time_botl
2024-01-05 05:58:51 -05:00
nhmall
49a5d043c0 consistent use of TRUE vs 1 with botl and botlx 2024-01-04 23:48:38 -05:00
nhmall
22e52ee905 bundle the display-related hints, that tell bot() and others
that an update is required, into a struct. Remove it from
context since there is no reason to save those.
2024-01-04 23:16:27 -05:00
PatR
35eb289cc3 "partly used candle" fix
If you wished for "lit candle" you'd get an unused candle that
is pre-lit but the feedback as it's added to inventory would be
"partly used candle (lit)".  If snuffed out immediately, it reverts
to "candle" (ie, not partly used).

This fixes the first aspect:  you will get "candle (lit)" added to
inventory.  On the next turn it changes to partly used as expected.
The second aspect, reverting to not-used-yet after being lit during
the wish is left as-is.
2023-12-23 16:15:38 -08:00
PatR
a696cb8d90 some NONNULLs
Update the prototypes of some functions which return a pointer that
will never be NULL.  Only covers pager.c and part of objnam.c.
2023-12-20 15:55:21 -08:00
nhmall
3bf2f0daee Revert "allow readobjnam arg to be nonnull"
This reverts commit 10f29a9760.
2023-12-17 07:20:35 -05:00
nhmall
10f29a9760 allow readobjnam arg to be nonnull
Have it key on &do_random_str instead of NULL,
and modify makewish() in zap.c for the new protocol.
2023-12-16 19:30:34 -05:00
PatR
4bd7f265f1 wizard mode terrain wishing at drawbridge spot
When trying to reproduce the wand of striking "interesting effect (0)"
report, I tried wishing for lava under the castle drawbridge.  That
wasn't handling drawbridges properly.  This fixes wishing for moat,
lava, ice, or floor at a drawbridge span location whether the bridge
is currently open of closed.  It also allows wishing for room or floor
or ground at room spots; that hasn't had much testing.

Wishing for furniture, pool|moat|water, or lava at an ice location
wasn't cancelling any pending melt timer.

ice_descr() was declared as returning const but returns its non-const
output buffer argument.  Change to 'char *' so that wizterrainwish()
can capitilize that output without jumping through any hoops.
2023-12-11 19:54:20 -08:00
nhmall
3230babae0 uhandedness follow-up
avoid (wielded in right hands)
2023-12-03 20:27:01 -05:00
nhmall
e4e8eea4e8 track the handedness of the hero
Don't make either LEFT_HANDED or RIGHT_HANDED be an advantage
or a disadvantage.

use suggested macros
2023-12-02 11:23:43 -05:00
PatR
dd6c249a8c remove obsolete comment 2023-11-12 10:26:59 -08:00
nhmall
76d328d86a gi.invalid_obj -> hands_obj 2023-11-11 19:49:38 -05:00
nhmall
27e727d7d7 another missed cast removal 2023-11-10 11:31:24 -05:00
nhmall
314a2a9489 use gi.invalid_obj instead of cg.zeroobj
cg.zeroobj was originally added (under its previous unprefixed name)
for providing a one-line way to zero out the fields of a struct obj.

    struct obj tempobj;
    tempobj = cg.zeroobj;

    initfn(struct obj *otmp)
    {
        if (otmp)
            *otmp = cg.zeroobj;
    }

More recently, the address of cg.zeroobj began to be used as a return
flag to indicate some things, but the 'const struct obj zeroobj' wasn't
an ideal fit for the purpose and required a number of casts, including
casting away const.

Provide a better fitting variable (gi.invalid_obj) and eliminate a
number of casts.
2023-11-10 11:07:49 -05:00
Pasi Kallinen
2e8adda028 Clouds cannot have engravings in them
... so delete the existing engraving if a cloud is put on the map.
2023-11-09 18:08:00 +02:00
PatR
4dc8429d9e thawing ice followup
Modifying an() [actually just_an()] to treat "<thickness> ice" and
"frozen <hallucinatory liquid>" as special cases which shouldn't be
prefixed with "a" or "an" affected using something like "shaved ice"
or "frozen yogurt" as named fruit.
 |a) shaved ice
 |b) frozen yogurt (weapon in hand)
now have article "a" preceding them:
 |a) a shaved ice
 |b) a frozen yogurt (weapon in hand)
However, the existing cases
 |c) iron bars
 |d) an iron bars (weapon in hand)
still get item 'c' wrong.  'd' is slightly odd but that's because the
fruit name is ambiguous as to whether it's singular or plural.
2023-10-26 01:28:56 -07:00
PatR
04d6789c98 report ice's thaw state
Classify nearby ice as "solid" (no melt timer), "sturdy" (more than
1000 turns left), "steady" (101 to 1000 turns left), "unsteady" (51
to 100 turns left), "thin" (15 to 50 turns left), or "slushy" (1 to
14 turns left, matching walking on ice with the Warning attribute).
[I'm not thrilled with "steady" and particularly "unsteady".]

I was originally going to do this just for probing downward, but ended
up also doing it for look-here and getpos's autodescribe.  It nearly
got out of hand and touched more files than anticipated.

'mention_decor' ought to treat moving from ice firmer than thin to
thin or slushy, from thin to slushy, from slushy to any other, and
from thin to firmer as if moving onto different terrain but I haven't
attempted to tackle that.

The melt timer could work more like a candle's burn timer, triggering
at intermediate stages and resetting itself, so that ice which changes
to a weaker state under the hero could be reported to the player.  But
this doesn't implement that.
2023-10-25 13:26:03 -07:00
PatR
78607a37a5 more obufs - two-handed weapon in "hands"
Pointed out by entrez:  prevent doname() from consuming two obuf[]
buffers when it constructs the plural of "hand" while formatting a
wielded two-handed weapon.

Since only one such item should be able to occur in any list of
objects, it is not likely to be the cause of any message oddities
that might happen when a cached value is in a formatting buffer gets
re-used too soon.  However, not releasing a second buffer right away
prevents an attempt to release the first one from succeeding because
it won't be the last one allocated anymore, so some buffer churn was
happening.
2023-08-16 18:16:11 -07:00
Michael Meyer
d57a359bba Add correct Cyclops pluralization
The correct plural of "Cyclops" is "Cyclopes", not "Cyclopses".  I don't
know if anyone would actually use that as a fruitname, but it wouldn't
hurt to add it -- especially since a Cyclops does appear in the game.
2023-07-04 22:37:38 -07:00
PatR
e9c58c2fe4 breaking crystal armor
Instead of a 5% chance for crystal plate mail or crystal helmet to
break each time it's subjected to breakage, switch to a 10% chance
but the damage is treated as erosion rather than break/don't-break.
'crystal foo' will need to go through four stages of damage before
breaking:  cracked crystal foo, very cracked crystal foo, thoroughly
cracked crystal foo, then gone.  Crackproof handling is included,
described as tempered crystal foo.

It mostly still applies to throwing and kicking the item.  Having
some hits trigger damage might be worthwhile but isn't implemented.

Object creation within lua code probably needs to be updated, and
when the Mitre of Holiness is created in the priest/priestess quest
it should start out as tempered (erodeproof).  Perhaps it ought to
be erodeproof regardless of where/how it's created.
2023-06-14 15:54:04 -07:00
PatR
450f060132 github issue #1060 - crystal helmet
Issue reported by vultur-cadens:  changing helm of brilliance to
crystal made it stop being classified as "hard helmet" so it gave
less protection against things falling onto the hero's head.

Change the is_metallic() tests used on helmets to new hard_helmet().
Unlike when thrown, crystal helmets don't break when objects fall
on them.

Fixes #1060
2023-06-14 06:13:11 -07:00
PatR
bf47cc878e fountain and sink bookkeeping
This replaces most of commit 0ca2af4d8b
from a couple of days ago with something more robust.  That change
actually introduced redundant code that caused fountain and/or sink
count to be off instead of preventing it.

Revise set_levltyp() to update level.flags.nfountains and
level.flags.nsinks if setting the type to or from fountain or sink.
A bunch of places that were setting levl[x][y].typ directly needed
to be revised to use set_levltyp() instead.  set_levltyp() itself
hadn't been updated to handle LAVAWALL (to force such to be lit).
2023-06-12 15:07:34 -07:00
PatR
0ca2af4d8b wizwish fountain and sink bookkeeping
Noticed while considering the pull request about loosening
restrictions on trap creation at furniture locations.  If you wish
for a terrain feature while on a fountain or sink, the counters
used to control whether sounds for those should be given will be
off by one.

It was incrementing the appropriate counter if you wished for a
fountain or sink, but it shouldn't do that if recreating the same
feature (perhaps to reset a magic fountain or looted sink) and it
needed to decrement when replacing either of those with some other
feature.  After the count became wrong, if all fountains or sinks
on the level were destroyed, those splashing, gurgling, &c sounds
would continue to be generated periodically.
2023-06-10 01:46:35 -07:00
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