<Someone> reported: You kill it! A potion of invisibility shatters!
Change the rule in hero_breaks() to avoid giving info for things out of
sight, except when from_invent is set, to preserve desired behavior.
Several places were not using safe_qbuf or anything equivalent to avoid
overflowing a QBUFSZ buffer. Add more uses plus one special case. For
the current max lengths returned by xname(), I think this is
sufficient. This addresses a reported buffer overflow for a
"thoroughly rusty thoroughly corroded helm of opposite alignment", plus more.
Suppress "Mr" or "Ms" title for shopkeepers when they're going by a
first name rather than a surname. The bug report was for Izchak, but it
would have happened with the two last resort names (which I've never seen
in actual use) and for the "hippie names" used in post-3.4.x health food
shops. I have not attempted to specify gender for those, just flagged
them as first names. This prepends a prefix character to the name string
(see comment in shknam.c) to specify gender and/or first name vs surname.
Shop items stolen or destroyed without being in inventory were handled
inconsistently compared to simply picking up unpaid items because different
criteria got used to decide whether the shk cares about something. Last
December a hack to deal with this for container contents was introduced but
that left the problem for ordinary items. This patch attempts to address
it by using a common check for theft and for pickup's add-to-bill.
It hasn't had nearly enough testing and I won't be very surprised if
one or more new obscure shop bugs have now come into being, but perhaps
they'll at least be consistent bugs as far as shop billing is concerned....
Neither nymphs nor monkeys can steal a ring worn underneath gloves
since they can't see them. If such rings are randomly targetted, try to
take gloves instead.
Succubi trying to take worn ring of adornment will attempt to take
off worn gloves first. (Presumeably they can sense magic rings hidden
beneath gloves better than nymphs can; they're about to try to take all
worn armor off anyway....) If the glove removal fails, ring theft will
too. Likewise for incubi, remove gloves before trying to force the hero
to put on ring of adornment.
At the moment succubi and incubi can't remove gloves which are
blocked by a welded weapon, but they can manipulate rings then if there
aren't any gloves involved. I don't think that's right. The latter is
nymph-like and could be attributed to magic, but if that's the case why
aren't they able to remove gloves from under cursed weapons too?
Prevent monkeys from stealing any ring which the hero can't remove due
to it being stuck inside the grip of a cursed weapon. Nymphs can still do
so though. From a bug report.
Fix the two problems that <Someone> reported about stale pointer use
after a bag of holding has exploded. use_container() passed the wrong
variable for quantity when calling useupf(), and doapply() had no way to
tell if the object being used had been destroyed so could use an invalid
pointer when checking for speaking artifact. The fix for the latter is
much simpler than what <Someone> suggested.
Someone in the newsgroup mentioned that there is no warning from blessed
food detection if you attempt to eat a tin of Medusa meat. touch_petrifies()
isn't enough to catch that. A warning was given about Medusa's corpse, but
only if you lacked poison resistance. Eating a tainted Medusa corpse had a
similar problem; the check to override food poisoning so that petrification
takes effect missed it. This makes the petrification checks be consistent,
including hypothetical case of Medusa egg.
When a wish request for "<foo> armor" fails to match anything, check
whether it matches "<foo> mail" before resorting to selecting a random piece
of armor. Most of the suits are named "mail", and while I don't think many
people will ask for "ring armor", I do think that "crystal plate armor" and
"gray dragon scale armor" are sometimes tried.
This also greatly simplifies the handling for spelling variant "armour"
by rewriting it to "armor". Unfortunately "grey" vs "gray" can't be handled
the same way since both spellings are used by the program.
A user recently complained that he started an activity such as
searching and specified a repeat count, right after getting--and not
realizing the significance of--the first message in the countdown
sequence for turning into stone. He suggested that subsequent messages
interrupt multi-turn activity so that the player has a chance to do
something to prevent imminent death. This implements that, with the
added wrinkle that it won't interrupt if the activity is something that
might save the character's life: attempting to eat a tin that is either
sure to help (if ID'd as food that cures stoning) or a desparate gamble
(if unID'd). Some hooks for similar behavior for other conditions like
turning into slime are included, although no tins can help for anything
other than petrification so far.
Shouldn't fatal illness have an end-is-near countdown too?
Bug Report:
>> Status of the doppelganger (neutral): Level 13 HP 1433(1433) AC 5.
>> [See the HPs!! ]
Michael:
> I used a debugger and traced this massive hit point growth
> to this line in mon.c, function newcham(). (I watched the mhp
> jump from 58 to 567 with this one calculation!
>> Ah, I see that this problem is fixed in the trunk but still present in
>> the branch. This seems serious/abusive enough to warrant the fix to be
>> applied to the branch too, doesn't it?
Pat:
> I don't think it's all that important but you're welcome to
> extract and adapt the patch if you like.
From a bug report:
> If the Summon Nasties monster spell gates in two minions instead of one,
> the message still says "A monster appears from nowhere!"
The code wasn't counting any summoned monsters who had an opposite alignment
to the summoner. It also assumed that the 10% chance for demon summoning
in Gehennom always yielded exactly one monster even though that can produce
zero or more than one.
On Sat, 18 Dec 2004 14:07:14 +1300, <email deleted> wrote:
> Adding one of several candles to a candelabrum which already has six
> gives an ungrammatical message.
<Someone> wrote:
>> If the previous character was non-neutral, the unicorn would have
>> started off as hostile. When a bones file is loaded, I don't think
>> hostiles are made non-hostile, although the reverse is certainly true
>> (pets of the deceased are usually hostile).
>
> In the general case, they are, or rather their hostility is
> re-evaluated with respect to the new character; see the peace_minded()
> call in getlev(). However, co-aligned unicorns always being created
> peaceful is a special case in makemon(), _not_ part of peace_minded(),
> so they'd just have the usual chance of being made peaceful or not
> depending on alignment strength, as for any other co-aligned monster
> not explicitly declared always peaceful or always hostile.
<Someone> wrote:
> The "/* Fix up the quest nemesis */" code in role_init()
> adds M3_WAITFORU but _doesn't_ remove M3_CLOSE;
> since the Master of Thieves as the Rogue Quest Leader is
> defined with that flag, he keeps it when acting as the Tourist
> Quest Nemesis. Thus, when STRAT_WAITFORU
> is cleared by your actions, STRAT_CLOSE may stay in
> place making him stay meditating when another Nemesis
> wouldn't.
<email deleted> wrote on Friday, December 10, 2004:
> I was in a barracks with the soldiers sleeping. I started fighting one soldier
> and threw a potion of acid on him. I got the "The soldier shrieks in pain!"
> message, but none of the other soldiers in the barracks woke up.
Fix for first issue reported in this bug report:
<email deleted>
Sent: Thursday, December 09, 2004 7:13 AM
Subject: Two wrong messages
I would like to report two cosmetic issues:
1. "its gaze is reflected by the invisible [pet]'s shield."
Wrong capitalization.
2. The message given when decapicating an ettin {,zombie} with the Vorpal
Blade fails to mention the second head. This could be pretty tricky to
fix, but, per <Someone>'s suggestion, the easiest explanation would be
to say that the blade's wielder cuts off both heads at once.
The patch would look similar to:
*dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER;
> if(mdef->data==&mons[PM_ETTIN]
> ||mdef->data==&mons[PM_ETTIN_ZOMBIE)
> pline("%s goes through both necks of %s at once like butter!",
> wepdesc, mon_nam(mdef));
> else
pline(behead_msg[rn2(SIZE(behead_msg))],
wepdesc, mon_nam(mdef));
otmp->dknown = TRUE;
(and the same for youdefend)
Add the extra feedback suggested by <Someone> so that being blinded
by moving into a stinking cloud is explicitly pointed out to the user. It
makes things more verbose but seems reasonable. You get blinded for 1 turn
with every step, so the message gets repeated each time too, but since you
also get a choking or coughing message on each step it's only a modest
increase in the overall verbosity.
From a bug report: when a black light explodes and triggers
hallucination, its own monster symbol--or warning marker for same--could
be seen changing. Since nothing is left after it explodes, you shouldn't
hallucinate anything at its location. Fix by killing it off (so removing
it from the map) before initiating Hallucination.
The same occurred for fountains and drinking surrounding water while
underwater.
I also added a !Levitation check for sinks, like already exists for
fountains. I cannot believe sinks are taller than an altar, and if you
can't pick up stuff from an alter while levitation, it stands to reason you
cannot drink from a sink then either.
<Someone> reported that riding a steed into a magic portal can
give "steed is still eating" message, feedback normally used to explain why
you can't go down stairs. Rather than preventing portals from activating
in that situation, just force the meal to be finished in order to suppress
the message. Proper fix is probably to prevent all steed movement while
eating, but that would most likely result in no one ever riding again.
Fix the wizard mode crash From a bug report. Move the WIZKIT
message suppression to a lower level instead of trying to guard against
present and future pline() calls in the wishing code. The way that was
being handling wasn't suitable for dealing with quest feedback.
This also includes a couple of additional wishing synonyms.
Someone in the newsgroup expressed surprise that he didn't get any
special message after surviving the eating of a cockatrice corpse. Combine
the cliche that unconventional meat inevitably tastes like chicken with
the mythology that cockatrices are a bizarre hybrid of chicken and reptile
(or whatever). This will give a message about tasting like chicken for
corpses or smelling like chicken for tins when the hero has petrification
resistance (poly'd into a xorn, for instance) or is hallucinating.
A user reported that when breaking potions inside a box in a shop, he
wasn't charged for them. The code was calling stolen_value() as intended,
but that routine only charged for types of items which the shop normally
carries. That meant that breaking the contents of a box in a general
store would charge for them but doing so in a tool shop would, not even
though the tool shopkeeper would gladly sell such things when you picked
them up instead of causing them to go away.
When fixing this, I noticed that stolen_value() was only charging
for single items. Most of the time that was right, because throwing and
kicking things always split one off, but there are cases (such as zapping
a wand of teleportation at shop goods) where an entire stack gets stolen
as a group. This makes stolen_value() handle all quantities.
Eggs thrown straight up which don't splatter on the ceiling yield
"you've got it all over your face", so wearing a helmet shouldn't protect
against petrification from cockatrice eggs in that situation. This was
part of my delayed helm vs hat stuff; I can't remember whether it was done
before or after this same issue came up in the newsgroup.
Something from <Someone>'s list: some messages have hardcoded references
to "helmet" which sound strange when the character is wearing a hat or cap.
helm_simple_name() is comparable to the existing cloak_simple_name(). It
returns "helm" or "hat" depending upon whether the helmet provides the
same protection that yields the assorted repetitions of "fortunately,
you are wearing a hard helmet". This choice ends up categorizing elven
leather helm as a hat (which I think is ok given that its undiscovered
description is "leather hat"), contrary to <Someone>'s suggestion that the
distinction be made based on whether the helmet was made of cloth.
I started on this a year and a half ago but didn't commit it.
Unfortunately I don't remember why and haven't done any significant
additional work now--just recovered from some intervening bit rot and
confirmed that the patch as is seems to be working ok (in the trunk; the
branch side has not been tested). I suspect that I meant to look for
additional helmet messages which could benefit from conditional headgear
description. (Those "hard helmet" ones don't need it, although they
should perhaps be moved into a common routine instead of being replicated.)
Allow the #adjust command to be used to split an inventory stack
as well as for moving things to specific slot letters. Splitting is
accomplished by specifying a count along with the letter of the stack to
operate on, similar to when dropping a stack with 'd'. The comment above
doorganize() has more details.
This change will make it possible for users to split stacks of cursed
loadstones which they couldn't easily do before, but I don't see anything
wrong with that. It was always possible to have multiple stacks of load-
stones by starting with ones that had different curse/bless status, so this
hasn't introduced a totally new situation. On the other hand, I haven't
tested this with the GOLDOBJ configuration and am not sure whether there is
any need to prevent gold from being split there. The getobj() call doesn't
specify COIN_CLASS so perhaps it's irrelevant (unless it ought to be
changed the other direction by adding that to intentionally allow gold to
be split?).
Despite lack of feedback from the beta testers about it, add the code
which tries to stack an object being added to inventory with the quiver
before trying with other carried objects. Only matters to user if quiver
is non-empty and one or more other slot(s) are compatible with it, but
that's not uncommon for someone who starts a rogue by splitting the initial
daggers into separate wield and throw slots. Firing a dagger from quiver
and then having it merge with wielded weapon instead of back into quiver
when picked back up leads to tedious inventory manipulation. Assigning
different names to the two stacks solves this, but can't help when picking
up an unnamed item which is otherwise compatible. (A rogue with starting
daggers wouldn't encounter that since unnamed ones won't be sufficiently
identified to stack, but any character who just gathers unID'd daggers and
uses them for both melee and throwing has a chance of running into the
"picked up into less desireable slot" trap whenever new ones are found.)
<Someone> reported that she got "your weapon slips from your hands" when
inflicted with slippery fingers while wielding multiple daggers. That
should be "weapons" plural and they're only being dropped from one "hand"
singular. Fix that and also give more specific feedback than "weapon"
for non-swords based on their weapon skill category names. This works
pretty well for most common weapons but might need some more tweaking for
ones where different types have gotten lumped together in the skills.
old feedback:
Your weapon slips from your hands.
Your tool slips from your hands.
Your food slips from your hands.
twoweapon:
Your sword slips from your hands.
Your other sword also slips from your hands.
new feedback:
Your daggers slip from your hand.
Your <one-hander> slips from your hand.
Your <two-hander> slips from your hands.
Your pick-axe slips from your hand.
The corpse slips from your hand.
twoweapon:
Your sword slips from your left hand.
Your other sword also slips from your right hand.
From the newsgroup: if you were polymorped into a cockatrice and
a trapper attempted to swallow you, the 't' displayed at its location
would be left behind after it turned to stoned. This fixes that and a
much more serious issue as well: if you were punished at the time, the
game would panic on your next attempt to move because the ball&chain were
left in limbo. There would also have been strangeness (monster sharing
your location, stale u.ustuck setting) if the swallower was life-saved,
but I didn't try to make that happen so am not sure how bad things would
have been.
From a bug report, but pulls back" while successfully
praying. Gas spores' only "attack" is to explode when dying, so the code
that checks whether the monster has any attack needs to handle AT_BOOM as
a special case. Unfortunately this change means that you won't interrupt
an occupation when a gas spore approaches, and a subsequent kill by your
pet might end up causing you harm while still occupied. The callers of
`noattacks()' are messy enough that I didn't want to try to address that.
This also moves noattacks() from mhitm.c to somewhere more sensible.
Reported last December by <email deleted>. Using
a wand or spell of undead turning inside a shop used up corpses without
checking whether they were owned by the shop. Although the report didn't
mention it, using stone-to-flesh on statues had the same problem.
I'm not completely satisfied by some aspects of this code, but if I
don't commit what I've got now I probably never would. My original notes
are lost; I thought that there were some additional fixes present, but
looking at these diffs I don't see anything else significant enough to
warrant mention in the fixes file.
Fix the two minor grammar problems for messages given when eating
that were From a bug report: inappropriate or inconsistent
capitalization in mid sentence for
Ulch - That <object> was rustproofed!
and missing punctuation for the appended clause for cannibalism in
Ulch - that meat was tainted cannibal!
Patch was sent in by <Someone> on Sep 8:
This bug causes a number of impossible messages (starting with splitbill:
no resident shopkeeper??)
Repeat by:
Enter a large shop.
Wish for a large stack of projectiles.
Sell your projectiles and then pick them up again.
Trap shopkeeper against the door with a scroll of earth.
Throw the projectiles at the shopkeeper to anger him.
Move away from the boulder trap and wait for the shopkeeper to leave the
shop.
Throw one of the projectiles at the free space.
It appears that the Athena text widget in recent XFree86 distributions
does not properly honor the XawtextScrollWhenNeeded flag, so the text
widget created by X11_display_file() does not have a vertical scroll bar
when the text does not entirely fit in the window. I have seen this bug
in XFree86 versions from 4.0.2 through 4.3.0. Using XawtextScrollAlways
for the vertical scrollbar ensures it will always appear.
Objects which were destroyed by dipping them into lit potions of oil
didn't get unworn or unwielded in cases where that was needed. This left a
stale pointer which could result in various strange things (user saw it be
formatted as "glorkum" but that isn't guaranteed) and there was no update of
any attributes or intrinsics conferred by the item, so persistent levitation
or water walking or dexterity boost could occur.
Eliminate two minor anomalies in the behavior of the rnl() function
which returns a random number that is modified by the hero's Luck attribute.
Integer division by 3 on requests for small ranges and the fact that the
chance of making a modification was lower for good luck than for bad luck
meant that highest luck did not produce best chance to avoid worst result.
The actual effect on game play is sure to have been negligible. More
troubling is that the program has several rnl(3) and rnl(4) calls. These
practically guarantee a result of 0 when the hero has maximum luck. The
rnl() function really shouldn't be used for such tiny ranges (unless the
actual intent is that high level characters are expected to almost always
have the 0 outcome...).
<Someone> Cced from rgrn:
<email deleted> (<Someone>) writes:
[killed by a boulder trap, left bones]
> Then I realized... there's no boulder. Did the boulder disappear
> because I died from the attack, thus bypassing the code that moves the
> boulder to its intended destination? Did the creation of the bones
> file destroy the boulder? Do boulder traps sometimes get
> "deactivated" when bones files are loaded?
The first of these. If you look at launch_obj(), there's an
obj_extract_self() early on, then all the tracking its trajectory,
then a place_object() when it comes to rest; since the thitu() call
kills you during the trajectory part, the boulder never gets re-placed
onto the map. This is, I think, a bug (and one that will apply to any
monster-thrown object that kills you, as well); reported to the
DevTeam.
A user pointed out that you lose pacifism conduct if you kill your
pet by displacing it into a trap but you don't gain any experience in
the process. Make this consistent with killing monsters in other ways:
if you get blamed for it then you should also get credit for it.
Probably minliquid() and mintrap() should take another argument so
they can call killed() instead of mondead() when necessary, but I didn't
go to that much effort....