This is an overhaul to the NetHack drawing mechanism.
- eliminates the need to have separate lists in drawing.c
for the things and their associated explanations by grouping
those thing together on the same inializer in a struct.
- replaces all of these options: IBMgraphics, DECgraphics, MACgraphics,
graphics, monsters, objects, boulder, traps, effects
- drawing.c contains only the set of NetHack standard symbols for
the main game and a set of NetHack standard symbols for the
roguelevel.
- introduces a symbols file that contains named sets of
symbols that can be loaded at run time making it extensible
for situations like multinational code pages like those reported
by <Someone>, without hardcoding additional sets into the game code.
- symbols file uses names for the symbols, so offsets will not break
when new things are introduced into the game, the way the older
config file uchar load routines did.
- symbols file only contains exceptions to the standard NetHack
set, not entire sets so they are much less verbose than all of
the g_FILLER() entries that were previously in drawing.c
- 'symset' and 'roguesymset' config file options for
preselecting a symbol set from the file called 'symbols'
at startup time. The name of the symbols file is not under the
users control, only the symbol set name desired from within the
symbols file is.
- 'symset' config file option loads a desired symbol set for
everything but the rogue level.
- 'roguesymset' config file option loads a desired symbol set
for the rogue level.
- 'SYMBOLS' config file option allows the user to specify replacement
symbols on a per symbol basis. You can specify as many or as few symbols
as you wish. The symbols are identified by a name:value pair, and line
continuation is supported. Multiple symbol assignments can be made on
the same line if each name:value pair is separated by a comma.
For example:
SYMBOLS = S_bars:\xf0, S_tree: \xf1, S_room:\xfa \
S_fountain:\xf4 \
S_boulder:0
- 'symbols' file has the following structure:
start: DECgraphics
Handling: DEC
S_vwall: \xf8 # meta-x, vertical rule
S_hwall: \xf1 # meta-q, horizontal rule
finish
start: IBMgraphics
Handling: IBM
S_vwall: \xb3 # meta-3, vertical rule
S_hwall: \xc4 # meta-D, horizontal rule
finish
- 'symbols' file added to the source tree in the dat directory
- Port Makefiles/scripts will need to be adjusted to move them into
HACKDIR destination
I don't know if this was introduced post 3.4.3 or not, but the
DOS port was doing a chdir at the start, but not doing one
at the finish of the game, so you ended up in the same
directory as the NetHack.exe executable post-game.
It was doing the chdir even if NOCWD_ASSUMPTIONS was
defined.
> Give demon lords and other monsters who teleport to your location a
> oneshot arrival message. [...]
> The fixes entry is deliberately a bit vague (and I put it in the new
> feature section rather than the fix section).
And apparently I neglected to commit it with the rest of that patch last
week.
<Someone> wrote:
>>comments:
>>When you commit suicide with a potion of oil (lit), sometimes nethack
>>reports an `obj_is_local' error just after disclosing all the game
>>variables. This has been found in-game (don't ask) and reproduced in
>>wizard mode and in-game (start-scumming).
>
> 0) a neutral human wizard (the scrolls/spellbooks burning, potions boiling ;))
> 1) wish up 3 potions of oil (so that the 2 remaining will definitely kill you)
> 2) a'pply one of them
> 3) stand 1 square away from a wall, like "| @"
> 4) throw the lit potion into the wall (`h' in this case)
> 5) answer `yes' on all prompts.
The thrown potion of oil, which was extracted from any chain
during the throw, still had its timers attached when the call to
splatter_burning_oil() was made. If that killed the hero, a
panic would result during bones file creation (saving timers)
because (obj->where == OBJ_FREE) on the potion.
Remove the timer prior to splattering the oil inside.
Incorporate part of <Someone>'s changes to address
the main part of bug W343-3.
One other patch yet to come needs to provide a way
to limit the IBMGraphics symbols to various subsets that are
available on some international versions of Windows. Pat
suggested that we not incorporate that patch as is, so I'll be
working on an overhaul of the {DEC|IBM|MACgraphics mechanism.
* Checks for the presence of the Unicode
APIs. If GetVersion() returns the 31st bit set, NetHack is running on
a 95-based version of Windows. The Unicode APIs are not available
and NetHack will revert to the pre-patch behavior. This fix isn't needed
on 95-based Windows anyway.
* Fixes console output for text strings.
The character is converted according to the user's configured IEM code
page and passed to the Unicode version of WriteConsoleOutputCharacter.
* Fixes console output for map symbols.
The character is converted according to a fixed mapping containing
code page 437 plus the symbols in the space from 00 to 1F. A fixed
table is used so that a player using Lucida Console can get full
IBMgraphics (original set, i.e. level 3) regardless of the code page.
A table is used instead of MultiByteToWideChar so that the space from
00 to 1F will be converted correctly; this is necessary for correct
display of the Rogue level.
If you specified one or more palete options in the config file,
but not all 16, you ended up with black for any you didn't
specify - oops.
This patch ensures that the table has a full complement
of 16 colours by initializing it to the windows default colours
just ahead of the first palette option encountered.
As before, if the config file has no palette option in it,
no calls to change the palette are made at all. If the
undocumented method breaks in a future release of
Windows, then avoiding palette options will work
around the problem.
If you get "you have summoned <demon>" after making a same-race
sacrifice, treat that as having been the "<demon> appears" message so that
the latter won't be given if it subsequently teleports to you after you've
moved out of sight of it. There are probably some more cases like this
still lurking in the code.
Give demon lords and other monsters who teleport to your location a
oneshot arrival message. Brought about by the report of the late "<demon>
appears" message delivered during its bribery demand, after the character
had already been able to see it for long enough to extract gold from a bag.
Now, if you can't see or sense a monster before it teleports to you, and
you can see or sense it after, you'll get "<monster> suddenly appears!".
The message will be given at most once for any given monster, and it won't
be shown at all if you already see/sense the monster before it teleports or
still don't see/sense it afterwards. The fixes entry is deliberately a bit
vague (and I put it in the new feature section rather than the fix section).
The change from long to unsigned long for monst.mstrategy may bring
some lint complaints along with it. The various constants (STRAT_xxx) used
to populate it are still signed. I didn't increment EDITLEVEL for this;
existing data should still work ok.
Allow config file entries to adjust win32 console colours.
The following entries in a config file are examples:
OPTIONS=palette:black-0-0-0
OPTIONS=palette:red-210-0-0
OPTIONS=palette:green-80-200-0
OPTIONS=palette:brown-180-100-0
OPTIONS=palette:blue-0-0-200
OPTIONS=palette:magenta-128-0-128
OPTIONS=palette:cyan-50-180-180
OPTIONS=palette:gray-192-192-192
OPTIONS=palette:dark gray-100-100-100
OPTIONS=palette:orange-255-128-0
OPTIONS=palette:bright green-0-255-0
OPTIONS=palette:yellow-255-255-0
OPTIONS=palette:bright blue-100-100-240
OPTIONS=palette:bright magenta-255-0-255
OPTIONS=palette:bright cyan-0-255-255
OPTIONS=palette:white-255-255-255
This uses an undocumented way to adjust the console
colours in a win32 console application. The method and
code snippet used comes from www.catch22.net by James Brown.
This page:
http://www.catch22.net/about.asp
states the following:
"you do not have to pay anything to use the software, and there are no
licencing terms for any sourcecode that you may download from this site.
This means you can freely use any sourcecode or portions of code in
your applications, whether they be free software or professional, retail
products."
Unaware; fix #H202 and extend the fix for #H179 (trunk only)
Turn being unconscious (via several reasons, including fainted from
hunger) into a pseudo-property named `Unaware' and use it in several
places where only being asleep was checked. #H202 was about a stunned
character who got the recovery message when it timed out while fainted.
This suppresses messages for several difficulties when they begin or end
while hero is Unaware. Messages about fatal illness, sliming, or
petrification aren't suppressed; they're too important to hide from the
player. "You feel ..." messages come out as "You dream that you feel ..."
when Unaware; fairly lame but hopefully adequate.
nethack.rankin [Sun, 27 Aug 2006 02:09:39 +0000 (02:09 +0000)]
fix #H179 - blinding attack while fainted
From a bug report, being hit with a
yellow light explosion while fainted from lack of food caused blindness
but being hit while sleeping did not. Make being in fainted state become
a protection against light-induced blindness.
nethack.rankin [Sun, 27 Aug 2006 01:48:04 +0000 (01:48 +0000)]
data.base entry: playing style
A couple of short quotes which needed a good home. The first is a
bit of verse from a short story, the second is part of the opening theme
song of the TV series "Monk". (That's the main character's surname, not
his profession/vocation :-).
Also make the change to the actual monk entry suggested by <Someone>.
nethack.rankin [Thu, 24 Aug 2006 04:50:45 +0000 (04:50 +0000)]
fix #H184 - rndmonnum plan B
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).
nethack.rankin [Tue, 22 Aug 2006 03:31:32 +0000 (03:31 +0000)]
discovering divine gifts
<Someone> says he reported this five years ago, but I don't think I ever
saw it. Receiving an artifact as the result of #offer would add it into
the discoveries even if the hero was blind and never saw it. It either
needed to have the dknown bit set, as if it had been seen, or else should
not be added to the list. I've opted for the latter.
nethack.rankin [Tue, 22 Aug 2006 03:03:03 +0000 (03:03 +0000)]
inappropriate unblock_point() calls
Mentioned by <Someone>, who suspected that the fix for C343-114 dealt with
this. When a giant picks up a boulder from a location where more than one
is present, line-of-sight would be inappropriately cleared, as if the
remaining boulders were transparent. (He said that he got no pickup
message when the giant picked up the boulder. I do, and have not tried to
figure out whether this is a post-3.4.3 difference.) Pushing a boulder
onto a landmine had the same bug, although you wouldn't notice unless there
were at least three boulders to be pushed (mysterious ability to push more
than one boulder in a turn strikes again: first one triggers the trap and
is destroyed, allowing hero to see through any others; second fills in the
resulting pit; third gets moved to the former trap spot and [probably--I
haven't checked] re-blocks vision; fourth, if any, stays put; if only one
or two are present, the change in vision is expected and the fact that it
happens too soon in the two boulder case would probably go unnoticed.
Polymorph of a boulder also opened up vision without checking whether any
others are present.
An existing, evidently overly optimistic, fixes34.4 entry covers this.
nethack.rankin [Sat, 19 Aug 2006 05:29:16 +0000 (05:29 +0000)]
fix #H177 - mimicking gold while hallucinating (trunk only)
From a bug report, having hallucination time out while
mimicking an orange (instead of gold, after eating a mimic corpse), you'd
still get the hallucinatory end-of-mimicking message about not wanting to
be peeled. If hallucination state is toggled, update the pending message
and change the hero's appearance. In practice, only the orange-to-gold
case can occur. Anything which might trigger gold-to-orange will have
terminated the hero's mimickery befort that happens.
nethack.rankin [Thu, 17 Aug 2006 04:35:08 +0000 (04:35 +0000)]
fix grab/engulf by tame/peaceful monster (trunk only)
<Someone> reported being swallowed by his pet purple worm during
Conflict, then being stuck inside once Conflict ended. I'm not entirely
sure what dog_move() intended by the "swallowed case handled above" comment.
It returns without letting the pet move when the distance between pet and
hero is 0; that wasn't much in the way of "handling" being swallowed.
Grabbing pets did let go, but peaceful monsters didn't until you actually
attempted to move away from them. Now all four combinations (grabbed or
swallowed by tame or peaceful monster) are handled the same: the monster
will let the hero go next time it gets a chance to try to move, using up
its move in the process.
nethack.rankin [Sun, 13 Aug 2006 06:03:23 +0000 (06:03 +0000)]
fix #H167 - entering monster filled level
When the hero arrives on a level and a monster at his destination can't
be relocated to make room for him, goto_level() would place the hero on top
of the monster. From a bug report, who said that the
game panicked (without providing specifics, at least so far). I wasn't able
to reproduce a panic but get a pair of impossible warnings and can confirm
that there is a monster on the same spot as the hero, which could easily
lead to strangeness depending upon what actions the monster attempts to
perform. This fix causes a non-relocateable monster in that situation to
be moved to the migrating monsters list for later arrival back on that same
level. That's inconsistant with the migrating monster arrival routine,
which kills off any monster it can't place; I'm not sure which action is
more reasonable, deferred arrival or outright removal.
There are three or four dozen ``(void) rloc(mon)'' calls which don't
do anything special when rloc fails to move the monster. Those need to be
reviewed and the ones where it's making a space for some other monster have
to do something about failure. (Failed teleport attempts can simply leave
the monster in place, so most of those calls won't need any extra handling.)
nethack.rankin [Thu, 10 Aug 2006 00:45:32 +0000 (00:45 +0000)]
shopkeeper/temple priest teleporting (trunk only)
Forwarded from the newsgroup by <Someone>: temple priest might
abandon his post via teleport if conditions are obscure enough. Change
rloc_pos_ok() to only accept spots inside the same shop or temple when a
shopkeeper or temple priest is teleported to a random destination. rloc()
tries rloc_pos_ok() 500 times before reverting to goodpos(), so this will
usually succeed for a large room; it may fail for a small one (reverting
to the current behavior, more or less). Shopkeepers or priests who get
polymorphed into a critter which teleports to the stairs when in need of
healing will still leave their shop or temple if wounded (no change).
Priests resist if the player tries to teleport them, but shopkeepers
don't. So for direct attack by the player, this only affects shopkeeper
destination. But it affects both types as far as being hit by quantum
mechanics (probably caused by player's use of conflict) or if polymorphed
into monsters which steal and then flee (again, probably caused by the
player since those strong monsters won't voluntarily polymorph).
nethack.rankin [Wed, 9 Aug 2006 23:27:29 +0000 (23:27 +0000)]
fix #H164 - boulder pushing bug (trunk only)
From a bug report...): pushing a boulder onto a level teleporter trap
could repeat the
You push the boulder and suddenly it disappears!
message. That would happen whenever the teleport destination was the same
as the current level (20% chance). The boulder wasn't being moved onto the
trap location so was still present when the pushing code tried to handle
the next one in the pile. I've changed so that pushing stops whenever a
pushed boulder is affected by a trap, and also so that the boulder gets
moved as usual when a level teleporter fails to send it somewhere.
I've always thought it's pretty strange that pushing ever operates
on more than one boulder in the same turn in any situation, but I haven't
changed that for the non-trap cases. (Usually the first boulder pushed
ends up blocking the second one, so you get a "you try to move it, but
in vain" message which seems odd since you just moved one. But if there's
a pool of water or lava in the path, you can actually push multiple
boulders successfully.)
nethack.rankin [Tue, 8 Aug 2006 05:08:23 +0000 (05:08 +0000)]
mon vs mon attack message phrasing
From <Someone>:
Pet picks up 8 spears.
Pet wields 8 spears.
Pet thrusts its spear at Foe.
The routine to handle a monster attacking the hero are already uses "mon
thrusts one of its spears" in this case, so make monster against monster
messages do the same. Also, it's no longer necessary to save one monster
name before formatting another when using two monster names in the same
message, so switch to the more straightforward usage here. (The Blind
check is needed in the mhitu case but not in the mhitm one, where it's
redundant because the caller has already verified that both monsters'
locations are visible, but I left it in.)
nethack.rankin [Sun, 6 Aug 2006 05:16:23 +0000 (05:16 +0000)]
more #H166 - quest locate level message
More tweaking brought about by the report of falling through a
trapdoor above the quest locate level and landing below it (which won't
happen randomly any more, but can still be achieved via controlled level
teleport). You don't get any message for the locate level when arriving
from below, and giving the full initial message if you manage to make a
return visit from above produces silly results. This adjusts the logic
for delivering those messages; once you've been on the level, you won't
get the full initial message later even if it wasn't given the first time.
You will still get the shorter secondary message, up until the nemesis has
been killed. (In some cases it might not make much sense since its wording
is based on the assumption that you've already seen the full message.)
The handling for these messages will never be completely correct
unless the messages themselves are rewritten (and the result would
probably end up with really wishy-washy phrasing so there's not much point).
They assume that you'll be arriving via the stairs, even for the case where
you do come from above rather than unexpectedly from below, and they can
be misleading or confusing if you arrive someplace else. We could improve
things by having alternate FIRSTLOCATE and NEXTLOCATE messages for use when
not on--or next to, for the case where a pet displaces your arrival--the
stairs. But I'm not going to attempt to compose those.
nethack.rankin [Sun, 6 Aug 2006 05:13:22 +0000 (05:13 +0000)]
fix #H166 - trapdoors on quest levels
From a bug report, it was possible
to fall from above the quest locate level to below it even though it has
nondiggable floors (hence no trapdoors or holes to pass through). Since
the game can't verify that it is nondiggable (which could vary on a role
by role basis depending upon their quest descriptions) when it is not the
current level, restrict falling past it only when it hasn't been visited
yet. Impose the same restriction for random level teleport. This enforces
proper sequencing of the quest feedback, which was the more significant
thing that went wrong in the reported case (player finally got the full
locate level message on a return visit, when descending from above, after
having already cleared out that level on his way back up from falling).
Once the locate level has been reached or passed, it is no longer a
barrier to falling or random teleport. (When it is eventually visited,
there's no attempt to remember whether it allows holes, since that
information and the corresponding fall check would need to be extended to
every level in the dungeon. Also, controlled teleport is still allowed to
bypass it even when it hasn't yet been visited, so the "enforces proper
sequencing" claim above is an exaggeration.)
nethack.rankin [Thu, 3 Aug 2006 04:00:07 +0000 (04:00 +0000)]
fix #H158 - typo in monk data.base entry
From a bug report, the whatis description
for monks (a passage about a monk being invited to a meal) was using "month"
where "mouth" is clearly intended. I think this came up a few years ago
when monk was first added and am not sure why it wasn't changed them, even
if it happens to be an accurate transcription from the quote's source.
fix #H148 - applying a pickaxe doesn't respect pushweapon
From a bug report, applying a pick-axe will
wield it in place of the primary weapon but wouldn't update the alternate
weapon. Make objects which become wielded when applied (pick, lamp, whip,
grappling hook, pole-arm) honor the pushweapon option (where the previously
wielded weapon becomes the alternate weapon without use of 'x' command) the
same as when explicitly wielded. Old behavior matched the documentation,
but that seemed overly restrictive.
I'm pretty sure that some pre-standard compilers don't know how to
apply an initializer to a variable of type union. Unfortunately, I don't
have access to one to check. Fortunately, there's no need to explicitly
initialize `zeroany' since the default value is what we want--the first
field will be set to zero or null as appropriate (null in this case).
Strictly speaking, this isn't adequate; what if long is wider than a
pointer rather than narrower? Using `= {DUMMY}' didn't handle that case
either; the ordering of the union's fields controls which bits get stored.
As a practical matter, it should make no difference. As long as the code
reading a union accesses the same field as the code writing that union set
up in it, anything in extraneous bits should be irrelevant--except perhaps
when a debugger tries to format things. The whole issue has always been
implicitly based on the assumption that null pointers have all bits zero
in the first place; that's typical but not guaranteed.
botl.c conversions. All the ports seem to be using genl_status_update(),
rather than a window port specific version, so botl.c was the only place
this had to be adjusted.
Also a uudecode cast for the result of strlen, since it isn't using
config.h
remove pointer to long conversions - part 3 of 3 (trunk only)
Remove some more code that forced pointers into a long int, and
vice versa where information could be lost (P64 platforms such as
WIN64 have a 64 bit pointer size, but a 32 bit long size.)
This 3rd part deals with region functions switching
some arguments from type genericptr_t to 'anything'.
Like the previous 2 parts, this needs to increment
EDITLEVEL in patchlevel.h.
remove pointer to long conversions - part 2 of 3 (trunk only)
Remove some more code that forced pointers into a long int, and
vice versa where information could be lost (P64 platforms such as
WIN64 have a 64 bit pointer size, but a 32 bit long size.)
This 2nd part deals with timeout functions switching
some arguments from type genericptr_t to 'anything'.
Like part 1, this needs to increment EDITLEVEL in patchlevel.h.
remove pointer to long conversions - part 1 of 3 rev 2 (trunk only)
[the problem in the earlier rev was tracked to cleanup_burn(),
where arg was holding a (genericptr_t) timer id, and
passed directly to del_light_source() as is.]
P64 (Win64) has a 64 bit pointer size, but a 32 bit long size.
Remove some code that forced pointers into a long int, and
vice versa where information could be lost.
This part deals with light source functions and their
arguments mostly, and switches some arguments
from type genericptr_t to 'anything'.
remove pointer to long conversions - part 1 of 3 (trunk only)
P64 (Win64) has a 64 bit pointer size, but a 32 bit long size.
Remove some code that forced pointers into a long int, and
vice versa where information could be lost.
This part deals with light source functions and their
arguments mostly, and switches some arguments
from type genericptr_t to 'anything'.
Hide pointer formatting in alloc.c by eliminating the need for callers
to know how big a buffer is required. I generally prefer the caller to
pass in its own buffer for this sort of thing, but in this case the usage
is almost entirely for debugging so using static buffers results in less
clutter in the rest of the code.
compilation w/o WIZARD
> Michael Allison wrote:
> There are unresolved functions in the trunk if you build without WIZARD
> defined and attempt to link:
Also to a lesser extent, in the 3.4.4 branch.
<Someone> wrote on Tuesday, July 27, 2004 at 06:46:15
> In the region.c function rest_regions allocates storage for the possible
> enter_msg and leave_msg strings. But the function free_region does not relese
> this storage.
Also ensures that some code that is currently ifdef'd out
makes copies of the strings into memory from alloc()
to ensure that no problems with free() result if the function
gets passed a literal string.
<Someone> wrote on Tuesday, July 27, 2004 at 06:46:15
> In the region.c function rest_regions allocates storage for the possible
> enter_msg and leave_msg strings. But the function free_region does not relese
> this storage.
Also ensures that some code that is currently ifdef'd out
makes copies of the strings into memory from alloc()
to ensure that no problems with free() result if the function
gets passed a literal string.
<Someone> wrote:
> NetHack feedback form submitted by
> <email deleted> on Friday, June 30, 2006 at 17:31:12
> ---------------------------------------------------------------------------
>
> mailversion:1.35
>
> nhversion:3.4.3
>
> nhfrom:Our 3.4.3 source release, unmodified
> comments:
> telnet nethack.alt.org with the terminal set to 21 rows.
> Choose to pick a char, not accept pot luck, and game segfaults.
> (same happens from linux console)
I was able to reproduce something similar in win32 by setting
the console to 21 rows. As he stated, don't let the game pick you
character for you to reproduce the problem. As soon as I chose
Archeologist the problem occurred:
Where:
In hack.c, weight_cap()
if (Levitation || Is_airlevel(&u.uz) /* <email deleted> */
#ifdef STEED
|| (u.usteed && strongmonst(u.usteed->data))
#endif
)
Examination of the preprocessor output of that section
of code reveals that
"Levitation" becomes:
(u.uprops[47].intrinsic || u.uprops[47].extrinsic ||
((youmonst.data)->mlet == 5))
so it is the is_floater(youmonst.data) causing the crash.
Call stack:
weight_cap() line 2300 + 24 bytes
inv_weight() line 2342 + 5 bytes
calc_capacity(int 0) line 2354 + 5 bytes
near_capacity() line 2365 + 7 bytes
bot() line 607 + 5 bytes
docorner(int 47, int 19) line 2378
erase_menu_or_text(int 5, WinDesc * 0x00a22550, char 0) line 994 + 25 bytes
tty_dismiss_nhwindow(int 5) line 1664 + 15 bytes
tty_select_menu(int 5, int 1, mi * * 0x0006fc40) line 2248 + 9 bytes
tty_player_selection() line 442 + 16 bytes
pcmain(int 3, char * * 0x00a20eb0) line 457
main(int 3, char * * 0x00a20eb0) line 91 + 13 bytes
This adds a check for a valid youmonst.data in
bot().
nethack.rankin [Thu, 29 Jun 2006 05:03:15 +0000 (05:03 +0000)]
header reorg (trunk only)
Move the new VOID_ARGS and some other argument manipulation stuff
from global.h to tradstdc.h where it feels like a better fit. Make the
definition of VOID_ARGS more general; it should work nearly everwhere
these days even if it is only needed for one configuration. XXXconf.h
can redefine it as empty if necessary.
For MONST_P and OBJ_P, I left "void*" as is but I'm pretty sure that
the lack of space in between the two components was never part of the
issue there. (The Ultrix system I used to have access to is long gone.
It was chugging along on autopilot, effectively defenseless, at the time
a linux box on the same subnet got hacked. It probably would have been
shut down for Y2K anyway if it had lasted til then.)
nethack.allison [Sun, 25 Jun 2006 19:54:31 +0000 (19:54 +0000)]
function pointer assignment warnings in VC2005
The latest Micrsoft compilers complain when a function is
assigned to a function pointer, and the function's argument
list does not match the prototype precisely.
It was evem complaining about the difference between this:
int x()
{
[...]
}
and a prototype of
int x(void);
when assigning that function's address to a function pointer.
This quiets those warnings, without suppressing the mismatch
check altogether for more serious mismatches.
nethack.rankin [Thu, 22 Jun 2006 05:03:48 +0000 (05:03 +0000)]
detected hidden monsters
From a bug report, attempting to attack
a hidden monster who is revealed by ongoing monster detection (blessed
potion or skilled spell) gave "wait! there's a <monster> hiding there"
response and prevented the attack. Make it behave the same as when the
hidden monster is revealed by telepathy; the monster comes out of hiding
and the hero's attack proceeds.
nethack.rankin [Thu, 22 Jun 2006 04:08:40 +0000 (04:08 +0000)]
shop theft/breakage (trunk only)
The recent fix for "breaking glass wand in tool shop" looked suspect,
adding a call to costly_alteration after an existing call to stolen_value.
Either one or the other ought to suffice. (For items on the floor,
costly_alteration() calls stolen_value(); for items in inventory, or just
released from inventory and not placed on floor yet, costly_alteration()
adds a usage fee to the shop bill but doesn't annoy the shopkeeper into
adding surcharges to prices or summoning the kops if already hostile.)
In 3.4.3, stolen_value() wasn't smart enough to charge for an out-of-
shk's-field item (like a wand in a tool shop) taken from a shop container,
and that's the problem the user was reporting. But the post-3.4.3 code was
changed to handle that by checking billable() instead of saleable(); this
bug should have been gone. Unfortunately, billable() treats items already
on the bill as not interesting--from the perspective of adding things to
the bill--so the change accidentally resulted in stolen_value() no longer
handling objects which are marked unpaid, triggering the same symptom for
a different reason. (Other events besides the breakage of thrown objects
suffered from the bug's new incarnation since various places deliberately
call stolen_value() for unpaid objects.) This updates stolen_value() and
stolen_container() to account for the behavior of billable(). And a few
calls to subfrombill() go away since stolen_value() now takes care of that.
nethack.rankin [Tue, 20 Jun 2006 02:31:37 +0000 (02:31 +0000)]
#tip horn of plenty (trunk only)
Bug in #tip handling for horn of plenty. Emptying one while levitating
would trigger an "obj not free" panic by flooreffects() due to following
hitfloor() with redundant/inappropriate dropy().
nethack.rankin [Sun, 18 Jun 2006 05:20:36 +0000 (05:20 +0000)]
bag of tricks, horn of plenty, #tip (trunk only)
<Someone> reported that he applied an unID'd bag and it became
discovered as a bag of tricks even though a spellbook appeared on the floor
next to him rather than having a monster show up (the monster was a mimic).
Suppress the bag discovery unless you can see or sense a monster appear.
(This doesn't really achieve much for most players, who'll recognize the
bag because they know that only one type of container doesn't prompt to
take things out and/or put things in, but I think it does make sense.)
While mucking with bag of tricks I decided that to be consistent with
the behavior of other containers, the #tip command should release all the
monsters in the bag instead of just one.
And after doing that, I realized that horn of plenty ought to behave
much the same, so #tip will operate on it now. However, it won't be listed
as a likely candidate in the "which item?" prompt unless/until it has been
discovered. (Attempting to empty any other type of horn yields "nothing
happens", same as for a horn of plenty with no charges left.) Emptying a
horn of plenty in a shop can be extremely verbose, but I don't think that
qualifies as a bug and don't currently have any plans to alter it.
nethack.rankin [Sat, 17 Jun 2006 04:43:44 +0000 (04:43 +0000)]
wielded candles vs rust (trunk only)
From a bug report: [ slashem-Bugs-1206099 ] Torches are not extinguished with rust traps).
A rust trap that hits the torso candles causes all lit objects being carried
to be extinguished, but one which hit the weapon arm didn't have same affect
on a wielded light. This fix causes wielded candles or lamps (not Sunsword)
to go out if affected by any rust, such as hitting a rust monster with one,
rather than use his patch that just handled the trap case. It also excludes
wielded lights from the existing torso splash since having them be hit by
both instances is too obviously buggy.
I think brass lanterns ought to be exempt from being extinguished by
water (at least splashing which is less drastic than total submersion) since
there are references to them operating by batteries rather than fire, but I
didn't want to track all the places which would be affected.
nethack.allison [Wed, 14 Jun 2006 23:44:16 +0000 (23:44 +0000)]
throwing and breaking glass wand in shop (trunk only)
<email deleted> wrote:
> - when in a hardware store, I put a glass wand out of a sack (the glass wand
> will cost you 266 zorkmids) and threw it in the shop => shattered into a
> thousand pieces BUT if I try to pay, I do not owe the shopkeeper anything !!!
> If I break a potion with a /oS, I have to pay !
nethack.allison [Wed, 14 Jun 2006 10:48:09 +0000 (10:48 +0000)]
win32 embedded version info
I noticed that the NetHack version being reported in the
system's event log was old:
Faulting application nethackw.exe, version 3.4.2.0,
faulting module nethackw.exe, version 3.4.2.0, fault address 0x001648eb.
nethack.rankin [Tue, 13 Jun 2006 03:15:03 +0000 (03:15 +0000)]
polyself bit (trunk only)
Some recent code shuffling introduced an unintended change in behavior
(not observable to the player; just unnecessary deletion and re-creation of
light source with identical radius when polymorphing from one light emitting
form to another). The fixup for light range 1 would need to be repeated for
`old_light' when outside the `if (old_light != new_light)' block; move it
back inside where that isn't required. Also, youmonst.data is valid all the
time so a couple of `Upolyd' tests in the surrounding code can be dropped.
nethack.allison [Sun, 11 Jun 2006 18:27:55 +0000 (18:27 +0000)]
build warning
- remove an unreferenced variable
- continue with recent code trend towards having DEADMONSTER()
check in its own if/continue statement in a few more places
nethack.rankin [Sun, 11 Jun 2006 06:09:35 +0000 (06:09 +0000)]
polyself changes (trunk only)
Several polymorph tweaks, most dealing with specifying form under
polymorph control or for wizard #polyself:
1) allow "were<critter>" and "human were<critter>" for your type of
<critter> when you're inflicted with lycanthropy; now you'll toggle
shape rather than be told "you cannot polymorph into that".
2) allow your own role; now you'll become a new man (or whatever race)
rather than get "you can't".
3) allow "human" to force a new man (or whatever) regardless of race.
No change for human characters, but elves, dwarves, and such can now
use either their own race or "human". (They never become humans.)
4) for wizard #polyself only, override the 20% chance of becoming a new
man instead of taking on the selected form. (This implicitly prevents
the annoying "your new form isn't healthy enough to survive" death
since your experience level won't drop below 1.)
5) remove a redundant drowning check in polyself(); it's already handled
in polymon() and polyman(for newman()) via spoteffects().
This also gets rid of an old use of 0 as not-a-valid-monster (not
responisble for any bugs though since giant ants aren't lycanthropes).
nethack.rankin [Sun, 11 Jun 2006 04:00:40 +0000 (04:00 +0000)]
temple sounds (trunk only)
The user (<email deleted>) who recently suggested a
dump command for containers also wanted atmospheric sounds on levels which
have altars. Right now we'd have to find unattended altars the hard way
(by scanning the entire level) but we could add a counter (or set of
counters, one per alignment) like for fountains and sinks if we really
wanted to do that. [Now that I think about it, the #overview patch may
have already done something of the sort.] But what noises would an altar
be expected to produce? This only adds sounds for temples, where the
attending priest can be the source of the noise.
I'm not real thrilled with the initial set of sounds, particularly
the hallucinating one, but the implementation works. The "carcass" one is
a little clumsy; it's intended to add a hint for new players who haven't
figured out what the #offer command does.
nethack.allison [Sat, 3 Jun 2006 17:55:24 +0000 (17:55 +0000)]
lost ball and chain (trunk only)
Saving the game while punished, not carrying the attached ball,
and while swallowed by a purple worm resulted in losing the
ball and chain.
Since the required information was not being written to the
save file at all, I couldn't come up with a clean way to do this
for the branch, and preserve save file format. I could think
of lots of kludgy ways to do it (insert ball and chain into
the hero's inventory prior to saving, and remove it on restore, etc.)
nethack.allison [Sat, 3 Jun 2006 17:48:22 +0000 (17:48 +0000)]
lost ball and chain (trunk only)
Saving the game while punished, not carrying the attached ball,
and while swallowed by a purple worm resulted in losing the
ball and chain.
Since the required information was not being written to the
save file at all, I couldn't come up with a clean way to do this
for the branch, and preserve save file format. I could think
of lots of kludgy ways to do it (insert ball and chain into
the hero's inventory prior to saving, and remove it on restore, etc.)
nethack.rankin [Thu, 1 Jun 2006 04:27:35 +0000 (04:27 +0000)]
golem life
When testing the spoteffects/drown hack I noticed that draining myself
with Stormbringer (toss up, get hit on head) while in iron golem form gave
messages about it drawing or draining life. (I'm sure that this has come
up before....) I've altered the artifact hit message rather than making
golems become resistant, although the opposite approach seems at least as
valid. The drain life spell uses different wording and isn't affected.
nethack.rankin [Thu, 1 Jun 2006 03:54:25 +0000 (03:54 +0000)]
recursive spoteffects (trunk only)
Attempt to fix a buglist item: if hero poly'd into iron golem form
enters a pool of water and drowning triggers reversion to human/whatever
form due to water damage, he will fall into that pool again, crawl or
teleport out, then redundantly crawl or teleport out for the initial entry.
[ spoteffects -> drown -> losehp -> rehumanize -> polyman -> spoteffects
-> drown ]
I don't have a lot of confidence in this fix. It does handle the
reported problem, and hasn't broken a couple of earlier tricky cases
(ice melting to water, land mine turning into a pit). But drown() and
lava_effects() seem to leave a trail of special case handling wherever
they appear so they--or spoteffects, or both--ought to be redone somehow.
nethack.rankin [Tue, 30 May 2006 04:07:34 +0000 (04:07 +0000)]
invocation vs being trapped
I can't find the report about this; I must have deleted it after
reading, or else recently reread something so old that I'm not going back
far enough now. When you perform the invocation ritual to create the
stairs down to Moloch's Sanctum, any trap at your location gets deleted.
But if you were in a trapped state at the time then you got left in that
state. Descending stairs doesn't check for traps so you wouldn't notice
unless you tried to move around on the same level first. Then you'd get
"you're stuck in a pit/beartrap/web" even though it wasn't there anymore.
nethack.rankin [Sat, 27 May 2006 04:13:20 +0000 (04:13 +0000)]
unseen monsters vs hiding hero
While testing the hiding vs traps patch, I became a mimic and hid.
It gets stuck to you.
Huh? Nothing was visible; nothing became visible (aside from the ']' at my
position changing back to 'm'). Display the invisible monster glyph when
an unseen monster bumps into you while you're hiding or mimicking gold.
That's usually handled by the hit and miss routines, but they aren't used
when you're just brought out of hiding instead of attacked.
nethack.rankin [Sat, 27 May 2006 03:46:03 +0000 (03:46 +0000)]
hiding monsters vs traps (trunk only)
From a bug report, the game gave feedback
about a monster becoming stuck in a web but there seemed to be no monster
around because it immediately began hiding under an object at the web's
location. Prevent monsters--or poly'd hero--from hiding when trapped in
anything other than a pit or spiked pit. Also, prevent them from hiding if
they're holding you or you're poly'd and holding them. I'm not sure whether
either of those cases ever actually happened but big mimics are capable of
both hiding and grabbing on.
nethack.rankin [Sat, 27 May 2006 01:58:22 +0000 (01:58 +0000)]
fix #H108 - lost protection
Fix the problem From a bug report, where
giving a temple donation of the appropriate amount would fail to restore
protection previously stolen by gremlin attack iff the old protection amount
was big enough that the donation wouldn't have yielded a bonus in the normal
not-stolen case. It shouldn't be checking the magnitude of u.ublessed at a
time when lack of the intrinsic renders that value inoperative. After this
fix, the lost intrinsic will be granted and the old protection value will
be restored, same as happens when a prayer boon yields divine protection
(where no u.ublessed magnitude check is made) and as happened with donations
when the old protection was a more modest amount (magnitude test passed).
nethack.rankin [Sat, 27 May 2006 01:26:50 +0000 (01:26 +0000)]
protection enlightenment (trunk only)
Yesterday's change to have enlightenment give "you have a <small,
moderate,&> defense bonus" instead of "you are protected" would yield
"you have a small defense penalty" if the combined protection value (from
rings, divine gift, and spell) was 0. This changes the formatting routine
to give "you have no defense bonus" in that situation, then changes the
caller to only display the protection/defense attribute when non-zero so
the "no bonus" case will never actually happen.
nethack.rankin [Fri, 26 May 2006 03:31:57 +0000 (03:31 +0000)]
enlightment for protection and magic cancellation (trunk only)
The bug report about losing/regaining the Protection intrinsic reminded
me of a couple of things. First, as an intrinsic, Protection seems to be
completely useless and we ought to redo it. Second, periodically people in
the newsgroup have complained about how it's nearly impossible to figure
out the important--possibly crucial--armor attribute of magic cancellation.
Wearing a cloak greatly increases characters' survival rates, but beyond
that, magic cancellation is just spoiler fodder.
This doesn't do much about Protection other than to change "you are
protected" into "you have a <small,moderate,&c> defense bonus" similar to
how the attributes conferred by rings of increase damage and increase
accuracy are handled. For magic cancellation, it adds new feedback:
You are protected. -- mc factor 3
You are guarded. -- mc factor 2
You are warded. -- mc factor 1
(with no extra feedback for mc factor 0, the normal naked state. The mc 3
case might cause some confusion over the changed meaning of a previously
existing item, but I think it'll be ok and not need re-wording.)