* 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
Instead of just "while helpless", the death reason will tell
more explicitly why the player was helpless. For example:
"while frozen by a monster's gaze"
* 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).
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.
> On 01/30/2012 08:20 PM, <Someone> wrote:
> The boulder from a rolling boulder trap can be generated on a
> lava pool. mkroll_launch() in trap.c, line 1584 checks only for pools
> of water.
Add dupstr() as a substitute for strdup() so that out-of-memory
handling will be consistent with the rest of nethack, and make it aware
of nethack's heap logging. It's treated like alloc() so that its caller
can be logged for NH_HEAPLOG.
I put it into use in a few places, but there are lots more candidates
besides the existing calls to strdup() that should be replaced.
While testing something, I noticed that I could eat a tin (off the
floor) while polymorphed into a bat. The code to check whether the hero
could open a tin was testing for limbs, so winged critters passed. Now
it requires hands instead of limbs, and also that the current form be big
enough to be capable of wielding something (even though you don't need to
be wielding anything to open a tin).
This means that a hero poly'd into a dog or cat will no longer be
able to serve him-/herself dinner from a tin....
Simplify many of the intrinsics macros from
#define xxx_resistance (Hxxx || Exxx || resists_xxx(&youmonst))
down to
#define xxx_resistance (Hxxx || Exxx)
by setting or clearing an extra bit in Hxxx during polymorph so that the
resists_xxx() check becomes implicit.
Unfornately there were lots of places in the code that treat Hxxx
as a timeout number--primarily for Stunned, Confused, and Hallucination;
Stunned happens to be one of the revised macros--rather than as a bit
mask, so this patch needed a lot more changes than originally antipated.
<email deleted> suggested that eating a cursed apple
give a Snow White reference. The apple eaten by Snow White is described
as poisoned, but cursed seems close enough. Fall asleep for 20..30 turns
if you eat a cursed apple when you lack sleep resistance.
While looking at fixing the mfrozen issue for monsters (there's no
way to tell whether it's been caused by sleep or paralysis, necessitating
that some messages be vague or suppressed when actions impact monsters
who can't move), I noticed a drawbridge bug for the hero. It was using
the misleadingly named Sleeping intrinsic incorrectly. When that is
nonzero, the hero is prone to falling asleep at random intervals, not
necessarily asleep right now. I've always intended to rename it to
something that's not misleading, but hadn't ever gotten around to doing
so, until now: change the SLEEPING property to SLEEPY and the Sleeping
intrinsic/attribute to Sleepy.
This may be moot for the drawbridge. I can't remember any hero ever
jumping to safety instead of being crushed by either the bridge or its
portcullis, and I'm sure sleepiness hasn't been a factor. So I haven't
included any fixes entry about misusing Sleeping when it meant u.usleep
(or better yet, unconscious(); or even better, Unaware [a post-3.4.3
pseudo-property that tests both unconscious() and fainted() when checking
whether hero is incapacitated]).
Contributed by <email deleted>, give an
alternate message when eating a corpse while hallucinating, including one
that gives homage to Tony the Tiger from old Frosted Flakes commercials
if you happen to be polymorphed into a tiger. Even players who try to
keep their characters hallucinating all the time are unlikely to ever run
into "tastes gr-r-reat!".
I rewrote the conditional expression to only test Hallucination once.
And I added the comment about omnivores, who'll never get "is delicious"
result with the current carnivore vs herbivore logic. (That behavior has
been around for quite a while, but seems somewhat suspect.)
MAC is defined for MacOS 9 but not for 10 (and it shouldn't be). Add a MACOSX
define and use it in eat.c to pick up the joke meant for all Mac systems.
Suggested by <Someone> <email deleted>, fainting from lack
of food while wielding a cockatrice corpse should fall on that corpse
and be fatal, like triggering a pit or moving down stairs while too
heavily encumbered. I put the fixes entry in the new features section
even though it probably qualifies as a bug.
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.
A change yesterday made putting on an amulet of restful sleep avoid
clobbering the timeout from having already eaten one, only replace it if
the new timeout is shorter. This does the inverse; when eating one, if
you're already sleepy from also wearing that type of amulet, only replace
the timeout if new one is shorter. And don't clobber the other intrinsic
bits with FROMOUTSIDE, just add it to whatever ones might already be set.
Neither should have any observable effect on game play, so no fixes entry.
Implement something <Someone> suggested a long time ago: eating a
disenchanter corpse has a chance to remove an intrinsic. Uses the same
routine as nighttime gremlin attacks, which chooses an intrinsic randomly
and attempts to remove it, so has no effect if it chooses one the hero
lacks. This can be used to remove "aggravate monster" but is much more
likely to target something the player wants to keep. [By the way, a lot
of potential candidates are missing: sleep, shock, and disintegration
resistance and teleport control come immediately to mind.]
Also, it has been bugging me that you can get both strength and
fire/cold/shock resistance from the same fire/frost/storm giant corpse.
The code prevents mind flayer corpses from conferring both intelligence
and telepathy, so strength handling was inconsistent (even though it
predated mind flayers...). This causes strength boosting to be treated
as an extra candidate when selecting an intrinsic to confer, so you'll
either get strength or resistance (which might be a no-op) but not both
from those giants. And it special cases the other giants to have the
same 50% chance for boosting strength, even though the alternative in
their case is to do nothing instead of trying to confer something else.
Lastly, it now gives a message when you succeed in gaining strength.
From the newsgroup:
The tin opens like magic!
<some interruption occurs>
You stop opening the tin.
Either it opens immediately or it doesn't, so the "opens like magic"
message is inaccurate. Rather than simply changing the phrasing, this
gives blessed tins a 50% chance to really open immediately so that their
contents are available for eating on the same turn, and 50% to behave as
before but with a message which is suitable for the single turn delay.
Hero poly'd into a metalivore always gets the same-turn case when eating
any tin. Use of a tin opener has a chance to do so (always when blessed,
50/50 for same-turn vs 1 turn delay when uncursed, 33/33/33 same-turn or
1 or 2 turn delay when cursed).
Overall, blessed tins are better than they used to be, since half
of the time you'll save a turn, but they're still not reliable to eat in
the midst of combat since sometimes you'll need another turn and will be
likely to get interrupted in that situation. Uncursed tin openers still
give the same behavior as opening blessed tins, so are also better than
they used to be. Blessed tin openers are now superior, and cursed ones
are slightly inferior in addition to being welded to hero's weapon hand.
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.
New macro slimeproof() to decide whether something is susceptible
to turning into green slime. Most of this is just making use of existing
cached permonst values in damageum() and mdamagem() and shouldn't affect
anything. I wanted to avoid mixing that in with the actual slime changes
which are coming.
A couple of things noticed when looking at the death-by-brainlessness
code. The 3.4.3 code ran a loop while life-saving was keeping the hero
alive, which would work if someone added other sources of life-saving than
the amulet but not if they added some form which didn't get used up when
it kicked in. Post-3.4.3, the dev code eliminated the loop but was no
longer guarding against additional forms of life-saving. This attempts to
clear the relevant field once any form of life-saving takes effect (for
brainlessness). It's not perfect since someone could change `Lifesaved'
to look at something other than the hero's properties, but at least it
still avoids the risk of getting stuck in a loop if someone makes a really
bad customization.
Also, make life-saving use min(2*level,10) instead of flat 10 for
amulet or 8*level for explore/wizard survival when it saves someone whose
max HP have been clobbered somehow. Other places assume that 1 HP per
level is the lowest the hero will have; saved-life gives a modest bit more.
Lastly, some post-3.4.3 code to make ghosts/shades immune to brain
sucking was using mon_nam() to start a sentence; Monnam() is needed there.
Make polymorphing or changing alignment perform a touch check (as is
done when catching lycanthropy) on wielded weapon(s) to see whether the
hero can still use them in his new form. Part [2 of 2] will update
retouch_equipment() to check all items in use rather than just weapon(s).
(A comment or two in part 1 already refers to expected behavior of part 2.)
From a bug report, trying
to invoke a wielded artifact after changing alignment resulted in "the
<artifact> evades your grasp" but it remained wielded, contradicting the
message. This adjusts the message in touch_artifact() if the object is
already in inventory, and adds retouch_object() to handle cases where
failing to be able to touch ought to force unwearing/unwielding.
There's newsgroup discussion about a mind flayer sucking the brains
of a ghost, plus speculation that the fix for C343-121 has already taken
care of it. I agree with them that ghost's brains are too insubstantial
to be hit by brainsuck damage from mind flayers' tentacles. C343-121 is
vague enough to cover this; the corresponding fixes entry was more specific
and is augmented here.
From a bug report, but
just received: if you choked while eating a cockatrice egg and survived,
the turn-to-stone sequence wouldn't be initiated. For such eggs, turning
to stone starts when the food is finished rather than when it's started,
and fpostfx() wasn't called for food that triggered choking so the egg
went away without actually being finished. Fortune cookies, lumps of
royal jelly, and a few other things suffered from the same situation.
From a bug report: you could vomit when polymorphed into a rat but real life
rats can't/don't vomit. The latter was confirmed by <Someone> and <Someone>.
While testing a fix for this, I discovered a couple of other problems.
Healing magic which cured sickness failed to heal Vomiting (potion or
spell; unicorn horn deals with them separately). Enlightenment failed to
report Vomiting (it's not shown on the status line). Most significant was
that vomiting_dialogue() called vomit() twice (also make_confused() and
make_stunned() three times for every once intended). It was dividing the
remaining turns by 3 and then using that value to decide what to do, but
only message display took into account that the same divided value would
occur on 3 consecutive turns (or just 2 for the final countdown to 0,
because dialog routine gets called before timed-property decrement).
From the newsgroup: if polymorphed into a metallivore, you could eat
artifacts that you couldn't touch with your hands. Now you can't eat ones
which evade your grasp, and you take some damage from other touchy items
on--actually, prior to--the first bite. (Those still "taste delicious" if
you survive; I'm not sure whether this ought to be changed.)
There was code to give feedback if you attempted to offer the Amulet
on a regular altar instead of the final high altar, but that code was
unreachable; getobj() yielded "that's a silly thing" whenever you picked
an amulet while not on the Astral (or recently changed, Sanctum) level.
This allows you to try to offer the real or fake Amulet of Yendor on any
altar, but they'll only be listed as likely candidates when on the Astral
level. Conversely, it no longer lists carried corpses as likely candidates
at the Astral high altars; they're still acceptable but not what the hero
is supposed to be fiddling with there. Also, allow corpses on the floor
to be offered on high altars, fixing a complaint we've gotten a few times
over the years. (Unfortunately there's no way to suppress them as likely
candidates on the high altars while still allowing them to be sacrified.)
Change safe_qbuf() so that instead of picking one of three strings
for sprintf() to plug into a prompt string, it actually constructs the
full prompt string itself. Also pass in the unformatted object and a pair
of formatting functions instead of performing dual formatting in advance.
The actual formatting is done via new routine short_oname() which also
takes an object and a pair of formatting routines plus a target length.
It uses the first routine, typically xname() or doname(), and formats the
object, then if the result is too long it makes some transformations, and
tries again. If truncating "called foo" and "named bar" down to 12 chars
and omitting "uncursed, rustproof, thoroughly corroded" attributes still
result in a string that's too long, it uses the other formatting routine.
The latter calls one of several jacket routines around simple_typename()
to produce a short result.
This has been through about four incarnations now and has gotten a
bit less testing each time, but I need to get it in place before I end up
running out of gas and abandoning it. I've got some changes to shk.c
(where safe_qbuf is needed but not currently used) that now need to be
redone and will come eventually.
From a bug report: if you
attempted to eat a Rider corpse and got the 1/7 chance that non-yet-rotten
food will be treated as rotten, then also got "the world spins and goes
dark" result for rotten food, you would both survive the eating attempt
and also end up with a partly eaten Rider corpse. This patch treats Rider
corpses like lizard and lichen corpses; they'll never yield rotten food
effects. That way, they'll always be fatal to eat. They'll still end up
being partly eaten if you are life-saved, but since they'll immediately
revive, the only way you'll know that is to use probing or stethoscope to
discover that they've revived at less than full health.
Nearly two years ago, <email deleted>
suggested that lembas wafers and cram rations be treated like fortune
cookies and never yield the rotten food result. I'm guessing that cookies
are handled that way so that rotten food feedback doesn't override false
rumor delivery when they're cursed, rather than because they're considered
to be rot-proof. This implements <Someone>'s suggestion, except that cursed
lembas and cram will still behave like rotten food.