Commit Graph

540 Commits

Author SHA1 Message Date
PatR
49b046f2e5 disallow assigning type name to Amulet of Yendor
Something I noticed when testing the item-action handling for name and
call; applies to the C/#name command too.  You were allowed to call the
real Amulet something and allowed to call fake ones something [else].
If you did that, xname/doname didn't show it but the discoveries list
did, giving away information when the player had access to more than
one unID'd Amulet of Yendor.  Rather than messing about with discovery
handling, make real and fake Amulet be ineligible from being given a
type name.  (They can still be given individual names.)
2022-04-19 14:19:48 -07:00
PatR
5489b3ebd9 command queue handling in getobj, yn_function
Mostly attempting to clean up potential error handling but I don't
have any error cases to test with.  Doesn't seem to break anything
when there aren't any errors....
2022-04-19 13:53:40 -07:00
PatR
be3d9bcd1a item-action refinements for name/call and read
Switch the verb from "name" to "call" for type-naming.  Format menu
choices for name or call of unique items more carefully.

Read actions got some extra details so move them out of the main
item-action routine to avoid cluttering it up.

Avoid "r - Study the spellbook" for novels.  It's changed for known
Book of the Dead too, but I'm not sure "r - Examine the tome" conveys
"read" sufficiently.  ("Read" and "peruse" seem too mundane for it;
perhaps it should revert to "study" even though the hero isn't
attempting to learn a spell from it.)

Change "r - cast the spell on this scroll" to "r - read this scroll
to activate its magic".  Leave off the last phrase if it's a known
scroll of blank paper or scroll of mail.
2022-04-19 12:26:54 -07:00
PatR
9f0e511b00 item-action name/call
Add opportunity to name an individual object or call the type of an
object to the context-sensitive inventory item-actions.
2022-04-19 04:33:01 -07:00
PatR
52cfe40d33 eating, drinking via #herecmdmenu
Fix eat floor food and drink from dungeon feature via #herecmdmenu.
That uses queued commands, but those two actions were changed to
skip the floor when queued input was present because asking about
floor items interfered with context-sensitive inventory item-actions.

I was misled by a comment that says it couldn't insert an m-prefix;
that was for treating the 'm' key as typed text rather than as a
command.  There's no problem with inserting a #reqmenu command which
is what 'm' is these days.  So item actions can force 'm' to skip the
floor and go directly to inventory, also the #eat and #quaff commands
don't have to alter their behavior when queued input is pending so
the #herecmdmenu usage for them gets fixed.
2022-04-16 15:32:41 -07:00
PatR
feac8c8f68 'm' prefix for drinking and dipping
Allow the player to precede q/#quaff or M-d/#dip with the 'm' prefix
to skip asking about fountains, sinks, or pools if one of those
happens to be present, similar to how using it for e/#eat skips food
on the floor and goes straight to inventory.

If you use it and don't have any potions, you'll get "you don't have
anything to drink" or "you don't have anything to dip into", same as
when there is no suitable dungeon feature present combined with no
potions.  However, if an applicable dungeon feature is present and
you don't use the prefix but answer 'no' to drink from fountain,&c
and you don't have any potions, "else" will be inserted into the
message: "you don't have anything else to drink".

A big part of the diff is just a change in indentation level for
code that is now inside 'if (!iflags.menu_requested) {' ... '}'.
2022-04-13 03:14:39 -07:00
PatR
60c504dd40 context-sensitive inventory - action sequencing
rhack() normally calls parse(), parse() sets context.move to True
assuming that the player's next action will take game time, then
when it returns, rhack() sets context.move back to False if the
assumption turned out to be incorrect.  But when performing actions
after picking something in inventory, rhack() doesn't call parse()
so context.move is left at False.

This was hidden by making the inventory command take game time if
the player picked an item and set up an action to be done with it
even though the action hadn't taken place yet.  So time was being
accounted for but if the hero didn't get consecutive moves then
monsters got their turn between the shouldn't-take-time inventory
command and the ought-to-behave-like-normal-command queued action.

My initial attempt to fix this (before figuring out how context.move
works) by stopping inventory from taking time didn't work because
queued item-actions stopped taking time too, or rather the fact that
they took no time became exposed.  This second attempt doesn't have
that problem and I think it is correct.
2022-04-12 14:56:38 -07:00
PatR
11543620f9 context-sensitive dipping
Normally dipping gets the thing to dip first and what to dip it
into second and the item-action handling knows that.  I'm not sure
why that wasn't working as intended and I couldn't figure out how
to make it do that, so went another way:  this adds an internal
extended command that executes an alternate dip routine which gets
the potion to dip into first and the thing to dip into it second.

The #dip command should allow an 'm' prefix to skip fountains and
pools, similar to how eating accepts it to skip food on the floor.
But this doesn't implement that.
2022-04-12 02:20:40 -07:00
PatR
f68b90e1ea inventory context: drop and wield
For context-sensitive actions when picking an item from inventory,
exclude drop and wield from the choices if the item is being worn.

Move 'O'ffer into alphabetical order.

Formatting: fix a couple of cases of '&&' or '||' placed at the end
of first half of a split line instead of at the start of second half.
2022-04-11 11:34:53 -07:00
PatR
7b351bc20d add #tip to context-sensitive invent
Add a menu option for #tip when selecting a container from inventory.
Also, move the recently added 'unwield' option to the order it gets
placed in the menu for primary weapon:  before 'a' because it's
spelled '-'.
2022-04-11 02:18:41 -07:00
PatR
fbbcd7c9cb object bypass bit sanity for container contents
Noticed when adding a 'tip container' choice to item-actions for
context sensitive inventory (update pending).  Putting items into a
container with menustyle traditional and then takiing them out with
the #tip command while 'sanity_check' is On would produce warnings
once they were on the floor.

askchain() uses object bypassing to be able to cope with multi-drop
potentially changing invent, and it tried to reset that when done.
But it did so with the original object list (invent in this case)
and that doesn't reset individual objects that have been moved to
any other list.  The between-turn resetting of bypass bits wasn't
doing so for container contents.  The sanity check wasn't--still
isn't--checking those either, so it wasn't noticeable while items
were still inside the container.  But taking them out with #tip
doesn't touch any bypass bits, so between-turn reset isn't triggered
and the items that came out of the container with bypass set
continued to have it set while on floor.  sanity_check complained.

Change clear_bypasses() to handle container contents, and change
askchain() to call it instead of just clearing bypasses for whatever
is left of its input chain.  (The latter probably isn't necessary
now that the between-turn cleanup deals with contents.)
2022-04-11 02:16:22 -07:00
Pasi Kallinen
32fa807050 When autopicking objects, you can count to two
Show "two" instead of "a few" when autopicking up objects, and
there's some left you didn't pick up.
2022-04-11 11:31:32 +03:00
PatR
4195722df6 context-sensitive inventory
Add '-' choice if player picks wielded weapon.  'w-' is effectively
the unwield command but a normal inventory list doesn't present '-'
as something that can be picked, so there's no context menu entry
that can suggest wielding it.

Make 't' clearer.  Don't offer it as a choice when selected item is
worn, distinguish between throwing and shooting, and introduce a bit
of plural handling.

Since we aren't using a magic 'A' command to "equip" and "unequip",
make the uses of P/R/T/W match up with how they normally operate so
that player can learn them while using item menus.

Do something similar for offer vs sacrifice.
2022-04-10 12:22:21 -07:00
PatR
138d34198e getobj vs CMDQ handling
The queued command handling rejected a non-object even in cases where
getobj()'s object callback would accept it.
2022-04-10 12:14:07 -07:00
PatR
58bc545cc6 \#dotypeinv ('I') - show title for inventory subset
When asking for an inventory subset for one of the meta-classes that
can generate output which spans object classes (so B,U,C,X, and P),
insert a title at the start of the resulting inventory list.  (Iu and
Ix produce alternate output that already includes a title.)

Also, stop handling '$' differently for menustyles traditional and
combination from full and partial.  'I$' was running the '$' command
for the first two styles but just showing the inventory entry for
gold for the last two.  Change to the latter for all styles.
2022-04-10 06:52:39 -07:00
Pasi Kallinen
e53a4c0abd Context sensitive item usage from inventory
Allow selecting an item from inventory and show a menu of actions
applicable for that particular item. Some of the entries might
be slightly spoilerish (eg. it'll reveal that you can read T-shirts),
but the improved usability for new players is more than worth it.

Generally known as "item actions", this was first implemented
in AceHack by Alex Smith.
2022-04-09 15:28:23 +03:00
Pasi Kallinen
eb9c7d77d4 Improve therecmdmenu
Turning on herecmd_menu and clicking with mouse is now actually
somewhat playable.
2022-04-06 21:23:27 +03:00
PatR
6a2ff5743a items destroyed by exploding chest
From a report by a beta tester 8 years ago:  kicking a chest gave
"THUD!  The chest explodes!" but the chest remained intact.  The
explosion was destroying all floor items at the hero's spot rather
than at the chest's spot.  Fixing that results in the chest being
destroyed because it's one of the items at its own spot.

While fixing that I noticed that delobj() was only protecting the
Amulet and the invocation items from destruction, not Rider corpses.
You could destroy one or more of those by getting a trapped chest's
explosion while using a key at its spot rather than by kicking it
from adjacent.  (Getting the exploding chest result is not easy,
particuarly with positive luck.  I eventually resorted to forcing
it with a debugger.)
2022-03-27 17:55:52 -07:00
PatR
56c2e63492 "just picked up" tweaks
For menustyles traditional and combination, allow 'IP' to request
inventory listing of just picked up items even if not carrying any
items flagged as just picked up.  The not carrying any such items
feedback was already present but couldn't be triggered.

For menustyles partial and full, the special menu entry for 'P'
when only one item applies shows the item instead of the category
"Items you just picked up".  [That sort of thing probably ought to
be done for every menu entry rather than just for 'P'.]  Rephrase
it from
| P - <item>
to
| P - Just picked up: <item>
in case it is player's first time seeing that category be listed.

Clear the just picked up flag for any item that is dipped or read.
Lots of other actions besides drop or put-into-container probably
ought to do that too.  [Maybe even just picking an item with getobj()
could be sufficient so that it wouldn't have to be replicated all
over the place.]
2022-03-22 11:33:17 -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
nhkeni
ff1289e828 Add Strlen(), a strlen(3) that panics if string is stupid long and returns unsigned.
First batch of changes to use it to suppress warnings.
2022-03-16 21:34:21 -04:00
PatR
5db6dac863 menuinvertmode
Change the 'menuinvertmode' default from 0 to 1 so that it gets more
exercise.  It can be changed back to 0 via option settings but it's
doubtful that anyone will care enough to bother.

Some pickup/take-off actions have been using it to avoid setting
their 'all' choice when bulk toggling for current-page or whole-menu
takes place; 'O' specifies it for its '?' help choice.  This adds
the skipinvert flag to the 'all' choice of #wizidentify.

The comments describing it now state that menuinvertmode applies to
bulk set-on operations as well as to toggle-on/off operations but
that will only be true if/when interfaces call menuitem_invert_test()
for set as well as for invert.  tty is about to start doing that.
2022-03-16 16:19:30 -07:00
nhkeni
81b014977d Some easy loss-of-precision fixes. 2022-03-16 17:49:29 -04:00
PatR
d37fa4138a found_artifact() groundwork
Lay groundwork for generating a log event when finding an artifact
on the floor or carried by a monster.  This part should not produce
any change in behavior.

Move g.artidisco[] and g.artiexist[] out of the instance_globals
struct back to local within artifact.c.  They are both initialized
at the start of a game (and only used in that file) so don't need
to be part of any bulk reinitialization if restart-instead-of-exit
ever gets implemented.

Convert artiexist[] from an array of booleans to an array of structs
containing a pair of bitfields.  artiexist[].exists is a direct
replacement for the boolean; artiexist[].found is new but not put to
any significant use yet.  If will be used to suppress the future
found-an-artifact event for cases where a more specific event (like
crowning or divine gift as #offer reward) is already produced.

Remove g.via_naming altogether and add an extra argument to oname()
calls to replace it.

Add an extra argument to artifact_exists() calls.
2022-03-07 02:06:55 -08:00
Pasi Kallinen
8e91320d2f Use u_at macro 2022-02-23 20:28:55 +02:00
SHIRAKATA Kentaro
dc7d434f98 add missing initializer of jcp 2022-02-20 14:43:33 -08:00
nhmall
c26bae521b static keyword on prototype, but function missing it
error 28 in line 4090 of "invent.c": redeclaration of var <adjust_ok> with new storage-class
error 28 in line 4100 of "invent.c": redeclaration of var <adjust_gold_ok> with new storage-class
error 28 in line 610 of "mdlib.c": redeclaration of var <count_and_validate_winopts> with new storage-class
error 28 in line 3846 of "options.c": redeclaration of var <pfxfn_cond_> with new storage-class
error 28 in line 3886 of "options.c": redeclaration of var <pfxfn_font> with new storage-class
error 28 in line 5307 of "options.c": redeclaration of var <determine_ambiguities> with new storage-class
error 28 in line 5343 of "options.c": redeclaration of var <length_without_val> with new storage-class
error 28 in line 6853 of "options.c": redeclaration of var <illegal_menu_cmd_key> with new storage-class
error 28 in line 7708 of "options.c": redeclaration of var <count_apes> with new storage-class
error 28 in line 2686 of "pickup.c": redeclaration of var <stash_ok> with new storage-class
error 28 in line 1008 of "read.c": redeclaration of var <can_center_cloud> with new storage-class
error 28 in line 31 of "rnd.c": redeclaration of var <whichrng> with new storage-class
2022-02-02 15:33:49 -05:00
nhmall
e4e65c4b8b whitelist several non-literal format strings
djgpp cross-compiler was griping about several.

This also removes these lines from sys/unix/hints/include/compiler.370.
    CFLAGS+=-Wno-format-nonliteral
    CCXXFLAGS+=-Wno-format-nonliteral

-Wformat-nonliteral should not be incompatible with the printf
argument-checking capabilities on literal format strings and there
shouldn't be any new warnings created.

-- &< --

artifact.c: In function 'artifact_hit':
artifact.c:1309:23: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 1309 |                       mon_nam(mdef));
      |                       ^~~~~~~
artifact.c:1328:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 1328 |                 pline(behead_msg[rn2(SIZE(behead_msg))], wepdesc, "you");
      |                 ^~~~~

ball.c: In function 'drop_ball':
ball.c:896:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  896 |                 pline(pullmsg, "pit");
      |                 ^~~~~
ball.c:899:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  899 |                 pline(pullmsg, "web");
      |                 ^~~~~
ball.c:904:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  904 |                 pline(pullmsg, hliquid("lava"));
      |                 ^~~~~
ball.c:908:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  908 |                 pline(pullmsg, "bear trap");
      |                 ^~~~~

dig.c: In function 'liquid_flow':
dig.c:747:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  747 |         pline(fillmsg, hliquid(typ == LAVAPOOL ? "lava" : "water"));
      |         ^~~~~

fountain.c: In function 'floating_above':
fountain.c:28:5: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
   28 |     You(umsg, what);
      |     ^~~

invent.c: In function 'hold_another_object':
invent.c:1018:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 1018 |                 pline(drop_fmt, drop_arg);
      |                 ^~~~~
invent.c:1073:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 1073 |         pline(drop_fmt, drop_arg);
      |         ^~~~~
invent.c: In function 'silly_thing':
invent.c:1811:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 1811 |         pline(silly_thing_to, word);
      |         ^~~~~

lock.c: In function 'pick_lock':
lock.c:375:19: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  375 |             pline(no_longer, "hold the", what);
      |                   ^~~~~~~~~
lock.c:379:19: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  379 |             pline(no_longer, "reach the", "lock");
      |                   ^~~~~~~~~
lock.c: In function 'pick_lock':
lock.c:375:19: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  375 |             pline(no_longer, "hold the", what);
      |                   ^~~~~~~~~
lock.c:379:19: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  379 |             pline(no_longer, "reach the", "lock");
      |                   ^~~~~~~~~
mcastu.c: In function 'cast_cleric_spell':
mcastu.c:670:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  670 |             pline(fmt, Monnam(mtmp), what);
      |             ^~~~~

mhitu.c: In function 'hitmsg':
mhitu.c:68:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
   68 |             pline(pfmt, Monst_name);
      |             ^~~~~

mkobj.c: In function 'insane_object':
mkobj.c:2848:20: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2848 |         impossible(altfmt, mesg, fmt_ptr((genericptr_t) obj), where_name(obj),
      |                    ^~~~~~
mkobj.c:2852:20: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2852 |                    objnm);
      |                    ^~~~~

mon.c: In function 'mon_givit':
mon.c:1469:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 1469 |         pline(msg, Monnam(mtmp));
      |         ^~~~~
mon.c: In function 'mondead':
mon.c:2485:33: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2485 |                                 | SUPPRESS_INVISIBLE), FALSE));
      |                                 ^

muse.c: In function 'mon_reflects':
muse.c:2438:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2438 |             pline(str, s_suffix(mon_nam(mon)), "shield");
      |             ^~~~~
muse.c:2445:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2445 |             pline(str, s_suffix(mon_nam(mon)), "weapon");
      |             ^~~~~
muse.c:2450:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2450 |             pline(str, s_suffix(mon_nam(mon)), "amulet");
      |             ^~~~~
muse.c:2458:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2458 |             pline(str, s_suffix(mon_nam(mon)), "armor");
      |             ^~~~~
muse.c:2464:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2464 |             pline(str, s_suffix(mon_nam(mon)), "scales");
      |             ^~~~~
muse.c: In function 'ureflects':
muse.c:2476:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2476 |             pline(fmt, str, "shield");
      |             ^~~~~
muse.c:2483:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2483 |             pline(fmt, str, "weapon");
      |             ^~~~~
muse.c:2487:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2487 |             pline(fmt, str, "medallion");
      |             ^~~~~
muse.c:2493:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2493 |             pline(fmt, str, uskin ? "luster" : "armor");
      |             ^~~~~
muse.c:2497:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2497 |             pline(fmt, str, "scales");
      |             ^~~~~

polyself.c: In function 'polyman':
polyself.c:201:5: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  201 |     urgent_pline(fmt, arg);
      |     ^~~~~~~~~~~~

potion.c: In function 'make_hallucinated':
potion.c:423:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  423 |             pline(message, verb);
      |             ^~~~~
potion.c: In function 'peffect_gain_level':
potion.c:1033:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 1033 |                 You(riseup, ceiling(u.ux, u.uy));
      |                 ^~~
potion.c:1044:21: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 1044 |                     You(riseup, ceiling(u.ux, u.uy));
      |                     ^~~

priest.c: In function 'intemple':
priest.c:487:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  487 |                 You(msg1, msg2);
      |                 ^~~

read.c: In function 'doread':
read.c:522:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  522 |         pline(silly_thing_to, "read");
      |         ^~~~~

shk.c: In function 'shk_names_obj':
shk.c:2576:15: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2576 |         pline(fmtbuf, obj_name, (obj->quan > 1L) ? "them" : "it", amt,
      |               ^~~~~~
shk.c:2579:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2579 |         You(fmt, obj_name, amt, plur(amt), arg);
      |         ^~~
shk.c: In function 'shk_chat':
shk.c:4506:13: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 4506 |             pline(Izchak_speaks[rn2(SIZE(Izchak_speaks))], shkname(shkp));
      |             ^~~~~
shk.c: In function 'check_unpaid_usage':
shk.c:4633:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 4633 |         verbalize(fmt, arg1, arg2, tmp, currency(tmp));
      |         ^~~~~~~~~

sounds.c: In function 'dosounds':
sounds.c:66:21: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
   66 |                     pline(throne_msg[2], uhis());
      |                     ^~~~~
sounds.c:259:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  259 |                 You_hear(msg, halu_gname(EPRI(mtmp)->shralign));
      |                 ^~~~~~~~

timeout.c: In function 'choke_dialogue':
timeout.c:269:26: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  269 |                          body_part(NECK));
      |                          ^~~~~~~~~
timeout.c:274:17: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  274 |                 urgent_pline(str, hcolor(NH_BLUE));
      |                 ^~~~~~~~~~~~
timeout.c: In function 'levitation_dialogue':
timeout.c:339:26: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  339 |                          danger ? surface(u.ux, u.uy) : "air");
      |                          ^~~~~~
timeout.c: In function 'slime_dialogue':
timeout.c:379:34: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  379 |                     urgent_pline(buf, hcolor(NH_GREEN));
      |                                  ^~~
timeout.c:381:30: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
  381 |                 urgent_pline(buf, an(Hallucination ? rndmonnam(NULL)
      |                              ^~~

uhitm.c: In function 'hmon_hitmon':
uhitm.c:1398:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 1398 |         pline(fmt, whom);
      |         ^~~~~
uhitm.c:1421:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 1421 |         pline(fmt, whom);
      |         ^~~~~
uhitm.c: In function 'stumble_onto_mimic':
uhitm.c:5301:9: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 5301 |         pline(fmt, what);
      |         ^~~~~

../win/tty/wintty.c: In function 'tty_clear_nhwindow':
../win/tty/wintty.c:1649:15: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 1649 |         panic(winpanicstr, window);
      |               ^~~~~~~~~~~
../win/tty/wintty.c: In function 'tty_display_nhwindow':
../win/tty/wintty.c:2339:15: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2339 |         panic(winpanicstr, window);
      |               ^~~~~~~~~~~
../win/tty/wintty.c: In function 'tty_dismiss_nhwindow':
../win/tty/wintty.c:2432:15: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2432 |         panic(winpanicstr, window);
      |               ^~~~~~~~~~~
../win/tty/wintty.c: In function 'tty_destroy_nhwindow':
../win/tty/wintty.c:2477:15: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2477 |         panic(winpanicstr, window);
      |               ^~~~~~~~~~~
../win/tty/wintty.c: In function 'tty_curs':
../win/tty/wintty.c:2503:15: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2503 |         panic(winpanicstr, window);
      |               ^~~~~~~~~~~
../win/tty/wintty.c: In function 'tty_putsym':
../win/tty/wintty.c:2599:15: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2599 |         panic(winpanicstr, window);
      |               ^~~~~~~~~~~
../win/tty/wintty.c: In function 'tty_add_menu':
../win/tty/wintty.c:2967:15: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 2967 |         panic(winpanicstr, window);
      |               ^~~~~~~~~~~
../win/tty/wintty.c: In function 'tty_end_menu':
../win/tty/wintty.c:3032:15: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 3032 |         panic(winpanicstr, window);
      |               ^~~~~~~~~~~
../win/tty/wintty.c: In function 'tty_select_menu':
../win/tty/wintty.c:3140:15: warning: format not a string literal, argument types not checked [-Wformat-nonliteral]
 3140 |         panic(winpanicstr, window);
      |               ^~~~~~~~~~~
2022-01-09 14:18:10 -05: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
8db18275a6 Define engulfing_u, making clearer code 2021-12-31 21:12:21 +02:00
HMM
706b1a939b Have the '$' command include gold in your pack
In verbose mode, the gold in your wallet is totaled separately from
that in containers in your pack, and the two are listed separately.
In terse mode, just print the total of both.

Only known gold is mentioned.
2021-12-30 21:12:38 +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
PatR
43317a2ef7 Qt misuse of Role_if()
The Qt paper doll highlights known blessed/uncursed/cursed items with
a color border.  It was trying to force obj->bknown for non-blinded
priest[ess] but passed the old role letter argument to Role_if()
instead of the monster number that's used these days.  It was also
potentially modifying an invent item in a way that's observable to
the player but not updating persistent inventory to show that.

Probably didn't matter though; I don't think the situation it checks
for can occur anymore.  On the off chance that it could, move the
check-and-set out of #if ENHANCED_PAPERDOLL so that same inventory
update would occur for ordinary paper doll even though that doesn't
care about displayed items' bless/curse state.
2021-12-27 14:27:35 -08:00
PatR
e2ca016484 decaying globs of {ooze,pudding,slime}
Globs never rotted away but did become tainted after a relatively
short while, which seemed like a contradiction.  Change them to never
be tainted but shrink by 1 unit of weight approximately every 25
turns.  An ordinary glob (one that hasn't combined with any others)
starts out weighing 20 units, so it takes about 500 turns to vanish.
That's roughly twice as long as a corpse takes to rot away.

Shrinking globs give feedback when in hero's invent or in a container
in hero's inventory, but rarely (when going from an exact multiple
of 20 weight units; that is, from integral number of N globs to
N-1 + 19/20, or if weight reduction triggers an encumbrance change).
When a glob goes away completely, there is feedback for those two
circumstances and also for seeing the glob vanish from the floor.

I haven't touched how much nutrition eating a glob confers.  I have
changed formatting of glob names to use "small", "medium", "large",
"very large" instead of "small", [no adjective], "large", &c.  You
still need to have at least five globs coalesced together for the
adjective to become "medium", same amount as before.

I don't think EDITLEVEL needs to be modified but have incremented it
anyway to play things safe.
2021-11-06 18:24:36 -07:00
PatR
01cb9d312f unused variable: g.restoring
Get rid of the last reference to 'g.restoring' (which managed to
unintentionally survive the change to 'g.program_state.restoring').

Also have suppress_map_output() check 'g.program_state.saving' and
switch the couple of checks against that flag to use the function.
2021-10-05 01:57:27 -07:00
Pasi Kallinen
b30061b5ad Allow dropping just picked up items
When using a menu to drop or put in items into a container,
allow putting in the item (or items) you picked up previously,
by selecting the 'P' entry from the item class menu

Inspired by the itemcat patch by Stanislav Traykov.

Invalidates saves and bones.
2021-09-17 21:00:06 +03:00
PatR
e43ec0cef1 fix odd messages caused by buffer re-use
Reported and diagnosed by entrez:
"The <mon> yanks <two-handed weapon> from your corpses!"

It became unwielded and that triggered a perm_invent update and
such updates reformat entire inventory, so if that contains a dozen
or more items it will use all the obuf[] static buffers as least
once.  In this case, the bullwhip code had plural of "hand" in one
of those buffers and by the time it delivered the message which
used that, the value had been clobbered.

As the diagnosis mentioned, it can be tricky to reproduce since
either &obuf[0] or &obuf[PREFIX] might be used and if the value
being clobbered didn't overlap, the effect wasn't noticeable.

Instead of fixing the bullwhip message, this changes inventory
display so that it should no longer churn through all the buffers.

It also adds a fixes entry for #K3401, which was already fixed for
3.7 but I hadn't been able to reproduce it for 3.6.x (which I now
blame on the PREFIX trickiness).
2021-09-15 20:56:06 -07:00
PatR
3736f2ba4c delobj() rejection
If the Amulet or an invocation item refuses to be deleted, make sure
the retained object doesn't get left with its in_use bit set.  I'm not
sure whether there are any cases where this matters.
2021-08-19 14:55:22 -07:00
PatR
4c31bac353 tool_in_use()
tool_in_use() [for the '(' and '*' commands] has nothing to do with
the obj->in_use bit, so rename it to tool_being_used().
2021-08-19 14:20:43 -07:00
Michael Meyer
a326f622f6 Permit blind feeling for objects on trapdoor
Items on a trap door or on the edge of a hole are accessible (they can
be picked up, kicked, etc), but these locations were considered
inaccessible for purposes of feeling the ground for objects while blind.
2021-08-10 20:14:27 -04:00
PatR
8e3fbb3588 known_branch_stairs
New routine known_branch_stairs() was performing two different things
and was unnecessarly complicated because of that.  Split off newer
routine stairs_description() to handle one of those.
2021-07-30 14:11:26 -07:00
PatR
f2019e2ec6 concealing unknown branch stairs
First cut at displaying branch stairs/ladder up/down as ordinary
stairs/ladder up/down if the destination hasn't been visited yet.

Stepping on stairs with 'mention_decor' enabled, or using ':' when
already on them, will report regular stairs' destination level.
Probably not very useful since it's just N+1 for downstairs or N-1
for upstairs when currently on level N.

It's based on whether the destination level has been visited, not
on whether the stairs have been traversed, so reaching a level via
trap or level teleporation can make the level's stairs known when
their destination really shouldn't be discovered yet.
2021-07-29 03:32:58 -07:00
PatR
f7436fd02d fix pull request #540 - don't autoquiver aklys
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.

Fixes #540
2021-07-10 19:09:17 -07:00
Pasi Kallinen
491adc6a69 Mark some extended commands as no-fuzzer
... instead of checking the fuzzer being on in the commands themselves.
2021-07-08 11:35:43 +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
b630d5e038 fix issue #509 - shop 'glob' pricing segfault
A recent change made it possible for a glob to have its dknown flag
cleared and that exposed globby_bill_fixup() passing Null shopkeeper
to get_cost(), triggering a crash.

Make the routine that clears dknown/known/bknown/&c also be the
routine used to initialize those flags for a new object so that it
is the place that handles various special cases.  That hides the
shop bug again.

But also fix the shop bug even though it won't be triggered.

Fixes #509
2021-05-12 16:13:40 -07:00
PatR
ad7f2afef9 fix github issue #493 - hero item knowledge
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
2021-05-06 12:36:32 -07:00
PatR
2d2c584c96 another scrambled message when given '-' as object
This is similar to commit 98d381de46
(which mis-classified the bug as post-3.6), using #rub on a lump
of royal jelly and supplying '-' rather than an egg as the target
yielded "You mime rub the royal jellying on something."  Change
it to be "You mime rubbing the royal jelly on something."
2021-04-18 17:34:26 -07:00
PatR
b65c93cdff menustyle:full's 'A' choice
Change how menu choice 'A' (auto-select everything) works.  It will
now auto-select all things that match any other choices (object
class(es) or BUCX state(s) or possibly unpaid status).  So it still
skips the second menu of specific objects.  And it still picks all
objects when it is the only choice or if player uses '.' to select
it along with all the rest of the first menu's possibilities.

This change won't help anyone who picks 'A' without really meaning
to.  (Maybe add a paranoid_confirm setting to for full-menu-A?)

Affects container apply/#loot and Drop-multiple.  The invent.c part
is just formatting.
2021-04-02 12:26:41 -07:00
PatR
fb7b7d5721 another getobj/force_invmenu fix
For !force_invmenu when attempting a command that needs an object,
if inventory is completely empty
 What do you want to <foo>? [*]
will report "Never mind" and stop asking if player presses return
or report "Not carrying anything" and reprompt if player types '*'.
But for force_invmenu, it would report
 Not carrying anything.  Never mind.
without any reprompting in between the two messages.  Just skip
the second message in that situation.

Perhaps the first case should avoid reprompting too but I haven't
gone that far.
2021-03-20 10:52:46 -07:00