Dead monsters that had traits saved with the corpse would revive as
the same gender, but ordinary corpses revived with random gender so
could be different from before they got killed.
Since corpses of monsters lacked gender, those for monsters with
gender-specific names were described by the neuter name.
This is a fairly big change for a fairly minor problem and needs a
lot more testing.
Fixes#531
Change the default value of autopickup to off. Having it on is
harmful for new players, making them very easily burdened.
We can't expect new players to know how to configure
pickup_types, pickup_burden, and pickup exceptions.
Change the default value of color to on. We can safely assume
new users have a terminal that supports color, and most people
want color.
Have curses call the core get_count() routine instead rolling its
own so that backspace and delete are supported. That part was
trivial to accomplish. Unfortunately it brought the disappearing
menu phenomenon back so it became more complicated overall.
rename sys/winnt to sys/windows
move vs (visual studio) folder out of win/win32 and into sys/windows
rename include/ntconf.h to include/windconf.h
rename winnt.c to windsys.c
place visual studio projects into individual subfolders.
This will hopefully resolve GitHub issue #484 as well.
Allow killing your quest leader, just to make games winnable if you
converted before doing the quest.
Boost the quest leaders and give them some equipment. King Arthur
gets Excalibur. Killing quest leader gives really bad luck and
makes your god angry at you, and killing quest guardians gives
smaller penalties.
This is based on both the EvilHack implementation by
k21971 <keith.simpson1971@gmail.com>, and xNetHack
implementation by copperwater <aosdict@gmail.com>.
Despite active explosion attacks being called explosions in-game,
they only affected a single target, and were handled differently
from actual explosions. Make them do an actual explosion instead.
This should make spheres more interesting and inspire different
tactics handling them.
Because spheres deal more damage on average and can destroy items
in their explosions, their difficulty has been increased slightly.
Polyselfed hero exploding won't cause elemental damage to their
own gear.
Originally from xNetHack by copperwater <aosdict@gmail.com>.
Adds possible callbacks for "start_new_game", "restore_old_game",
"moveloop_turn", and "game_exit" which when defined, will be called
from core code at the appropriate time.
Adds lua hooks for dump_fmtstr (only if DUMPLOG), dnum_name, u.moves,
u.uhave_amulet, and u.depth.
Higher charisma will make it more likely for monsters to be affected.
Conflict will also now require the monster to see the hero.
Originally from SporkHack by Derek Ray.
Touch of death will now do 50 + 8d6 damage, and drain max HP for half
of that. If the drain is equal or greater than your max HP, then it
will kill you instantly.
Change originally from SporkHack by Derek Ray.
If monsters see you resist something, generally elemental or magical
attack, or if they see you reflect an attack, they learn that and
will adjust their attack accordingly.
Originally from SporkHack, but this version comes via EvilHack with
some minor changes.
Fix a couple of places that set obj->dknown to 0 to deal with some
special cases where it should be left at 1. (Other places do that
but deal with potions where hardcoded 0 remains appropriate.)
A recent change made it possible for a glob to have its dknown flag
cleared and that exposed globby_bill_fixup() passing Null shopkeeper
to get_cost(), triggering a crash.
Make the routine that clears dknown/known/bknown/&c also be the
routine used to initialize those flags for a new object so that it
is the place that handles various special cases. That hides the
shop bug again.
But also fix the shop bug even though it won't be triggered.
Fixes#509
Allow creating webs without spiders in the lua level scripts:
des.trap({ type = "web", spider_on_web = 0 });
Based on xNetHack commit by copperwater <aosdict@gmail.com>.
Also changes the Spider nest themed room to generate without
spiders when the level difficulty is 8 or less.
Allow specifying "waiting" for monsters created via lua level scripts.
This sets the monster strategy to make it wait for the hero
to be in visual range before allowing the monster to move.
Also makes the monster inside the Mausoleum themed room use this feature,
to prevent out of depth liches bothering the player unprovoked.
For example:
des.monster({ class = "D", waiting = 1 });
that has no nutritional value. Prevent applying the partly eaten
attribute to wished for food if the full nutrition isn't at least 2.
The problem case was 0 nutrition wraith corpse, yielding "partly
eaten food (1) more nutritious than untouched food (0)" when setting
the corpse's weight. That one was possible in 3.6.x, unlike corpse
that was actually partly eaten and then revived as a zombie (which
was just fixed for triggering the same warning).
Wishing really ought to ignore "partly eaten" for anything that is
normally eaten in one bite but I'm not sure how to handle that.
Fixes#504
Issue was about being asked what to call a previously seen potion
which has been picked up and thrown by an unseen monster. Hero
shouldn't remember what the item description was. This is a much
more general change than just fixing that. Any item picked up by
an unseen non-tame monster will have all its *known flags cleared
since the hero can't see what that monster does to it. Same if an
item is picked up while seen but then used when unseen.
Unseen pets are excluded from the pick up case--but not the use
case--because they pick up and drop stuff continually and players
would just slaughter them if they caused item information to be
forgotten.
Fixes#493
If the killer and the paralyzer are the same monster, truncate
that to "Killed by a foo, while paralyzed". When not the same,
spell out the paralyzer's monster type instead of using generic
"monster". "Killed by a fox, while paralyzed by a ghoul", or
"Killed by a ghoul, while paralyzed by a ghoul" *if* they were
two different ghouls.
Restore some old behavior for the apply command that was changed
by the "getobj refactor" patch. You couldn't attempt to apply
potions to determine whether they were oil, couldn't apply gray
stones once touchstone was discovered, and attempting to apply
arbitrary items gave "that is a silly thing to apply" rather
than "sorry, I don't know how to use that."
Issue is about monster shape changes being sensed via telepathy
while hero is swallowed, so player gets told about things that
aren't being shown on the map. Similar situation while underwater;
only monsters in adjacent water spots are shown on the screen, but
messages about sensed monsters will continue to be given. It isn't
limited to shape changing; lots of places include telepathy,
extended monster detection, and warning against specific types of
creatures as criteria to decide whether the hero 'sees' something
that isn't directly visible happen.
Change sensemon() to behave as if being swallowed or underwater
blocks telepathy, extended monster detection, and warning. I
consider this to be experimental, but it needs much wider testing
than would take place if put into its own test branch. It can be
tweaked or reversed if that turns out to be necessary.
There should be no change in behavior when not swallowed and not
underwater. But for either of those two situations, some messages
that have been getting delivered may be different (such as using
"it" instead of sensed monster's name) or suppressed.
Fixes#486
We used to have the contents of chests and large boxes be immune to
water damage, oilskin sacks immune unless the sack was cursed, other
containers be vulnerable. Some reddit discussion about ice boxes in
unnethack indicates that they are treated like oilskin sacks, which
makes sense. This adds that to nethack and also makes chests and
large boxes behave similarly. So it's now: nothing is immune even
when cursed (except statues); oilskin sacks, ice boxes, and other
boxes are immune to water damage unless cursed; all other containers
vulnerable even when not cursed.
|
| Old New
|immune all statues, statues
| the time chests, large boxes
|
|immune when BU, oilskin sacks oilskin sacks,
| vulnerable if C ice boxes,
| chests, large boxes
|
|vulnerable ordinary sacks, ordinary sacks,
| all the time bags of holding, bags of holding
| ice boxes
|
I suspect that the old ice box classification might have been an
accident caused by the Is_box() predicate yielding False for it.
The changes won't make much difference to actual play. Chests and
large boxes are rarely carried and never start out cursed, ice boxes
even more so, and sacks/bags haven't been changed. However, players
might intentionally curse a container to keep strong pets from
picking it up, or be carrying a box because they haven't found a bag
yet and then muck about with fountains or thrones and get it cursed.
'final_fpos' shouldn't have been moved to the 'g' struct. Even if
a game went all the way through topten and was restarted as a new
game that also went all the way through topten, 'final_fpos' would
get a new value rather than being messed up by a stale old one.
When swallowed and blind, the swallowing monster is described
accurately, but being held rather than swallowed describes the
monster as "it". That's normal, but the status feedback section
of ^X output lists
|You are held by it.
which looks pretty weird. Change that to be
|You are held by an unseen creature.
Zapping wand of opening or spell of knock at engulfer while swallowed
would make the engulfer expel the hero; this change makes zapping
other holders release their hold. Zapping self now achieves the same
effect, as does breaking a non-empty wand of opening. When poly'd
hero is holding a monster rather than being held, that monster will
be released.
Engulfers can't re-engulf for 1 or 2 turns after releasing the hero
in order to prevent hero from being immediately re-engulfed. Impose
the same limitation on other holders.
From newsgroup discussion where slash'em changes have revealed a
latent nethack bug: prevent placing level teleporters in single-
level branches. The Knox level doesn't have any level teleporters
(or random traps) but wizard mode wishing could create them there.
They wouldn't do anything because the only possible destination
would be the same level. Pushing a boulder onto one used to trigger
an infinite loop (and still does in slash'em, which has other
single-level branches besides Ft.Ludios) trying to relocate it.
Boulder pushing was changed 15 years ago to prevent the infinite
loop and to avoid giving "the boulder disappears" message when a
level teleporter failed, but rolling boulder traversal lacked that
same change--it wasn't vulnerable to looping but could give an
inaccurate message claiming that the boulder disappeared when it
actually didn't. Fixing this is a bit late; rolling boulder trap
creation was recently changed to not choose a path that rolls over
teleportation or level tele traps any more.
Change Trollsbane versus troll corpse revival: instead of revival
failing if Trollsbane is wielded at time of revival attempt, mark
the corpse no-revive if killed by Trollsbane (whether by the hero
or a monster).
If a no-revive corpse is within view when time to revive occurs,
give "the troll corpse twitches feebly" even when the hero isn't
responsible. That used to only apply if the hero zapped the
corpse with undead turning, which would have become inoperative
because now being zapped by undead turning clears the no-revive
flag and revives as normal. In other words, undead turning magic
overrides killed-by-Trollsbane or non-ice troll having been in an
ice box.
Player's pet killed a troll with Trollsbane and the corpse later
revived. He assumed that killing a troll with Trollsbane is what
prevents troll corpse revival but that is inhibited by the hero
be wielding Trollsbane at the time revival is attempted.
Having killed-by-Trollsbane be the reason for blocking revival
would be much better but looks like a lot of work for something
which was supposed to be a one-line enhancement to an under-used
artifact. This extends revival inhibition to having anyone on
the level be wielding Trollsbane rather than just the hero.
Not a proper fix but I think it's better than nothing.
Closes#475
I accidentally toggled the 'altmeta' option On and got this
non sequitur result when trying to toggle it back Off:
|The altmeta option may not both have a value and be negated.
Apply visibility fixups for monsters triggering door trap
explosions or digging through doors similar to the monster-opens-
door-handling from a couple of days. Again, the issue is that
hero/player can see a closed door in situations where they can't
see an open one, and messages about the door being opened or
destroyed need to take that into account when seeing a closed
door go away.
Not as thoroughly tested as monster just opening closed door.
Incorporate the changes from pull request #467, which itself
incorporates a fix for issue #441. Allows hands/self to be an
acceptable but hidden choice (don't think any command actually
needs this). When 'force_invent' option is on, show all the
acceptable but usually hidden choices if no ordinary candidates
are available instead of having an empty menu. Also, omit
force_invent's "* - (list everything)" extra menu entry if the
menu already contains everything.
Cleans up a couple of whitespace issues too. I changed at least
one more and added a couple of comments. I'm not sure about the
comment change that I made in hack.h; the original said "foo is
identical to foo" but the revision might not be accurate.
Fixes#467Fixes#441
The pull request that fixed a couple of instances where it was
possible to have multiple entries for gold in inventory indirectly
pointed out that the error checking was clumsy. If you executed
the #adjust command while having two '$' items in inventory, you
were told twice that you had multiple stacks of gold in inventory.
Change how that's handled so that the warning appears at most once
for any given #adjust command. Also avoids having #adjust's use
of getobj() re-scan entire invent for every item in invent.
Also, if player did manage to get two or more '$' entries, #adjust
would allow moving any but the last to a letter entry. Once in a
letter, further #adjust with count specified could split the letter
gold entries into even more gold entries. Now, if the player picks
gold as the #adjust 'from' item (which is only possible when there
are wrong letter gold entries or multiple ones or both) then #adjust
will now force 'to' slot to be '$' (without asking player to pick).
Lastly, the inventory check for multiple and/or wrong slot gold is
now performed by wizard mode sanity_check() in addition to #adjust.
Change the '|'/#perminv final positioning for X11 to be the same
as for curses: finishing with <escape> leaves the current view,
with <return> resets to unscrolled.
Actually getting ESC and RET to the right place wasn't trivial;
down the rabbit hole and out the other side. Using yn_function()
to get the #perminv keystrokes is less than ideal. (curses also
started that way but switched to raw character input for this.)
Add new '|' command, aka #perminv, which allows the player to
send menu scrolling keystrokes to the persistent inventory window.
Implemented for X11, where its usefulness is limited, and for
curses, where it is more needed and also more fully functional.
The interface can either prompt for one keystroke, act upon it,
and return to normal play, or it can loop for multiple keystrokes
until player types <return> or <escape>. X11 does the former if
the 'slow' application resource is False so that prompting uses
popups, and the latter when 'slow' is True where prompting is in
a fixed spot and doesn't end up causing the persistent inventory
window to be stacked behind the map window. curses always does
the loop-until-done approach. It also accepts up and down arrow
keys to scroll one line at a time.
Also adds two new menu scrolling commands, menu_shift_right (key
'}' by default) and menu_shift_left ('{') if wincap2 flags contain
WC2_MENU_SHIFT. Shifting allows different substrings of too-long
lines to be seen.
For X11, neither works because their handling requires a horizontal
scrollbar and for some reason that escapes me our menus don't have
one of those. If they did, shifts could work for all menus but a
shifted window would hide the selection letters. So shifting would
be most usefully done as: pan right, read more of any long lines,
immediately pan back to the left.
For curses, they only apply to the persistent inventory window.
Shift right redraws it with class headers and inventory letters
shown normally but the item descriptions omit their leftmost
portion, showing more text towards the end. Shift left reverses
that and does nothing if the beginning is already in view. Forward
and backward scrolling while shifted leave the shift in place.
Give the window-port side of *_update_inventory() an argument.
Calls in the core still omit that; invent.c's update_inventory()
is the only place that cares.
Looking up scrollbars did not work as intended. The code wanted an
ancestor widget that had both horizontal and vertical scrollbars,
but menus either have none or just vertical. The lookup code found
some top level widget and returned bad data.
OPTIONS=menu_previous_page:\mv
BINDINGS=M-v:menu_previous_page
both worked, but
OPTIONS=menu_previous_page:M-v
BINDINGS=\mv:menu_previous_page
both failed. Make all four variations work. Tiny change made large
by the need to move some things around.
The option definition for menu_first_page had a couple of its flag
bits swapped. I didn't try to figure out whether that had any impact.
When panictrace feedback occurs due to catching a signal rather
than controlled panic, the backtrace is useless when running the
curses interface unless the terminal gets reset first. Let's
just hope that the signal triggering a panictrace doesn't occur
while resetting the terminal.
Some warnings were mentioned
Add a prototype ahead of the function
Use a non-const copy of SERVER_ADMIN_MSG
quick-tested by:
- uncommenting the following in include/unixconf.h
/* #define SERVER_ADMIN_MSG "adminmsg" */
- building NetHack
- creating a test message:
echo "server_admin: system is going down at 2 pm" >~/nh/install/games/lib/nethackdir/adminmsg
- playtested and received the desired message
des.region() accepted booleans for the joined field, whereas des.room
accepted xchars. These were only being used as truth values, so this
converts the room ones into booleans for consistency. I don't think
accidentally using an int or a boolean wrongly would actually crash the
level generator, but consistency is good.
This converts an schar field in struct mkroom into a boolean; on most
systems these are probably 1-byte types and save files won't be broken,
but it might be best to treat this as a save breaker anyway.
Its value is only used as a boolean, so there's no real need to keep it
as a confusing int.
Shouldn't be a save-breaking change; it doesn't look like g.coder is
saved.
"Demote" wizmgender from an obscure wizard mode extended command
to an obscure wizard mode boolean option. Behaves the same except
that no message is given when the value gets toggled.
When persistent inventory window is up, remove it if 'perm_invent'
option gets set to False. This has a side-effect of fixing the
end-of-game prompting problem it caused.