Reported by entrez: if a monster or explosion kills the hero with an
object that has timers or is a light source, it could trigger a panic
when end of game cleanup can't find it because it has been removed
from the map or monster's inventory and not placed back on the map
yet. This isn't much different from something thrown by hero which
had a similar situation dealt with a long time ago. Fix by setting
'thrownobj' for monster-launched and explosion-launched missiles.
That way done_object_cleanup() called from really_done() will place the
missile on the map where saving bones or general cleanup can find it.
It doesn't bother dealing with exploding a lit potion of oil that
kills the hero by missile damage before the potion explodes. If that
ends up in bones, it should still be lit and might blow up before the
new character reaches it. (Not verified.)
The code for a hero polymorphed into a unicorn and catching a thrown
gem has been moved into its own routine. No change in behavior, just
less clutter in the thrown-object-hits-hero section of the monster
throwing routine.
When hallucinating, use nonsensical names for the rays
(wands, spells, and breath weapons), and random ray glyphs.
Original code from xNetHack by copperwater <aosdict@gmail.com>,
inspired by a YANI by Kahran042.
Implement the suggestion that falling rock traps and rolling boulder
traps be harmless to xorns. I've extended that to all missiles made
of stone (rocks, gems, boulders, a handful of other things that will
only matter if poly'd hero throws in '<' direction or is hit by stuff
scattered by an explosion).
I excluded ghosts because they would become even harder to kill and
the missile handling would need extra checks to test for blessed objs.
When testing the urgent message for having weapon be snagged by a
bullwhip, in between the occasional weapon grabs (which mention
flicking the bullwhip) I saw lots of regular attacks that said
"<mon> swings his bullwhip." That is accurate but seems odd, so
change it to "<mon> lashes his bullwhip." Do same for the hero.
While working on that, I discovered that monsters using a polearm
for a ranged attack always showed "<mon> thrusts <a polearm>" even
for ones that aren't defined as piercing so should be swung rather
that thrust. And they're allowed to do that when adjacent where
there isn't enough room to thrust or swing a long polearm. Now it's
"<mon> bashes with <a polearm>" in that situation.
I thought there were more places that checked for "it" and substituted
"someone" or "something". Perhaps there are and I'm just not finding
them now. Anyway, this extends x_monnam() and adds some_mon_nam() and
Some_Monnam() to do that during monster name formatting instead of
having various bits of code try fix it up after the fact. The fixups
could be fooled by monsters given the name "it" or "It"; x_monnam()
won't be.
Reported by entrez, wielding something fragile (potion of acid
perhaps), and using F to smash it against iron bars called breaktest()
directly, then a second time indirectly through hero_breaks() via
hit_bars(). There is a random chance to resist breaking (99% for
artifacts, 1% for other items) so breaktest() might say that something
will break on the first call and that it will not break on the second
call, or vice versa. That could remove uwep from inventory then leave
it in limbo without destroying it, or destroy uwep without removing it
from inventory first triggering impossible "obfree: deleting worn obj".
whitelist the valid cases showing up
If an earlier version of clang is showing more cases (particularly
if they don't make sense), the re-enabling of the warning in
sys/unix/hints/include/compiler.2020 can be made clang-version
specific instead. I had no way to test earlier versions.
Make missiles that aren't launched by the hero and that hit a monster
use the routine that protects the Amulet and invocation items against
being deleted. I don't think there are any cases where this matters
because those items don't break when they hit something, but be more
cautious.
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.)
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
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.
Move the check for monsters that want to stay away from hero
due to having a ranged attack into a separate function.
Add monsters with polearms and breath attacks to it.
Monsters with breath attacks stay away only if they haven't
used their breath recently, or if they are injured.
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.
If a monster threw a cocktrice egg that hit and petrified another
monster, the hero would credit (experience) and blame (possible
alignment penalty, &c) for it.
Fixes#410
I looked for places where changing "{blinding,acid} venom" into
"splash of {blinding,acid} venom" might make messages become too
verbose. Turns out to have been unnecessary work because the full
name won't be used unless you get a venom object in inventory and
formally identify it. Wizard mode, or bones from wizard mode, is
necessary for that to happen so the possibility can be ignored.
[The name change is still useful for wizard mode wishing though.]
Many messages use hard-coded "venom" instead of xname() so won't
be affected even if such identification takes place. However,
thitmon() was producing
|The <mon> is hit by the splash of venom.
|The splash of venom blinds the <mon>.
which seems rather redundant even without the longer full object
name. So change the second message to be generated as
|The venom blinds the <mon>.
It also shortens "cream pie" in first line to "pie" in second one.
m_lined_up() was declared 'boolean' but returned 0, 1, or 2.
The 1 case isn't actually used any more. I changed it to 'int'
rather than 2 to TRUE; it could just as easily be the other way
'round.
Fixes#240
Monster versus monster (melee and throwing) didn't handle shades
(need silver or blessed weapon to take damage) or silver feedback
(extra info when silver-haters are hit).
I did a lot of test, revise, re-test but didn't always re-test
everything that had previously been tested, so bugs that I thought
were quashed might have crept in.
Now if a missile weapon "passes harmlessly through the shade" it
will continue on and maybe hit something else. (Regular misses
still stop at the missed target.)
A couple of minor ball&chain changes accidentally got included.
Changing
if (ammo_and_launcher(otmp, uwep) && mwep->otyp == ELVEN_BOW)
(with 'uwep' typo) to
if (mwep->otyp == ELVEN_BOW && ammo_and_launcher(otmp, mwep))
(with fixed 'mwep') moved ammo_and_launcher()'s hidden non-null
test to after 'mwep->otyp'. If mwep was Null (so monster must be
throwing non-ammo such as darts or daggers rather than shooting
with a launcher), a crash occurred. (Throwing such things while
the monster is wielding any weapon doesn't have this problem.)
I don't think 3.6.2 can crash here. If hero's uwep is a bow, otmp
must be arrows to get past pre-3.6.3's incorrect ammo_and_launcher()
check. And a monster won't shoot arrows unless wielding a bow, so
monster's mwep would be non-Null regardless of what uwep is.
I tested a kobold with darts and an elven bow. But I also gave it
one elven arrow to provoke it into wielding the bow and my test
didn't throw darts with nothing wielded....
A typo caused the bow and arrow check when a monster was wielding an
elven box to test the hero's weapon with monster's ammo. [I looked
at the old slash'em code where I think this came from and it doesn't
have the typo but does have a different bug. A monster could get a
multi-shot volley by wielding an elven bow when throwing darts or
spears. The extra bow and arrow check is intended to prevent that.
The typo was probably by me but I have no memory of that code....]
Elves with bows (or other monsters who manage to pick up and wield an
elven bow) will shoot bigger volleys after this fix. That will make
them more dangerous but also cause them to run out of arrows more
quickly.
Preserve temporary fake object's previous dknown value by storing it
as a flag value within the m_ap_type field of the posing monster, and
recalling it when it is needed.
This is intended to help eliminate observable differences in price display
between real objects and mimics posing as objects.
98% of this is just switching the code to utilize macro M_AP_TYPE(mon)
everywhere to ensure that the flag bits are stripped off when needed.
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).