Wizard mode's $WIZKIT can specify an unlimited number of items to
add to starting inventory and they'd be put there without regard to the
number of slots in use, potentially resulting in an arbitrary number of
'#' slot items. Cap at 52 slots, same as when picking up, and put any
excess items at the hero's feet. It's slightly tricky because the level
hasn't been created yet at the time the wizkit gets processed.
For GOLDOBJ configuration, relax the 52 object limit for inventory
when gold uses the special $ slot instead of a letter. Takes care of an
old buglist entry from the beta testers. [It will need to be revisited
if we ever implement multiple coin types that can't all fit in one slot.]
Also for GOLDOBJ, prevents nymphs and monkeys from stealing coins,
since allowing that made their steal-item attack be a complete superset
of leprechaun's steal-gold attack.
Reported to us by <email deleted>:
'You are beginning to feel hungry. You trip over it.'
and also recently in the newsgroup by "<Someone>":
There is ice here. *You see here an electric eel corpse.*
Bib hits the electric eel. Bib misses the electric eel.
Bib misses the electric eel. The electric eel misses Bib.
The electric eel misses Bib. *You trip over it.*
slip_or_trip() was oversimplifying things by assuming that if there
is one object at the hero's location, a message about what that object is
has just been given. Any timeout message which precedes Fumbling (lots
of candiates besides hunger) could intervene, as could monster activity
between the hero's move and timeout handling. Aside from the reported
cases, that code hadn't been updated to account for the new pile_limit
option which could be set to 1 and force a popup display instead of the
usual "you see <an item> here". This fix adds a flag that can be used
to track the most recent message. It is cleared by pline for every
message, so pline's caller sets it _after_ the message of interest has
been displayed.
From newsgroup discussion, reproduced with current dev code (the
missing capitalization is a post-3.4.3 buglet):
The orc tries to wield a halberd.
the orc's bow is welded to her hand!
The orc thrusts a halberd. You are almost hit by a halberd.
Caused by overloading polearm attacks with throwing. The monster throwing
code didn't enforce that a polearm must be successfully wielded.
Noticed while looking at something else: doorganize() goes out of
array bounds for alphabet[] when inventory contains something in the '#'
slot, or in the '$' slot for GOLDOBJ config. Both # and $ pass the
(let <= 'Z') test, then produce a negative result for (let - 'A' + 26).
In my case, it was harmlessly clobbering the tail end of buf[] but it
could potentially be a lot worse.
From another many year old news posting: if you picked up a stack
of potions of oil in a shop and then applied them, one potion was split
off and started burning but you were forced to pay for all of them.
Split the to-be-lit one off first so that the remainder of the stack
stays as ordinary unpaid shop goods.
This also fixes an old bug with bill_dummy_object sometimes charging
a different price than the player got quoted when an object was picked up.
From a four year old news posting: hero was levitating via #invoke
on the Heart of Ahriman, then dropping that artifact yielded:
You drop a gray stone named The Heart of Ahriman.
You float gently to the floor.
A gray stone named The Heart of Ahriman hits the floor.
That might be strictly correct, assuming that both hero and stone fall at
the same speed; if the stone was dropped from perhaps waist height then
the hero's feet would touch first. But it looks strange, like a cartoon
where something hangs in midair until someone notices that it should fall.
Removing the artifact from inventory causes the #invoke property to
toggle off. Unfortunately it has to be done here before the object can
be placed at its destination. Modifying message order seemed unviable;
this fix fiddles with the Levitation property in order to defer hero's
descent until after object handling is finished. Now same setup gives:
You drop a gray stone named The Heart of Ahriman.
A gray stone named The Heart of Ahriman hits the floor.
You float gently to the floor.
You see here a gray stone named The Heart of Ahriman.
Prevent remote ID of the three high priests on the Astral Plane via
wand of probing or via their own actions (observing "high priest of Foo
drinks a potion of speed" and so forth). When not immediately adjacent,
you'll get "the high priestess" instead of "the high priestess of Foo".
The prompt to a hero with lycanthropy and polymorph control about
whether to change into beast form had an extra space between the question
and the [yn] answer choices.
I came across an old bug report which stated that steeds missed out
on their chance to counterattack if the hero had just taken some action
other than moving.
[1: monster attacks steed instead of hero ]
[2: if monster died while attacking, return 1 ]
if (i & MM_DEF_DIED || u.ux != u.ux0 || u.uy != u.uy0)
return (0);
[4: otherwise, steed counterattacks monster ]
Sometime since whatever version the 2001 report was for, but before the
current cvs repository was set up someone addressed this by changing it
to be
if (i & MM_DEF_DIED || !u.umoved)
return (0);
but I think that fixed the wrong thing. I believe that the original code
was attempting to make sure that the steed was still in position to be
able to counterattack. There's no reason to care about the hero's most
recent action; he had to have done something that caused time to elapse
in order for the other monster to have initiated an attack in the first.
(The new range check is actually redundant; mattackm() also enforces it.)
From a bug report, reviving a snake corpse
produced a snake monster which was hidden under nothing--it hid under its
own corpse and wasn't revealed when that corpse got used up. Rather than
fiddling with sequencing to remove the corpse before making the monster,
force any monster who revives in hidden state to unhide.
Forwarded from newsgroup by <Someone> in February, 2005: non-cursed
unicorn horn fixes lost Str/Con/&c stats even when ring of sustain ability
is supposedly locking those at current value. This makes unicorn horn
honor the Fixed_abil intrinsic. The potion and spell of restore ability
still override that, so they now have potential for use even after player
has acquired a unihorn. Prayer also continues to override Fixed_abil.
Major prayer result to heal crippled strength now attempts to uncurse a
ring of sustain ability (or gloves or weapon covering it up--similar
situation as with cursed levitation). Minor prayer result to fix lost
stats resets those without attempting to do anything about Fixed_abil.
Something else <Someone> forwarded from the newsgroup long time ago:
attempting to read a dull spellbook ought to have a chance of making the
hero fall asleep.
Suggested by <Someone> in March, 2005 based on newsgroup discussion
at the time: hallucination protects against touch of death attack by
disrupting how the hero's brain reacts, so why not against gaze attacks
too? This gives hallucinating hero 75% chance of being unaffected by
gazes. If unaffected or if the gazer has been cancelled, the gaze will
fail with some feedback. Previously, all cancelled gazes failed but only
Medusa's gave feedback.
This will give players another way to defeat Medusa, but since it
isn't foolproof and there are several sure fire ways already, I don't
think it'll hurt play balance there. It may be useful to avoid getting
repeatedly stunned by Archons though.
"The death ray hit it." Changes to vtense() during the makeplural
makesingular overhaul four weeks ago contained a typo, or rather a set of
matching thinkos.
From a bug report, 2005:
engulfers affected by conflict might swallow and kill monsters in pools
(not mentioned: or lava or traps) and move to that spot, then not drown
til next move. Make drowning and trap checks when engulf attack succeeds
instead of waiting for next turn.
[This was #2 of the 3 minor bugs; the others have already been fixed.
They were: (1) placing and exploding a land mine on a lowered drawbridge
would leave a pit instead of destroying the bridge; and (3) cause of death
string "killed by Mr. Izchak, the shopkeeper" should omit "Mr.".]
From a bug report, 2005: applying a
polearm towards a monster ignores the `confirm' option. It's a wielded
weapon attack but is handled internally as a throw since it's also a
ranged attack. The report included a small patch for use_pole() but I'm
calling the regular attack confirmation routine instead.
Also, move the penalty for samurai attacking peaceful monsters into
the same routine that handles knight attacking defenseless monsters so
that they're more consistent.
Revise untrap() to handle being unable to reach the floor. That
whole routine is a mess and should probably be rewritten.
Included at no extra charge: #untrap didn't check whether player
picked a spot off the edge of the map so could go out of array bounds.
From a 7.5 year old news posting (with a reply by Kevin Hugo speaking
on behalf of slash'em...): when a monster "nimbly jumps to evade" hero's
kick, it can pass through walls and grid bugs can jump off their grid.
Likewise when a joust or staggering blow knocks a monster back, it could
move grid bugs diagonally. This fixes both cases.
Offhand I can't think of any other non-standard movement situations
which might need similar handling, but it wouldn't surprise me if there
are some. Leashed movement is close but I don't think maybe_mnexto helps.
The documentation for symset also changed Guidebook.tex to use the
hyperref package, which the old DECUS TeX distribution I'm using doesn't
have. I can't remember any discussion about inserting URLs into the
Guidebook and using LaTeX to generate html output. If there was, no
comments to that effect made it into the .tex file or the cvs log text.
So I'm guessing that \usepackage{hyperref} was a work-around for the
font issue (below) and that the latter was a side-effect of converting
from deprecated \documentstyle{} to recommended \documentclass{}.
I tried installing hyperref after tracking it down, but using it
generated complaints about several other packages either being too old
or missing entirely. Coping with them would be too much hassle. I also
tried just commenting it out, but that results in a font warning that I
assume isn't present when it gets used. I managed to cobble together
a fix for that, but since hyperref.sty isn't actually needed by our
Guidebook, it was simpler to revert to the way things were done back in
the old days....
Last fall when Michael added the symset stuff to supersede the old
handling for IBMgraphics and DECgraphics, Guidebook.tex was changed to
support multi-page tables in the output. But that requires that the
input be processed twice, because it requires feedback stored in
Guidebook.aux and the first pass can't rely on that file being present
or up to date. This updates the Unix, VMS, and OS/2 makefiles to do
two-pass processing. (I didn't see latex usage anywhere else, and the
branch version doesn't include the formatting change which needs this.)
Rephrase "a type of object" to "the type of an object" in the menu.
#name
What do you want to name?
a - a monster
b - a particular object in inventory
c - the type of an object in inventory
d - the type of an object on discoveries list
Implement <Someone>'s menu-mode for #name, primarily because it
is the natural place to add [re]naming entries in the discoveries list,
something that was requested in the newsgroup ten or so years ago. The
latter allows changing the type name of something which has previously
been named and is no longer being carried.
This also makes the C command become a synonym for #name or vice
versa; one or the other could now be reassigned to something else.
Implement <Someone>'s menu-mode for #name, primarily because it
is the natural place to add [re]naming entries in the discoveries list,
something that was requested in the newsgroup ten or so years ago. The
latter allows changing the type name of something which has previously
been named and is no longer being carried.
This also makes the C command become a synonym for #name or vice
versa; one or the other could now be reassigned to something else.
#name
What do you want to name?
a - a monster
b - a particular object in inventory
c - a type of object in inventory
d - a type of object on discoveries list
Menu group accelerators provide unseen alternate choices: C for monster,
y for individual object, n for object type (and d for discoveries, but
that's only interesting if inventory is empty so that usual b & c are
omitted and discoveries entry moves up to b). These alternates allow
`#name y' and `#name n' to work the same as before, for users who have
trouble retraining their fingers. Using C to name a monster now takes an
extra keystroke, but using `C C' for it could make that be less annoying.
Something else from a copy of an old news message:
You return to human form!
Do you want your possessions identified?
I don't think that this can actually happen any more because the pieces
of code which subtract hit points should all be polyself aware now, so I
didn't bother with a fixes entry for it.
This is probably on <Someone>'s bug list, but I don't remember where
that lives. I found a copy of an old news message by him which pointed
out that gem probabilities are set for a given dungeon level at the time
it is being created, but they don't get reset when an existing level is
revisited. So giants' inventory creation and any monsters' death drops
generate gems using values from the level most recently made rather than
from their/hero's current location. That can lead to high level gems in
the main dungeon after entering the mines.
While testing something, I noticed that my last remaining discovery
would never be forgotten. The formula
count = ((count * percent) + 50) / 100
always yields 0 with count==1 and percent==25 (the value used for mind
flayer attacks). Not likely to come up in actual play very often....
From a bug report: nymphs could steal
boulders even though they aren't allowed to pick those up. It happened
becuase can_carry() is only called for monkeys (consequently, they don't
have this problem), not for nymphs.
From a bug report: amulet of strangulation
continues to kill hero if he polymorphs into a creature which doesn't
need to breathe or doesn't have a head or even a circulatory system.
Currently, the messages are different when the hero doesn't need to
breathe, but that doesn't seem good enough. This makes strangulation
stop when you polymorph into something which shouldn't be vulnerable and
restart if you poly into something vulnerable while still wearing the
bad amulet.
can_be_strangled() is doing more checks that necessary, in case the
strangulation property ever gets conferred by something other than an
amulet. Its criteria for protection from strangling might need tweaking.
From the newsgroup: Conflict caused tame engulfer to swallow hero.
To try to get out, player hit it (with Magicbane, but that's not relevant
other than to provide an alternate "you hit it" message).
The magic-absorbing blade probes the invisible Audrey!
You get regurgitated!
placing defunct monster onto map?
Program in disorder, &c
[some look_here() feedback]
You kill poor invisible Audrey!
The problem was caused by hmon_hitmon(): it subtracted damage from the
target's hit points, did some bookkeeping and message delivery, then
called killed(). One bit of bookkeeping was to call abuse_pet() and
monflee() when the target is tame, regardless of whether the damage was
fatal. monflee() -> release_hero() -> expels() puts the hero and the
engulfer back onto the map, and that warning was triggered because the
former engulfer had no hit points left.
From a bug report, getting the "you kick at
empty space" result doesn't use any turns but can have side-effects like
waking up monsters and negatively exercising hero's stats. It should take
a turn even though nothing gets kicked.
Add #vanquished command to show the vanquished monsters list during
play. At present it's only available in wizard mode. Slash'em has it as
a regular mode command, and I found it handy sometimes: when I managed to
kill an unfamiliar monster, I could immediately get an idea of how the game
ranked its difficulty compared to other monsters. But having this command
available might encourage extinctionism. On the other hand, it might stop
some existing extinctionists from cycles of save+copy+restore+quit to view
disclosure data for their current game.
This also makes merging the wizard mode extended commands into other
extended commands be more robust. It will panic instead of going out of
array bounds if someone adds entries to debug_extcmdlist[] without also
expanding extcmdlist[] to make room.
From some notes I made prior to release of 3.4.3, about applying a
carried mirror in the direction of a monster:
invisible player applying mirror toward monster which can't see invisible
should have no effect (monster can't see hero's equipment);
similarly when inside engulfer regardless of whether it can see invisible;
applying mirror at worm tail shouldn't work but does;
applying mirror toward unseen monster that can see invisible (so should be
able to see its own image) doesn't work because bhit() won't target it;
mirror shouldn't work when target is only visible via infravision.
The fourth one is iffy since it assumes that invisible monsters produce
invisible reflections rather than no reflections. The reverse of that is
probably more reasonable but isn't as interesting. The fifth one may be
contradictory; it fails to extend that logic to "infravisible monsters
produce infravisible reflections."
splatter_burning_oil() is called when a lit potion of oil gets
broken, and it can dish out fatal damage to the hero. An earlier fix
to prevent a light-source panic (thrown item is not on any of the object
lists) during bones creation didn't address leaving that lit potion
intact if it was on the floor (which can happen if the breakage is caused
by striking or force bolt rather than its being thrown or kicked). Use
the existing obj->in_use mechanism as a more general fix, after teaching
bones code that it applies to other things besides the hero's inventory.
From the newsgroup: Sunsword is ineffective against shades. It
gets a special bonus of double damage vs undead, but since it's not made
of silver it was only doing 1 point of damage against shades. Make the
bonus-vs-undead attribute override the silver-required criterion. (No
comparable handling for flimsy weapons against thick-skinned critters
this time.)
Reverse the previous patch. It made other artifacts like Fire Brand
also do full damage against shades, which wasn't inteded. Back to the
drawing board....
From the newsgroup: Sunsword is ineffective against shades. It
gets a special bonus of double damage vs undead, but since it's not made
of silver it was only doing 1 point of damage against shades. Make the
bonus-vs-undead attribute override the silver-required criterion. (If
there's ever a whip or other flimsy weapon which gets a bonus against
some type(s) of thick-skinned monster, its attack will override the skin
thickness in similar fashion.)
A change a couple of weeks ago to have player's chosen ammo be auto-
quivered when using the 'f' command while quiver is empty was excluding
objects with quantity 1. That was on the basis that it was in the process
of being thrown so there was no point in putting it into the quiver slot
first. But if it was a boomerang, or Mjollnir under suitable conditions,
there was a chance for it to be available for another throw, so there is
a point to quivering it. Also, player can hit ESC at the direction prompt
and end up not throwing it after all. So, put even quantity 1 items into
the quiver when 'f' command is used with empty quiver.
I found a copy of a news posting from 1996 which suggested that
using a[pply] to break a wand which has 0 charges should have a chance of
wresting out one extra charge, like zapping. That way the player can't
destroy spent wands with impunity, and it makes the two wand actions be
more consistent. Also, it's trivial to implement. :-)
Move some common code from makeplural & makeingular into a separate
routine. Also, add ``candelabrum <-> candelabra''. Wizard mode wishing
for "candelabra" now works; "Candelabra of Invocation" does not--not due
to case but because the " of " isn't preceded by 's' in the plural form.
From the newsgroup: attempting to #chat to a gnome elicited "the
gnome grunts" (because gnomes have MS_ORC sound, and MS_ORC is just a
synonym for MS_GRUNT) even when the hero was a gnome. This patch makes
MS_ORC (orcs, gnomes, kobolds, a couple of named demons) or MS_GRUNT
(ogres, ettins, trolls, gargoyles) behave as MS_HUMANOID when the hero
has same race. That by itself wasn't quite enough; hostile MS_HUMANOID
monsters other than fake players wouldn't respond, so this gives those
a generic message (threatening the hero). In a somewhat similar case,
peaceful MS_CUSS monsters wouldn't respond; now they say something too.
Spotted by Janet: in the ``using #monster to breath[e] at self''
patch I accidentally reversed the Half_spell_damage adjustment (to breath
only from non-breath attacks only, not by doubling instead of halving
damage :-). Changing it to include zaps by the hero is intentional.
When testing the monster-breath-at-self patch I noticed that trying
to cure green slime by having hero breathe at self didn't work. The code
was calling buzz() with arguments that produced an attack directed against
the hero's location, but there was a chance for it to miss outright and
when it didn't, reflection would block it. This makes breathing at
yourself with `#monster' comparable to zapping a wand or casting a spell
at yourself: it always hits.