mon_arrive() -> m_into_limbo() -> migrate_to_level() -> wormgone()
followed by place_monster() "for relmon". relmon() was changed (last
November, cc5bb44a9a) to not require
the monster be on the map, so just get rid of the place_monster() that
was trying to put the "gone" long worm at <0,0>.
Also, another m_into_limbo() bit: make mdrop_special_objs() check the
location and send any dropped items to random locations if the monster
dropping things isn't on the map, instead of placing them at <0,0>.
During level change, when a monster from mydogs (monsters accompaying
hero, usually pets) couldn't be placed because the level was full, it
was set to migrate to that level (in order to get another chance to
arrive if hero left and returned). The code sequence
mon_arrive()-> mnexto()-> m_into_limbo()-> migrate_to_level()-> relmon()
tried to remove the monster from the map, but it wasn't necessarily on
the map (depending upon whether it couldn't arrive at all, or arrived
at the hero's spot and couldn't be moved out of the hero's way). The
EXTRA_SANITY_CHECKS for remove_monster() issued impossible "no monster
to remove". relmon() now checks whether monster is already off the map.
While investigating that, I discovered that pets set to re-migrate
to the same level to try again on hero's next visit didn't work at all.
migrating_mons gets processed after mydogs so moving something from
the latter to the former after arrival failure just resulted in
immediate second failure when the more general list was handled during
the hero's current arrival. And failure to arrive from migrating_mons
would kill the monster instead of scheduling another attempt.
The sanest fix for that turned out to be to have all monsters who
can't arrive be put back on the migrating_mons list to try again upon
hero's next visit. Pets still fail twice but are no longer discarded
during the second time, and now do arrive when hero leaves and comes
back provided he or she has opened up some space before leaving. If
there's still no space on the next visit, monsters who can't arrive
then are scheduled to try again on the visit after that.
Recent fix for invalid corpses becomes moot. Monsters aren't killed
during arrival failure so there are no resulting corpses to deal with.
Migrating monster attempting to arrive on a level which is already
full of monsters gets killed off. It was leaving a corpse without
regard for whether it was a type of of monster which should never
leave corpses.
I'd prefer that it be put back on the migrating_mons list rather
than be killed off, but this just suppresses impossible corpses.
Calling wormgone will also remove the long worm monster from
the map, not just the worm tail. Put the monster back on map
so relmon can actually remove it properly.
Sometimes we free the monster data, but the monster is not on the
map - usually this happens if the map is full of monsters and a new one
is migrated on the level.
Make m_detach check the monster x coordinate, so it knows not to touch the map
if the monster isn't on it.
Remove trailing spaces, and remove tabs from the files that had
trailing spaces.
Also, rndorcname() was using a random value to terminate a loop
and was recalculating a new one each iteration.
Changes to be committed:
modified: include/decl.h
modified: include/dungeon.h
modified: include/extern.h
modified: include/hack.h
modified: src/decl.c
modified: src/do_name.c
modified: src/dog.c
modified: src/dokick.c
modified: src/makemon.c
modified: src/mkmaze.c
modified: src/mkobj.c
modified: src/pager.c
This commit is an attempt to address the complaints about
the orc town variation taking away lots of stuff that is
normally available in mine town. The statement in the level
description says "A tragic accident has occurred in Frontier
Town...It has been overrun by orcs."
The changes in this commit attempt to uphold that premise,
while making things a bit more interesting and perhaps
more palatable for the player.
This update does the following in keeping with the mythos:
- While many of the orcs still remain to wander about the
level, many of the orcs took off deeper into the mines with
some of the stuff that they plundered. You may now be
able to hunt some of it down.
- Adds some appearance of this particular horde of marauding
orcs working as part of a larger collective.
- This evolves the Orc Town mine town variation into a
a feature over multiple levels of The Gnomish Mines,
rather than just the single-level "feature" that it was
previously.
- You may have to work longer and a bit harder for some
things than other mine town variations, but at least with
these changes, there is hope that some of it may be found
elsewhere.
Game mechanics notes (maybe spoily?)
- Add mechanism to place objects into limbo (okay, really
place them onto the migrating_objs list for transferring
between levels etc.) and destine them
to become part of the monster inventory of a particular
species. In this particular usage case, it's using the
M2_ORC flag setting to identify the recipients.
- At present, there is no mechanism in the level compiler
for placing objects onto the migrating objects, nor
with more sophisticated landing logic, so a somewhat
kludgy hard-coded fixup and supporting routines were used.
Some day the need for that might change if additional
capabilities move to the level compiler.
This is a NetHack-3.6.2-beta01 update. Please give it a workout.
Fixes#127
Report was for a blinded horse which ate a carrot but remained blind.
This fixes that, and also lets blinded carnivorous pets eat carrots.
Gelatinous cubes now handle carrots too, but since they lack eyses
there won't be any noticeable effect for them.
My old monkey patch was a bit more extensive than Pasi's, although
it didn't originally include letting apes be tameable with bananas.
No sense in throwing it away:
1) Make monkeys and apes be omnivores instead of carnivores.
2) Make bananas be preferred food for herbivore/omnivore subset
of Y-class, so excludes carniverous ape, owlbear, and yeti.
[Sasquatch remain omnivorous but aren't tameable with bananas.]
3) While updating befriend_with_food(), make horses be affected
only by food they might eat, not by meat and corpses and tins.
So they'll be somewhat harder to cope with for characters not
strong enough to kill them. [Dogs and cats are unchanged.]
Not included (not even implemented...):
0) Allow archeologists to choose monkey for starting pet.
[The one in "Raiders of the Lost Ark" didn't actually belong
to Indiana Jones but spent a lot of time accompanying him.]
Fixing up mis-indented block comments, but hit some files that hadn't
had the earlier mixture of tab replacement, etc, so it's bigger than I
expected. If I get to it, they'll be another round of this tomorrow.
Mostly && and || at end of the first half of a continued line rather
than at the start of the second half. The automated reformat got
confused by comments in the midst of such lines.
foo ||
bar
was converted to
foo
|| bar
but
foo ||
/* comment */
bar
stayed as is.
Some excluded code [#if 0] was also manually reformatted, but this is
mainly stuff that can be found via regexp '[&|?:][ \t]*$' (with a lot
of false hits for labels whose colon ends their line).
I'll push a formatting guide at some point. There may still be
outstanding changes, but please feel free to resolve those as you arrive
a them.
To the best of my knowledge, there is no changes to the actual code
content, but the formatter does have the occasional bug. If you run into
an issue, please fix it!
From a bug report, if you rob a shop, let the
angry shopkeeper catch up with you outside his shop, escape to another
level with adjacent shk tagging along, then pacify the shk by paying him
off, he will dismiss kops on the present level and return to his shop
but when you return to his shop level there'll still be kops chasing you
there. This fix adds an extra flag to the eshk structure so that kops
can be dismissed a second time when the shk migrates back to shop level.
The first dismisal (on the "wrong" level) still takes place in case any
kops are around. Neither dismissal actually occurs if there happens to
be another angry shk present on the level where dismissal is being done.
From the newsgroup: hero's steed can become untame if killed while
it is wearing an amulet of life saving, leaving the hero still mounted
and resulting in repeated "placing steed onto map?" warnings when the
steed tries to move. Force the hero to be thrown off the mount in that
situation.
From a bug report, pets able to eat
acidic and poisonous corpses (black naga was the case cited) would eat
green slime corpses without turning into green slime, unlike the hero.
This prevents such monsters from eating green slime unless they're
starving, implements transformation into green slime for the case where
it does get eaten, and prevents non-pet gelatinous cubes from devouring
such corpses. meatobj() is reorganized to hopefully become clearer, and
it removes the assumption that the object eater is a g.cube in case we
ever adopt slash'em's "tasmanian devil" monster.
Monsters with digestion attacks who swallow green slime monsters
are turned into green slime, but ones who swallow hero poly'd into green
slime are not. This doesn't address that.
Redo the $WIZKIT overflow handling from a few days ago. Instead of
having two migration codes which both mean "with the hero", combine them
and add a mask flag to control scattering at the destination to be able to
get the alternate behavior.
While testing the figurine timer patch, I observed
The goblin wields a crude dagger.
You see a goblin drop out of your pack!
Rather than try to get the sequencing right, just prevent monsters made
by figurine activation or by the create familiar spell start without any
inventory. This will have a side effect of making wishes for a blessed
figurine of an archon be less powerful, because the subsequent pet A won't
come equipped with a shield of reflection and an artifact--or at least
rustproof--long sword anymore.
There was a report recently about "<pet> is still eating" coming out
on the console at end of game for player using X11 or Qt. That happened
because the end-of-game pet handling takes place after the message window
has been closed. It won't happen with the dev code any more because eating
no longer prevents pets from accompanying on final ascent or escape. But
a pet carrying the Amulet should still fail to tag along and yield similar
result. However, levl_follower() was changed (probably by me...) to have
pets not attempt to follow when they carried the Amulet, rendering code
in keepdogs()--which reported them as being confused--unreachable. This
reverts levl_follower() to have Amulet-carrying monsters other than the
Wizard try to accompany the hero during level changes (and keepdogs still
prevents them from succeeding). It also reorganizes keepdogs() a bit,
giving trapped followers an extra chance to escape from their trap and
preventing those who fail that chance from tagging along (previously,
non-pets ignored being trapped).
After doing that, I got tty to behave similarly to the X11/Qt report:
a message behaved strangely. In my case, it was delivered between a pair
of clearings of the screen and only visible by using terminal emulator's
scrolling buffer. I think there's a wait_synch() missing somewhere, but
haven't tried to figure out where. Instead, this makes the end-of-game
call to keepdogs() take place sooner, while pline() still works normally.
From the newsgroup: if a pet was hiding under an object next to you
when you changed levels, it could arrive hidden at the destination if there
was something available to hide under there too, and sometimes you'd start
the new level with a hidden monster glyph at its location. I was able to
reproduce that once with current trunk code, but while trying to figure
out what is actually happening I've been unable to make it happen again.
However, it doesn't make sense for a monster to be able to remain in hiding
during the level change in the first place, so this patch prevents that.
(I'd still like to know how/why map_invisible() is sometimes getting called.
[The test character was a level 1 tourist without auto-search capability.]
I'm reasonably sure that it won't happen any more once this fix in place.)
This also brings adjacent pets out of hiding when they accompany you
during ascension or dungeon escape, but it seems that that wasn't actually
necessary. The end of game disclosure already lists such by name rather
than as "it", contrary to my expectations. (I had forgotten that end-of-
game forces true names so that blindness and hallucination don't interfere
with disclosure; obviously that ends up handling hidden monsters too.)
- remove an unreferenced variable
- continue with recent code trend towards having DEADMONSTER()
check in its own if/continue statement in a few more places
move oattached and oname and other things that vary
the size of the obj structure into a separate
non-adjacent oextra structure, similar to what has
already been done for mextra. The obj structure
itself becomes a fixed size.
New macros:
#define ONAME(o) ((o)->oextra->oname)
#define OMID(o) ((o)->oextra->omid)
#define OMONST(o) ((o)->oextra->omonst)
#define OLONG(o) ((o)->oextra->olong)
#define OMAILCMD(o) ((o)->oextra->omailcmd)
#define has_oname(o) ((o)->oextra && ONAME(o))
#define has_omid(o) ((o)->oextra && OMID(o))
#define has_omonst(o) ((o)->oextra && OMONST(o))
#define has_olong(o) ((o)->oextra && OLONG(o))
#define has_omailcmd(o) ((o)->oextra && OMAILCMD(o))
changed macros:
has_name(mon) becomes has_mname(mon) to correspond.
The CVS repository was tagged with
NETHACK_PRE_OEXTRA
before commiting these, and
tagged with
NETHACK_POST_OEXTRA
immediately after. The diff
between those two tags is this oextra patch.
The associated mail daemon changes to use an oextra
structure instead of a hidden command located in the
name after the terminating NUL, have not been tried
or tested.
I doubt if many players in nethack ever have pet ghouls (in slash'em
they're the necromancer's starting pet), but if so, provide them with a
portable food source by letting ghouls eat dead eggs in addition to tainted
corpses. Also, let them eat fresher varieties of either when they're about
to starve to death. Treat lizard & lichen corpses as always fresh since
they never become tainted (probably ruining slash'em necromancers' present
pet food of choice, though they'll still be able to eat lizard corspes if
starving).
I set the omnivore flag in their monster definition. Previously they
had been left as non-eaters despite the fact that they need to eat. When
the flag wasn't set, a hero who poly'd into one and then put on an amulet of
unchanging could go a very long time (thousands of turns) before the hunger
imposed by wearing an amulet finally made him/her become hungry. (Same as
with any other truely non-eating monster, so not really a big deal.)
Also, avoid the expression &mons[obj->corpsenm] for objects where the
corpsenm field isn't applicable, in case the default value ever changes from
0 (PM_GIANT_ANT) to NON_PM (-1).
Note: The CVS repository was tagged with NETHACK_PRE_MEXTRA
prior to application of this patch to allow easy withdrawal if necessary.
Adds a new mextra structure type that has a set
of pointers to various types of monster structures
including:
mname, egd, epri, eshk, emin, edog
Replaces the mextra bits in the monst structure
with a single pointer called mtmp->mextra of type
(struct mextra *).
The pointer can be null if there are no additional
structures attached. The mextra structure is not
adjacent to the monst structure.
Reduces the in-memory footprint of the monst that
has no other structures attached, at the cost
of adding 6 extra long ints per monster to
the save file
The new mextra structure has the mextra fields
independent of each other, not overlapping as was
the case with previous NetHack versions.
This patch doesn't do anything to capitalize on
that difference however.
Consolidates vault.h, epri.h, eshk.h, emin.h and edog.h
into mextra.h
Adds a macro for checking for whether a monster has
a name:
has_name(monst)
This fixes the magic trap panic
expels() -> spoteffects() -> dotrap() ->
domagictrap() -> tamedog()
because the monst no longer varies in size so no
replacement is required.