Noticed when incorporating the "vampire dancing" patch: losing a level
while polymorphed would subtract from your normal hit points but didn't
affect your monster hit points. Now they'll lose d8 from max and current,
similar to the amount they increase when gaining a level.
This also addresses an issue from the newsgroup a few weeks back:
someone mentioned an assumption that Stormbringer drained an amount other
than d8 for monsters who use some other formula for their hit points. It
wasn't true, but now it will be (approximately). Most monsters with unusual
hit points aren't subject to level drain, so it shouldn't have much impact.
Fix the problem pointed out by <email deleted>
where polymorphing into a new man at level 1 could be used to approximately
double or triple your hit points and spell power. With means to drain
level back down to 1 and with amulets of life saving to survive those times
you lose levels instead of gain, you could do this repeatedly and end up
with HP and Pw values in the millions.
This uses the earlier patch that records the HP and Pw increments from
level gains. Now when polymorphing into a new man, level based HP and Pw
are removed from the current values, remainder get multiplied by 80%, 90%,
100%, or 110% (average 95%, so tend to drop slightly), then a brand new set
of level gain increments (reflecting new man's Con and Wis) are added in.
Code for calculating spell energy is moved from pluslvl() and u_init()
into new routine newpw(). It and newhp() take over responsibility for
remembering the level based increments from pluslvl() which didn't deal
with the initial amount (stored in slot [0]; earlier patch didn't need it).
<email deleted> sent a report with
subject "Vampire-dancing can give you unlimited maxhp/maxmp" about how you
can manipulate your hit points and spell energy by using equipment to
lower Con and Wis prior to deliberately losing a level, then switching to
alternate gear to raise them prior to gaining the trivial 1 XP needed to
regain the lost level. With Stormbringer (to toss up so that it falls on
your head) or spell of drain level (to cast at yourself), you can do this
level toggling as much as you like since it doesn't consume any resources
in the process. All you is a supply of non-threatening monsters to kill
for the regaining half.
In March he sent "vampire-dancing (patch)" which didn't include a
patch but did give a URL ( http://nethack.angband.pl/vampdance.patch )
for one. That contained his suggested fix: recording the hit points and
energy points given each time you gain a level and then using those exact
amounts when you lose the corresponding level. It's still possible to
manipulate HP and Pw by losing multiple levels after you've boosted Con
and Wis to ascension ready status (you'll lose the original values but can
expect to get better ones when gaining levels back), but can only gain a
modest improvement and repeating it doesn't augment the effectiveness.
Plus it's much harder to regain multiple levels than it is to get just one.
His patch had a couple of bugs which I've fixed. I suppose that there
could be additional potential problems but the idea and its implementation
are both pretty straightforward. (This doesn't address the other recently
reported situation of using polymorph into "new man" while at level one to
multiply HP and Pw.)
I've gotten tired of seeing newsgroup claims along the lines of
"since devteam is aware of this and has chosen not to eliminate it, they
must endorse it", so weaken the tactic of "pudding farming". It is still
possible to gain unlimited experience (past level 15 or so there's not
much point), but will be less effective for gaining items and for providing
sacrifice fodder. Keep track of which monsters have been created via
cloning (mostly puddings; gremlins and blue jellies are affected too but
nobody's likely to care much about them) so that they can receive special
handling. Make cloned monsters progressively less likely to leave corpses
as the number killed for a particular type goes up, and also much less
likely to drop random items at death. This is sure to need some tuning
once hard core farmers point out how they can still abuse it. For the
absurdly extreme case, see
http://scavenger.homeip.net/farmbot/HomePage
FYI, farmbot/PuddingFarmingHOWTO includes an impressive screen shot of a
dungeon level where rampant farming is taking place.
Make it easier for a low level character with ordinary Max HP to get
the healing result from a successful prayer. Mid level characters are the
same as before: will be healed if at 1/7 (or worse) of max. High level
characters, or anyone with Max HP really high for their level, will need
to wait until current HP is lower before being able to obtain that result.
This mainly affects spoilers; the actual impact for any player who doesn't
know the old formula is fairly small. The exception is for "protection
racketeers" who manage to build up a high HP without gaining any levels;
a level 1 character will only get healed when at HP 5 or less, regardless
of what percentage of max their current hit points are.
Under the old system you could get healed at 6 HP if you had 42, at
7 HP out of 49, and so forth. Now you'll need to be at least level 2 to
get healed at 6 HP out of 30 or more, at least level 3 for 7-9 out of 35-45.
"Normal" max is capped at 15 times level and anyone above normal is treated
as if their max was that lesser normal value. Levels 1 to 5 use a new
threshold of current HP being 1/5 (or worse) of max, levels 6-13 use 1/6,
14-21 retain old 1/7 threshold, 22-29 now use 1/8, and level 30 uses 1/9.
The somewhat odd level break points are based on where rank titles change.
[This ought to be suitable for the branch version too but I'm not going to
spend the effort to migrate it there.]
Recently From a bug report, reducing
the value of a shop object via cursed enchantment was ignored by shopkeeper.
This replaces the existing costly_cancel() routine with costly_alteration()
which performs a similar task: bill for any item whose value has been made
less. The hero owns the resulting object but must pay for the original one
before being allowed to leave the shop.
This covers the majority of cases where bill_dummy_object() was already
being used: cancelling a charged or enchanted item, casting drain life at
same, diluting potions or blanking scrolls or books by dipping them into a
potion of water, dulling a weapon by engraving with it, eating unpaid food
or opening unpaid tins, applying a cream pie to hit yourself with it in the
face, applying a wand to break it, burning something by dipping it into lit
potion of oil, and clearing potions by dipping a unicorn horn into them.
The shop billing behavior for those actions hasn't been changed, just
consolidated into one place which delivers a common message for them.
This also covers many cases which weren't being handled: stripping
wand or magic tool charges via cursed scroll of charging, reducing a charged
ring's enchantment via same, reducing weapon or armor enchantment via cursed
scroll of enchant weapon or armor, stripping an item's rustproofing via
confused enchantment, making a crysknife revert to a worm tooth, unblessing
potions of holy water or uncursing potions of unholy water. (That last one
won't be billed if it's the result of prayer rather scroll, spell, or #dip.)
And this tries to handle the reverse situation more thoroughly too:
many actions which improve the value of an unpaid item now also cause the
shop bill to be updated to reflect its new higher price. Aside from the
basic enchanting and charging magic, it covers converting dragon scales into
dragon scale mail and worm tooth into crysknife. Some things which might be
expected to inflate shop prices, like rustproofing or increasing the number
of charges in a wand, don't actually affect the price. And there are bound
to be cases where the price is affected but I've overlooked.
As From a bug report, twice. Change max_passive_dmg to multiply the
result by the number of direct attacks the aggressor can make. This way, a
tame mind flayer, for example, will avoid pounding on a spotted jelly and
dying as a result of the Nth passive response.
Implement a user suggestion that tame humanoids should avoid eating
corpses of their own species. Prevent them--except for kobolds, orcs, and
ogres--from doing so unless starving. Arbitrary: tame elves won't eat
other elves even when starving. A polymorphed character will incur the
effects of cannibalism when eating either his/her underlying race _or_
the current one (player orcs and cavemen aren't affected though).
As reported, you'd get the "float gently to the ground" message even while
riding a flying steed. Rearranged the code and added a new case for this.
I found it odd that Hallucination protected you from falling out of the
saddle due to the Sokoban air currents. The message implied otherwise, so
I've made the sokoban_trap code apply in both cases.
<Someone> reported that if you polymorph into a flying monster while in a
pit, you must take u.utrap turns to first climb out before you can fly. Of
course, once you're out, you can swoop down into the pit to pick things up
w/o delay. Rather that have you automatically fly out (e.g. like quaffing
a potion of levitation), I thought it was better to take a turn to fly out,
so that's what I've implemented.
The code to deal with exiting a pit is moved to a new climb_pit function
and the "up" command now lets you climb from a pit too (something I've
found non-intuitive in the past).
Finally, I noticed that non-moving monsters could still go up/down even
though they couldn't move around. Added non-moving checks in doup/dodown.
move the message so it's before the mintrap test. newsym's are needed
to ensure the display is correct if a --More-- prompt results. I left the
"frighten" message alone, except for tense. As per Pat's suggestion, I
changed the wording to future-proof the message.
On Mon, 03 Jan 2005 12:04:29 +0000, <email deleted> wrote:
> Dear NetHack win32 developers,
>
> This bug does not affect the win32 binaries that you distribute but it
> does affect NetHack 3.4.3 if I build it from source. The difference may
> be due to different compilers or whatever. I'm using mingw32-gcc v3.2
>
> I don't quite understand what's going on (I never was much good at
> win32 programming), but it appears that the WM_KEYDOWN message for
> AltGr-4 is being translated into a WM_CHAR message with a wParam of
> 128. I don't understand why that should be, but anyway. The problem
> then occurs when NetHack casts wParam to char which, since char is
> signed, gives -128. onListChar() then passes -128 to isdigit() which
> causes the crash. The fix appears to be to simply drop the cast:
Also
> <email deleted>
> Newsgroups: rec.games.roguelike.nethack
> Subject: Changing tile set for item list?
> Date: 1 Jan 2005 20:03:08 -0800
> <email deleted>
>
> I'm using the windows interface for Nethack 3.4, and I've successfully
> changed the tileset used by changing defaults.nh. The only problem is,
> the item list (i.e. The list that comes up when I press "i") still uses
> the old tiles. Is there any way to change the list so it uses the new
> tiles? I've searched the guidebook to no avail. I'm debating if it is
> even possible.
>
> Thanks for the help,
> -Zmann
trunk patch:
- menu: display custom tiles if map is not ASCII
- menu: display '-'/'+'/'#' in place of a tile if map is ASCII
- fix isdigit() crash on AltGr-4 with mingw
It looks kinda weird with huge tiles (e.g. absurd96) but that could
be just me. Comments/suggestions are welcome.
-<Someone>
- always write plname into save file, no longer conditional
- add 'selectsaved' wincap option to control the display of
a menu of save files for ports/platforms that support it.
- add support for win32 tty using normal nethack menus.
- the win/tty/wintty code is generalized enough that any
tty port could support the option if the appropriate port-specific
code hooks for wildcard file lookups are added to src/file.c
specifically in the get_saved_games() routine. There is posix
code in there from Warwick already, and there is findfirst/findnext
code in there from win32. Warwick has the posix code only
enabled for Qt at present, but with wintty support, that could be expanded
to other Unix environments quite easily I would think.
Here is what the tty support looks like:
NetHack, Copyright 1985-2005
By Stichting Mathematisch Centrum and M. Stephenson.
See license for details.
Select one of your saved games
a - Bob
b - Fred
c - June
d - mine3
e - Sirius
f - Start a new character
(end)
The following files existed in the NetHack SAVEDIR directory
at the time:
ALLISONMI-Bob.NetHack-saved-game
ALLISONMI-Fred.NetHack-saved-game
ALLISONMI-June.NetHack-saved-game
ALLISONMI-mine3.NetHack-saved-game
ALLISONMI-Sirius.NetHack-saved-game
Note that despite the file names, the actual character name
is drawn from the savefile.
The WIN32CON support passes
USER-*.NetHack-saved-game
to findfirst/findnext where USER is your login name of course.
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.
<Someone> wrote:
> From the mkclass() comments:
>
> /* Assumption #2: monsters of a given class are presented in ascending
> * order of strength.
> */
>
> And monst.c:
>
> * Rule #2: monsters of a given class are presented in ascending
> * order of strength.
>
> * Rule #4: monster subclasses (e.g. giants) should be kept
> * together, unless it violates Rule 2. NOGEN monsters
> * won't violate Rule 2.
>
> Inspecting my monster-difficulty spoiler, I see the following places
> that these precepts are violated: do they cause potential problems?
> (Insofar as occasionally incorrectly miscalculating the probabilities
> for monster generation is a "problem", that is...)
>
> SPECIES DIF
> ~~~~~~~~~~~~~~~~~~~~~~ ~~~
> d dog 5
> d large dog 7
> d dingo 5
>
> d warg 8
> d winter wolf cub 7
> d winter wolf 9
>
> u white unicorn 6
> u gray unicorn 6
> u black unicorn 6
> u pony 4
>
> H frost giant 13
> H storm giant 19
> H ettin 13
>
> P black pudding 12
> P green slime 8
>
> S pit viper 9
> S python 8
> S cobra 10
>
> Z giant zombie 9
> Z ghoul 5
>
> @ nurse 13
> @ soldier 8
> @ sergeant 10
>
> & horned devil 9
> & succubus 8
>
> & balrog 20
> & sandestin 15
>
> (I've just realised that these may have already been fixed, and
> waiting on a file-compatibility-breaking release; if so, ignore me :-)
[Attention: This patch increments EDITLEVEL in patchlevel.h, rendering all
previous save and bones files obsolete.]
Here's the first cut at the two recommended flags lknown and cknown.
I've attempted to stay close to Pat's recommendations:
"Containers ought to have two new flags: lknown for lock status known,
and cknown for contents known (ie, `secret'). Formatted box and chest
descriptions should include locked/unlocked/broken when that is known
and empty/nonempty (or something like "holds N items") when contents
are known. The contents indicator would also apply to nonlockable
containers."
I probably overlooked a place where a flag should be adjusted, but this
should give us a good starting point.
I wasn't sure what to do with the case of the auditory feedback for
magical locking "Click" and "Clunk". The question that came to my mind
was: Should those reveal the locked or unlocked status of a box?
I suppose if you knew the type of wand you were zapping or the spell
you were casting, you could argue that they should.
In the end, I opted for setting lknown right off the zap/cast effect
for anyone playing a Wizard role, and not setting it for anyone else,
thus advancing class differentiation a little bit too.
I haven't checked the cknown results under all flags.menu_style options
at this point, only MENU_FULL.
Fix the situation <Someone> reported where a shopkeeper removing a trap
from the shop doorway yielded "you see the shop door reappear" instead of
reporting about the trap. It made sense if the door had been destroyed
but not when intact.
For trunk only, try to fix up the shop repair message situation when
multiple repairs occur at the same time. Some things were being treated
as mutually exclusive when they aren't. This part needs more testing,
probably using a debugger to force multiple pending repairs to all occur
on the same turn. At any rate, using wizard mode and hoping for some
simultaneous activity was ineffective.
- can shift into fog clouds, vampire bats, and vampire lords into wolves
- after being "killed" in shifted form, they transform back rather than get
destroyed, and you must take them on in vampire form to defeat them
- can deliberately shift into fog clouds to pass under closed doors
This is a foundation patch for patches to follow.
- use a full short index for mon->cham field.
- The current system of providing CHAM_XXX values
was limited to the 3 bits allocated in the bitfield and invalidated
save/bones if the field was expanded.
- The current system didn't provide an easy backwards change
if multiple monster types wanted to use the bit, there was a one
to one mapping: For instance, if you wanted a CHAM_VAMPIRE,
and you wanted vampires, vampire lords, and Vlad to use it, you
would have to have CHAM_VAMPIRE, CHAM_VAMPIRE_LORD,
and CHAM_VLAD defined to achieve that with the one-to-one backward
mapping.
- This new way just uses the mon[] index in the mon->cham field and
eliminates the need for CHAM_XXX (CHAM_ORDINARY is still used).
- no longer requires the cham_to_pm mappings
Play a character without see invisible. Wear speed boots. Generate a troll.
Zap it with a wand of make invisible. Kill it. Stand on the same square and
wait for it to rise from the dead. It will appear as a 'T'. Hitting it then
produces the normal "Wait, there's something here you can't see!"
[ incorporate slashem-Bugs-951439 fix ]
on Sunday, April 4, 2004 at 20:27:06:
> On occassion when restoring a game where the
> character is wielding Sting, floor glyphs
> will show up before the --more-- prompt.
> These floor glyphs usually correspond to the
> location of monsters (sometimes they are just
> cavern features such as walls). Some of these
> floor glyphs are not in the character's line
> of sight upon restoring.
Also in this patch is a restore of Sting's ability
to glow blue.
This patch increments editlevel making existing save and bones files useless.
Add polywarn() code to grant the ability to detect certain monster
types while polymorphed into other specific monster types.
If you polymorph into a vampire or vampire lord, you are able to
sense humans.
And just for fun, if you polymorph into a purple worm, you are able to
sense shriekers :-)
Give more information about your attributes in debug mode
via Control-X.
I'd like to see some way of getting bits of this info to the
player during the game (from the Oracle or something),
but this patch keeps it limited to debug mode.
On mazelike levels, mimics will mimic either boulders or statues (of giant
ants, as it turns out). However, it does not make sense to mimic a boulder
on a hole or even a pit, since boulders would typically fall in. Also,
statues are not typical objects in Sokoban. So, skip statue special case
in Sokoban and always avoid the forced emulation of a boulder when on a
trap location outside a room. This is a bit drastic, but I couldn't think of
an argument for adding the code to do this only for pits, holes, et al,
which are the most likely traps outside rooms anyway.
Try to fix the report of a doppelganger (created from using stone-
to-flesh on a fake statue of Demogorgon) having 1700 hit points after
reverting to its native form. The problem was due to the special monster
level of Demogorgon rather than anything to do with shape changers; the
actual bug was use of `mdat->mlevel' where it should have been using
`mtmp->data->mlevel'. But the whole section of code was rather suspect
since it didn't attempt to handle other types of monsters (dragons, golems,
elementals) which have non-standard hit points, so I knocked some out.
Monsters who have gained or lost levels prior to changing form will no
longer carry that adjustment along; the new form will always be a brand
new one of its type. However, if the old form is injured at the time of
change, the new form will be too (same as before).
Since the rogue level does not have closed doors, mimicking one there makes
no sense. Similar to what wand of locking does there, make mimics that end
up there mimic a wall instead of a door.
There was already code to ensure that if a hidden monster moved, it would
no longer be hidden. However, if the monster is asleep or whatever under
a rotting corpse, when the corpse rotted away, the monster would not
immediately become detected. Add a check to the rot code before the newsym.
Attempting to go > while blind and floating over unknown stairs/ladder
would refer to the stairs in the "high above" message (however, the
stairs/ladder remained unidentified on the map). Change this case so
it only refers to stairs/ladder if that's what the hero remembers on the map.
<Someone> wrote:
> "You kill the invisible storm giant. The boulder fills a pit."
> [...] why did I find the corpse *lying on* and not *buried in* the
> former pit?
Ensure that the corpse ends up buried in that case.
If you kick something while in the air (i.e. on the Air level or while
in a bubble on the water level), 1) greased objects were treated specially
and 2) messages were given about the object sliding.
- add checks for kicking in the air, and always increased distance a bit
(I didn't add any checks to deal with the transition from air to water or
visa versa)
- don't set the flag that causes the "slides" message in these cases either
This patch simply keeps the score from wrapping by capping it at LONG_MAX.
If someone wants to change the score to be unsigned, some changes will
need to be made to tweak this code (and use ULONG_MAX instead).
I'm assuming that our platforms all have limits.h.
<Someone> reported that freezing the swamp on Juiblex' level would result
in message about a frozen moat. Avoid this by using waterbody_name
to to determine if it's a moat or not.
Extend the previous patch to cover all blown instruments. Also covers
the case of the player strangling. The test is moved to a new can_blow
function to keep the test in one place. It supports any monster, although
all current tests are for the player.
Restrict poly'd whistle use to monsters that can blow a whistle. The
restriction includes those that make no sound (or just buzz, which is a
wing-thing) and are either breathless, tiny (eg ants), headless or water
natives. Searching monst.c, this appeared to provide a reasonable set of
restrictions. There are a couple cases one might quibble about if someone
feels like refining this further.
A long time ago, a message to the list suggested that whistles should not
work underwater. I did some google research and this does appear to be
true for most whistles. However, magic whistles are magical, so I left
them alone (also, I did find one high-tech whistle in my research that
claimed to work underwater). Since being underwater affects pitch,
adjusted the magic whistle message slightly for that case.
While looking at the behavior of sitting hiders, I noticed other related
odd behavior.
- player hiding while poly'd as a hider that hangs on the ceiling now drops to
the floor before sitting (similar to the behavior of movement commands).
- trappers, as per data.base, don't hang on the ceiling. Changed the
mattacku case dealing with hiders to not treat trappers as ceiling hiders.
- updated can_reach_floor to also exclude ceiling hiders. This covers a
bunch of cases, such as pickup, look-here-while-blind, and so on. Another
alternative would have been to automatically unhide for all such cases.
trunk only, it's a minor bug IMO and we appear to be close to a release.
Add the ability to select the windowtype on the command line on Unix using
a new -wwindowtype option. I had thought the proposed patch could core
dump, but the default windowtype selection occurs earlier and ensures
that raw_print will always work. So, the only problem with the proposed
patch was it didn't move the linux and sco special-case code until after
the selection was made. That special-case code really should be moved to
to wintty.c, IMO since it doesn't affect other windowtypes.