Add two new monsters and two new objects:
gold dragon
baby gold dragon
gold dragon scale mail
set of gold dragon scales
A couple of variants seem to have added these already, but this came
off my ancient list of monsters to add and was done from scratch.
It's a clone of silver dragon, but instead of having reflection and
breathing cold, a gold dragon emits light and breathes fire; because
of the latter it can be seen with infravision like a red dragon.
Adult gold dragons are lawful as in the AD&D Monster Manual rather
than chaotic as the wiki pages show for the variant versions.
Worn gold dragon scales operate similar to wielded Sunsword: when
blessed, radius is 3 (same as a lamp), if uncursed, radius is 2, and
if cursed, radius is 1 (but functions as 2 when worn by the hero,
otherwise there would be no tangible effect). Gold dragon scale mail
gets an extra +1, making blessed gold DSM have a bigger radius than
lamps. Embedded scales have radius 1 regardless of BUC state; light
for that case comes from the gold dragon monster form the hero is in.
When not worn, gold scales and scale-mail don't emit any light.
The tiles use a mix of yellow (for gold) and red. The two object
tiles seem reasonable variations of the corresponding silver dragon
ones. The two monster tiles definitely need work since the silver
ones were mostly cyan and changing that to red did not produce very
good result; subsequent attempt at a mixture was haphazard at best.
When deleting obsolete generated files (monstr.c, vis_tab.[ch])
for src 'make clean' or clean called from src 'make spotless' or
from top Makefile, don't complain if they aren't present.
Deletion failure wasn't stopping 'make' but did result in looking
like something might be wrong.
Before:
rm monstr.c vis_tab.c ../include/vis_tab.h #obsolete generated files
rm: monstr.c: No such file or directory
rm: vis_tab.c: No such file or directory
rm: ../include/vis_tab.h: No such file or directory
make[1]: [clean] Error 1 (ignored)
After:
rm -f monstr.c vis_tab.c ../include/vis_tab.h #obsolete generated files
(no extra feedback from rm or make).
Heinrich Kuttler [Thu, 22 Jul 2021 07:42:34 +0000 (09:42 +0200)]
termcap.c: Don't use hilites[CLR_BLACK] = NULL for ANSI_DEFAULT
This didn't crash since xputs is defensive and checks if it got a NULL
string, but it also didn't display black entries (dragons, unicorns,
orcish arrows, ...) as black or otherwise different from gray entries.
Michael Meyer [Wed, 21 Jul 2021 20:19:58 +0000 (16:19 -0400)]
Fix: engraving with dry magic marker
Engraving with a marker can use up remaining charges to write
semi-permanently in ink, or--if the marker has no remaining charges--can
draw in the dust as with a normal blunt item. Handling in engrave after
a recent refactor (9c6a5fc423) didn't fully cover this second case, and
as a result using an empty marker to engrave would deduct a charge per
attempt and cause an impossible. This could be exploited by repeatedly
engraving with the same empty marker to underflow the marker charges.
Michael Meyer [Wed, 21 Jul 2021 16:18:40 +0000 (12:18 -0400)]
Fix: off-by-one error in movecmd
The for loop which iterates through the list of movement keys in
movecmd(cmd.c) was updated in 5abf948116 to count down to 0 instead of
up to the end of the list. This commit inadvertently introduced an
off-by-one error which started the loop one past the actual end of the
array. On my system this made 'H' stop working as the 'run West' key.
Add "ukulele" to the exceptions that yield "a u<something>" in case
someone names their fruit that. Add the shortened form "uke" too.
While in there, generalize "one" handling to accept "one", "one<space>
<anything>" and "one<underscore><anything>" as exceptions in addition
to existing "one<dash><anything>", and "eu<anything>" to replace
existing "eucalyptus".
Fix heap-use-after-free when attacking monster with potion
Attacking a monster which has a passive attack (e.g. a red mold) with a
wielded potion that breaks during the attack, the variable weapon would
not be correctly reset and passive() would be called with the pointer to the
freed object.
Michael Meyer [Thu, 29 Oct 2020 21:19:31 +0000 (17:19 -0400)]
Add 'readable' Hawaiian shirt designs
Functionally similar to reading a T-shirt or apron, but rather than
actual text printed on the shirt being displayed, the design of the
Hawaiian shirt is described: for example, "hula dancers on an orange
background" or "tropical fish on an abstract background". Much like
T-shirts have their text included in the game-end inventory list ('a
blessed +2 T-shirt with text "foo"'), Hawaiian shirts now have a brief
description of their design appended to their item name under the same
circumstances.
Because 'reading' a Hawaiian shirt doesn't actually involve reading
text, using the 'r' command in this way doesn't break illiterate
conduct.
Trigger divine wrath if hero vomits at an altar's location. (What
about adding throne and maybe sink special effects too?)
If poly'd into a yellow dragon, breathe (acid) on self. (I'm not
sure why.)
If on ice and poly'd into an acidic form, melt the ice. Also,
change melt_ice() to give its message when melting happens at the
hero's location even if hero can't see.
Zapping at an object with teleportation resulted in scrambled zap
targetting as soon as any object was hit.
flooreffects() got changed to set bhitpos for handling erosion damage,
but bhitpos is used by wand/spell zap handling to pick the next target
spot. So a zap that teleported an object resumed one step beyond the
object's destination rather than one step beyond where it was hit.
The rest of the zap could hit things (monsters as well as other
objects) which weren't in line with the original zap. Reported case
was one of the Riders on Astral, coming from beyond multiple walls to
arrive adjacent to hero (usual position when a Rider gets teleported).
when polymorphing into "new man". Characteristic stats are shuffled
if turning into new man, but when already polymorphed those get
overridden by the old pre-polymorph characteristics, resulting in
another encumbrance check which might contradict the one that just
happened. Skip the encumbrance check done when shuffling stats so
that there's only one and it comes after all changes are finished.
If player throws a wielded aklys and it fails to return, and quiver
is empty when picking it back up, don't put it into that slot because
it needs to be wielded to achieve best throwing effect. A player who
had wielded it and was using 'f' to throw it might not notice that
it isn't returning until it hasn't returned several times. Moot if
quiver already has some missile readied. Don't autoquiver even if
some other weapon is wielded because that might have been done just
to go retrieve the aklys.
The game doesn't keep track of whether a previously thrown item was
wielded at the time, and shouldn't be changed to auto-wield in such
situation. Leaving quiver empty so that player is prompted for what
to throw is sufficient.
One of the gold kicking changes I had pending. The "Thwwpingg"
message is obviously intended as a sound effect so shouldn't be
given if the hero is Deaf.
Changes in wish parsing included with figurine gender implementation
3 or so weeks ago accidentally broke asking for "large box" and
possibly other stuff.
Re-do "paperback book" handling to accept "paperback" and "paperback
book" but to reject previously accepted "paperback spellbook" when
wishing for a novel by description.
Something I noticed recently: a wish request for "paperback book"
yielded "Nothing fitting that description exists in the game."
Asking for "paperback spellbook" worked though.
I'm not sure whether this is the best way to handle this particular
exception but wishing for "paperback book" now works.
Pasi Kallinen [Fri, 9 Jul 2021 10:13:26 +0000 (13:13 +0300)]
Improve special level shop and door linking
When creating a shop via des.region, allow creating the shop door
either with a map character in a des.map, or with des.door
before or after the shop region.
Also allow a shop door to open directly into another shop.
when encountering a hiding monster that's still unseen after being
revealed (so most likely invisible when hero lacks see invisible).
Change
|Wait! There's an it hiding under <an object>!
to
!Wait! There's something hiding under <an object>!
when hero tries to move onto the object.
Also, when a hidden monster reveals itself by attacking, change
|It was hidden under <an object>!
usually followed by "It hits." or "It misses."
to
|Something was hidden under <an object>!
without changing whatever follows.
Pasi Kallinen [Sat, 3 Jul 2021 12:19:53 +0000 (15:19 +0300)]
Movement key reworking
Put the rush and run movement keys into g.Cmd instead of bit twiddling
the normal walk keys in multiple places to get the run and rush keys.
Allow meta keys in getpos. Use the normal running keys to fast-move
in getpos, instead of explicit HJKL - I polled couple places online,
and number_pad users did not use the HJKL keys in getpos.
when perm_invent is displayed. The persistent inventory window
showed unpaid items with their prices, but when using itemized
billing those prices went away when an item was purchased.
The prices and item-by-item prompting continued correctly with
remaining unpaid items; only the perm_invent display was affected.
should cure sliming. Implement the suggestion that quaffing a
burning potion of oil while turning into green slime will cure the
latter.
It's somewhat iffy since the slime is on the outside moving in and
the burning oil ends up on the inside, but the message sequence is
|You burn your face.
|The slime that covers you is burned away!
and it could be that igniting part of the slime quickly spreads to
the rest.
Implemented for monsters as well as for the hero. They will light
and drink the oil in a single turn in the extremely rare situation
where they actually have a potion of oil and need to use it.
PatR [Sun, 27 Jun 2021 00:06:37 +0000 (17:06 -0700)]
web spinning tweak for Sokoban
When spiders try to spin webs, don't let them do so in Sokoban
unless the level has already been solved or the spider can see the
stairs up (which was the simplest way I could achieve something
close to "is in the same room as the stairs up") where it can't
interfere with solving the level.
Pasi Kallinen [Sat, 26 Jun 2021 12:10:38 +0000 (15:10 +0300)]
Clear all room data
Restoring a level cleared residence pointer from those subrooms
which were in the restored level, but if the previous level had
more subrooms, those pointers weren't cleared.
This caused weird problems when a shopkeeper data was looked
up based on the subroom number.
Just to be safe, clear all the room data when freeing the level.
Pasi Kallinen [Sat, 26 Jun 2021 10:00:32 +0000 (13:00 +0300)]
Fix strange object mimic in shop sanity error
Shop population code set the mimic shape to strange object
without checking for protection from shape changers.
Let set_mimic_sym (via makemon) handle it correctly instead.
PatR [Fri, 25 Jun 2021 21:43:14 +0000 (14:43 -0700)]
still more "<mon> appears in a cloud of smoke"
For Angels who appear in a flash of light, temporarily light the
spot where they arrive. If not previously visible, it will go back
to dark and change the angel to the remembered, unseen monster glyph,
usually before the player even notices.
Add more monsters to msummon_environ() so that it has latent support
for various light, fire, and lava creatures from mondata.h even
though these extra ones, like previous vortices, don't get summoned
by msummon().
Pasi Kallinen [Fri, 25 Jun 2021 16:50:02 +0000 (19:50 +0300)]
Adjust shopkeeper damage fixing
Allow shopkeeper to remove webs and pits.
Change the damage fix messaging to be more specific when
shopkeeper removes a trap. Before this the message was
"A trap was removed from the floor", which sounds really silly
when it comes to holes.
Change the damage fixing so the shopkeeper will fix one damage spot
at a time (instead of all at once), so it's more like a monster action.
Some code cleanup, splitting into smaller functions.
While doing this, I noticed that shopkeepers don't actually bill
the hero for the damage, but that'll have to be another commit...
Pasi Kallinen [Fri, 25 Jun 2021 10:22:19 +0000 (13:22 +0300)]
Reorg shopkeeper litter routine
When shopkeeper fixes a wall and there are items on that location,
shopkeeper tries to move those items into their shop. Split
the code dealing with that into separate functions.
Pasi Kallinen [Wed, 23 Jun 2021 19:42:29 +0000 (22:42 +0300)]
Allow spiders to spin webs
Revisited this feature, and the chance of a spider spinning a web
depends now on the number of webs already present on the level.
For a giant spider to spin a web in the middle of a room with no
supports, the limit of existing webs is 4, next to one support 9,
next to two supports 14, and so on. Cave spider limits are much lower.
PatR [Tue, 22 Jun 2021 00:47:51 +0000 (17:47 -0700)]
more "<mon> appears in a cloud of smoke"
Now that the appear message isn't limited to summoning by demon,
seeing "the Angel of <foo> appears in a cloud of smoke" seems
strange. Angels weren't covered by the vapor/dust/&c change for
elementals. Make angels appear in a flash of light.
PatR [Tue, 22 Jun 2021 00:44:35 +0000 (17:44 -0700)]
monster name formatting
While testing monster summoning by using a debugger to force the
outcome, I saw "the renegade Angel of <foo> appears in a cloud of
smoke" as if only one such creature existed. Trying to change
that to "a renegate Angel" pointed out some problems: type names
like Angel, Green-elf, and Uruk-hai fool an() into using "the"
because of their capital letter. Fixing that was a bit of a hack
and worked for Green-elf and Uruk-hai but not for Angel because
it has the eminion extension so uses priestname() instead of the
guts of x_monnam(). Fixing that involved more hackery and now I
feel unclean, but it seems to be working.
It wasn't as noticeable as it might have been because most of the
time that "the Angel of <foo>" or "the priest of <bar>" was shown,
the caller is requesting "the" rather than "a/an".
PatR [Sun, 20 Jun 2021 23:45:42 +0000 (16:45 -0700)]
"<foo> appears in cloud of smoke."
Have water demons appear in a cloud of vapor rather than a cloud of
smoke. This adds a few other alternatives but they'll never happen.
Elementals could only be summoned by Angels but Angels never call
msummon() as far as I can tell. Vortices aren't summoned at all
but the smoke/vapor/&c routine has provisions for them.
The cloud of smoke message used to be given only when the summoner
is a demon. Now it will be given if the last--or only--summoned
creature can be seen to arrive, no matter whether summoned by a
demon, a non-demon (which I think isn't possible), or post-Wizard
harassment.
PatR [Thu, 17 Jun 2021 23:03:45 +0000 (16:03 -0700)]
gender for figurines
Use (obj->spe & CORPSTAT_GENDER) for figurines as well as for
statues and corpses.
Support wishing for
"{female,male,neuter} {corpse,statue,figurine} [of <monster>]".
and
"{female,male,neuter} <monster> {corpse,statue,figurine}".
Also
"{corpse,statue,figurine} of {female,male,neuter} <monster>"
where the qualifier might be in the middle instead of a prefix.
Pasi Kallinen [Wed, 9 Jun 2021 06:02:31 +0000 (09:02 +0300)]
Add assistance to fire-command
Allows the fire-command to autowield a launcher; it will now
do either swapweapon or wield an appropriate launcher, if you
have ammo quivered.
This assistance can be turned off with the fireassist boolean option.
Adds a rudimentary command queue, which allows the code to add keys
or extended commands into the queue, and they're executed as if
the user did them. Time passes normally when doing the queue,
and the queue will get cleared if hero is interrupted.
PatR [Wed, 16 Jun 2021 01:42:30 +0000 (18:42 -0700)]
fix bullwhip-induced panic
While testing some corpse/statue name manipulation changes I managed
to trigger a panic during end-of-game cleanup. Using a bullwhip to
snatch a wielded cockatrice corpse from a monster's inventory into
the hero's inventory and being turned to stone due to lack of gloves
took the corpse out of the monster's inventory but didn't place it
anywhere. If no life-saving took place, it led to an "obj_is_local"
panic during timer cleanup when freeing the level.
This patch includes some of the stuff I've been testing rather than
just the fix for the panic (which is the very last bit of the diff).
PatR [Sat, 12 Jun 2021 10:07:30 +0000 (03:07 -0700)]
mon_pmname(), obj_pmname()
Revive some code from 5 or so years ago that's been sitting in a
defunct local git branch. There are a couple of references to
figurines having gender; the old, unfinished code did already have
support for that, the current code doesn't. It probably won't take
much effort to add it in but I want to get this first part out of
the way.
Replace some of the
pmname(mon->data, Mgender[mon]) calls with simpler
mon_pmname(mon) and some
pmname(&mons[statue->corpsenm],
(statue->spe & CORPSTAT_GENDER) == ... ? ... : ...) with simpler
obj_pmname(obj). There are other instances of them which haven't
been changed but could be.
PatR [Sat, 12 Jun 2021 09:25:16 +0000 (02:25 -0700)]
corpse/statue gender fix when wishing
Wishing for "{corpse,statue} of gnome queen" would produce a corpse or
statue of a gnome queen, but wishing for "gnome queen {corpse,statue}"
would produce corpse or statue of a gnome king. The matching for
gender-specific monster name was only passing back the corresponding
gender when an exact match occurred (which happens for "foo of pmname"
but not for "pmname foo" since 'pmname' through end of string is what
the name_to_mon() matching code is looking at).