Noticed while testing an earlier fix - after your pet consumes a large mimic
corpse don't have it remain leashed once it begins to mimic something
that isn't leashable
Using #monster to make the steed use the breath weapon often
failed because the steed did not want to breathe at weak or
too strong monsters.
Make #monster force the steed use the breath, and if there is
no targets available, make the steed make some noise as feedback.
Issue reported by ars3niy: pets with reflection or ranged attacks
would only attack floating eyes when rolling the 10% random chance
that other pets have even though they could have always safely
attacked.
This fixes the situation for melee attacks by pets who have
reflection.
dog_move() is too complicated for my feeble brain to cope with the
ranged attack aspect. Pets still won't use ranged attacks against
floating eyes.
With the fix for reflection, I discovered that silver dragons
would be subjected to floating eyes' passive paralysis even when
their breath attack was suppressed. (It wouldn't impact them, due
to reflection, but the message about the floating eye being hit by
its reflected gaze was being delivered without being preceded by
any message since no attack had taken place yet.) This fixes that.
\#1336 is still open
gcc has recognized various "magic comments" for white-listing
occurrences of implicit fallthrough in switch statements for
a long time:
The range and shape of "falls through" comments accepted are
contingent upon the level of the warning. (The default level is =3.)
-Wimplicit-fallthrough=0 disables the warning altogether.
-Wimplicit-fallthrough=1 treats any kind of comment as a "falls through" comment.
-Wimplicit-fallthrough=2 essentially accepts any comment that contains something
that matches (case insensitively) "falls?[ \t-]*thr(ough|u)" regular expression.
-Wimplicit-fallthrough=3 case sensitively matches a wide range of regular
expressions, listed in the GCC manual. E.g., all of these are accepted:
/* Falls through. */
/* fall-thru */
/* Else falls through. */
/* FALLTHRU */
/* ... falls through ... */
etc.
-Wimplicit-fallthrough=4 also, case sensitively matches a range of regular
expressions but is much more strict than level =3.
-Wimplicit-fallthrough=5 doesn't recognize any comments.
Plenty of other compilers did not recognize the gcc comment convention,
and up until now the compiler warning for detecting unintended
fallthrough had to be suppressed on other compilers. That's because the code
in NetHack has been relying on the gcc approach, and only the gcc approach.
The C23 standard introduces an attribute [[fallthrough]] for the
functionality, when implicit fallthrough warnings have been enabled.
Several popular compilers already support that, or a very similar attribute
style approach, today, even ahead of their C23 support:
C compiler whitelist approach
--------------------------- -------------------------------------
C23 conforming compilers [[fallthrough]]
clang versions supporting
standards prior to
C23 __attribute__((__fallthrough__))
Microsoft Visual Studio
since VS 2022 17.4.
The warning C5262 controls
whether the implict
fallthrough is detected and
warned about with
/std:clatest. [[fallthrough]]
This adds support to NetHack for the attribute approach by inserting a
macro FALLTHROUGH to the existing cases that require white-listing, so
other compilers can analyze things too.
The definition of the FALLTHROUGH macro is controlled in include/tradstdc.h.
The gcc comment approach has also been left in place at this time.
A pet with the hides-under attribute could hide under cursed objects
if it first moved reluctantly to their location. Also, the messages
seem contradictory:
| The cobra slithers reluctantly over a scroll labeled DUAM XNAHT.
| You see your cobra slither under a scroll labeled DUAM XNAHT.
First over, then under, but that was actually accurate; the monster
moved, then after it was on the pile it hid underneath.
Change hideunder() to not let pets hide under an object if it is
cursed or any object in its pile is cursed. Initially I was just
going to check the top item and the item directly beneath it, but
reluctance to move there extends to the whole pile so I made hiding
do so too.
Change the first message to move reluctantly "onto" an object since
"over" suggests that it has continued past the item, unless it is
actually flying or levitating so truly "over" the pile.
The g? structs had a mix of variables that were written to
the savefile, and those that were not.
For better clarity and to distinguish those that end up in
the savefile, relocate some g? variables that get written
directly to the savefile into different structs.
This updates EDITLEVEL, although technically it probably
didn't need to, since savefile contents are not changing.
Details:
gb.bases -> svb.bases
gb.bbubbles -> svb.bbubbles
gb.branches -> svb.branches
gc.context -> svc.context
gd.disco -> svd.disco
gd.dndest -> svd.dndest
gd.doors -> svd.doors
gd.doors_alloc -> svd.doors_alloc
gd.dungeon_topology -> svd.dungeon_topology
gd.dungeons -> svd.dungeons
ge.exclusion_zones -> sve.exclusion_zones
gh.hackpid -> svh.hackpid
gi.inv_pos -> svi.inv_pos
gk.killer -> svk.killer
gl.lastseentyp -> svl.lastseentyp
gl.level -> svl.level
gl.level_info -> svl.level_info
gm.mapseenchn -> svm.mapseenchn
gm.moves -> svm.moves
gm.mvitals -> svm.mvitals
gn.n_dgns -> svn.n_dgns
gn.n_regions -> svn.n_regions
gn.nroom -> svn.nroom
go.oracle_cnt -> svo.oracle_cnt
gp.pl_character -> svp.pl_character
gp.pl_fruit -> svp.pl_fruit
gp.plname -> svp.plname
gp.program_state -> svp.program_state
gq.quest_status -> svq.quest_status
gr.rooms -> svr.rooms
gs.sp_levchn -> svs.sp_levchn
gs.spl_book -> svs.spl_book
gt.timer_id -> svt.timer_id
gt.tune -> svt.tune
gu.updest -> svu.updest
gx.xmax -> svx.xmax
gx.xmin -> svx.xmin
gy.ymax -> svy.ymax
gy.ymin -> svy.ymin
Related note:
There are some pointer variables that are heads of chains that were not
moved from 'g?' to 'sv?', because they are not actually written to the
savefile directly, but the objects/monst/trap/lightsource/timer in the
chains they point to are. That can be changed, if desired.
Examples: gi.invent, gm.migrating_objs, gb.billobjs, gm.migrating_mons,
gf.ftrap, gl.light_base, gt.timer_base
A pet titan dropped a boulder over a pool, and the code killed
the titan, because the code was considering the titan to be in
the water.
If a flyer or a floater is over the pool, don't kill them off
if a boulder is dropped in there. Also make the pet movement
code handle the case where the pet might've died while dropping
items.
Add a way to request that unpaid_cost() produce the cost for a single
item, which is necessary for the price adjustment made in
bill_dummy_object. Another option would be to simply divide by quan in
bill_dummy_object, but this might be more future-proof in case
unpaid_cost ever involves more than simple multiplication by quan
(e.g. the use of alternate units vs the base price, as are used for
globs).
Fixes#1236
Improve the feedback for an unnamed pet eating a mimic corpse.
|You see a tripe ration where Rover was.
is ok.
|You see a tripe ration where the dog was.
looks somewhat odd. Change that to be
|You see a tripe ration where your dog was.
Adds a new boolean option, accessiblemsg. If on, some game messages
are prefixed with direction or location information, for example:
(west): The newt bites!
(northwest): You find a hidden door.
I added the info to the most common messages, but several are
still missing it.
Some players of 3.6 recently noticed that sometimes, mimics in shops
seemed to have moved around even before the player had entered the shop
or done anything to uncloak them. I found that this was because
finish_meating was being called for all non-eating monsters when
restoring a level (monsters that weren't eating anything would have
meating == 0 so always pass the 'imv > meating' check). This would
uncloak mimics -- but not all the time, because the 'mappearance != 0'
test meant mimics disguised as strange objects weren't uncloaked. I
think that was meant to be an additional check to confirm the monster
really did have a disguise, but in reality it meant that M_AP_OBJECT
"strange object", M_AP_MONSTER "giant ant", etc disguises wouldn't be
removed by finish_meating.
As it turns out, this was mostly fixed by coincidence in 221e4a7, which
fixed the "exclude actual mimics" check in finish_meating. So at this
point in 3.7 it's largely a latent bug, but it still had the potential
to improperly uncloak non-mimics who can disguise themselves (like the
Wizard of Yendor, maybe?), and could cause other problems if
finish_meating were updated to have additional effects, or if some
monster types were made to disguise themselves as a strange object when
eating a mimic.
Don't allow stick/wrap/engulf attacks directed at long worm tails
to succeed. Achieved by making sure that 'notonhead' is up do date
in a bunch of places and utilizing the fairly recent can't-{stick,wrap,
engulf}-unsolid-monsters code.
Should prevent a 'sanity_check' warning about being too far from
u.ustuck that would happen when holding the tail while the head was
not adjacent to the hero.
Also don't let pet ranged attacks from choosing a long worm's tail
as target. They'll still be able to target long worms provided that
the head is lined up and not shielded by tail segment(s).
Pet ranged attack code was using the same variable for
both pet attacking a monster and then the monster's possible
retaliation attack. The retaliation obviously overwrote the
pet attack return code, allowing pet to move afterwards.
In certain case this could result in "no monster to remove"
warning.
While looking for something in dogmove.c I did some source cleanup.
Undefine its macros by the end of the file, and redo some pet vs
guardian angel handling that dated from when the monst extensions for
those two were overlaid.
The overly simplistic fix to prevent pets from picking up objects
while they were busy eating had unwanted side-effects, making them
seem to be paralyzed in some situations such as #chat. Reverse the
recent change done in commit 754e9333f5
("fix pet picking something up while eating") and handle it in the
pet pick-up code instead.
The <x,y> params of dog_eat are the pet's starting position that turn,
not necessarily the position of the object being eaten. If the pet is
doing a combined move-and-eat action, <x,y> will be its original spot,
but it will have already moved to <mtmp->mx,mtmp->my>, where the food
object also is.
The attempt to check whether the eating was happening out-of-sight
underwater (to suppress the message in that case) was checking the pet's
starting location, not its new location/the location of the food object.
So if a pet moved from water to land to eat something, the chowing-down
message would be improperly suppressed (and presumably the message for a
pet moving from land to water to eat would be improperly left
_un_suppressed, though I didn't actually try to reproduce that).
I think moving the m_consume_obj call (which will free the eaten item)
further down should fix this without causing any really wacky message
sequencing issues, but if maintaining the exact order is important
obj->unpaid and its price could be cached before the free instead.
This code was in three different places; pet eating,
monster eating metal, and monster eating other objects.
Other than very minor changes (eg. rustproofing completely
protects pets from bad effects, rustproof items are no longer
giving apport, and monsters eating corpses are healed), it
should behave the same as before... But I haven't exhaustively
gone through every iteration.
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
^ ^
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() */
Reported by Umbire:
|You kill SpaceMannSpiff! SpaceMannSpiff puts on a dwarvish cloak.
|SpaceMannSpiff puts on a dwarvish iron helm.
|The seemingly dead SpaceMannSpiff suddenly transforms and rises as
| a Vampire.
This was tough to reproduce but I finally managed it. The issue
text mentions that it was fixed by copperwater in xNetHack with
commit 8c4af50f0aa3e72522f3eb98df039ff25c2a1ea0 to the repository
for that variant. My attempt to cherry-pick that failed--I'm not
even sure whether it should have been expected to work--and some of
the code has been impinged upon by changes, so I ended up applying
the contents of that commit manually.
The commit changes how/when monsters put on new armor rather than
anything directly related to vampires. Circumstances similar to
the example above now yield:
|You kill SpaceMannSpiff!
|The seemingly dead SpaceMannSpiff suddenly transforms and rises as
| a Vampire.
on one turn, then on the next turn the revived vampire produces:
|SpaceMannSpiff puts on a dwarvish cloak.
My test case only had one item of interest; I assume that the second
item of armor gets worn on a subsequent turn rather than at the same
time as the first one.
Fixes#843
The pull request included some changes that were neither accidental nor
unintentional, so only a subset of the changes from pull request #869
submitted by klorpa were manually applied.
behaviour -> behavior
speach -> speech
knowlege -> knowledge
incrments -> increments
stethscope -> stethoscope
staiway -> stairway
arifact -> artifact
extracing -> extracting
The uses of "iff" were left alone.
Close#869
Apply the patch from entrez that makes pet gelatinous cubes who eat
containers engulf rather than digest the contents, like non-tame
g.cubes. Unlike the latter, tame ones will immediately drop the
stuff they just engulfed and might subsequently eat it all anyway.
Commit 32234b1d in 2003 mentioned in its commit message that pet dragons
shouldn't be able to eat underwater food items. This was mostly true:
non-swimming pets wouldn't select underwater food as a goal, and
wouldn't spend an action eating something unreachable on their current
position. But the "combined eat and move" case in dog_move didn't check
could_reach_item, so if a non-swimming pet happened to move to a spot
with underwater food for some reason, they could eat it on that turn
anyway. This commit should close this loophole and prevent non-swimming
monsters from eating underwater food (or other unreachable food) even if
they happen to fly over its position.
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