magic_map_background() would overwrite remembered objects and traps.
That meant discovery of secret corridors by secret door detection
or ^E would forget embedded objects at their locations.
^E and wand of secret door detection used to just update the map
without any other feedback, but were changed post-3.6 to issue a
message about what things are being discovered. But the message is
misleading if [some of] the things revealed are obscured by objects
or by monsters. Presumeably by regions too.
If player uses the 'm' prefix before the #vanquished command when
the vanquished monsters list has fewer than two types so far,
select the preferred sort for #vanquished even though it won't be
applicable yet.
Also, when prompting about vanquished monsters during end of game
disclosure, where an 'a' response is given special meaning, use
"[ynq]" instead of "[ynaq]" if there is only one type of monster
vanquished. It's skipped altogether when the list has zero types
and there's no point in picking sort order when there is just one
type. The player can still answer with 'a' when [ynq] doesn't show
that (for tty and curses at least, probably X11); 'a' will end up
behaving as 'y' in that case.
Explicitly sort and label Riders before major demons when displaying
vanquished monsters with sort-by-class. They're lumped in with '&'
but they aren't really demons.
When looking at a monster that's inside a gas cloud, include that
fact in the output for farlook and for probing. When the monster
being examined is sensed rather than seen, you'll sense the presense
of the cloud as well as the monster even if the cloud can't be seen.
Do likewise for self when using look-here (':'). Bonus fix: zapping
wand of probing at self while engulfed reported that you were just
held by the engulfer.
Also fix an old comment typo/thinko.
Support tab separation for the region portion of #timeout output.
This works ok under Qt. However, the output from #timeout uses a
fixed-width font so tab separation isn't necessary.
No idea how well it will work for mswin.
Some_Monnam() returns "Someone" or "Something", not "Someone" or "It".
Removing the redundant '&& uchain != NULL' test shouldn't produce any
change in behavior.
Testing the shopkeeper speed change, I noticed that zapping the shk
with speed monster made her angry. Since being hasted is beneficial
for the target, don't become angry.
Allow farlook/quicklook to step through all engravings--corridor
ones as well as room ones--with repeated '`' when picking location
with getpos(), similar to how repeated '^' goes through all traps
no matter what display character they use.
It isn't possible to look at corridor engravings by using their
default symbol '#'. It is possible by using 'a' for "anything of
interest" but that matches lots of other stuff.
This tries to add an NHDT tags line to sym.h. That was followed by
'git nhadd' which did stage it for commit, but date/branch/revision
tag expansion isn't working. I did something similar to defsym.h
about 5 weeks ago; that one worked and I don't recall having needed
to do anything special.
From a change made about two and half months ago: eating a pyrolisk
egg tried to use it up from inventory even when it was on the floor.
That would trigger an object lost panic.
When hero was swallowed and a temporary region at swallower's spot
expired, hero was told "the gas cloud around you dissipates". This
just suppresses the message rather than changing it into "the gas
cloud around <engulfer> dissipates".
Various bits tried while flailing about with map display of monsters
in visible regions. The newsym()/mon_overrides_region() part is
definitely an improvement because the logic about whether to show a
monster in a region or just the region wasn't easy to comprehend and
was even harder to extend.
I'm not sure whether the _map_location() part is necessary.
This fixes the bug where a monster displayed instead of a gas cloud
because the hero was next to it didn't revert to gas cloud when hero
moved and was no longer next to the monster.
It is possible to have a known trap be at the same location as a gas
cloud region. When paranoid_confirm:trap is set, ask for confirmation
about entering the region before confirmation about entering the trap
since the map will be showing the region rather than the trap.
Dual confirmations will be annoying but not new. Before this change,
it would ask about entering the trap, and if the answer was yes, it
would ask about entering the region. The situation seems to be too
rare to warrant implementing a single combined confirmation, and the
code to accomplish that would likely be messy.
Show visible regions among the other timed events. Turn number is
relative rather than absolute. Location is the internal bounding box
which tends to cover more area than just the gas cloud spots.
When multiple regions are present (common on Plane of Fire), they're
listed in arbitrary order. It would be better to order them by
timeout or by location or both, but the extra effort to do that seems
unjustified.
Extend paranoid_confirm:trap to also ask for confirmation when
attempting to enter a gas cloud region (scroll of stinking cloud,
breath from green dragons or iron golems, steam clouds from boiling
water, vapor left by fog cloud movement, no doubt several others).
Like with traps, can be overridden for a given move by using the
'm' prefix. Unlike traps, doesn't try to guess whether moving into
a region will be harmless.
Doesn't affect movement into cloud terrain (Plane of Air).
Update the Guidebook to describe the revised behavior of
paranoid_confirm:trap and to mention how #terrain deals with regions.
'any_visible_region()' got mixed in with this but isn't used yet.
Affects extern.h and region.c.
While trying to track down a display problem with regions
[when a monster is shown over a region because the hero is
adjacent, it doesn't revert to the region's cloud glyph when
hero moves farther away; that's not resolved yet],
I discovered a different display problem for the same thing. If
you pick a #terrain choice that keeps traps it is supposed to show
region spots too, but that didn't work when there was a monster at
the same spot. It removed the monster but showed background there.
A recent change was setting mon->data prior to canspotmon(mon) but
that triggered a crash if the temporary mon->data was Null. All the
testing was done with vampshifers and this affects non-vampshifers.
Push even more shapechange messaging into newcham() by not trying to
determine whether requesting a message from it will oblige.
Messaging for vampires changing into fog clouds was inconsistent
in 3.6.x but already fixed in to-be-3.7.
However, maintaining an extra set of shape change messages (one
in newcham(), the other in vamp_shift() which turns out to only be
used when a vampshifter turns into a fog cloud in order to pass
under a closed door) was a nuisance. Redo vamp_shift() to use
newcham() feedback. Update that feedback to be accessibility-aware
and also to use "Your <mon>" instead of "The <mon>" when appropriate.
While in there, remove a couple of trailing spaces and eliminate
use of one dynamically constructed format string that necessitated
warning manipulation.
Issue reported by loggersviii: monsters killed by liches can
produce corpses which auto-revive as zombies, but liches aren't
able to harm zombies and get stuck in an endless slap fight when
those revive.
Liches have a touch attack for cold damage and they have a spell
casting attack. They don't use their spell attack in monster vs
monster combat, so cold resistant foes don't receive any damage.
Prevent them from becoming harmless by changing the cold damage to
physical damage if the target resists cold.
Fixes#1263
Issue reported by elunna: none of the display choices for #terrain
offered a way to show the terrain beneath temporary gas/cloud
regions (except "full map" in wizard mode or explore mode). That
prevented the command from being used to find stairs and portals
which had been mapped before becoming covered up.
Adding extra menu choices to deal with visible regions would result
in #terrain becoming a mess. Instead, treat regions as if they were
traps. Picking a choice that includes traps will show region spots
which are in view as cloud or poison cloud, picking one that excludes
traps will show the underlying terrain. Region spots which aren't
within view are handled the same as before: whatever the hero
remembers at their location gets displayed.
The default menu choice excludes traps so will display stairs that are
covered by gas cloud regions, but not portals, same as when no regions
are present. When showing traps and one is covered by a gas cloud,
the trap will be shown rather than the gas cloud, making it possible
to see known portals.
At the moment the new "#terrain handles regions like traps" feature
hasn't been documented anywhere. That might get rectified someday.
I'm not sure whether trap detection ought to also detect regions now.
This doesn't attempt to tackle that and I think that I'll pretend
that the idea never occurred to me.
'parnoid_confirm:traps' definitely ought to prompt for confirmation
when entering a visible harmful region. This doesn't add that.
Bonus fix: it's possible for a visible region to cover up a not yet
explored location. Searching next to such a spot wasn't changing the
spot to be marked as explored (unless hero was blind). Now it will.
Fixes#1262
> If there's a trap on a no-dig level, the floor beneath it will always be "too hard to dig into", making it impossible to remove the trap.
>
> As you can still dig pits in these levels (just not holes), the floor under the trap itself resisting to become a pit seems inconsistent.
>
> Steps to reproduce:
>
> Go to no-dig level like Mine's End
> Make a trap
> Dig a pit next to it -> works
> Dig on the trap -> does not work
Return more information about the dig_check() results to caller (was
just a boolean).
Move the messaging that was in dig_check() into a separate
digcheck_fail_message() function that uses the expanded return
information.
Resolves#1254
.
Plus a bit of reformatting where extending "static" to "staticfn"
on the first segment of a would-have-wrapped line made the other
segment(s) no longer line up.
Fix misleading indentation that the polyfood() macro inherited from
the misformated polyfodder() macro.
Fix a case where a non-pet monster would avoid eating a cockatrice
corpse but would eat Medusa's corpse.
The previous is_shapeshifter() test meant that pets were still perfectly
willing to eat genetic engineer corpses and be polymorphed. Use
polyfood() instead.
Fixes#1183.
'Polyfodder' is already a term frequently used by players to describe
items which are useful to hang on to specifically to zap polymorph at
(for example, extra unicorn horns, which can be turned into magic
markers). Using it as the name of a macro which tests whether a food
item will polymorph the creature consuming it is somewhat confusing, and
I think 'polyfood' is a lot clearer.
player's input as a comma-separated list of option:value settings
Several compound values that aren't amenable to menus prompt for a
line of input and pass it to parseoptions() as if it came from the
run-time configuration file. That shouldn't be treating commas as
option separators.
The fix is trival, at least for handling the text properly without
introducing new warnings to complain about rejections. Some options
notice an unwanted comma and complain, others don't notice and the
extra text gets ignored.
The look-at-screen code was setting bhitpos before calling
look_at_monster() but that hasn't been needed for around 25 years.
Fix is trivial.
However, having such a low level routine as show_glyph() call
do_screen_description() seems like a recipe for trouble.
Issue reported by Meklon2007: some theft feedback during nymph
attacks refers to the attacker as "she" and others as "it" if hero
is blind.
The "she" references are intentional. However, mixing them with
"it" references when a series of messages occurs is jarring. This
changes "it" to "someone", which is still different from "she" but
hopefully enough less so to be tolerable.
That resulted in monkeys also being referred to as "someone" because
they're classified as humanoid. Change x_monnam()'s AUGMENT_IT
handling, which chooses between "someone" and "something" when the
monster is not seen, to override humanoid for animals (affects 'Y'
class) and for mindless (affects zombies, mummies, and golems).
So an unseen monkey will be "it" again.
The final message for current item was relying on a cached monster
name value. If an unseen nymph or monkey stole a worn blindfold
so that hero's vision was restored: "It <stole> item" before the
changes and "Someone|Something <stole> item" after. So update the
cached name if sight gets regained, to give "<Mon> stole <item>."
(If the item is worn armor and the thief is a nymph, it was and
still is "She stole <item>".)
The message for having any worn item be stolen, which got split
into two parts within the past year, was giving "<Mon> takes off
<alt weapon>". When not dual-wielded, the alternate weapon isn't
really worn. Rather than suppress it outright, change the message
for uwep/uswapwep/uquiver to say "disarms" instead of "takes off".
For accessories, change "takes off" to "removes". Those are more
or less interchangeable these days but "removes" matches R instead
of T.
While testing, my pet evidently killed a nymph (I was blinded and
couldn't see it happen) while she stole my gloves and the next
message I got was "You finish taking off your suit." The gloves
weren't worn anymore so equipname() defaulted to suit. Get rid of
equipname() altogether and switch to armor_simple_name() which
doesn't rely on the worn-armor pointers.
Fixes#1257
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
Since save and bones files just got clobbered, make another clobbering
change. The 'queuedpay' field added to shop's ESHK(shkp)->bill[] was
replaced last week by a similar field in the transient itemizing bill.
At the time, the old field was left in place to avoid incrementing
EDITLEVEL.
shkp->mextra->bill[] is saved and restored, so its queuedpay field was
too. Eliminate that no longer used field.
Unrelated: bill[]->useup is declared as boolean but being assigned 1
or 0. Change the assignments to use TRUE or FALSE.
Implement a couple of missing bits for wall of lava terrain. It was
immune to being distorted by hallucination, unlike molten lava and
wall of water. And the presence of wall of lava made molten lava,
after being shortened to "lava", no longer be listed as something
represented by the "}" character.
I started to renumber S_water, which would eliminate some hackery
from farlook's do_screen_description(), but that will require an
EDITLEVEL increment and make it necessary to reorder/renumber the
corresponding tiles so I stopped short.
This adds NHDT tags to the first line of defsym.h.
The old nowrap_add() had different semantics from its replacement,
performing an assignment as well as an addition. Now just does
the addition; its caller needs to perform the assignment.
If the quest leader observes the hero attacking a peaceful monster,
only become angry if that peaceful monster is a quest guardian. And
when becoming angry, stop waiting for the hero to approach.
If a quest guardian observes the hero attacking any peaceful monster,
don't run away.