Handle items in gaps of a wall shared between adjacent shops.
Make handling of shop boundaries more explicit: walls, the door,
and the "free spot" by the door aren't classified as 'costly' but
obj->unpaid and obj->no_charge are valid there.
Move unpaid/no_charge checking into its own routine to unclutter
objlist_sanity().
Pushing a shop-owned boulder to the free spot or doorway or gap in
wall triggers the sanity check for the time being.
When dist2() got changed to use coordxy parameters, a macro that uses
it in its definition was overlooked and it had (int) casts in it.
That caused a warning about possible data loss when the int
then got converted to coordxy for the dist2() call.
Give online2() coordxy parameters instead of int, like its bretheren.
Avoid a couple of implicit conversion warnings where ints were being assigned
to smaller uchar or ints being assigned to smaller short.
A couple of signed vs unsigned warnings on some rumor processing.
Avoid some signed vs unsigned warnings in mdlib/makedefs where a signed int
param eventually got used in an external call that took size_t.
Eliminate all of it by just having the outer NetHack routine also take
a size_t.
Lastly, insert some default C99 alternative time-related code
in mdlib/makedefs since asctime() and ctime() are being flagged as
deprecated in the upcoming C23 standard and will now start to trigger
warnings for anyone using a C23-compliant compiler.
Pushing a shop-owned boulder out of the shop wouldn't charge the hero
anything. Remedy this (and remove the boulder from the bill if the hero
then pushes it back in). Also tried to handle a couple other uncharged
boulder "theft" scenarios: pushing a boulder into lava or water, into a
trapdoor or hole, or into a level teleporter (various other traps
already charged for the boulder -- it was pretty inconsistent).
I externified onbill() for this, since relying on otmp->unpaid by itself
impossibles if you push a boulder through a gap in a wall between two
adjoining shops.
Short for distu(mtmp->mx, mtmp->my) (i.e. the distance between the hero
and the specified monster), which is a very common use of distu(). The
idea is that this would be a convenient shorthand for it; I actually
thought it (or something very similar) existed already, but couldn't
find it when I tried to use it earlier. Based on the number of uses of
fully-spelled-out 'distu(mtmp->mx, mtmp->my)' replaced in this commit
I'm guessing I just imagined it.
Instead of using a compile-time macro to suppress inclusion of the
menu entry to show UNIX command-line usage in the help menu, use a
sysconf setting instead.
Default is HIDEUSAGE=0, to include the entry for command-line usage.
Set HIDEUSAGE=1 to exclude that. Does not affect 'nethack --usage'
if player actually has access to the command-line.
Write up a description of how the command line works on UNIX and put
that in new file dat/usagehlp. Add support for
|nethack --usage | --help | -? | ?
to display it and exit.
Also add a menu entry for nethack's help command to show it during
play. That can be suppressed by uncommenting new '#define HIDE_USAGE'
in config.h since it won't be useful on servers that don't give
players access to command lines.
New genl_display_file() just writes to stdout. opt_usage(), which
calls it, might need some suid/sgid handling to make sure the output
is done as the player rather than as nethack.
doc/nethack.6 is already out of date again.
1. remove all window interface bits from compiler.370, and have
the preceding include files set some variables to control
the behavior of compiler.370 when it comes to c++.
2. some more common Makefile lines into sys/unix/hints/include/multiw-3.370.
3. make it so you can pass cppregex=1 on the Make command line to build with
sys/share/cppregex.cpp instead of posixregex.c
4. fix sys/share/cppregex.cpp so that it will build with clang compiler
(required an additional header include). I don't know if it would have
worked with g++ without that change. The include can be placed into an #ifdef
block if there's an issue with the change on other compilers.
5. Anything that needs to compile using c++ (Qt, sys/share/cppregex.cpp) can
just ensure that CPLUSPLUS_NEEDED Makefile variable is set above the lines
in compiler.370 to ensure that things get set up for c++. It no longer
checks specifically for Qt. That is what sys/unix/hints/include/multiw-2.370
does now.
Condense the setup of PCHAR/PCHAR2 and OBJCLASS/OBJCLASS2 (last one
renamed from OBJCLASS7) so that it's easier to see the variations
at once on an ordinary size terminal/window. Revise some of the
indentation and other spacing, also to try to enhance readability
a little.
Unrelated: remove a trailing space that crept in with a recent pull
request.
Now, the only usage of GCC_WARN is for the guard of PRINTF_F in wincurs.h.
This guard can be removed safely, as PRINTF_F is already used unconditionally in extern.h.
We don't know at compile time whether the X server even supports
Unicode. So take the configured map font, change the registry to
ISO10646 and try the resulting font string. Keep the configured
font if that doesn't work.
GCCs older than 3.1 understand __attribute__(printf(...)), but only
with functions; it doesn't work with function pointers. This change
uses PRINTF_F_PTR to remove the attribute from two function pointers.
This change establishes GCC 3.0 as the minimum version to build
NetHack. Older versions have trouble with the variadic macros and
variable declarations in mid-block.
I made more things in dump_enums() static and/or const. In the
process I discovered both compile problems for NODUMPENUMS and when
fixed, link problems for NODUMPENUMS+ENHANCED_SYMBOLS.
The uft8map.c portion has no changes, just reformatting.
Option parsing rejected
|OPTIONS=!cond_X
for all valid X.
Using the menu to unselect all condition options treated that as not
having made any choice and didn't make any changes. That would be
reasonable if nothing was preselected, but things are so unselecting
all of them is a choice. (A bizarre one, but still should be viable.)
Mostly this deals with including cond_X options when #saveoptions is
used to write a new RC file. It now produces something like
|OPTIONS=!cond_barehanded,cond_blind,!cond_busy,cond_conf,!cond_deaf,\
| cond_iron,cond_fly,cond_foodPois,!cond_glowhands,cond_grab,\
| cond_hallucinat,!cond_held,!cond_ice,cond_lava,cond_levitate,\
| !cond_paralyzed,cond_ride,!cond_sleep,cond_slime,!cond_slip,\
| cond_stone,cond_strngl,cond_stun,!cond_submerged,cond_termIll,\
| !cond_tethered,!cond_trap,!cond_unconscious,!cond_woundedlegs,\
| !cond_holding
after the last alphabetical option and before the bound keys, menu
colors, and others which aren't simple OPTIONS=X settings. This only
happens if there is already one or more OPTIONS=cond_X entries in the
old file when it was read or if 'mO' gets used to make any changes.
Not fixed: after my RC had something similar to the above and before
I changed status conditions to accept negation, I was getting several
"the cond_ option may not both have a value and be negated" messages
written to stdout instead of the config file error handler. So they
vanished when the screen was initialized without providing a --More--
prompt to acknowledge that they have been seen.
Instead of using index() macro defined to strchr, use C99 strchr.
Instead of using rindex() macro defined to strrchr, use C99 strrchr.
If you want to try building on a platform that doesn't offer those
two functions, these are available:
define NOT_C99 /* to make some non-C99 code available */
define NEED_INDEX /* to define a macro for index() */
define NEED_RINDX /* to define a macro for rindex() */
Reverts 690e072, which changed the various is_foo macros from this:
| #define is_elf(ptr) ((((ptr)->mflags2 & M2_ELF) != 0L)
to this:
| #define is_elf(ptr) ((((ptr)->mflags2 & M2_ELF) != 0L) \
| || ((ptr) == g.youmonst.data && \
| !Upolyd && Race_if(PM_ELF)))
This is a problem because g.youmonst.data is not unique to the hero:
the '(ptr) == g.youmonst.data' test will also be true of all player
monsters of the same role. For this reason, any of those player
monsters will be treated as sharing the hero's race, producing strange
results. For example, if the player is an elven ranger, any ranger
player monster generated will be considered 'elven' too (so will get a
to-hit bonus when attacking orcs, etc) -- but only while the hero is
unpolymorphed.
There are already other ways of checking the hero's race in addition to
her current polyform, most notably the maybe_polyd() macro. maybe_polyd
or something similar is already used in nearly all the cases where the
hero's race is being evaluated, meaning Race_if gets used instead when
the hero is in her natural form. So I think the check of the hero's
race in is_foo had very little effect except for the unintended
side-effects on player monsters.
In reviewing all the uses of is_{elf,dwarf,gnome,orc,human}, I noticed
only one case that relied on the hero-race-checking behavior. That has
been changed in this commit to use maybe_polyd (there's another 'raw'
is_human(g.youmonst.data) a few lines down, but it doesn't need
maybe_polyd since it already distinguishes between 'hero in nonhuman
polyform' vs 'nonpolyd or human polyform'). same_race(mondata.c) is
another case where &g.youmonst.data can be passed to is_foo, but
everywhere that calls it for the hero also calls your_race() or
same_race(&mons[Race_switch]) to handle the racial case.
There was a TODO about this; not exactly a great challenge but it feels
like a worthwhile change since the name was misleading. I also updated
the name of the do_intrinsics parameter of extract_from_minvent(worn.c),
since it was in a similar situation (and directly related, since it
controls whether to call update_mon_{in/ex}trinsics).
A giant mummy starts out with a mummy wrapping but couldn't wear it.
Allow humanoids who are bigger than human size (including poly'd hero
when applicable) to wear such cloaks. They won't do so if they are
invisible and the cloak would let hero start seeing them.
cansee(), couldsee(), and templit() are macros which are described
as boolean and used as if boolean, but they've been using bit
masking to return integer values greater than 1. That works since
C treats any non-zero as True but doesn't match boolean intent.
Reported by entrez: using ^A instead of #retravel after interrupted
travel can pick wrong location if cursor was previously positioned
with movement commands rather than feature targeting because it
won't be starting from the original spot. Also, ^A after ';' will
just redescribe whatever was examined previously instead of having
the player pick a new spot.
This suppresses cursor positioning from the do-again queue so that
repeating travel or quick-look or other command that needs player
to choose a position will repeat the command but then need to have
a position chosen. For interrupted #travel, the cursor will already
be placed on the previous destination so that's relatively painless,
but also allows a different destination to be chosen.
It adds iflags.remember_getpos that callers of getpos() could set to
be able to restore the old behavior but none do so far.
Fixes#905
Issue reported by vultur-cadens: Elbereth used to be effective in
inhibiting monster movement when an object was present on the same
spot, but since 3.6.0 it isn't. It only functions that way when the
hero--or hero's displaced image--is present these days. So special
levels that have been using engraved Elbereth to try to protect
objects from monsters haven't been providing any useful protection.
This makes Elbereth that's engraved during level creation work like
it used to in 3.4.3 and earlier: when there's at least one object
on the engraving's spot, monsters who are affected by Elbereth will
be affected. [I'm fairly sure that that behavior started out
unintentionally, as a side-effect of an optimization to only check
for scroll of scare monster when there was at least one item present
which is a necessary condition for such a scroll.]
Old-style Elbereth includes Elbereth chosen as a random engraving
during level creation in addition to engravings specified in special
level definitions. Engravings by the player don't have the required
attribute and player-engraved Elbereth behaves in the 3.6 way.
This ought to be replaced by something more general. Perhaps a new
engraving type not usable by the player?
Fixes#900
Fix most of the things pointed out by #wizmondiff.
Weakening of placeholder 'elf' is due to recent removal of M2_STRONG
for it as part of the "orc strongmonst" changes.
I assume that the discrepancies for multiple quest leaders came about
as part of the change that allows killing the leader as an alternate
way to gain access to the lower levels of the quest, but didn't check.
I don't know what's up with 'piranha' but just changed it to match
generated value.
'{freezing,flaming,shocking} sphere' still show up as discrepancies
with hardcoded (mons[].difficulty) value higher than generated value.
They got harder when their explosion was beefed up, so the formula to
calculate difficulty ought to be updated to account for that.
Force windowtype to be the first option written to new RC file since
its value can affect how other options are processed. (Only saved if
comes from existing RC file, not command line.) doset() lists a few
compound options before the rest too. Combine the two sets of want-
to-be-first and move the handling for that to optlist.h where the only
cost is that the options are no longer in alphabetical order.
Handle alternate values for hero poly'd into a 'strongmonst' form
more thoroughly by propagating max values other than 18/100 to the
attribute manipulation routines.
ATTRMAX(A_STR), which used to be a relatively simple expression, now
contains a function call.
Along the way, change the races[] terminator's value for 'mnum' from
0 (giant ant) to NON_PM.
Since losestr and losehp calls go together most of the time, this feels
like it probably makes more sense than repeating the killer name/format
twice in a row all over the place.
Remove callers' responsibility to deal with possible hero death when
calling losestr. This is less fragile and error-prone than leaving it
in the caller's hands, but it means that death from the monster spell
'weaken target' no longer goes through done_in_by, and the death reason
is no longer "killed by <monster name>".
Killer format isn't a boolean, since it has 3 possible values
(KILLED_BY_AN, KILLED_BY, NO_KILLER_PREFIX). It shouldn't make any
difference behind the scenes, but it's confusing to use 'boolean' for
it.
Monster purple worms can now gain intrinsics from swallowing foes whole,
so maybe the hero should be able to do so too. Intrinsics aren't
granted immediately upon swallowing (that would probably have been
easier), but only once a corpse is created and then entirely digested.
I'm not sure if this is too powerful and was being avoided deliberately
for that reason, since it includes potential level gain from wraith
corpses in addition to other intrinsics. That's consistent with monster
purple worms but may be a bit too much in the hands of the hero, though
it is limited by needing the corpse creation roll to succeed.