Commit Graph

408 Commits

Author SHA1 Message Date
PatR
0479625c94 cancelled zombification
Don't let cancelled zombies or cancelled liches create new zombies.
2021-03-30 17:33:31 -07:00
PatR
ac37aba4bd sanity_check of steed
For wizard mode sanity_check, add a check for steed's saddle when
hero is riding.
2021-03-17 09:14:22 -07:00
PatR
27a0351cd2 fix #H3734 - "see an angry guard" when that guard
is invisible and hero can't see him/her.  Reported for 3.4.3 in
late 2014....
2021-02-23 02:04:21 -08:00
copperwater
ee7664684a Unify code for extracting an object from a monster's inventory
The code for doing this (basically an obj_extract_self() call plus
handling if the object was worn or wielded) was duplicated all over, and
inconsistent - for instance, though all of them updated the monster's
misc_worn_check to indicate it was no longer wearing something in
whatever slot, only one call also set the bit that flags the monster to
consider putting on other gear afterwards.

Under a new function, extract_from_minvent, all this extra handling is
checked in one function, which can simply replace the obj_extract_self
call.

A few callers (such as stealing) have some common code *after* the
object is extracted and some other things happen such as message
printing, such as calling mselftouch if the object was worn
gloves. extract_from_minvent does not handle these cases.
2021-01-29 19:19:03 -05:00
nhmall
f963c5aca7 switch source tree from k&r to c99 2021-01-26 21:06:16 -05:00
Dean Luick
3a30038b49 Add a missing fall-through comment
This eliminates a gcc warning.
2021-01-20 22:39:08 -06:00
Michael Meyer
47884d63ac Merge branch 'NetHack-3.7' into fix322 2020-12-30 14:05:16 -05:00
PatR
9c6a65f49b fix github issue #432 - bad sanity check
The block of sanity check code that is causing impossible warnings
about the Wizard mimicking a monster was initially only used for
furniture and objects specifically because of the Wizard.  When it
got extended to check for mimicking monsters, an exception for the
Wizard was needed but not added.

Fixes #432
2020-12-29 14:34:37 -08:00
PatR
5c4996c701 mimics in inaccessible locations
Suppress insane sanity check.
2020-12-27 05:27:02 -08:00
nhmall
0c3b9642e4 pmnames mons gender naming plus a window port interface change
add MALE, FEMALE, and gender-neutral names for individual monster species
to the mons array. The gender-neutral name (NEUTRAL) is mandatory, the
MALE and FEMALE versions are not.

replace code uses of the mname field of permonst with one of the three
potentially-available gender-specific names.

consolidate some separate mons entries that differed only by species into a
single mons entry (caveman, cavewoman and priest,priestess etc.)

consolidate several "* lord" and "* queen/* king" monst entries into
their single species, and allow both genders on some where it makes some
sense (there is probably more work and cleanup to come out of this at some
point, and the chosen gender-neutral name variations are not cast in stone
if someone has better suggestions).

related function or macro additions:
    pmname(pm, gender) to get the gender variation of the permonst name. It
    guards against monsters that haven't got anything except NEUTRAL naming
    and falls back to the NEUTRAL version if FEMALE and MALE versions are
    missing.

    Ugender to obtain the current hero gender.
    Mgender(mtmp) to obtain the gender of a monster

While the code can safely refer directly to pmnames[NEUTRAL] safely in the
code because it always exists, the other two (pmnames[MALE] and
pmnames[FEMALE] may not exist so use:
    pmname(ptr, gidx)
      where -ptr is a permonst *
            -gidx is an index into the pmnames array field of the
             permonst struct
pmname() checks for a valid index and checks for null-pointers for
pmnames[MALE] and pmnames[FEMALE], and will fall back to pmnames[NEUTRAL] if
the pointer requested if the requested variation is unavailable, or if the
gidx is out-of-range.

Allow code to specify makemon flags to request female or male (via MM_MALE
and MM_FEMALE flags respectively)to makedefs, since the species alone doesn't
distinguish male/female anymore. Specifying MM_MALE or MM_FEMALE won't
override the pm M2_MALE and M2_FEMALE flags on a mons[] entry.

male and female tiles have been added to win/share/monsters.txt.
The majority are duplicated placeholders except for those that were
separate mons entries before. Perhaps someone will contribute artwork in the
future to make the male and female variations visually distinguishable.

tilemapping via has the MALE tile indexes in the glyph2tile[]
array produced at build time. If a window port has information that the
FEMALE tile is required, it just has to increment the index returned
from the glyph2tile[] array by 1.

statues already preserved gender of the monster through STATUE_FEMALE
and STATUE_MALE, so ensure that pmnames takes that into consideration.

I expect some refinement will be required after broad play-testing puts it to
the test.

    consolidate caveman,cavewoman and priest,priestess monst.c entries etc

This commit will require a bump of editlevel in patchlevel.h because it alters
the index numbers of the monsters due to the consolidation of some. Those
index numbers are saved in some other structures, even though the mons[] array
itself is not part of the savefile.

Window Port Interface Change

Also add a parameter to print_glyph to convey additional information beyond
the glyph to the window ports. Every single window port was calling back to
mapglyph for the information anyway, so just included it in the interface and
produce the information right in the display core.

The mapglyph() function uses will be eliminated, although there are still some
in the code yet to be dealt with.

win32, tty, x11, Qt, msdos window ports have all had adjustments done to
utilize the new parameter instead of calling mapglyph, but some of those
window ports have not been thoroughly tested since the changes.

Interface change additional info:

    print_glyph(window, x, y, glyph, bkglyph, *glyphmod)
            -- Print the glyph at (x,y) on the given window.  Glyphs are
               integers at the interface, mapped to whatever the window-
               port wants (symbol, font, color, attributes, ...there's
               a 1-1 map between glyphs and distinct things on the map).
            -- bkglyph is a background glyph for potential use by some
               graphical or tiled environments to allow the depiction
               to fall against a background consistent with the grid
               around x,y. If bkglyph is NO_GLYPH, then the parameter
               should be ignored (do nothing with it).
                -- glyphmod provides extended information about the glyph
               that window ports can use to enhance the display in
               various ways.
                    unsigned int glyphmod[NUM_GLYPHMOD]
               where:
                    glyphmod[GM_TTYCHAR]  is the text characters associated
                                          with the original NetHack display.

                    glyphmod[GM_FLAGS]    are the special flags that denote
                                          additional information that window
                                          ports can use.

                    glyphmod[GM_COLOR] is the text character
                                       color associated with the original
                                       NetHack display.

Support for including the glyphmod info in the display glyph buffer
alongside the glyph itself was added and is the default operation.
That can be turned off by defining UNBUFFERED_GLYPHMOD at compile time.
With UNBUFFERED_GLYPHMOD operation, a call will be placed to map_glyphmod()
immediately prior to every print_glyph() call.
2020-12-26 11:23:23 -05:00
PatR
c709c45780 concealed monster sanity checks
Add some more checks to sanity_check_single_mon().  If mon->data
is discovered to be bad, panic instead of just issuing a warning
since a subsequent crash would be inevitable.  Make sure hidden
ceiling hiders have a ceiling to hide at (so not on the planes of
air or water; some quest levels should probably be classified as
"no ceiling" but currently aren't).  Perform a few mimic checks.

Protection from shape changers had a couple of minor bugs.  A mimic
hidden at a spot the hero couldn't see would be allowed to remain
hidden (and stay that way once within view because protection from
shape changers isn't re-checked during ordinary activity).  Also,
if a pet was shape-changed while eating a mimic corpse at the time
protection from shape changers started, it would fall into untimed
sleep as part of being forced back to normal shape [rescham()] if
its location could be seen.
2020-12-18 15:05:54 -08:00
PatR
e9d729733b bargethrough/monster-vs-monster displacing
Fix the regression that monster movement flag unification
introduced for monsters able to swap places with adjacent
monsters.  It used to be restricted in order to prevent
Riders swapping places with other Riders so that they didn't
repeatedly exchange places when one was right behind the other
and the farther one moved first.  Then when displacer beasts
were added, that restriction was extended to prevent them
swapping places with Riders (but not the other way around.)
The flags change inadvertently let any displacer swap with any
other displacer.
2020-12-13 15:51:23 -08:00
PatR
87818188e1 fix #3120,#3122 - dwarf pass_wall without digging
I couldn't reproduce this so can't confirm that this fix works,
but inspection of the code reveals that something was missing
in the unified mon movement flags code.  I think what has been
happening is that a dwarf without a pick-axe might not bother
wielding that but movement behaved as if it had, then digging
decided it wasn't.
2020-12-07 12:46:46 -08:00
Pasi Kallinen
44920d4650 Remove duplicate lines 2020-12-05 19:00:19 +02:00
PatR
df8e2dcd74 -Wshadow fix
Not caused by a hidden macro this time...

|mon.c:1549:10: warning: declaration shadows a variable in the
|      global scope [-Wshadow]
|    long flags = 0L;
|         ^
|../include/flag.h:392:29: note: previous declaration is here
|extern NEARDATA struct flag flags;
2020-11-28 20:15:30 -08:00
Pasi Kallinen
fb188dc1aa Unify mfndpos monster movement flags 2020-11-28 12:49:18 +02:00
PatR
5361958bdc more "golem rust in peace"
Be prepared for life-saving to contradict "<mon> falls to pieces".
Purely hypothetically at present (with no plans to change) since
golems don't benefit from amulets of life-saving.
2020-11-28 02:19:28 -08:00
PatR
bb9df368af fix github issue #401 - roast/rust/rot in peace
This tries to fix the problem of the extra message when a tame
golem is completely destroyed (paper or straw golem burned, iron
golem rusted, wood or leather golem rotted) being issued at odd
times.  I basically punted on the visibility aspect since the
original logic was strange:  you had to be able to see both the
attacker's and defender's spots and at least one of those two
monsters.  Now mon-attacks-mon visibility requires that you be
able to see one of the two and if you don't see both, the unseen
one will be referred to as "it".  The "may the iron golem rust
in peace" message is independent of that and may be displayed
after "you have a sad feeling", but now that's intentional and
will refer to an unseen pet by name or monster type, not "it".

This needs a lot of testing and hasn't attempted to address
issue #402:  only some attacks that should compeletely destroy
a golem actually do so.  (So a hit by fire elemental against a
paper golem does, but passive fire counterattack when a paper
golem hits a fire elemental doesn't, nor does a wand of fire
or being hit by Firebrand.)

Fixes #401
2020-11-27 02:38:17 -08:00
Pasi Kallinen
229930e505 Fixes and sanity checks for monster undetected and trapped states
Adds sanity checks for mtrapped and mundetected states.

Fixes cases where those were left in wrong state.

1. Trapped monster (eg. a nymph) teleported out of a trap
2. Monster was hiding under ball or chain, which then got removed
3. While restoring a level, a zombie corpse revived while monster
   was hiding under it
4. A general case where the only object was deleted off floor and
   a monster was hiding under it

Monsters hiding under ball or chain will now get revealed when
the b or c are moved.
2020-11-24 19:37:43 +02:00
Pasi Kallinen
6ec55a3624 Rework stairs structure
Use a linked list to store stair and ladder information, instead
of having fixed up/down stairs/ladders and a single "special" (branch)
stair.

Breaks saves and bones.

Adds information to migrating objects and monsters for the dungeon
and level where they are migrating from.
2020-11-13 20:27:17 +02:00
PatR
ea0ef81ecd fix github issue #408 - stuck to distant mimic
Attacking a concealed mimic at range by applying a polearm
could make the hero be stuck to that mimic in addition to
bringing it out of hiding.  Only do that when adjacent.

This also adds a new sanity check when setting u.ustuck.
It may get triggered by other sticking activity since only
attacking has been tested.  The check must be explicitly
enabled by setting the wizard mode 'sanity_check' option.

Fixes #408
2020-11-08 16:07:42 -08:00
Pasi Kallinen
aeb0ea65e3 Mild Zombie Apocalypse
When a zombie (or lich) kills a monster in melee without a weapon,
the monster can rise few turns later as a zombie.

The only creatures that can be zombified are ones that actually have
a zombie counterpart monster. A zombie cannot turn a jackal into
a zombie, for instance. But it could turn a shopkeeper into a human
zombie, or a dwarf king into a dwarf zombie.

Zombies will fight with monsters that can be turned into zombies.

Originally this was a SliceHack feature, but this is based on xNetHack
version of it, with some modifications.
2020-10-23 19:47:10 +03:00
Pasi Kallinen
566dde8683 Match object description via single function
making the code more readable.

Instead of doing strcmp(OBJ_DESCR(objects[otyp]), "foo"),
just call objdescr_is(obj, "foo")

(via xNetHack)
2020-10-20 19:19:57 +03:00
PatR
5df5079700 peacefuls witnessing attack against peaceful mon
The short exclamations ("Gasp!", "Why?", &c) led to ambiguity
about which monster was vocalizing them.  Use full sentences
which refer to the speaker.  It can become quite a bit more
verbose but is less likely to lead to confusion.  Perhaps it
should cut those off after a modest number of them have been
issued?
2020-09-24 00:44:07 -07:00
PatR
cf482f1f42 fix #K2203 - animals can talk
The code for peaceful monsters witnessing the hero attack another
peaceful monster and getting angry had a 20% of making them gasp in
surprise or exclaim "why?" in shock.  It was only requiring them to
have humanoid shape rather than checking for speech capability, so
peaceful zruty or minotaur, possibly other animals, could exclaim
comprehensibly.  Other things which shouldn't talk, like mummies,
would behave similarly.

This categorizes how a bunch of MS_foo types should react.  It has
only been lightly tested.
2020-09-20 18:38:31 -07:00
PatR
a48b4aa8ba fix #K1963 - warning after placing worm tail
Report described this as a panic triggered by the sanity_check
option, but that's because it was running under the fuzzer, which
escalates any impossible() to panic(), rather than because nethack
panicked.

I couldn't find anything wrong--which doesn't mean that there
isn't something wrong--with place_worm_tail_randomly() and
random_dir().  They use xchar for map coordinates which should be
fine as long as no negative values are generated and I couldn't
discover any such.  The suggested fix of changing xchar to int
might indicate a compiler bug (although the odds of that are low).
The bogus coordinate of -15000 in the report suggests that
 typedef short int schar;
(which changes xchar too) is being used in the configuration but
I don't recall having any problems attributable to that.

This switches from xchar to int as a side-effect of replacing the
offending code entirely.  The new code might produce an 'ny' of -1
before goodpos() rejects it, so xchar would be inappropriate now.
The old code is commented out via #if 0 _after_ changing it from
xchar to int.

This also adds an extra sanity_check for worm tails, unrelated to
the current bug.  I'm not aware of any instance where it fails.
EXTRA_SANITY_CHECKS needs to be defined for it to do anything.
2020-09-08 03:03:03 -07:00
PatR
bce7834f71 polearm context
Move clearing of polearm context from migrate_to_lev() to lower
level relmon().  Add missing transfer of polearm context from
old mon to new mon in replmon().  These days it seems to only be
used for creating a monster from saved traits, so polearm context
in it should be moot.
2020-09-05 11:35:28 -07:00
PatR
1df2fdca44 fix pull request #379 - is_displacer()
A couple of places which could/should have been using existing
is_displacer() macro weren't.

No change in behavior.

Fixes #379
2020-08-27 17:38:11 -07:00
nhmall
ac9ba38449 file header bump from "NetHack 3.6" to "NetHack 3.7" 2020-08-03 22:07:36 -04:00
PatR
9cb3fa9cf2 mon->mhpmax sanity check
The check for mon's max HP being at least as high as its level
turns out to be wishful thinking.  Just disable it.  Maybe we'll
flag critters who got or gave up HP during cloning and let them be
exceptions, then turn it back on, but not now.  Or maybe reduce
mon->m_lev when cloning.  That would weaken them though.

Keep the 1 extra HP that an earlier fix for this check gave to
monsters who rolled the minimum possible value while being created
(Nd8 that yielded N boosted to N+1, 1d4 for 1 boosted to 2).
2020-08-01 05:11:20 -07:00
PatR
abe4db6e60 fix pull request #365 - monster max HP
The recently added sanity check for monster maximum HP was giving
false complaints when Nd8 monster had N mhpmax.  Most noticeable
for level 1 monsters (level 0 monsters use 1d4 instead of 0d8 and
weren't affected) but possible for higher level ones if they were
unlucky--from their own perspective--with all their d8 rolls.

Give level N monsters a minimum of N+1 HP, so minimum of 2 for
level 1 monsters, making 1/8 of those stronger.  Same minimum for
level 0 monsters, 25% of which will become stronger now.  (The pull
request's patch gave every Nd8 monster 1 extra HP; this only does
so for Nd8 and 1d4 ones which have rolled lowest possible amount.)

Also relax the sanity check so that existing to-be-3.7 save files
don't continue to trigger sanity complaints for existing monsters
that have the old minimum.

Fixes 365
2020-07-14 17:03:51 -07:00
PatR
a37975b625 fix pull request #367 - mind flayer psychic blast
hitting a hidden monster didn't reveal that monster.  It stayed
hidden despite the feedback describing it as if it could be seen.

The pull request's two line fix handled a monster's blast hitting
another monster but left two related issues as-is:  monster's blast
hitting hidden poly'd hero left hero unrevealed and poly'd hero's
blast left hidden monster unrevealed.  Same code, different bug:
poly'd hero's blast affected mindless monsters.

This unhides an affected target before the message about it being
hit rather than after.  That would look better if preceded by a
message describing the object (mimic or hides-under) or furniture
(mimic) or empty spot (ceiling hider) as being or concealing a
monster but I didn't put in sufficient effort to accomplish that.

Fixes #367
Fixes #362
2020-07-14 04:55:53 -07:00
Michael Meyer
5a2c94f8e3 Rollback changes to NHDT-Date 2020-07-13 11:16:18 -04:00
Michael Meyer
64c26771f3 Remove find_ghost_with_name(mon.c) 2020-07-13 06:18:00 -04:00
PatR
12498ffa44 fix github issue #372 - Wizard escaping dungeon
If the Wizard fled up the stairs on level 1 and escaped the dungeon
(which can only happen if he isn't carrying the Amulet or any of
the invocation items), the number_of_wizards counter wasn't being
decremented.  If that was the only Wizard, he couldn't be brought
back into play because he wasn't on the migrating monsters list, and
he wouldn't appear on the Plane of Earth when the hero eventually
went there.  If that was one of two, the remaining one couldn't use
Double Trouble anymore.  (I'm not sure about Earth handling in that
situation; should be moot now.)

Wizard mode blessed genocide of "*" when the Wizard is on current
level caused the same problem.

Fix by keeping the number_of_wizards counter up to date if mongone()
is called for the Wizard, handling both cases.  Also, don't let the
Wizard escape the dungeon unless he's one of two at the time, making
the first case no longer possible.

If wizard mode blessed genocide of "*" is used on the level where
the quest nemesis is present, the killed-the-nemesis feedback will
now be given.  I'm not completely convinced that this was the right
thing to do, but it only applies to wizard mode so may not matter.

Fixes #372
2020-07-13 01:58:44 -07:00
PatR
7d7b98f0ae mhpmax of life-drained monsters
The report about problems after stone-to-flesh on a petrified
long worm included stethoscope feedback of 0(-1) hit points, after
life-draining.  I was unable to reproduce a maximum hp of -1 and hope
that it was a side-effect of the [already fixed] stale mon->wormno
value used when resurrecting the long worm.  Anyway, this changes
life-draining to never take mon->hpmax below mon->m_lev + 1 (the +1
is needed to cope with m_lev==0 monsters).  The same limit is also
applied to monster life-saving but more to avoid replicating the
arbitrary minimum of 10 (four instances) then because it might be
less than m_lev+1 somehow.

Sanity checking now tests whether a monster's max HP is less than
its level + 1 so if there are ways other than life-drain attacks for
it to drop that low, the fuzzer will choke.  The new check also tests
whether a monster's current HP is greater than max HP.

Polymophred hero killing a golem or vortex by vampire bite reported
"<Mon> dies."  Give an alternate message since those aren't alive.
2020-06-27 18:15:19 -07:00
PatR
503df6823d fix github issue #354 - stealarm() impossible
A thieving monster could be killed while the hero was busy taking
off armor which needs multiple turns (normally a suit) and if that
happened on the same turn as the take-off finished, the warning
"stealarm(): dead monster stealing" was issued.  Cited case was
having the thief be killed by a stinking cloud but it could happen
if the death was caused by a pet or by some other monster trying
to attack the hero.  If the thief died sooner, the situation was
silently ignored.  So this could have been fixed by just getting
rid of the impossible() feedback.

'stealmid' and 'stealoid' should have been static in steal.c rather
than global and as such should have been moved into 'struct g'.
This moves them there and then takes advantage of having access to
'stealmid' outside of steal.c.  That's just a minor optimization
since m_detach() could call new thiefdead() unconditionally and the
latter could check whether the dead monster matches 'stealmid'.

Fixes #354
2020-06-01 06:17:07 -07:00
PatR
7817e69c41 two new monsters from slash'em
Adds two monsters originally from slash'em.  I used the slash'em
tiles this time, also its code as a starting point but made various
revisions.  Both the tiles could benefit from some touch-ups.

displacer beast:  blue 'f'.  Attempting a melee hit (ie, trying to
  move to its spot) has a 50:50 chance for it to swap places with you.
  Fairly tough monster to begin with, then half your ordinary attacks
  effectively miss and if you try to face a mob by retreating to a
  corridor or backing into a corner you can end up being drawn back
  into the open.  I added bargethrough capability, and also it won't
  be fooled about hero's location by Displacement.  [It only swaps
  places during combat when contact is initiated by the hero, not
  when attacked by another monster or when attacking.]

genetic engineer:  green 'Q'.  Its attack causes the target to be
  polymorphed unless that target resists.  Hero will almost always
  have magic resistance by the time this monster is encountered, but
  it can make conflict become risky by hitting and polymorphing other
  monsters.  Slash'em flagged it hell-only but I took that flag off;
  I also took away its ability to teleport.  Slash'em polymorphs the
  hero if a genetic engineer corpse is eaten; that's included and I
  introduced that for monsters too.

I added both of these to the list of candidates for monster spell
'summon nasties' and for post-Wizard harassment.

I also gave all the 'f's infravision.  Probably only matters if the
hero polymorphs into a feline.

Displacer beast is originally from AD&D which depicts it as a six-
legged cougar with a pair of tentacles; it has Displacement rather
be able to affect an attacker's location.  I think genetic engineer
is original to slash'em where it expands Q class but seems mainly to
be the base monster for Dr.Frankenstein (a unique monster with a
one-level side-branch lair in slash'em's incarnation of Gehennom).
2020-05-03 14:13:08 -07:00
PatR
49df1e184e monster eating (2 of 2)
Some instances of monsters eating nurse corpses or tins of nurse
caused blindness to be cured, others didn't.  Always do that to
match the effect on the hero.

Also, fix a couple more obsolete references to green slime corpses.
2020-04-29 13:24:31 -07:00
Pasi Kallinen
6d1df04eda Remove incorrect comment 2020-04-12 15:45:13 +03:00
PatR
995a6bf4fe purple worms
Compiler complained about 'ptr' possibly being used unitinialized
in meatcorpse() and in this case it was right.  meatcorpse() was
cloned from meatobj() but the necessary initialization was missing.

Purple worm would devore an entire stack of corpses in one bite.
Split one off and have it eat that instead.

I'm not sure whether attempting to revive a Rider corpse can force
a monster off the level to make room.  If so, meatobj() and
meatcorpse() weren't prepared to handle that, nor was their caller.
It appears that the monster (either g.cube or purple worm) will
only eat as it moves so can't revive a Rider on a completely full
level since it won't be able to move in that situation.  I fixed
the caller to be prepared to handle a result of 3 (no further
action allowed) instead of just dealing with 2 (died), but I didn't
fix either of the meatfoo() routines to return 3 since bumping the
eating monster off the level seems to not be possible.

Don't let purple worms eat lichen corpses, regardless of whether
they'll swallow live ones.
2020-04-05 05:57:37 -07:00
Pasi Kallinen
cf1c725148 Purple worm changes
Shriekers only spawn purple worms when they're appropriate difficulty.
Non-tame Purple worms eat corpses off the ground.
Baby purple worms attack shriekers.
Hero polyed into baby purple worm is warned against shriekers.

Original changes by copperwater <aosdict@gmail.com>, added with some
formatting adjustments and consolidation.
2020-04-05 12:44:25 +03:00
Pasi Kallinen
e34f123698 Make hezrous stink 2020-04-03 21:05:49 +03:00
Pasi Kallinen
5f9714bf92 Remove workarounds for ancient compilers 2020-04-03 08:21:08 +03:00
PatR
8301fc06df warning fix
Fix a warning about mixing || and && without parentheses where
parentheses were present but a closing one was misplaced.

Also, isok() was redundant in 'isok() && is_pool()' because is_pool()
starts off with its own isok() check.
2020-04-02 12:48:27 -07:00
Pasi Kallinen
2f64f419ad Unify checking if monster is ok in poison gas 2020-04-02 20:53:08 +03:00
PatR
3eed500886 fix #K669 - 'nasty' monster summoning
Report complained about multiple Archons causing his character to
be swarmed by monsters on the Plane of Fire.  I don't think that
the behavior has changed significantly from how it worked in 3.4.3.
Nobody can summon an Archon directly because they're excluded from
the nasties[] list.  But whenever summoning picks a genocided
'nasty', the result gets replaced by random monster of appropriate
difficulty for the level (which could be an Archon for a high level
character in the endgame).  [Note that that won't pick an Archon
in Gehennom or at arch-lich outside of there because the random
monster creation honors the only-in-hell and never-in-hell flags;
picking from the nasties[] list doesn't.]

This prevents that for any creature (except arch-lich or the Wizard)
casting the summon nasties spell.  If a replacement creature is a
spellcaster it now has to have lower difficulty than the summoner.
If not, it will be discarded even though its difficulty is classified
as appropriate.  So to summon an Archon, the summoner has to have
higher difficulty than an Archon; arch-lich and the Wizard are the
only ones meeting that criterium.  When summoner is an arch-lich,
it can't summon another arch-lich (since that wouldn't have lower
difficulty than the summoner) and can summon (via replacement for
genocided type, and only if outside of Gehennom) at most one Archon.
When summoner is the Wizard, he could summon an arch-lich (when in
Gehennom; demoted to master lich elsewhere--see below) or an Archon
(outside Gehennom only), but at most one per summoning.

For post-Wizard harassment, which effectively has infinite
difficulty level, it could still happen.  However, each instance of
harassment is only allowed to create at most one Archon or arch-lich
now, so chain summoning should be lessoned.  Also if it tries to
pick an arch-lich when outside of Gehennom it will switch to master
lich instead (which won't be allowed to summon an Archon or an arch-
lich or even another master lich).

(The monmove.c bit is unrelated, just some comment formatting that
I had laying around that got mixed in.)
2020-03-27 19:05:52 -07:00
Pasi Kallinen
408321b4f7 Use TAINT_AGE for old corpses instead of hardcoded value 2020-03-16 11:28:09 +02:00
Pasi Kallinen
04c59fff0a Major amnesia revamp
Instead of forgetting maps and objects, make amnesia forget skills.
Forgetting maps and objects could be circumvented with taking notes,
or by using an external tool to remember the forgotten levels.

Forgetting skills allows the player to optionally go down another
skill path, if they trained the wrong weapon in the early game.

Amnesia still forgets spells.

As a replacement for the deja vu messages when entering a forgotten
level, those messages will now indicate a ghost with your own name
existing on the level, given only when the level is entered for
the first time.

These changes based on fiqhack, with some adjustments.
2020-03-15 11:57:34 +02:00
PatR
3981e3e6e5 controlling u.ustuck
Setting or clearing u.ustuck now requires that context.botl be set,
so make a new routine to take care of both instead of manipulating
that pointer directly.
2020-02-16 13:04:12 -08:00