Both u_on_rndspot() and losedogs() might result in having a monster
and the hero be at the same location. Have wiz_makemap() use the
same fixup for that as goto_level().
The need for resetting lock picking when swapping in a new level made
me wonder whether other things should be reset too, and there were a
bunch: digging, travel destination, polearm target, being in water,
being swallowed or held, hiding. Hero placement was ignoring arrival
region. Also, it turned out to be pretty easy to fix the FIXME about
steed.
when level teleporting or digging. Level teleporting while levitation
was blocked due to being inside solid rock didn't notice that it should
be unblocked until you moved from whatever type of terrain you landed
on (room, for instance) to some other type (such as corridor). Digging
down to make a pit or hole while inside solid rock converts that spot
to floor so should also check whether to unblock levitation/flying, and
not fall if unblocking occurs.
Redo the Ft.Ludios entry hack to suppress the lit walls on the left
and top rather than to light the upper-right corner. Only noticeable
if carrying a lit candle. Usually, that is. This simpler hack could
be detected visually from the treasure room side of the walls involved
but normally won't be.
The entry chamber for the Fort Ludios level would be completely lit
except for one corner wall if you arrived carrying a lit candle. The
unlit spot turns out to be correct, it is beyond candle radius, but
spots further away than that were showing up lit. That's due to them
bordering a lit region on the opposite side and lit regions seem to
be bigger than their specified dimensions.
I tried to make the lit walls be unlit but it wasn't working. (Making
the lit region be smaller would probably work but might have unintended
consequences when populating the zoo room. I didn't try that.) This
makes the unlit corner show up if light hits the spot next to it, so
that it behaves like the other lit walls surrounding that entry area.
I haven't marked the bug report closed because I don't think this is
the proper way to fix this.
Give the enum lists in several header files explicit values. Adding
or removing new entries will be more tedious, but doing that is rare
and being able to grep the headers for numeric values in addition to
names is very useful.
rm.h also has a bunch of tabs replaced with spaces.
melt_ice can delete the fire trap, in the case where the trap
is on ice, and a monster carrying a boulder triggers it, then drowns.
mintrap -> minliquid -> mondead -> ... -> mdrop_obj ->
flooreffects -> boulder_hits_pool -> delfloortrap
When SEDUCE is disabled, instead of swapping attacks in mons[] once,
do it on the fly in getmattk() whenever needed. That allows mons[]
to become readonly, although this doesn't declare it 'const' because
doing so will require a zillion 'struct permonst *' updates to match.
This seemed trickier than it should be, but that turned out to be
because the old behavior was broken. Setting SEDUCE=0 in sysconf or
user's own configuration file resulted in all succubus and incubus
attacks being described as monster smiles engagingly or seductively
rather than hitting (while dishing out physical damage). I didn't
try rebuilding 3.4.3 to see whether this was already broken before
being migrated to SYSCF.
A hero run by the fuzzer that has characteristics plummet to 3 and
then sometimes hang around there instead of being recovered by restore
ability is happening because loss that tries to reduce the base value
below 3 lowers the max (peak) value instead, and once that also gets
down to 3, restore ability is no longer able to do anything with it.
This changes an attempt to reduce a characteristic by N points below 3
to reduce it by rn2(N + 1) instead. That's N/2 on average and a 50%
chance to be 0 when N is 1, so the peak value reached doesn't plummet
to 3 quite to quickly. It can still drop to that though.
There is a pull request dealing with simplifying attribute handling
and part of it affects the code being changed here, but the bit of
simplification included in this patch doesn't use it.
Take a first step towards making the mons[] array be readonly.
The only other place that updates it is when changing succubus and
incubus AD_SSEX attacks to AD_SEDU ones and that can be handled
via existing getmattk(), but so far has proven to be trickier than
anticipated.
They're never modified. Minor complication: &zeroobj is used as
a special not-Null-but-not-an-object value in multiple places and
needs to have 'const' removed with a cast in that situation.
Some phrase substitution in getpos() or its helpers produced
``Pick a target interesting thing in view for travel''
for 'm _', which sounds pretty awkward. Change that to be
``Pick an interesting thing in view for travel destination''
leaving "target" implied.
For plain '_', typing '!' yielded
``Using a menu to show possible targets.''
but then nothing happened. Change that to be
``Using a menu to show possible targets for 'm|M', 'o|O', 'd|D',
and 'x|X'.''
to explain when a menu will actually appear.
'struct obj' contains a union of mutually exclusive pointers, but
removing an obj from a list wasn't clearing whichever one had been
in use. If something is removed from a monster's inventory, clear
the object's pointer back to that monster; if something is removed
from a container, clear the object's pointer back to that container;
and whenever something is removed from the floor, clear the pointer
to the object which followed it at that floor location.
More shop price determination fallout. After the most recent change
to get_cost_of_shop_item(), using ':' inside an engulfer carrying at
least one item while inside a shop would try to follow the item's
obj->ocontainer back-link and crash when that led to the engulfing
monster rather than to a container.
The recent attempt to have looking inside a container show shop
prices had multiple problems. Worst one was showing shop prices as
if the hero would be buying for items already owned by the hero.
Item handling inside containers on shop floor was inconsistent: if
shop was selling those items, they would include a price, but if not
selling--either already owned by hero or shopkeeper didn't care about
them--they were only marked "no charge" if hero owned the container.
This is definitely better but I won't be surprised if other obscure
issues crop up. Gold inside containers on shop floor is always owned
by the shop (credit is issued if it was owned by the hero) but is not
described as such.
This started out removing one tab and I got carried away. It moves
some labels to column 2, removes some parentheses where sizeof is
used on strings rather than types, adds or revises several comments,
replaces a couple of 'while' loops which can be simplified as 'for'
loops, and updates named fruit handling.
"glob of black pudding" became "candied glob of black pudding" if used
as a fruit name, but "small glob of black pudding" was used as-is and
became indistinguishable from an actual small glob. Unless you had
more than one; then you could try to check whether they merged into a
stack or coalesced into a bigger glob (but if neither of those changes
happened, you still couldn't tell which was the glob and which was the
named fruit).
Fix fuzzer feedback. The new wizard mode ^T menu had an early return
which bypassed destroy_nhwindow(), leaving the menu around. Fuzzer
eventually got "No window slots!" panic from tty. Make sure that the
menu window is torn down fully before returning.
Also, make the normal wizard mode teleportation chioce be preselected
so that not picking anything doesn't lead to an early return any more.
ESC still does though.
Fixes#172
Casting teleport-away via ^T used different requirements for energy,
strength, and hunger than casting it via 'Z'. The strength and hunger
requirements were more stringent, the energy one more lenient. When
it rejected a cast attempt due to any of those, it used up the move,
but 'Z' didn't.
When testing my fix, I wanted an easier way than a debugger to control
how ^T interacts with wizard mode, so finally got around to a first
cut at being able to invoke it via wizard mode but not override those
energy/strength/hunger requirements. It uses the 'm' prefix to ask
for a menu. 'm^T' gives four options about how to teleport. (There
are other permutations which aren't handled.)
Also noticed while testing: ^T wouldn't attempt to cast teleport-away
if you didn't know the corresponding spellbook. 'Z' will attempt that
because it is possible to forget a book and still know its spell.