Commit Graph

244 Commits

Author SHA1 Message Date
PatR
40d0caa157 'f'ire revamp
The fire command could claim that time passed when it hadn't (fill
quiver with ammo, which takes no time, then queue commands to switch
to matching launcher, which should also take no time while queueing,
only during subsequent execution).

If quiver is empty or has ammo in it, give wielded thrown-and-return
weapon (aklys) priority over filling quiver or switching to ammo's
launcher.  Don't do that if quiver has non-ammo in it, otherwise
players running Valks who wield Mjollnir with super strength but
want to throw quivered daggers would complain.

When player is being asked what to fill the quiver with, use the
\#quiver command to do that.  Using it honors a count to split a
stack, handles switching uwep or uswapwep to uquiver, and gives
feedback.  This is actually a fairly substantial change.

For 'fireassist', when switching to a launcher that isn't already
uswapwep pick one known to be blessed or uncursed over one having
unknown BUC status.  But use the latter as last resort.
2022-04-23 02:12:21 -07:00
Michael Meyer
a384f0353b Fix: "in the the purple worm's entrails"
The message printed if the hero threw gold while swallowed by an animal
used "the <mon_nam>'s entrails", which produced a doubled 'the'.  It
could also use the wrong possessive form, since it doesn't take
advantage of any of the special case handling in s_suffix.  I think the
only way that could ever be a problem with the current cast of engulfers
is if the hero was swallowed by a purple worm while hallucinating, but I
changed it to use s_suffix anyway.
2022-04-20 00:09:02 -07:00
PatR
385a9a7fde encumbrance checks
I polymorphed into something wimpy and became overloaded or even
overtaxed so I dropped everything.  The status line still showed
overloaded or overtaxed until my next move.  That didn't happen in
3.6.x or 3.4.3 but I didn't pursue trying to figure out what caused
this misbehavior.

I wanted to add an encumber_msg() call to freeinv() but that would
cause message sequencing issues.  Instead, add a call to it in a
few places where items are leaving hero's inventory, particularly
for the chain of calls for dropping stuff.  I've left it off in a
bunch of other potential places.

Also add a few missing (void) casts where the return value of
existing encumber_msg() calls is being ignored.
2022-03-22 10:48:23 -07:00
SHIRAKATA Kentaro
1c7faa0585 Add explicit cast to void
All other these calls not using a return value have a cast.
2022-03-19 20:50:40 +09:00
Pasi Kallinen
39acd095b2 Add helpless monster macro 2022-03-18 10:19:04 +02:00
Michael Meyer
480ba917a1 Collisions while hurtling can stone participants
Hurtling into a monster is described as "bumping into" it, so it makes
sense that hurtling willy-nilly into a cockatrice (or vice-versa) could
result in petrification.  Since hurtling for the hero usually involves
"floating in the opposite direction" (presumably backwards) after
throwing an item, check whether the hero is wearing any body armor which
would cover their torso rather than looking for gloves.  Do the same for
monsters on the general basis that it's a bodily collision, and for the
sake of consistency.
2022-03-18 06:42:19 +02:00
nhkeni
e51026aee1 LIMIT_TO_RANGE_INT macro and various casts. 2022-03-16 17:59:23 -04:00
Pasi Kallinen
006ae67029 Fix autowielding tools taking no time
When applying some tools (whips, polearms, grapples), or rubbing
a lamp, or when fireassist is on and you fire something without
wielded launcher, the automatic wielding should take as much time
as wielding the item normally does.

Fixes #696
2022-03-15 11:34:48 +02:00
Pasi Kallinen
70795fa124 Prevent monster hurtling outside map 2022-03-03 22:24:17 +02:00
PatR
ab2bcf4dac trap followup
Make the flags argument to dotrap() and mintrap() and the constants
passed to them all have consistent type: unsigned int.
2022-02-24 12:17:21 -08:00
Pasi Kallinen
6fa4fd46f7 Move output delay from walk_path to mhurtle_step
... in case walk_path is ever used for something that
doesn't need the delay.  The hero hurtling already had
delay, so it was done twice.
2022-02-24 19:50:37 +02:00
Pasi Kallinen
0c20bf116c Moving a monster with telekinesis hurles it through the air
... and at the end of the flight, it can't avoid a trap, if it
lands on one.
2022-02-24 19:27:59 +02:00
Pasi Kallinen
2777f45bd5 Get rid of force_mintrap, allow passing flags to mintrap
It uses the same flags as dotrap, so simulate force_mintrap
by passing FORCETRAP flag.
2022-02-24 17:13:23 +02:00
Pasi Kallinen
9716f22851 Make trap return values more consistent
Instead of returning monster's mtrapped-state, return specific
trap return values.
Add one extra trap return value, for when a monster was
moved by the trap.
2022-02-24 16:24:02 +02:00
Pasi Kallinen
547f6e9244 Remove forced trap activation from mhurtle 2022-02-24 15:18:00 +02:00
Michael Meyer
1e951db9bc Fix: monster hurtling and liquid
A monster hurtling over liquid would drown immediately the instant it
touched the first square of water, even if normally it would have kept
moving (e.g. hurtling over a short moat).  Additionally, its placement
on liquid would not take into consideration other monsters, so it could
overwrite an existing monster on that spot and lead to an impossible,
and/or two monsters occupying a single position.

Fix these issues, so that liquid effects like drowning only happen if
the monster ends up in liquid at the end of the hurtle, and so that
other monsters in the way will stop it early even if they're floating
over or swimming on a pool/water/lava square.

Also use canspotmon instead of canseemon for the wiztelekinesis debug
command.
2022-02-24 14:53:48 +02:00
Pasi Kallinen
645720d1bc Fix the force_mintrap 2022-02-23 19:11:32 +02:00
Pasi Kallinen
9ad1e7e620 Hurtling monster always triggers a trap 2022-02-23 18:59:57 +02:00
Pasi Kallinen
60642a8876 Wall of water stops monster hurtling 2022-02-23 13:54:07 +02:00
Pasi Kallinen
e965f6cf44 Give message trying to hurtle immovable monster
If the monster is too big, stuck to hero, or trapped.
2022-02-23 13:42:08 +02:00
Pasi Kallinen
5786ddadbb Use IS_WATERWALL and is_waterwall 2022-02-23 12:53:09 +02:00
Pasi Kallinen
362cb4a317 Fix comment, mhurtle now handles pools and lava 2022-02-23 11:34:35 +02:00
Pasi Kallinen
462e13f07b Handle water and lava when hurtling a monster
Also delay the output, showing the hurtle animation.
2022-02-22 16:51:18 +02:00
Pasi Kallinen
268022e5de Add #wiztelekinesis for testing purposes
For testing mhurtle, which is used for jousting or
bare-handed combat.

Improve mhurtle_step to handle bumping into another monster,
and when the monster gets killed or stuck in a trap.
2022-02-22 16:00:05 +02:00
Pasi Kallinen
733fc84934 Flint and hard gems break less often when thrown 2022-02-22 10:01:17 +02:00
PatR
e972d0b965 gamelog: hit with wielded weapon for first time
Reordering "killed for the first time" and "hit with a wielded weapon
for the first time" was done by moving the latter to hmon().  Hitting
with an applied polearm also gave the first-hit message since it
bypassed the routine that had been doing so.  But the throwing code
that handles applied polearms calls hmon() for damage, so after that
reordering, the first-hit log message became duplicated if triggered
by polearm usage.

Also, fix a quibble with the wizard mode conduct message given after
never-hit-with-wielded-weapon conduct has been broken.  The message
said "used a wielded weapon N times" when it meant "hit with a wielded
weapon N times".  "Used" is misleading if that wielded weapon happens
to be a pick-axe, so change the message to say "hit with".
2022-02-19 11:24:28 -08:00
Pasi Kallinen
91e2d3633e Use macro for a location next to hero 2022-02-12 11:05:10 +02:00
Pasi Kallinen
8ce3e08d00 Give a sound message when thrown item lands in water or lava 2022-02-11 20:05:46 +02:00
Pasi Kallinen
1e90f89203 Chronicle of major events, and livelog
Log game events, such as entering a new dungeon level, breaking
a conduct, or killing a unique monster, in a new "Major events"
chronicle. The entries record the turn when the event happened.
The log can be viewed with #chronicle -command, and the entries
also show up in the end-of-game dump, if that is available.

This feature is on by default, but can be disabled by
defining NO_CHRONICLE compile-time option.

This also contains "live logging", writing the events as they
happen into a single livelog-file. This is mostly useful for
public servers. The livelog is off by default, and must be
compiled in with LIVELOG, and then turned on in sysconf.

Mostly this a version of livelogging from the Hardfought server,
with some changes.
2022-02-09 22:49:25 +02:00
PatR
9aea7b587c fix #K3455 - rocks vs xorns
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.
2022-02-02 05:26:03 -08:00
PatR
afc2e1592d reconcile toss_up() with hmon_hitmon()
Throwing silver or blessed non-weapons upward and having them fall
back onto susceptible hero's head wasn't adding the extra bonus damage
that a weapon would get in that situation.

Make hitting vulnerable monsters with blessed just-about-anything get
the 1d4 bonus that blessed weapons get for that.  Doesn't apply to
things that have their own special handing, like potions or eggs.
2022-01-21 13:37:33 -08:00
Pasi Kallinen
68b822e4dc Add "user canceled" as extended command return value
Instead of returning ECMD_OK, the commands now return ECMD_CANCEL
when user declined to pick a direction or an object to act on.

Note that this can be ORed with ECMD_TIME, if the command still
took a turn.

For now this has no gameplay meaning.
2022-01-08 20:04:57 +02:00
Pasi Kallinen
a77e1602f1 Apply a wielded bullwhip with fire-command 2022-01-06 17:12:30 +02:00
Pasi Kallinen
5b02ad521d Don't autoquiver aklys
... even though it is a throwing weapon, it's meant to be wielded
and fired instead of fired from quiver.
2022-01-06 14:39:32 +02:00
Pasi Kallinen
48bca11d67 Accessibility: give message for created monsters
Always give a message when creating a detected monster
during gameplay (as opposed to during level creation).
To prevent the message, use the MM_NOMSG flag for makemon.

Most places already handled their own messaging, but there
were some, such as bag of tricks, create monster magic
and random monsters created during gameplay that didn't.
2022-01-06 14:06:49 +02:00
Pasi Kallinen
8db18275a6 Define engulfing_u, making clearer code 2021-12-31 21:12:21 +02:00
Pasi Kallinen
d53cd28d46 Make extended commands return defined flags
Instead of returning 0 or 1, we'll now use ECMD_OK or ECMD_TURN.
These have the same meaning as the hardcoded numbers; ECMD_TURN
means the command uses a turn.

In future, could add eg. a flag denoting "user cancelled command"
or "command failed", and should clear eg. the cmdq.

Mostly this was simply replacing return values with the defines
in the extended commands, so hopefully I didn't break anything.
2021-12-30 19:16:33 +02:00
Pasi Kallinen
fa41d5fe66 Apply a wielded polearm with fire-command
Wield a polearm and use 'f'ire to automatically hit with it,
if there's a single valid target.
With fireassist-option, will swapweapon to a polearm.
This only applies if quiver is empty and autoquiver is off.
2021-12-29 19:40:26 +02:00
PatR
5fbe1de2a7 hero_seq
'moves' is actually turns and there hasn't been any straightforward
way to track actual hero moves.  Add hero_seq for that.  It isn't a
counter but is distinct each time the hero makes a move.  I wanted
it for curses ^P support but so far use it for checking stethoscope
usage and for shopkeeper behavior when items in a shop are broken by
the hero.

Increment EDITLEVEL due to change in save file contents.
2021-12-26 00:16:55 -08:00
Pasi Kallinen
f6b7be49f4 Accessibility: give a message when teleporting a monster
Teleporting a monster only updated the map. Give a message
so blind players can get the same information.
Making a monster invisible gives the same message, if you
cannot detect invisible.
Several other places where monsters teleported themselves
now also give the same message.
2021-12-12 16:50:49 +02:00
PatR
37e63f6829 breaking wielded fragile item against iron bars
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".
2021-10-22 19:11:51 -07:00
Pasi Kallinen
e3a2dd7f40 Reveal the monster your strike moved
When you hit a small hidden monster (by eg. force-fighting)
that got moved by the strike, the monster stayed hidden, possibly
causing a sanity checking error.

Reveal the monster before hurtling it.
2021-09-12 19:44:39 +03:00
Pasi Kallinen
76f77ee0cc 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.
2021-06-16 13:14:32 +03:00
PatR
e3d6fa038b fix #K586 - eucalyptus leaf falling on hero's head
[From 14 months ago; I've got an old email for this but can't find
 it in the bug list.]

Some things shouldn't hurt the hero when thrown upward and falling
back on head.  I've been pretty conservative about what won't do
any harm.
2021-05-14 17:13:48 -07:00
PatR
a71d3185bf 'f' for aklys
Adopt a feature mentioned in the xNetHack release announcement.
If you use the fire ('f') command when wielding a throw-and-return
weapon while your quiver is empty and the 'autoquiver' option is
Off, throw the wielded weapon instead of prompting to fill the
quiver.  It will usually return and be re-wielded, so be ready to
fire again.

Implemented from scratch.
2021-03-26 16:19:24 -07:00
PatR
c3ccd93a88 fix pull request #469 - multiple '$' invent slots
Assigning a partial stack of gold to quiver (Qnn$) resulted in
an extra '$' slot in inventory, one for the unquivered part and
another for the quivered part.

Throwing a non-quivered partial stack of gold at self (tnn$.)
also resulted in an extra '$' slot after throwing at self was
rejected.

For the first case, reject the quiver-subset-of-gold attempt.
For both cases, recombine the two stacks back to original amount.

Fixes #469
2021-03-16 12:29:22 -07:00
Bart House
a54a8c6854 Remove awful kludges dealing with command counts. 2021-01-30 19:06:27 -08:00
nhmall
f963c5aca7 switch source tree from k&r to c99 2021-01-26 21:06:16 -05:00
copperwater
0b638592a4 Refactor getobj() to use callbacks on candidate objects
This replaces the arcane system previously used by getobj where the
caller would pass in a "string" whose characters were object class
numbers, with the first up to four characters being special constants
that effectively acted as flags and had to be in a certain order.
Because there are many places where getobj must behave more granularly
than just object class filtering, this was supplemented by over a
hundred lines enumerating all these special cases and "ugly checks", as
well as other ugly code spread around in getobj callers that formatted
the "string".

Now, getobj callers pass in a callback which will return one of five
possible values for any given object in the player's inventory. The
logic of determining the eligibility of a given object is handled in the
caller, which greatly simplifies the code and makes it clearer to read.
Particularly since there's no real need to cram everything into one if
statement.

This is related to pull request #77 by FIQ; it's largely a
reimplementation of its callbacks system, without doing a bigger than
necessary refactor of getobj or adding the ability to select a
floor/trap/dungeon feature with getobj. Differences in implementation
are mostly minor:
- using enum constants for returns instead of magic numbers
- 5 possible return values for callbacks instead of 3, due to trying to
  make it behave exactly as it did previously. PR #77 would sometimes
  outright exclude objects because it lacked semantics for invalid
  objects that should be selectable anyway, or give slightly different
  messages.
- passing a bitmask of flags to getobj rather than booleans (easier to
  add more flags later - such as FIQ's "allow floor features" flag, if
  that becomes desirable)
- renaming some of getobj's variables to clearer versions
- naming all callbacks consistently with "_ok"
- generally more comments explaining things

The callbacks use the same logic from getobj_obj_exclude,
getobj_obj_exclude_too and getobj_obj_acceptable_unlisted (and in a few
cases, from special cases still within getobj). In a number of them, I
added comments suggesting possible further refinements to what is and
isn't eligible (e.g. should a bullwhip really be presented as a
candidate for readying a thrown weapon?)

This also removed ALLOW_COUNT and ALLOW_NONE, relics of the old system,
and moved ALLOW_ALL's definition into detect.c which is the only place
it's used now (unrelated to getobj). The ALLOW_ALL functionality still
exists as the GETOBJ_PROMPT flag, because its main use is to force
getobj to prompt for input even if nothing is valid.

I did not refactor ggetobj() as part of this change.
2021-01-07 11:06:58 -05: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