I think this finally quashes the "cursed without otmp" issue.
Various ways of destroying wielded weapon used setnotworn() rather
than unwield(), so the previous change to have unwield() clear the
pending W_WEP bit from takeoff.mask wasn't sufficient to prevent
'A' moving on from another item (blindfold--it's the only thing
processed before primary weapon) to weapon which wasn't there any
more. Also, if weapon was already set in takeoff.what to be
processed on the next move, clearing W_WEP from takeoff.mask wasn't
sufficient either.
Move the previous unwield() 'fix' to setworn() and setnotworn() and
extend it to include cancel_don() if the item being replaced or
removed is in progress or scheduled for next. (Most of the time,
remove_worn_item() has already done that before setworn() or
setnotworn() is called.)
The do_wear.c part just eliminates some redundant code but shouldn't
produce any change in behavior.
The steal.c part should fix problems with 'A' when outer items are
taken off during theft in order to steal an inner item, where the
outer item is next to be removed (call to cancel_don() wasn't being
made). The wield.c part matches the X_off() behavior and is needed
to handle a weapon item that's slated for removal but isn't next (so
wouldn't pass the donning()/doffing() test to trigger cancel_don()).
If this seems a lot like trial and error, it is....
"Your pair of speed boots glow silver for a moment." should be
"Your pair of speed boots glows silver for a moment.". The fix
reverses a post-3.6.0 change to is_plural(). Also, add new
pair_of() to test for object formatted as "pair of Bars". For verb
usage, that's definitely singular, but for pronoun usage, sometimes
plural seems better (although it might actually be incorrect).
I fixed up the formatting of a block comment in obj.h, but it is
still a candidate for tab cleanup.
This ended up being more elaborate than I anticipated. 'Q' will
now accept the wielded weapon as a choice of item to quiver. If
that item is a stack of more than one, it will offer to split N-1
into the quiver and leave 1 wielded. If the offer is declined, or
if there is already just 1, it will require confirmation to move the
item from the weapon slot to the quiver slot. The alternate weapon
is handled similarly, with different phrasing when in twoweapon
combat mode.
Just to be crystal clear: a single object cannot be in more than
one weapon, alt-weapon, or quiver slot at the same time. 'Q's old
behavior of rejecting the wielded weapon was to avoid accidentally
becoming empty-handed, not anything to do with multiple worn/wield
slots.
'Q' will also accept a count when picking an inventory item, then
put 'count'-many into the quiver, leaving N-count in original stack.
Except when the chosen item is already in the quiver; it that case,
it undoes the stack split and leaves things as they were. (That
restriction may not have been necessary but I'm not planning to
revisit it....)
Reading a non-cursed scroll of enchant weapon has a side-effect of
uncursing a weapon welded to hand(s). Make it do the same thing for
cursed tin opener, the only non-weapon/non-weptool that welds to hand.
The automated reformatting put a space in casts of the form
'(type)(expression)', yielding '(type) (expression)', but it didn't
do that for '(typedef)(expression)'. There are lots of instances of
'(boolean)(expression)'; (uchar) and (xchar) also occur. I haven't
noticed other types, but I haven't looked in very many files yet.
Flesh out wet towels a bit:
1) wielding a wet towel--or a dry one which becomes wet--won't give a
"you begin bashing with your wet towel" message when attacking;
2) if a formerly wet towel dries out completely while wielded, *do* give
"you begin bashing with your towel" on the next attack;
3) successfully hitting with a wet towel no longer always loses wetness;
4) water damage to dry towel always confers at least 1 point of wetness;
5) taking fire damage (via burnarmor() which is used for most types of
fire damage) has a chance to partially or fully dry a wet towel
(regardless of whether it's wielded at the time; applies to monsters
as well as hero; each towel being carried is checked until one is
affected, then any others escape drying.
Not done:
-) attacking with a wielded wet towel perhaps ought to be treated as a
weapon attack using whip skill rather than an augmented arbitrary-
junk-by-weight attack;
-) throwing a wet towel should probably ignore wetness--it's just a wet
piece of cloth when not finishing with a whip snap; right now, it
loses a point of wetness when thrown and usually--#3 above--another
point if it hits...;
-) hitting burning creatures is no different than hitting anything else;
-) likewise for hitting wet creatures.
Add macros W_WEAPON and W_ACCESSORY, similar to existing W_ARMOR, bitmask
of all the relevant worn bits. Just for code readability; there should
be no change in behavior.
Also, reformat the "ugly checks" portion of getobj(). Slightly better
readability and fewer continuation lines, but only a modest improvement.
Replace instances of strings split across lines which rely on C89/C90
implicit concatenation of string literals to splice them together
with single strings that are outdented relative to the code that uses
them. It's uglier but it won't break compile for pre-ANSI compilers.
This covers many files in src/ that only have one or two such split
strings. There are several more files which have three or more. Those
will eventually be '(2 of 2)'.
Noticed along the way: the fake mail message/subject
Report bugs to devteam@nethack.org.
wasn't using its format string of "Report bugs to %s.", so would have
just shown our email address. Doesn't anybody enable fake mail anymore?
I modified that format to enclose the address within angle brackets and
made a similar change for the 'contact' choice of the '?' command.
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!
This old feature alert from 3.3.0 is pretty stale, so remove
if from the code because everybody has probably suppressed
it by now.
/* Because 'Q' used to be quit... */
if (flags.suppress_alert < FEATURE_NOTICE_VER(3,3,0))
pline("Note: Please use #quit if you wish to exit the game.");
This started out as a one line change. After I saw someone in the
newsgroup mention that Sunsword's light was inferior to that of a lamp,
I decided to make it work better (than in 3.4.3, that is, becoming the
same brightness as a lamp) when blessed and worse when cursed (useless to
hero but still visible if wielded by a monster). But then it needed to
change light radius when its curse/bless state changed, and it needed
message feedback when doing so, and that got kind of complicated. I
wouldn't have bothered if I'd known what I was getting into, but I don't
want to throw it away now that I've done all this work....
Sunsword now gives a light radius of 3 when blessed (same as a lit
lamp), radius of 2 when uncursed (same as a lit candle and as it has been
providing since added in 3.4.0), and a radius of 1 when cursed (nearly
but not completely useless, as mentioned above). Also, it now "shines"
rather than "glows" since we usually use the latter for temporary effects.
<email deleted> reported back on 8/31/06 that elven weapons were not
affected when he poked a fire elemental with them. This is true, but
moreover, there was no code to have passive fire to affect attackers.
Now erode_obj() supports all the same damage types as rust_dmg(), and added
the connecting code to allow passive fire attacks do something.
There probably should be macros for the damage types used by rust_dmg
and erode_obj, and possibly these functions should be combined, but they
are slightly different and dealing with that requires more thought.
From a bug report, trying
to invoke a wielded artifact after changing alignment resulted in "the
<artifact> evades your grasp" but it remained wielded, contradicting the
message. This adjusts the message in touch_artifact() if the object is
already in inventory, and adds retouch_object() to handle cases where
failing to be able to touch ought to force unwearing/unwielding.
From a bug report, applying a bullwhip
towards a monster to try to steal its weapon would report that a cursed
cockatrice corpse was welded to the monster's hands even though corpses
wielded by the player never become welded. Code for monsters deciding
what to wield knew that corpses don't weld; everywhere else seems to
assume that they only wield weldable weapons. Add a routine to check
whether a wielded item is welded, similar to what's done for the hero. I
fixed a couple of other spots besides use_whip() but didn't hunt all over.
From a bug report, hitting a rust monster with a
fireproof--but not identified as fireproof--weapon caused the rknown bit
to become set, identifying the item as fireproof. That would also happen
for a monster's anything-proof weapon if it hit a rust monster, whether
you could see it happen or not. The code involved is convoluted; I hope
this fix is correct.
Make worm teeth and crysknives be stackable. Positively enchanting
a stack of multiple worm teeth produces a single crysknife, negatively
enchanting a stack of multiple crysknives produces a single worm tooth.
A dropped stack of N fixed crysknives has 90% of remaining N crysknives,
10% of becoming a stack of N worm teeth, rather than produce an average
of 0.9*N crysknives and 0.1*N worm teeth. (The code which handles that
transformation operates on loose objects so cannot handle stack splitting
because it wouldn't have any idea of what to do with extra objects.)
Terminate multi-shot volley throwing of boomerangs if one comes back
and isn't caught. The sequence throw-catch-throw-catch is odd, but would
take a substantial amount of code and effort to be changed to the more
intuitive (for rapid volley throwing) throw-throw-catch-catch. Even if
feasible, doing that for underused boomerangs would be a waste of effort.
From a bug report, applying a pick-axe will
wield it in place of the primary weapon but wouldn't update the alternate
weapon. Make objects which become wielded when applied (pick, lamp, whip,
grappling hook, pole-arm) honor the pushweapon option (where the previously
wielded weapon becomes the alternate weapon without use of 'x' command) the
same as when explicitly wielded. Old behavior matched the documentation,
but that seemed overly restrictive.
From a bug report: [ slashem-Bugs-1206099 ] Torches are not extinguished with rust traps).
A rust trap that hits the torso candles causes all lit objects being carried
to be extinguished, but one which hit the weapon arm didn't have same affect
on a wielded light. This fix causes wielded candles or lamps (not Sunsword)
to go out if affected by any rust, such as hitting a rust monster with one,
rather than use his patch that just handled the trap case. It also excludes
wielded lights from the existing torso splash since having them be hit by
both instances is too obviously buggy.
I think brass lanterns ought to be exempt from being extinguished by
water (at least splashing which is less drastic than total submersion) since
there are references to them operating by batteries rather than fire, but I
didn't want to track all the places which would be affected.
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.
Extend the capabilities of corpse_xname() so that various callers can
be simplified. It can how handle an article prefix, effectively turning it
into corpse_doname() (not quite; still need doname() to see a count when
quantity is more than one, or to see bless/curse state). It can also handle
inclusion of adjectives like "partly eaten" or "bite-covered". For unique
monsters those come out in the form
the Chromatic Dragon's partly eaten corpse
instead of the old
partly eaten Chromatic Dragon corpse
[so wishing probably needs to be taught about potentially finding a monster
name before assorted adjectives such as blessed; also, name_to_mon() needs
to learn how to cope with the possessive suffix].
A sizeable chunk of this patch deals with consolidating some of the
redundant "petrified by a cockatrice corpse" handling. It may be possible
to consolidate all remaining instances together since they're quite similar,
but I didn't think about that until just now and I want to get this patch
over with.
Implement the suggestion that Fire Brand avoids damage from rust traps
by boiling away the water. Rather than making this be trap-specific, it
applies to all types of erosion which go through erode_obj(). That includes
hitting rust monsters but not dipping into potions or fountains, nor falling
into moats. And it doesn't provide 100% protection, just a high chance of
avoiding rust damage. Also, Frost Brand gets similar protection by freezing.
The message handling needed some rewriting for the branch version.
That compiles ok but hasn't been tested. It would have been simpler just to
move Yobjnam2() over even if nothing else was changed to use it yet....
[This ought to be suitable for the branch version too but I'm not going to
spend the effort to migrate it there.]
Recently From a bug report, reducing
the value of a shop object via cursed enchantment was ignored by shopkeeper.
This replaces the existing costly_cancel() routine with costly_alteration()
which performs a similar task: bill for any item whose value has been made
less. The hero owns the resulting object but must pay for the original one
before being allowed to leave the shop.
This covers the majority of cases where bill_dummy_object() was already
being used: cancelling a charged or enchanted item, casting drain life at
same, diluting potions or blanking scrolls or books by dipping them into a
potion of water, dulling a weapon by engraving with it, eating unpaid food
or opening unpaid tins, applying a cream pie to hit yourself with it in the
face, applying a wand to break it, burning something by dipping it into lit
potion of oil, and clearing potions by dipping a unicorn horn into them.
The shop billing behavior for those actions hasn't been changed, just
consolidated into one place which delivers a common message for them.
This also covers many cases which weren't being handled: stripping
wand or magic tool charges via cursed scroll of charging, reducing a charged
ring's enchantment via same, reducing weapon or armor enchantment via cursed
scroll of enchant weapon or armor, stripping an item's rustproofing via
confused enchantment, making a crysknife revert to a worm tooth, unblessing
potions of holy water or uncursing potions of unholy water. (That last one
won't be billed if it's the result of prayer rather scroll, spell, or #dip.)
And this tries to handle the reverse situation more thoroughly too:
many actions which improve the value of an unpaid item now also cause the
shop bill to be updated to reflect its new higher price. Aside from the
basic enchanting and charging magic, it covers converting dragon scales into
dragon scale mail and worm tooth into crysknife. Some things which might be
expected to inflate shop prices, like rustproofing or increasing the number
of charges in a wand, don't actually affect the price. And there are bound
to be cases where the price is affected but I've overlooked.
This patch introduces a change to yname() and Yname2() that avoids the
possessive "your" for the hero's normal, fully identified artifacts.
Quest artifacts still get the possessive, as do all other objects and all
objects not in the hero's possession. shk_your()/Shk_Your() are used in
many places with a specific, generalized name for the object, so I didn't
introduce the artifact behavior there, although I did change them to append
a space, which simplified some other code. Through added use of yname(),
there may be some places that used to just say "corpse" that will now be more
descriptive via yname()'s use of cxname(). I'm sure <Someone> will point
out any such places that are too onerous, although nothing obviously is.
I took the opportunity to inspect many uses of "your" and even Your(). Two
new functions are also introduced, yobjnam() and Yobjnam2(), which work
like aobjnam() and yname() combined, because I found that many uses of
aobjnam() were preceeded by "your" and I couldn't generally provide the
desired behavior for artifacts (or future artifacts) without a combined
function. In some cases, this change allowed better sharing of code.
rust_dmg() still takes a string as input which is sometimes initialized
from xname() and often prepends "your" to it. Currently, this isn't a
problem since there currently are no normal, armor artifacts. If/when any
are introduced, rust_dmg() will need to be addressed.
The patch is for the trunk only. A lot of research was required and I
didn't feel the upside was there for repeating it in the 3.4.3 branch.
A while back, I delayed applying this patch after a discussion about
quivering coins, because I didn't want to change the behavior of GOLDOBJ
vs non-GOLDOBJ games. I'm tired of seeing this diff in my tree, and I
recall there was some sentiment that I should have checked it in, so I'm
adding the feature in the trunk.
Prevent #rub from wielding an item that is already being worn
(which should narrow things down to the various types of eyewear;
other tools and weapons that go through wield_tool() can't be worn).
Fix up the wield_tool message spacing in the process.
This moves wield_tool() from apply.c to wield.c. Some plural
handling for messages is included; it is feasible to try to #rub a
"pair of lenses" or a stack of N candles.
hold_another_object() will try to quiver the object being held if
it's a weapon (or gem/rock ammo) and the autoquiver option is enabled and
the quiver is empty. It was doing that even if the object had just merged
with primary or secondary weapon, resulting in it being equipped in two
slots at once. (Easiest way to reproduce it is via wish+wield+wish for
similar item, but it could also occur when stealing while in nymph form.)
This also addresses one of the old items on <Someone>'s list: if you
carry a sling equipped in the alternate weapon slot, include gems and
rocks as likely candidates for quivering same as when wielding a sling.
This extends that to autoquivering; ammo appropriate for your alternate
is now given preference over arbitrary weapons (ammo for your wielded
weapon and arbitrary missiles still take precedence over alternate ammo).
Bug? pickup_object() is not autoquiver aware, hence autopickup isn't
either.
Bug too (perhaps moot if the above is changed)? Snagging a monster's
weapon with a bullwhip uses hold_another_object() so possibly autoquivers;
snagging an object off the floor with a grappling hook uses pickup_object()
so doesn't.
The complaint states:
It still won't let you unwield a cursed secondary weapon while
two-weaponing, even though you can drop such a weapon without problem.
You aren't supposed to be able to two-weapon
with a cursed alternate weapon at all. It appears that there are some
checks to prevent twoweaponing if uswapwep is cursed when you try.
This patch ensures that two-weaping stops if uswapwep gets cursed
while two-weaponing. I think this means the 'A' command will never
encounter the situation now in the complaint now.
The rules in wield.c state
The secondary weapon (uswapwep):
1. Is filled by the x command, which swaps this slot
with the main weapon. If the "pushweapon" option is set,
the w command will also store the old weapon in the
secondary slot.
2. Can be field with anything that will fit in the main weapon
slot; that is, any type of item.
3. Is usually NOT considered to be carried in the hands.
That would force too many checks among the main weapon,
second weapon, shield, gloves, and rings; and it would
further be complicated by bimanual weapons. A special
exception is made for two-weapon combat.
4. Is used as the second weapon for two-weapon combat, and as
a convenience to swap with the main weapon.
5. Never conveys intrinsics.
6. Cursed items never weld (see number 3 for reasons), but they also
prevent two-weapon combat.
> I'm working on a Nethack port, and one of the header files a
> library uses has a structure with a member named "red". Since
> includes/decl.h #defines red to something, this totally loses.
>
> Attached is a patch which fixes the color defines.
Fix some inconsistencies in armor handling. The 'T' command
wouldn't let you take off a suit or shirt if you were wielding a
cursed two-handed weapon, which makes sense; however, the 'A'
command neglected to impose the same restriction. Also, the 'W'
command had some code intended to prevent you from donning a suit
or shirt while wielding such a cursed weapon, but it didn't work.
This patch fixes the 'A' command's checks for whether an
item can be removed and it makes the 'T' and 'R' commands use the
same code as 'A' instead of maintaining multiple sets of checks.
It also fixes the trivial 'W' problem and attempts to prevent the
sequence of 1) get interrupted while removing a set of equipment
including suit and/or shirt; 2) wield a cursed two-handed weapon
or have already wielded one become cursed; 3) resume removing
armor via 'A' but I haven't tried to trigger that situation to
confirm the bug or this fix.
Eliminate or at least reduce one of the idiosyncratic differences
between enchant weapon and enchant armor: make reading enchant weapon
discover that scroll if the effect is adequately discernible, instead
of always asking the player to supply a name for it. If your weapon
is identified and its +/- enchantment value goes up, or you're wielding
a worm tooth and it transforms into a crysknife, you learn the scroll.
However for the negative effect of a cursed one, that's only applicable
when the scroll is already known to be cursed.