Another minor oddity (did not have time to trace it). Charges for damaged
weapon refer to it as "weapon in hand":
--
As you read the scroll, it disappears. Being confused, you mispronounce
the magic words... Demirci's long sword is covered by a mottled purple
glow! "You degrade that long sword, you pay for it!"
Call a scroll labeled VERR YED HORRE:
What do you want to wield? [- ajrw or ?*] j
j - a rustproof athame named Magicbane (weapon in hand) (10 aum).
What do you want to drop? [$a-df-rtwxM or ?*] r
You drop a long sword (40 aum).
Demirci offers 8 gold pieces for your long sword. Sell it? [ynaq] (y) y
You sold a long sword (40 aum) for 8 gold pieces.
You see here a scale mail (250 aum).
You see here a ring mail (250 aum).
A rustproof long sword (weapon in hand) (40 aum) for 15 zorkmids. Pay?
[yn] (n)
You paid for a rustproof long sword (weapon in hand) (40 aum) at a cost of
15 gold pieces. "Thank you for shopping in Demirci's used armor
dealership!"
--
I'll push a formatting guide at some point. There may still be
outstanding changes, but please feel free to resolve those as you arrive
a them.
To the best of my knowledge, there is no changes to the actual code
content, but the formatter does have the occasional bug. If you run into
an issue, please fix it!
Thinko fix: sanity checking for owornmask was mis-treating
OBJ_MIGRATING as OBJ_MINVENT of migrating monsters rather than as
unattended objects and would have had problems similar to obfree's
inappropriate impossible check.
Sanity checking for objects worn in invalid slots (amulet worn in
a ring slot and so forth) is extended to items worn by monsters.
Also add a check for wielded coins since the loophole that let them
become wielded has been closed.
Fix the problem with erroneously detecting wielded or quivered
chained ball which legitimately has more than one mask bit set.
Add an additional check for valid wornmask of an item somehow worn
in an invalid slot (such as an amulet in one of the ring slots).
Only lightly tested; it really needs debugger assistance to force
various invalid situations but I don't know gdb well enough for that.
Extend the processing done by the wizard mode 'sanity_check' option
to look for anomalies with obj->owornmask since there seem to have
been a few lately. I haven't actually triggered any so this code
isn't very well exercized yet.
sanity_check uses pline() rather than impossible() or debugpline()
to deliver messages so might not be very useful with keymasking.
A sizeable chunk of this diff is just cleaning up indentation so
that I could see what I was working with....
* don't let player wish for multiple globs
* use newsym() to clean up merged globs on floor
* food effects should match original corpse effects
* tidy up remaining crash when merging in place
it should be possible to wish for globs now; also hero's
inventory, containers, ground, monster inventories will all
honor the globbiness.
basically, any way you bring two globs together (adjacent on floor,
same inventory, same bag) should cause them to merge, combining
weight and nutrition as appropriate.
20 seems low-ish on nutrition for a pudding (kelp fronds are 30!)
at first glance but this is easy enough to fix later; don't really
want players to be able to stock up on food _this_ way and accidentally
obsolete all the other food-generation methods.
flooreffects() covers most dropped/thrown/etc. cases, and the hooks in
invent and mon handle "deathdrops" along with picking up items.
still need to check putting into/removing from containers
* Replace variadic debugpline() with fixed argument debugpline0(str),
debugpline1(fmt,arg), and so on so that C99 support isn't required;
* showdebug() becomes a function rather than a macro and handles a
bit more;
* two debugpline() calls in light.c have been changed to impossible();
* DEBUGFILES macro (in sys.c) can substitute for SYSCF's DEBUGFILES
setting in !SYSCF configuration (I hope that's temporary).
This finally eliminates all direct increases of `oeroded` and `oeroded2`
and moves them all to go via `erode_obj()`. They are still manipulated
directly in a few places, but not to erode objects.
This now merges the `fire_damage()` function to a common codepath, used
for items on lava and burning oil, but fire needs more work. There is
still a duplication between `destroy_item()` and `fire_damage()`; the
two codepaths should eventually be merged in some manner so that there
is only one codepath to say "an object was affected by fire". This path
might require some parameters, such as whether the fire will just erode
objects or burn them outright, but that can happen another day.
Move debugging output into couple preprocessor defines, which
are no-op without DEBUG. To show debugging output from a
certain source files, use sysconf:
DEBUGFILES=dungeon.c questpgr.c
Also fix couple debug lines which did not compile.
This also includes fixes due to Derek Ray to depugpline to work better
on other platforms.
There is a lot of code affected by this, and Pat Rankin correctly
observes that it would be better to store roguelike as a level flag
rather than just using Is_rogue_level. A note for the future.
branch only. This adds a check when setting a new fruit so that if no fruits
have been created since the last time the option has been set, the current
fruit is overwritten. Result: the user cannot repeatedly set the fruit
option and overflow the maximum fruit number.
From a bug report, if the high scores file
is brand new (empty), statues placed in a cockatrice nest (special room)
end up all being giant ant statues. Statue creation for that room
suppresses object initialization (to prevent the statues from containing
spellbooks), so statue type is left as 0 by mkobj(), then when 'record'
is empty it never gets overridden with a role value as intended.
This forces obj->corpsenm to be initialized as NON_PM instead of 0
by default, then overrides that for corpses, statues, and figurines even
when mkobj()'s caller requests that initialization be suppressed. So if
'record' is empty, there will be a sensible fallback statue type.
obj->corpsenm is overloaded for leashes ('leashmon', mon->m_id),
potions ('fromsink', fountain quaff hack), spellbooks ('spestudied', the
number of times the book has been read), and loadstones (corpsenm hack to
handle singular vs plural for "you can't let go of that/those" message).
If there are any other hidden corpsenm overloads, they may behave
strangely now that corpsenm is defaulting to -1 instead of 0....
From a bug report, the weight of a non-cursed bag
of holding would be off by 1 when the weight of contents was a multiple
of 2 (for uncursed) or of 4 (for blessed), since the round off handling
added 1 when it shouldn't in those cases. Mainly noticeable when empty;
the extra 1 unit made it be twice as heavy as it should have been.
Probably never noticed in actual play. He has implemented a patch
which shows weights as part of an object's formatted description, making
this stand out. Supposedly the Vulture's Eye interface also added a
patch like that a farily long time ago; I wonder why nobody using it ever
noticed. (Maybe the weight was suppressed for bags of holding there?)
Rename ``kickobj'' to ``kickedobj'' so that the tense matches that
of ``thrownobj''. Also, move their declarations to decl.h and their
definitions to decl.c since usage has spread from dokick.c/dothrow.c to
various files and is about to expand to another one.
A mimic posing as a statue was displayed as a tengu statue (and
recognizeable as such now that statues are displayed as the corresponding
monster rather than rock-class back tick), but the lookat code described
it as a giant ant statue (since there was no obj->corpsenm available to
indicate the monster type, it defaulted to 0). This adds monst->mextra
field `mcorpsenm' so that mimics have a place to remember what sort of
statue or corpse they are mimicking. And it picks a random monster type
when they take such forms so that the old tengu hack becomes irrelevant.
newmextra() and newoextra() initialized pointers via memset(...,0)
which is not portable; switch to explicit assignments. The wizard mode
code to display memory used for monsters and objects added in amounts
for the miscellaneous things pointed to by monst->mextra and obj->oextra
structs but didn't include memory for those structs themselves; add it.
Simplify monster save/restore slightly; there's no need for extra zeroes
to represent monst->mextra->X sizes when monst->mextra is null.
Update the startup banner for 2009. I should have done this with a
separate patch but I'm taking a shortcut. :-]
This started out as a one line change. After I saw someone in the
newsgroup mention that Sunsword's light was inferior to that of a lamp,
I decided to make it work better (than in 3.4.3, that is, becoming the
same brightness as a lamp) when blessed and worse when cursed (useless to
hero but still visible if wielded by a monster). But then it needed to
change light radius when its curse/bless state changed, and it needed
message feedback when doing so, and that got kind of complicated. I
wouldn't have bothered if I'd known what I was getting into, but I don't
want to throw it away now that I've done all this work....
Sunsword now gives a light radius of 3 when blessed (same as a lit
lamp), radius of 2 when uncursed (same as a lit candle and as it has been
providing since added in 3.4.0), and a radius of 1 when cursed (nearly
but not completely useless, as mentioned above). Also, it now "shines"
rather than "glows" since we usually use the latter for temporary effects.
I almost abandoned this when Michael beat me to it, but besides
handling the fruit rename bug it also moves `current_fruit' into the
context structure to eliminate separate save/restore for that.
From a bug report, wizard mode's sanity_check
option has a check for container contents but wasn't using it recursively
for nested containers, so the contents of the latter weren't checked.
This fixes that, and also adds a check for objects carried by migrating
monsters. And it now formats objects and monsters fully even if the hero
happens to be blind or hallucinating at the time.
Tested by using a debugger to poke in various bits of invalid data.
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.
Genociding * to clear a level in wizard mode, or paying off a
shopkeeper to dismiss kops in any mode, could trigger the recently added
warning about deleting worn items in obfree(). mongone -> discard_minvent
wasn't bothering to unwear/unwield monster gear before deletion.
Reported in August by <email deleted>, the code that handles
slower rotting for corpses on top of or buried under ice is misusing its
ROT_ICE_ADJUSTMENT factor such that a value other than the current 2 would
produce incorrect results. Instead of multiplying by 1/N it needs to use
(N-1)/N, which happens to be the same when N is 2. In a second message he
asked about why putting a corpse on ice starts out by subtracting from its
age to make it older, and it took me a while to decide that that is correct
behavior.
No effect on game play since ROT_ICE_ADJUSTMENT remains set to 2.
Someone in the newsgroup complained about zapping probing at a large
box dropped by a quantum mechanic and being told that it was empty rather
than that it held a corpse or live cat. This sidesteps the issue by
reporting "the box seems empty" instead of "the box is empty", and not
setting its contents-known flag. (That message is the main difference
between probing and the assorted other methods of observation [telepathy
and monster detection and possibly Warning for live cat, object detection
and food detection for dead cat's corpse] which might be expected to
trigger the cat's fate but don't.) This also makes probing of self and
of monsters set the contents-known and locking-known flags for containers
in inventory, same as is done for probing which hits objects. (Display of
container contents still only occurs for loose objects, not in inventory.)
From the newsgroup: you weren't charged anything if you broke the
lock of a box or chest which was owned by a shop. Force the hero to pay
for the damaged container; any contents remain owned by the shop and don't
affect the cost of the forced purchase. This existing entry in fixes35.0
is adequate to cover the fix:
various actions--such as enchanting--performed on an unpaid shop object
either force the hero to buy the item (when its value is lowered) or
increase the current bill (when its value is raised)
simple_typename and obj_typename operate on item types rather than
particular objects so have to assume that the item involved has been seen.
That means that simple_typename(obj->otyp) is not suitable; if obj->dknown
hasn't been set, it gives away information. This adds mininal_xname(obj)
to be used for that purpose. I'm not aware of any straightforward way to
actually expose the original problem; it's more than hypothetical but not
something anyone's likely to have come across.
Not fixed: test driver program reveals that obj_typename(GOLD_PIECE)
and simple_typename(GOLD_PIECE) yield "coin of gold piece". But I don't
think there's any way to get nethack to show that to the user.
Using #tip (post-3.4.3 code) on a container that's on a shop floor
didn't handle ownership correctly. Bag of tricks could be emptied for
free, and contents of other containers were being sold to the shop even
when the shop already owned them. This fixes bag of tricks and makes a
first cut at doing so for regular containers.
Message handling when #tipping any bag of tricks was also suboptimal
since the decision about message delivery was made again as each charge
released something instead of waiting until the whole bag was emptied.
So you could get inappropriate "nothing seems to happen" before or after
a monster visibily popped up if something unseen was also produced.
Make objects created by applying or #tipping a horn of plenty which
is owned by a shop also start out being owned by the shop. That's in
addition to the usage charge for using an unpaid item.
I think wishes conferred by unpaid objects, or by entities released
from unpaid objects, should probably work that way too, but have left
that alone.
From a bug report, the fallback selection criteria
(used when everything is extinct?) in rndmonnum() was excluding hell-only
monsters when outside of Gehennom, but failed to exclude never-in-hell ones
when inside. [Some of the never-in-hell monsters are Angels, but the rest
are all cold based creatures. That must date to when fire resistance was
required for the hero, which is no longer the case. Should those cold
monsters retain their never-in-hell setting?]
This also fixes a latent copy/paste bug in the unused mons[] definition
of Cerberus (it was the only unique monster which failed to specify G_NOGEN).