Commit Graph

4636 Commits

Author SHA1 Message Date
PatR
39b6a7e515 another warning fix
Comparison between signed and unsigned.  Compiler stupidity since
the range of possible values that signed 'i' can take is limited and
never negative.
2019-01-29 15:18:17 -08:00
PatR
1b49f60ded warning fix
The new code provoked several warnings; this fixes one of them.
Moving the declaration of 'rolecount' would have been sufficient,
but I've gone another way.
2019-01-29 15:00:07 -08:00
nhmall
57f03eca1b Merge branch 'alex-and-isaac' into NetHack-3.6.2-beta01 2019-01-29 07:20:17 -05:00
Alex Smith
0c96dd6a22 Consistently use rn2 in trap detection
It's a gameplay-affecting action (it updates the character's
memory of the map), and there's no way to spam it without using
resources, so rn2 is safe.
2019-01-29 03:37:08 +00:00
nhmall
54062e0ad6 include the rnd.c bits 2019-01-28 19:54:18 -05:00
nhmall
457e4b68aa merge Alex's dual rng proposal with the isaac64 rng code and adjust
This is branched from Alex's hallu-rng-stability branch,
with two build corrections (detect.c, zap.c), and merged
with  the isaac64 branch that we have ready to go.

Alex's dual rng is supported by setting up the array
of multiple isaac64 contexts.

I stuck with Alex's approach of passing the rng function
name around as the parameter (rng or rn2_on_display_rng)
for the new additional parameter needed for
set_random(), init_random(), reseed_random(),
and init_isaac64().
2019-01-28 19:43:55 -05:00
nhmall
819ee796f2 Merge branch 'countermeasures' into alex-and-isaac 2019-01-28 18:37:50 -05:00
PatR
30237c73ec fix #H8072 - failing wish segfaults
Having an artifact wish be refused uses zeroobj and code which
followed was attempting to update its weight, triggering a segfault
now that zeroobj is 'const'.
2019-01-28 09:10:52 -08:00
Patric Mueller
bd730dbcaa workaround for C89 not supporting inline 2019-01-28 15:00:04 +01:00
nhmall
0aa4d62a2c detect rng seed strength at runtime based on algorithm not compile time based on platform features 2019-01-28 10:32:57 +01:00
nhmall
0a430cab11 every platform provides sys_random_seed() and SYS_RANDOM_SEED goes away 2019-01-28 10:32:57 +01:00
Patric Mueller
97b8d0a50b Don't define Rand() if isaac64 is used 2019-01-28 10:02:09 +01:00
nhmall
6c114640f5 some system-specific adjustments for RNG routines
move some system-specific seed-related stuff from hacklib.c to
a system-specific source file and #define SYS_RANDOM_SEED to
utilize it during build.

Windows changes for random seed generation using
crypto next gen (CNG) api routines.

Corresponding vms changes due to disentangling of VMS and
unix when the unix seed bits got moved (untested).
2019-01-28 10:02:08 +01:00
Patric Mueller
f9433b2a87 integrate isaac64 into nethack
Also removed the float code from isaac64 as they are not used in
NetHack.
2019-01-28 10:02:08 +01:00
Patric Mueller
c81db872fd add file for the isaac64 random number generator
This is the version from the Comprehensive C Archive Network, licensed
under the CC0 "No Rights Reserved" Creative Common License.
http://ccodearchive.net/info/isaac.html
2019-01-28 10:02:08 +01:00
Patric Mueller
52d4b1a1aa reseed during level change to prevent deduction of rng state
For platforms that read from the system's random number generator,
reseed during level change, before the map of a new level is created and
after level creation has finished.
2019-01-28 10:02:00 +01:00
Patric Mueller
86d694c61b read rng seed from random number source device
Linux and BSD system have random number source devices that can be used
as source for a unguessable seed source.

Other platforms fall back to generate the seed with gettime().
2019-01-28 10:01:45 +01:00
Alex Smith
ce5184c3da Don't advance the main RNG during hallucination
This is based on the multiple-RNGs code fron NetHack4, but using
only the parts relevant to the display RNG (and with substantial
changes, both because of post-3.4.3 changes, and because Nethack4's
display code is based on Slash'EM's rather than NetHack's).
2019-01-28 04:45:26 +00:00
nhmall
55fdfb9200 domove_core() out of domove(); assess domove_core() results
new domove_core() assessment results

potentially smudge engravings

Proceed to wipe engraving after domove_core() now, but only under
all of the following conditions:
    - you can reach the floor
    - preceding domove_core() move attempt was marked as
      having succeeded in domove_core()
    - there is actually an engraving there to impact at
      your original spot, or your new spot, or both
2019-01-27 11:55:23 -05:00
PatR
deed117e7f fix #H6422 - hmonas against shades
I did much of this quite some time ago, as prequisite for a different
bug report about monsters vs shades, then set it aside.  It ended up
being more complicated than I anticipated.

When deciding whether various non-weapon attacks might hit a shade,
hmonas() was not checking for blessed or silver armor that should have
been applicable.  It did check boots when kicking, but not gloves or
rings (when no gloves) when touching, or outermost of cloak/suit/shirt
when hugging, or helmet when head-butting.  (The last one is actually
moot because nothing with a head-butt attack is able to wear a helm.)

The problem was more general than just whether attacks might hit and
hurt shades.  Various undead and/or demons are also affected by blessed
and/or silver attack but weren't for non-weapon attacks by poly'd hero.

At least two unrelated bugs are fixed:  a rope golem's AT_HUGS attack
gives feedback about choking but was fully effective against monsters
which fail the can_be_strangled() test.  And it was possible to hug a
long worm's tail, rendering the entire worm immobile.

The report also suggested that all artifacts be able to hit shades for
full effect, but by the time shades are encountered everyone has an
artifact so that would nullify a shade's most interesting ability.

TODO:  monster against hero and monster against other monster need to
have similar changes.
2019-01-22 18:15:49 -08:00
PatR
d0cc645961 vampshifter resurrection while being held
If poly'd hero is holding a bat/cloud/wolf which dies and revives as a
vampire, release the hold.
2019-01-22 17:54:58 -08:00
PatR
a14752ab47 shielding bashing
Extracted from a larger patch:  the only way to get silver damage
bonus from attacking with a shield of reflection (polished silver
shield) is to throw it or to wield it.  Give different feedback when
hitting something while wielding a shield (or an iron ball; it seemed
appropriate despite having nothing to due with wanting to dish out
silver damage).
2019-01-21 18:54:37 -08:00
PatR
3c7eca5418 hmonas() simulated twoweap
Regular two-weapon requires that both weapons actually be weapons or
at least weapon-tools.  Simulation of that while polymorphed allowed
any one-handed object as the primary weapon.
2019-01-21 18:49:44 -08:00
Pasi Kallinen
f6b9dc7d68 Don't try to write a zero-length message
If the message history contains a zero-length message line, skip it,
as trying to write a zero-length string will make bwrite panic.

Happened only on X11. This is post-3.6.1 bug.
2019-01-21 11:56:19 +02:00
Pasi Kallinen
77bc07f579 Make demon gating show a message
This was both an accessibility and comprehensibility issue.
2019-01-20 15:56:44 +02:00
PatR
9a39618fb3 fix #H7983 - inconsistent shop 'for sale' behavior
Items on floor in the free spot one step inside a shop's doorway were
showing shop sell prices.  Treat items on that spot as if they were
flagged no_charge as on the floor of other shop squares.

Report stated that sometimes they showed a 'for sale' price and
sometimes they didn't, but I didn't see any cases where they didn't.
2019-01-18 14:13:30 -08:00
PatR
3506c24d39 fix #H7980 - multiple weapon attacks when poly'd
This fixes the weapon related aspects of #H7980:  having an alternate
weapon be used in cases where it shouldn't when polymorphed into a
monster form with multiple weapon attacks.  The most egregious was
using an off-hand artifact, but it would also use off-hand two-handed
weapon, off-hand silver weapon when in silver-hating form, or any
reasonable off-hand weapon when wearing a shield.  That last is iffy
whether or not to allow, since you'll still get the extra attacks
whether it switches to secondary weapon or stays with the primary.
I've made it re-use the primary since two-weapon mode doesn't allow
a shield.  The other oddity was being able to use the secondary
weapon on the second swing even if the first swing was weaponless.
I went with ingoring the secondary weapon if there's no primary one
or if the primary is two-handed.

Report included "cursed secondary doesn't weld" but that has nothing
to do with polymorph attacking.  I've changed that to drop the weapon
if you attack with it when it's cursed, similar to what happens when
secondary weapon becomes cursed while two-weaponing.

It also included "marilith's attacks beyond the second don't use any
weapon and can hit cockatrices without touching them".  A marilith has
two weapon attacks and then four claw attacks.  Claw attacks only use
the weapon if it hasn't been used yet, so marilith hits with primary,
secondary (or primary a second time if no secondary), claw, claw,
claw, claw and that's the intended behavior.  It is able to hit
cockatrices if wielding anything at all, same as a monster with just
a single attack.  Since it is impossible to wield six weapons or three
pairs of gloves, that has to be intended behavior too.  Playability
trumps realism even if it is silly to hit without a 3rd through 6th
weapon and be safe from touching the target due to the 1st weapon or
one pair of gloves.  [Situation is different from having no control
over unsafely biting something after making a safe weapon or claw
attack; perhaps a better solution would be to refrain from using the
four claw attacks when attacking something that is fatal to touch.]
2019-01-18 13:22:43 -08:00
PatR
b9f38fdd14 fix #H6285 - flooreffects and deltrap panic
Reported 14 months ago, a monster reading a scroll of earth which
dropped a boulder that killed another monster in an adjacent pit
was giving credit/blame to the hero and could also trigger a panic.
If the monster was killed, the pit would be filled and deleted via
m_detach and then when flooreffects tried to delete the same trap,
it accessed freed memory and deltrap could panic.
2019-01-16 15:08:11 -08:00
PatR
521dbe8f94 potion mixing bit
Noticed when looking at whether alchemy ought to remove user-assigned
name.  Get rid of the potion being dipped into sooner so that it won't
still be present if a perm_invent update takes place.
2019-01-14 18:13:59 -08:00
PatR
97b28bd846 level arrival
The check I added to make sure that a monster was at the hero's
coordinates before deciding to move one or the other would have been
confused by a long worm's tail.  Check that they're at that spot but
not by comparing monst.<mx,my> coordinates with <ux,uy>.

Also, don't have wiz_makemap() assume that each level of the Wizard's
Tower has the same boundary coordinates.  Keep track of whether hero
is inside that tower before discarding the old level.
2019-01-14 16:35:19 -08:00
PatR
992f141ab7 \#wizmakemap followup
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().
2019-01-14 09:28:10 -08:00
PatR
d735d04b5b \#wizmakemap update
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.
2019-01-13 15:24:08 -08:00
PatR
355dec4d84 blocking or unblocking levitation or flight
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.
2019-01-13 15:17:40 -08:00
Pasi Kallinen
abcdb713d5 wizmakemap should reset lockpicking 2019-01-13 17:27:17 +02:00
Pasi Kallinen
5e2236a3ef Fix accessing deleted fire trap
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
2019-01-10 21:48:20 +02:00
PatR
b1782b813f SEDUCE=0
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.
2019-01-10 03:10:35 -08:00
PatR
79d40658c7 characteristics loss
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.
2019-01-09 18:18:11 -08:00
PatR
a637e91f37 miscellaneous formatting
Some minor stuff that's been sitting around for a while.
2019-01-09 18:15:43 -08:00
PatR
bb86fa2bb7 hero infravision
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.
2019-01-09 18:10:55 -08:00
PatR
dd13b10cf2 make zeroany, zeromonst, zeroobj 'const'
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.
2019-01-09 01:13:01 -08:00
PatR
d4e3f9d9d3 travel targetting via keyboard
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.
2019-01-08 14:42:54 -08:00
PatR
d1deafab05 stale vptrs for obj->{nexthere,ocontainer,ocarry}
'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.
2019-01-06 20:59:20 -08:00
PatR
a1fd4622f2 get_cost_of_shop_item() crash
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.
2019-01-06 02:36:41 -08:00
PatR
ab1bee1778 fix #H7865 - shop prices for container contents
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.
2019-01-05 03:21:39 -08:00
PatR
ab5b400aec options.c formatting; glob as named fruit
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).
2019-01-04 19:03:34 -08:00
PatR
c0cce3110e src formatting
Remove a couple of tabs, and for the affected files, put 'goto' labels
in column 2 where they're easier to spot.
2019-01-04 18:47:00 -08:00
PatR
9bcc42957b 'm ^T' menu fix
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.
2019-01-04 18:28:50 -08:00
PatR
600261d81f fix github #172 - ^T inconsistencies; add m^T
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.
2019-01-03 17:37:00 -08:00
PatR
b2ad4651f3 sortloot vs gems
Some object classes (such as armor and weapons) are split into
"subclasses" when sortloot applies an ordering (for armor, all helms,
then all gloves, then all boots, and so on).  Give gem class subsets.
Simple (1) valueable gem, (2) worthless glass, (3) gray stone, (4) rock
would give away information; instead, factor in discovery state and use
(1) unseen gems and glass ("gem")
(2) seen but undiscovered gems and glass ("blue gem"),
(3) discovered gems ("sapphire"),
(4) discovered glass ("worthless pieced of blue glass"),
(5) unseen gray stones and rocks ("stone"),
(6) seen but undiscovered gray stones ("gray stone"),
(7) discovered gray stones ("touchstone"),
(8) seen rocks ("rock").
If everything happens to be identified, the simpler ordering happens
(via 3, 4, 7, and 8) because the other subsets will be empty.
2019-01-02 14:20:53 -08:00
PatR
480e682454 create_particular long worm tail vs mkclass
Similar to ^G of 'I' triggering impossible "mkclass found no class 35
monsters", using a leading substring of "long worm tail" (other than
"l" and "long worm") would trigger impossible "mkclass found no class
59 monsters and kill the fuzzer when it escalates impossible to panic.
Tighten up the substring matching.

^G of '~' wasn't affected; it deliberately creates a long worm rather
than the tail of one.  But it was possible to ask for "long worm tail"
as a specific monster type and then override the switch to long worm
when prompted about whether to force the originally specified critter.
I've added a check to prevent that opportunity to override even though
a tail without a head seemed to be harmless.
2019-01-02 13:42:45 -08:00