diff --git a/Cross-compiling b/Cross-compiling index 590b786fab..b5a7c915e5 100644 --- a/Cross-compiling +++ b/Cross-compiling @@ -361,41 +361,44 @@ Using the cross-compiler, build the following targets: cross-compile and link with these compiler switches: -DCROSSCOMPILE and -DCROSSCOMPILE_TARGET - core sources (2019): src/allmain.c, src/alloc.c, src/apply.c, + core sources (2024): src/allmain.c, src/alloc.c, src/apply.c, src/artifact.c, src/attrib.c, src/ball.c, - src/bones.c, src/botl.c, src/cmd.c, src/dbridge.c, + src/bones.c, src/botl.c, src/calendar.c, + src/coloratt.c, src/cmd.c, src/dbridge.c, src/decl.c, src/detect.c, src/dig.c, src/display.c, src/dlb.c, src/do.c, src/do_name.c, src/do_wear.c, src/dog.c, src/dogmove.c, src/dokick.c, src/dothrow.c, src/drawing.c, src/dungeon.c, src/eat.c, src/end.c, src/engrave.c, src/exper.c, src/explode.c, src/extralev.c, src/files.c, - src/fountain.c, src/hack.c, src/hacklib.c, - src/insight.c, src/invent.c, src/isaac64.c, - src/light.c, src/lock.c, src/mail.c, - src/makemon.c, src/mcastu.c, + src/fountain.c, src/getpos.c, src/glyphs.c, + src/hack.c, src/hacklib.c, src/insight.c, + src/invent.c, src/isaac64.c, src/light.c, + src/lock.c, src/mail.c, src/makemon.c, src/mcastu.c, src/mdlib.c, src/mhitm.c, src/mhitu.c, src/minion.c, src/mklev.c, src/mkmap.c, src/mkmaze.c, src/mkobj.c, src/mkroom.c, src/mon.c, src/mondata.c, src/monmove.c, src/monst.c, src/mplayer.c, src/mthrowu.c, src/muse.c, src/music.c, - src/nhlsel.c, src/nhlua.c, src/nhlobj.c, - src/o_init.c, src/objects.c, src/objnam.c, - src/options.c, src/pager.c, src/pickup.c, - src/pline.c, src/polyself.c, src/potion.c, - src/pray.c, src/priest.c, src/quest.c, + src/nhlua.c, src/nhlsel.c, src/nhlobj.c, + src/nhmd4.c, src/objects.c, src/o_init.c, + src/objnam.c, src/options.c, src/pager.c, + src/pickup.c, src/pline.c, src/polyself.c, + src/potion.c, src/pray.c, src/priest.c, src/quest.c, src/questpgr.c, src/read.c, src/rect.c, - src/region.c, src/restore.c, src/rip.c, src/rnd.c, - src/role.c, src/rumors.c, src/save.c, src/sfstruct.c, - src/shk.c, src/shknam.c, src/sit.c, src/sounds.c, - src/sp_lev.c, src/spell.c, src/steal.c, src/steed.c, + src/region.c, src/report.c, src/restore.c,src/rip.c, + src/rnd.c, src/role.c, src/rumors.c, src/save.c, + src/selvar.c, src/sfstruct.c, src/shk.c, + src/shknam.c, src/sit.c, src/sounds.c, src/sp_lev.c, + src/spell.c, src/stairs.c, src/steal.c, src/steed.c, src/symbols.c, src/sys.c, src/teleport.c, src/timeout.c, src/topten.c, src/track.c, - src/trap.c, src/u_init.c, src/uhitm.c, src/vault.c, - src/version.c, src/vision.c, - src/weapon.c, src/were.c, src/wield.c, src/windows.c, - src/wizard.c, src/worm.c, src/worn.c, src/write.c, - src/zap.c, sys/share/cppregex.cpp + src/trap.c, src/u_init.c, src/uhitm.c, + src/utf8map.c, src/vault.c, src/version.c, + src/vision.c, src/weapon.c, src/were.c, src/wield.c, + src/windows.c, src/wizard.c, src/wizcmds.c, + src/worm.c, src/worn.c, src/write.c, src/zap.c, + sys/share/cppregex.cpp tty sources: win/tty/getline.c, win/tty/termcap.c, win/tty/topl.c, win/tty/wintty.c @@ -695,7 +698,7 @@ Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html +--------------------------------+ - | B7. Case sample: mips | + | B7. Case sample: mips | +--------------------------------+ Cross-compiler used: gcc-mipsel-linux-gnu, g++-mipsel-linux-gnu diff --git a/DEVEL/Developer.txt b/DEVEL/Developer.txt index 7cb0f8c07f..c70b6ba1af 100644 --- a/DEVEL/Developer.txt +++ b/DEVEL/Developer.txt @@ -58,6 +58,11 @@ NOTE: These instructions assume you are on the default branch; this _is_ NOTE: The following instructions require perl. If you do not have perl on your system, please install it before proceeding. +NOTE: More information on nhgitset.pl is available before installation via: + perldoc DEVEL/nhgitset.pl + After installation, the same information is available with: + git nhhelp nhgitset + A. If you have never set up git on this machine before: (This assumes you will only be using git for NetHack. If you are going to use it for other projects as well, think before you type.) diff --git a/DEVEL/VERSION b/DEVEL/VERSION index 01a759d530..3788cb6d58 100644 --- a/DEVEL/VERSION +++ b/DEVEL/VERSION @@ -1,40 +1,4 @@ -4 -Fixes: -- "nhcommit -a" has been fixed -- NHDT was hardwired in places -- no longer complain about a missing dat directory outside of the - NetHack source tree -- make update of gitinfo atomic -- Replace some hardwired directory separators with OS-dependent constructs - -Backwards Incompatibilities: -- NH_DATESUB's DATE() is now Date() to match the other variables -- MSYS2 requires an additional Perl package - the MSYS2 docs have - been updated - -New Help System: -- git nhhelp - This command mirrors "git help" for nh* commands. -- See git nhhelp nhsub for general help on substitution variables - -New Substitution Variables: --Brev() - An aBREViation of $PREFIX-Branch$:$PREFIX-Revision$ - this - may help get line length under control in file headers. --Assert(TYPE=VALUE) - If TYPE does not match VALUE, do not substitute on this line. - TYPE P checks VALUE against nethack.substprefix --Project(arg) - Returns nethack.projectname if there is no arg and an uppercase - version if arg is uc. - -Other New Features: -- Add nethack.projectname -- Documentation updates - see "git nhhelp nhsub" -- On checkout or merge of a branch, check for nhgitset version updates -- Move NH_DATESUB substitutions here from cron job to keep dates in sync -- PREFIX-* keywords now available in NH_DATESUB templates -- Support use of nhgitset.pl from a different repo; note that update - checks will be dependent on keeping the original source repo up-to-date - and in the same location. - +5 +Please see "git log DEVEL" for previous changes. +Make documentation of nhgitset.pl easier to find and +find out about. diff --git a/DEVEL/nhgitset.pl b/DEVEL/nhgitset.pl index 984d45a32a..e235a33ce0 100755 --- a/DEVEL/nhgitset.pl +++ b/DEVEL/nhgitset.pl @@ -153,6 +153,7 @@ BEGIN &add_help('NHsubst', 'NHsubst'); &add_help('NHgithook', 'NHgithook.pm'); +&add_help('nhgitset', 'gitsetdocs', '../../DEVEL/nhgitset.pl'); # removed at version 3 @@ -183,7 +184,7 @@ BEGIN print STDERR "Running directories\n" if($opt_v); -# copy directories into .git (right now that's just hooks +# copy directories into .git (right now that's just hooks and nhgitset.pl) my @gitadd = length($gitadddir)?glob("$gitadddir$DS*"):undef; foreach my $dir ( (glob("$srcdir$DS*"), @gitadd) ){ next unless(-d $dir); @@ -209,6 +210,7 @@ BEGIN &process_override($enddir, "POST"); } } +&do_file_nhgitset(); &check_gitvars; # for variable substitution @@ -219,26 +221,31 @@ BEGIN exit 0; +# @files: [0] is the name under .git/hooks; others are places to +# check during configuration sub add_help { - my($cmd, $file) = @_; + my($cmd, @files) = @_; - &add_config("nethack.aliashelp.$cmd", $file); + &add_config("nethack.aliashelp.$cmd", $files[0]); # pull out =for nhgitset CMD description... - my $desc = ''; - open my $fh, "<", "$DEVhooksdir/$file"; - if($fh){ - while(<$fh>){ - m/^=for\s+nhgitset\s+\Q$cmd\E\s+(.*)/ && do { - $desc = $1; - last; + my $desc; + foreach my $file (@files){ + open my $fh, "<", "$DEVhooksdir/$file"; + if($fh){ + while(<$fh>){ + m/^=for\s+nhgitset\s+\Q$cmd\E\s+(.*)/ && do { + $desc = $1; + goto found; + } } + close $fh; + } else { + warn "Can't open: '$DEVhooksdir/$file' ($!)\n"; } - close $fh; - } else { - warn "Can't open: '$DEVhooksdir/$file' ($!)\n"; } +found: - if(length $desc){ + if($desc){ &add_config("nethack.aliasdesc.$cmd", $desc); } else { &add_config("nethack.aliasdesc.$cmd", "(no description available)"); @@ -344,13 +351,25 @@ sub do_dir_hooksdir { } } -__END__ -(can we change the .gitattributes syntax to include a comment character?) -maybe [comment] attr.c:parse_attr_line -grr - looks like # is the comment character - - +sub do_file_nhgitset { + my $infile = "DEVEL/nhgitset.pl"; + my $outfile = ".git/hooks/gitsetdocs"; + open IN, "<", $infile or die "Can't open $infile:$!"; + open OUT, ">", $outfile or die "Can't open $outfile:$!"; + my $started; + print IN "die \"DO NOT RUN THIS FILE\n\""; + while(){ + m/^__END__/ && do {$started =1; next}; + print OUT if($started); + } + close OUT; + close IN; +} +#(can we change the .gitattributes syntax to include a comment character?) +#maybe [comment] attr.c:parse_attr_line +#grr - looks like # is the comment character +__END__ =head1 NAME nhgitset.pl - Setup program for NetHack git repositories @@ -363,9 +382,10 @@ =head1 SYNOPSIS =head1 DESCRIPTION -nhgitset.pl installs NetHack-specific setup after a C (or after -changes to the desired configuration, which are installed by re-running -nhgitset.pl). +nhgitset.pl installs NetHack-specific setup after a C or after +changes to the setup, which are installed by re-running nhgitset.pl. If +an upgrade is needed, you will be informed during a C or similar +operation. The following options are available: @@ -445,3 +465,5 @@ =head1 EXIT STATUS 1 Fail. 2 Intervention required. + +=for nhgitset nhgitset NetHack git helper installer diff --git a/Files b/Files index 8ce80a7ebe..21260b1068 100644 --- a/Files +++ b/Files @@ -12,8 +12,8 @@ Porting README azure-pipelines.yml DEVEL: (files for people developing changes to NetHack) -Developer.txt code_features.txt code_style.txt git_recipes.txt -gitinfo.pl nhgitset.pl +Developer.txt VERSION code_features.txt code_style.txt +git_recipes.txt gitinfo.pl nhgitset.pl DEVEL/DOTGIT: (file for people developing changes to NetHack) @@ -23,11 +23,11 @@ DEVEL/hooksdir: (files for people developing changes to NetHack) NHadd NHgithook.pm NHsubst NHtext TARGET applypatch-msg -commit-msg nhsub post-applypatch -post-checkout post-commit post-merge -post-rewrite pre-applypatch pre-auto-gc -pre-commit pre-push pre-rebase -prepare-commit-msg +commit-msg nhhelp nhsub +post-applypatch post-checkout post-commit +post-merge post-rewrite pre-applypatch +pre-auto-gc pre-commit pre-push +pre-rebase prepare-commit-msg dat: (files for all versions) @@ -93,15 +93,15 @@ dlb.h dungeon.h engrave.h extern.h flag.h fnamesiz.h func_tab.h global.h hack.h hacklib.h integer.h isaac64.h lint.h mail.h mextra.h mfndpos.h micro.h mkroom.h monattk.h mondata.h -monflag.h monst.h monsters.h nhmd4.h obj.h -objclass.h objects.h optlist.h patchlevel.h pcconf.h -permonst.h prop.h quest.h rect.h region.h -rm.h seffects.h selvar.h skills.h sndprocs.h -sp_lev.h spell.h stairs.h sym.h sys.h -tcap.h tileset.h timeout.h tradstdc.h trap.h -unixconf.h vision.h vmsconf.h warnings.h winami.h -wincurs.h windconf.h winprocs.h wintype.h you.h -youprop.h +monflag.h monst.h monsters.h nhmd4.h nhregex.h +obj.h objclass.h objects.h optlist.h patchlevel.h +pcconf.h permonst.h prop.h quest.h rect.h +region.h rm.h seffects.h selvar.h skills.h +sndprocs.h sp_lev.h spell.h stairs.h sym.h +sys.h tcap.h tileset.h timeout.h tradstdc.h +trap.h unixconf.h vision.h vmsconf.h warnings.h +winami.h wincurs.h windconf.h winprocs.h wintype.h +you.h youprop.h (file for tty versions) wintty.h @@ -532,6 +532,10 @@ sys/windows/vs/hacklib: (file for Visual Studio 2019 or 2022 Community Edition builds) hacklib.vcxproj +sys/windows/vs/lualib: +(file for Visual Studio 2019 or 2022 Community Edition builds) +lualib.vcxproj + sys/windows/vs/makedefs: (files for Visual Studio 2019 or 2022 Community Edition builds) aftermakedefs.proj makedefs.vcxproj diff --git a/doc/.gitattributes b/doc/.gitattributes index f4d35defc3..5edfa047ff 100644 --- a/doc/.gitattributes +++ b/doc/.gitattributes @@ -3,7 +3,6 @@ *.6 NHSUBST *.7 NHSUBST fixes* NHSUBST -*.txt NHSUBST config.nh NHSUBST Guidebook.txt NH_header=no tmac.n NH_header=no diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index c8fcbfcd3c..7590d5591e 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6680,4 +6680,3 @@ Izchak Miller Mike Stephenson .sm "Brand and product names are trademarks or registered trademarks \ of their respective holders." .\"EOF -changes diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 87e4e346c8..d8a2428e53 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1475,6 +1475,14 @@ a pet with the hides-under attribute could "move reluctantly over" a cursed object and then hide under it prevent monster generation in the sokoban trap hallway change MSGHANDLER from compile-time to sysconf option +allow changing extended command autocompletions via #optionsfull +if eating a tin's contents caused the hero to choke to death or turn to stone, + resulting bones would contain the tin still intact +when hero who is poly'd into metallivore form eats a tin, bypass "smells like + " feedback and the "Eat it?" prompt; just eat the contents + along with the tin without asking +digging in ice was handled inconsistently, particularly if done at the span + spot in front of closed drawbridge Fixes to 3.7.0-x General Problems Exposed Via git Repository @@ -2206,7 +2214,7 @@ curses: if user's terminal was set to 'application keypad mode' (DEC VTxxx "ESC SPC G"), nethack wasn't recognizing number pad keys curses: change petattr attributes, dropping support for curses-only ones curses: swap the grey and no-color color initialization -curses: allow changing default colors with the 'palette' config option +curses+Qt: allow changing default colors with the 'palette' config option (only if compiled with CHANGE_COLOR) curses: if messages have been issued during start-up (for instance, warnings about issues in run-time config file), prompt user to press @@ -2914,6 +2922,8 @@ split "cannot_push" on moverock_done() into a separate function (pr #1282 by argrath) split making pits on do_earthquake() into a separate function and eliminate some gotos on do_earthquake() (pr #1287 by argrath) +update the WASM cross-compile to work with the current + code (pr #1331 by guillaumebrunerie) Code Cleanup and Reorganization diff --git a/include/config.h b/include/config.h index b00be6a4bb..15aab1f7ee 100644 --- a/include/config.h +++ b/include/config.h @@ -266,7 +266,7 @@ #ifdef CRASHREPORT # ifndef DUMPLOG_CORE -# define DUMPLOG_CORE // required to get ^P info +# define DUMPLOG_CORE // required to get ^P info # endif # ifdef MACOS # define PANICTRACE @@ -463,7 +463,7 @@ */ #define INSURANCE /* allow crashed game recovery */ -#ifndef MAC +#if !defined(MAC) && !defined(SHIM_GRAPHICS) #define CHDIR /* delete if no chdir() available */ #endif diff --git a/include/extern.h b/include/extern.h index 34c50a31bb..b2c704a645 100644 --- a/include/extern.h +++ b/include/extern.h @@ -738,7 +738,7 @@ extern int Shield_off(void); extern int Shirt_off(void); extern void dragon_armor_handling(struct obj *, boolean, boolean); extern void Amulet_off(void); -extern void Amulet_on(void); +extern void Amulet_on(struct obj *); extern void Ring_on(struct obj *) NONNULLARG1; extern void Ring_off(struct obj *) NONNULLARG1; extern void Ring_gone(struct obj *) NONNULLARG1; @@ -2168,12 +2168,7 @@ extern void tutorial(boolean); #endif /* MAKEDEFS_C MDLIB_C CPPREGEX_C */ /* ### {cpp,pmatch,posix}regex.c ### */ - -extern struct nhregex *regex_init(void); -extern boolean regex_compile(const char *, struct nhregex *) NONNULLARG1; -extern char *regex_error_desc(struct nhregex *, char *) NONNULLARG2; -extern boolean regex_match(const char *, struct nhregex *) NO_NNARGS; -extern void regex_free(struct nhregex *) NONNULLARG1; +#include "nhregex.h" #if !defined(MAKEDEFS_C) && !defined(MDLIB_C) && !defined(CPPREGEX_C) @@ -3959,6 +3954,7 @@ extern boolean worm_cross(int, int, int, int); extern int wseg_at(struct monst *, int, int) NO_NNARGS; extern void flip_worm_segs_vertical(struct monst *, int, int) NONNULLARG1; extern void flip_worm_segs_horizontal(struct monst *, int, int) NONNULLARG1; +extern void redraw_worm(struct monst *); /* ### worn.c ### */ diff --git a/include/global.h b/include/global.h index d2651b3b82..7a32d105fc 100644 --- a/include/global.h +++ b/include/global.h @@ -482,6 +482,9 @@ extern struct nomakedefs_s nomakedefs; #if !defined(CROSS_TO_WASM) /* no popen in WASM */ #define PANICTRACE_GDB #endif +#ifdef CROSS_TO_WASM +#undef COMPRESS +#endif #endif /* Supply nethack_enter macro if not supplied by port */ diff --git a/include/nhregex.h b/include/nhregex.h new file mode 100644 index 0000000000..6dc989213b --- /dev/null +++ b/include/nhregex.h @@ -0,0 +1,17 @@ +/* NetHack 3.7 nhregex.h $NHDT-Date: $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: $ */ +/* NetHack may be freely redistributed. See license for details. */ + +#ifndef NHREGEX_H +#define NHREGEX_H + +/* ### {cpp,pmatch,posix}regex.c ### */ + +extern struct nhregex *regex_init(void); +extern boolean regex_compile(const char *, struct nhregex *) NONNULLARG1; +extern char *regex_error_desc(struct nhregex *, char *) NONNULLARG2; +extern boolean regex_match(const char *, struct nhregex *) NO_NNARGS; +extern void regex_free(struct nhregex *) NONNULLARG1; + +#endif /* NHREGEX_H */ + +/*extern.h*/ diff --git a/include/prop.h b/include/prop.h index 975a865deb..8dc52c043e 100644 --- a/include/prop.h +++ b/include/prop.h @@ -58,23 +58,24 @@ enum prop_types { CLAIRVOYANT = 35, INFRAVISION = 36, DETECT_MONSTERS = 37, + BLND_RES = 38, /* Appearance and behavior */ - ADORNED = 38, - INVIS = 39, - DISPLACED = 40, - STEALTH = 41, - AGGRAVATE_MONSTER = 42, - CONFLICT = 43, + ADORNED = 39, + INVIS = 40, + DISPLACED = 41, + STEALTH = 42, + AGGRAVATE_MONSTER = 43, + CONFLICT = 44, /* Transportation */ - JUMPING = 44, - TELEPORT = 45, - TELEPORT_CONTROL = 46, - LEVITATION = 47, - FLYING = 48, - WWALKING = 49, - SWIMMING = 50, - MAGICAL_BREATHING = 51, - PASSES_WALLS = 52, + JUMPING = 45, + TELEPORT = 46, + TELEPORT_CONTROL = 47, + LEVITATION = 48, + FLYING = 49, + WWALKING = 50, + SWIMMING = 51, + MAGICAL_BREATHING = 52, + PASSES_WALLS = 53, /* Physical attributes */ SLOW_DIGESTION = 53, HALF_SPDAM = 54, @@ -96,8 +97,8 @@ enum prop_types { STUN_RES = 70, BREATHLESS = 71, RABID = 72, + LAST_PROP = RABID }; -#define LAST_PROP (RABID) /*** Where the properties come from ***/ /* Definitions were moved here from obj.h and you.h */ diff --git a/include/rm.h b/include/rm.h index 1edabef25b..89e59dd140 100644 --- a/include/rm.h +++ b/include/rm.h @@ -108,7 +108,6 @@ enum levl_typ_types { #define IS_WALL(typ) ((typ) && (typ) <= DBWALL) #define IS_STWALL(typ) ((typ) <= DBWALL) /* STONE <= (typ) <= DBWALL */ #define IS_OBSTRUCTED(typ) ((typ) < POOL) /* absolutely nonaccessible */ -#define IS_CORR(typ) ((typ) == CORR || (typ) == SCORR) #define IS_SDOOR(typ) ((typ) == SDOOR) #define IS_DOOR(typ) ((typ) == DOOR) #define IS_DOORJOIN(typ) (IS_OBSTRUCTED(typ) || (typ) == IRONBARS) diff --git a/include/tradstdc.h b/include/tradstdc.h index c5a9368fb0..b607d4a991 100644 --- a/include/tradstdc.h +++ b/include/tradstdc.h @@ -327,13 +327,20 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ /* * Give first priority to standard */ -#ifndef ATTRNORETURN #if defined(__STDC_VERSION__) || defined(__cplusplus) #if (__STDC_VERSION__ > 202300L) || defined(__cplusplus) +#ifndef ATTRNORETURN #define ATTRNORETURN [[noreturn]] #endif -#endif -#endif +#ifndef __has_c_attribute +#define __has_c_attribute(x) 0 +#endif /* __has_c_attribute */ +#if __has_c_attribute(fallthrough) +/* Standard attribute is available, use it. */ +#define FALLTHROUGH [[fallthrough]] +#endif /* __has_c_attribute(fallthrough) */ +#endif /* __STDC_VERSION__ gt 202300L || __cplusplus */ +#endif /* __STDC_VERSION || __cplusplus */ /* * Allow gcc2 to check parameters of printf-like calls with -Wformat; @@ -366,12 +373,21 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ #endif /* !NONNULLS_DEFINED */ /* #pragma message is available */ #define NH_PRAGMA_MESSAGE 1 -#endif -#endif +#endif /* __GNUC__ greater than or equal to 5 */ +#endif /* __GNUC__ */ -#if defined(__clang__) && !defined(DO_DEFINE_NONNULLS) +#if defined(__clang__) +#ifndef FALLTHROUGH +#if defined(__clang_major__) +#if __clang_major__ >= 9 +#define FALLTHROUGH __attribute__((fallthrough)) +#endif /* __clang_major__ greater than or equal to 9 */ +#endif /* __clang_major__ is defined */ +#endif /* FALLTHROUGH */ +#if !defined(DO_DEFINE_NONNULLS) #define DO_DEFINE_NONNULLS #endif +#endif /* __clang__ */ #if defined(DO_DEFINE_NONNULLS) && !defined(NONNULLS_DEFINED) #define NONNULL __attribute__((returns_nonnull)) @@ -405,6 +421,7 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ #define NH_PRAGMA_MESSAGE 1 #endif +/* Fallback implementations */ #ifndef PRINTF_F #define PRINTF_F(f, v) #endif @@ -414,6 +431,9 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ #ifndef UNUSED #define UNUSED #endif +#ifndef FALLTHROUGH +#define FALLTHROUGH +#endif #ifndef ATTRNORETURN #define ATTRNORETURN #endif diff --git a/include/windconf.h b/include/windconf.h index f274dc7775..6030072022 100644 --- a/include/windconf.h +++ b/include/windconf.h @@ -98,7 +98,7 @@ extern char *windows_exepath(void); *=============================================== */ -#ifdef __MINGW32__ +#ifdef __GNUC__ #define MD_USE_TMPFILE_S # #ifdef strncasecmp @@ -110,10 +110,11 @@ extern char *windows_exepath(void); #ifdef __USE_MINGW_ANSI_STDIO #undef __USE_MINGW_ANSI_STDIO #endif -#define __USE_MINGW_ANSI_STDIO 1 +/* with UCRT, we don't define this to 1 */ +#define __USE_MINGW_ANSI_STDIO 0 #endif /* extern int getlock(void); */ -#endif /* __MINGW32__ */ +#endif /* __GNUC__ */ #ifdef _MSC_VER #define MD_USE_TMPFILE_S diff --git a/include/youprop.h b/include/youprop.h index 87395242f8..0e0202c772 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -168,6 +168,10 @@ #define Blind_telepat (HTelepat || ETelepat) #define Unblind_telepat (ETelepat) +#define HBlnd_resist u.uprops[BLND_RES].intrinsic /* from form */ +#define EBlnd_resist u.uprops[BLND_RES].extrinsic /* wielding Sunsword */ +#define Blnd_resist (HBlnd_resist || EBlnd_resist) + #define HWarning u.uprops[WARNING].intrinsic #define EWarning u.uprops[WARNING].extrinsic #define Warning (HWarning || EWarning) diff --git a/sound/windsound/windsound.c b/sound/windsound/windsound.c index 8ccfe9f654..0dc486f183 100644 --- a/sound/windsound/windsound.c +++ b/sound/windsound/windsound.c @@ -55,14 +55,13 @@ windsound_init_nhsound(void) } static void -windsound_exit_nhsound(const char *reason) +windsound_exit_nhsound(const char *reason UNUSED) { } static void -windsound_achievement(schar ach1, schar ach2, int32_t repeat) +windsound_achievement(schar ach1, schar ach2, int32_t repeat UNUSED) { - int reslt = 0; const char *filename; char resourcename[120], buf[PATHLEN]; int findsound_approach = sff_base_only; @@ -108,27 +107,27 @@ windsound_achievement(schar ach1, schar ach2, int32_t repeat) filename = base_soundname_to_filename(resourcename, buf, sizeof buf, findsound_approach); if (filename) { - reslt = PlaySound(filename, NULL, fdwsound); + (void) PlaySound(filename, NULL, fdwsound); } } static void -windsound_ambience(int32_t ambienceid, int32_t ambience_action, - int32_t hero_proximity) +windsound_ambience(int32_t ambienceid UNUSED, int32_t ambience_action UNUSED, + int32_t hero_proximity UNUSED) { } static void -windsound_verbal(char *text, int32_t gender, int32_t tone, - int32_t vol, int32_t moreinfo) +windsound_verbal(char *text UNUSED, int32_t gender UNUSED, int32_t tone UNUSED, + int32_t vol UNUSED, int32_t moreinfo UNUSED) { } static void -windsound_soundeffect(char *desc, int32_t seid, int32_t volume) +windsound_soundeffect(char *desc UNUSED, int32_t seid, int32_t volume UNUSED) { #ifdef SND_SOUNDEFFECTS_AUTOMAP - int reslt = 0; +/* int reslt = 0; */ int32_t findsound_approach = sff_base_only; char buf[PATHLEN]; const char *filename; @@ -147,7 +146,7 @@ windsound_soundeffect(char *desc, int32_t seid, int32_t volume) } if (filename) { - reslt = PlaySound(filename, NULL, fdwsound); + (void) PlaySound(filename, NULL, fdwsound); } #endif } @@ -155,7 +154,7 @@ windsound_soundeffect(char *desc, int32_t seid, int32_t volume) #define WAVEMUSIC_SOUNDS static void -windsound_hero_playnotes(int32_t instrument, const char *str, int32_t volume) +windsound_hero_playnotes(int32_t instrument, const char *str, int32_t volume UNUSED) { #ifdef WAVEMUSIC_SOUNDS int reslt = 0; @@ -239,6 +238,8 @@ windsound_hero_playnotes(int32_t instrument, const char *str, int32_t volume) /* the final, or only, one is played ASYNC */ maybe_preinsert_directory(findsound_approach, exedir, buf, sizeof buf); reslt = PlaySound(buf, NULL, fdwsound); + nhUse(filename); + nhUse(reslt); #endif } diff --git a/src/allmain.c b/src/allmain.c index af26b27796..107fbcfc6e 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -1099,6 +1099,7 @@ argcheck(int argc, char *argv[], enum earlyarg e_arg) extended_opt++; return windows_early_options(extended_opt); } + FALLTHROUGH; /*FALLTHRU*/ #endif default: diff --git a/src/apply.c b/src/apply.c index fbf0ea6b53..c81a275228 100644 --- a/src/apply.c +++ b/src/apply.c @@ -4292,7 +4292,8 @@ use_grapple(struct obj *obj) (void) thitmonst(mtmp, uwep); return ECMD_TIME; } - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ case 3: /* Surface */ if (IS_AIR(levl[cc.x][cc.y].typ) || is_damp_terrain(cc.x, cc.y)) pline_The("hook slices through the %s.", surface(cc.x, cc.y)); @@ -4407,6 +4408,7 @@ do_break_wand(struct obj *obj) discard_broken_wand(); return ECMD_TIME; } + FALLTHROUGH; /*FALLTHRU*/ case WAN_NOTHING: pline(nothing_else_happens); @@ -4458,6 +4460,7 @@ do_break_wand(struct obj *obj) Soundeffect(se_wall_of_force, 65); pline("A wall of force smashes down around you!"); dmg = d(1 + obj->spe, 6); /* normally 2d12 */ + FALLTHROUGH; /*FALLTHRU*/ case WAN_CANCELLATION: case WAN_POLYMORPH: @@ -4931,6 +4934,7 @@ doapply(void) pline("It rings! ... But no-one answers."); break; } + FALLTHROUGH; /*FALLTHRU*/ default: /* Pole-weapons can strike at a distance */ diff --git a/src/artifact.c b/src/artifact.c index eed4dead4e..5bd3b4122e 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -661,7 +661,10 @@ protects(struct obj *otmp, boolean being_worn) * unworn/unwielded/dropped. Pickup/drop only set/reset the W_ART mask. */ void -set_artifact_intrinsic(struct obj *otmp, boolean on, long wp_mask) +set_artifact_intrinsic( + struct obj *otmp, + boolean on, + long wp_mask) { long *mask = 0; const struct artifact *art, *oart = get_artifact(otmp); @@ -942,6 +945,13 @@ set_artifact_intrinsic(struct obj *otmp, boolean on, long wp_mask) && (u.uprops[oart->inv_prop].extrinsic & W_ARTI)) (void) arti_invoke(otmp); } + + if (wp_mask == W_WEP && is_art(otmp, ART_SUNSWORD)) { + if (on) + EBlnd_resist |= wp_mask; + else + EBlnd_resist &= ~wp_mask; + } } /* touch_artifact()'s return value isn't sufficient to tell whether it @@ -2877,6 +2887,10 @@ what_gives(long *abil) if ((art->spfx & spfx) == spfx && obj->owornmask) return obj; } + if (obj == uwep && abil == &EBlnd_resist + && (*abil & W_WEP) != 0L) { + return obj; /* Sunsword */ + } } } else { if (wornbits && wornbits == (wornmask & obj->owornmask)) diff --git a/src/attrib.c b/src/attrib.c index 3de6dd7219..5167d5c381 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -940,7 +940,8 @@ is_innate(int propidx) ignore innateness if equipment is going to claim responsibility */ && !u.uprops[propidx].extrinsic) return FROM_ROLE; - if (propidx == BLINDED && !haseyes(gy.youmonst.data)) + if ((propidx == BLINDED && !haseyes(gy.youmonst.data)) + || (propidx == BLND_RES && (HBlnd_resist & FROMFORM) != 0)) return FROM_FORM; return FROM_NONE; } @@ -948,7 +949,8 @@ is_innate(int propidx) DISABLE_WARNING_FORMAT_NONLITERAL char * -from_what(int propidx) /* special cases can have negative values */ +from_what( + int propidx) /* special cases can have negative values */ { static char buf[BUFSZ]; @@ -990,7 +992,7 @@ from_what(int propidx) /* special cases can have negative values */ else if (innateness == FROM_LYCN) Strcpy(buf, " due to your lycanthropy"); else if (innateness == FROM_FORM) - Strcpy(buf, " from current creature form"); + Strcpy(buf, " from your creature form"); else if (propidx == FAST && Very_fast) Sprintf(buf, because_of, ((HFast & TIMEOUT) != 0L) ? "a potion or spell" diff --git a/src/ball.c b/src/ball.c index aff5b8acaf..59089cad67 100644 --- a/src/ball.c +++ b/src/ball.c @@ -750,7 +750,8 @@ drag_ball(coordxy x, coordxy y, int *bc_control, SKIP_TO_DRAG; break; } - /* fall through */ + FALLTHROUGH; + /* FALLTHRU */ case 1: case 0: /* do nothing if possible */ diff --git a/src/date.c b/src/date.c index aef985e75b..f4b96fdb03 100644 --- a/src/date.c +++ b/src/date.c @@ -29,7 +29,7 @@ struct nomakedefs_s nomakedefs = { "Version 1.0, built Jul 28 13:18:57 1987.", (const char *) 0, /* git_sha */ (const char *) 0, /* git_branch */ - (const char *) 0, /* git_prefix */ + (const char *) 0, /* git_prefix */ "1.0.0-0", "NetHack Version 1.0.0-0 - last build Tue Jul 28 13:18:57 1987.", 0x01010000UL, diff --git a/src/dbridge.c b/src/dbridge.c index 0cfdddc54c..61be830c1e 100644 --- a/src/dbridge.c +++ b/src/dbridge.c @@ -277,6 +277,7 @@ create_drawbridge(coordxy x, coordxy y, int dir, boolean flag) break; default: impossible("bad direction in create_drawbridge"); + FALLTHROUGH; /*FALLTHRU*/ case DB_WEST: horiz = FALSE; diff --git a/src/dig.c b/src/dig.c index fe66de8b70..ca9ecb2d41 100644 --- a/src/dig.c +++ b/src/dig.c @@ -867,8 +867,9 @@ liquid_flow( } if (ttmp) - (void) delfloortrap(ttmp); /* will untrap monster is one is here */ + (void) delfloortrap(ttmp); /* will untrap monster if one is here */ /* if any objects were frozen here, they're released now */ + obj_ice_effects(x, y, TRUE); unearth_objs(x, y); if (fillmsg) @@ -2117,7 +2118,8 @@ bury_objs(int x, int y) } } -/* move objects from buriedobjlist to fobj/nexthere lists */ +/* move objects from buriedobjlist to fobj/nexthere lists; if caller + converts terrain from ice to something, it should call obj_ice_effects() */ void unearth_objs(int x, int y) { diff --git a/src/display.c b/src/display.c index 843137b63c..71945e1794 100644 --- a/src/display.c +++ b/src/display.c @@ -532,6 +532,7 @@ display_monster( default: impossible("display_monster: bad m_ap_type value [ = %d ]", (int) mon->m_ap_type); + FALLTHROUGH; /*FALLTHRU*/ case M_AP_NOTHING: show_glyph(x, y, mon_to_glyph(mon, newsym_rn2)); @@ -3246,7 +3247,8 @@ check_pos(coordxy x, coordxy y, int which) if (!isok(x, y)) return which; type = levl[x][y].typ; - if (IS_STWALL(type) || IS_CORR(type) || IS_SDOOR(type)) + /* Everything below POOL, excluding TREE */ + if (IS_STWALL(type) || type == CORR || type == SCORR || IS_SDOOR(type)) return which; return 0; } @@ -3710,6 +3712,7 @@ wall_angle(struct rm *lev) case SDOOR: if (lev->horizontal) goto horiz; + FALLTHROUGH; /*FALLTHRU*/ case VWALL: switch (lev->wall_info & WM_MASK) { diff --git a/src/do.c b/src/do.c index ab3f82574a..d1694a2e26 100644 --- a/src/do.c +++ b/src/do.c @@ -48,9 +48,9 @@ dodrop(void) */ boolean boulder_hits_pool( - struct obj *otmp, - coordxy rx, coordxy ry, - boolean pushing) + struct obj *otmp, /* the object falling into a pool or water or lava */ + coordxy rx, coordxy ry, /* coordinates of the pool */ + boolean pushing) /* for a boulder, whether or not it is being pushed */ { if (!otmp || otmp->otyp != BOULDER) { impossible("Not a boulder?"); @@ -139,8 +139,9 @@ boulder_hits_pool( losehp(Maybe_Half_Phys(dmg), /* lava damage */ "molten lava", KILLED_BY); } else if (!fills_up && flags.verbose - && (pushing ? !Blind : cansee(rx, ry))) + && (pushing ? !Blind : cansee(rx, ry))) { pline("It sinks without a trace!"); + } } /* boulder is now gone */ @@ -158,7 +159,10 @@ boulder_hits_pool( * away. */ boolean -flooreffects(struct obj *obj, coordxy x, coordxy y, const char *verb) +flooreffects( + struct obj *obj, /* the object landing on the floor */ + coordxy x, coordxy y, /* map coordinates for spot where it is landing */ + const char *verb) /* "fall", "drop", "land", &c */ { struct trap *t; struct monst *mtmp; @@ -237,12 +241,10 @@ flooreffects(struct obj *obj, coordxy x, coordxy y, const char *verb) You_hear("a CRASH! beneath you."); } else if (!Blind && cansee(x, y)) { pline_The("boulder %s%s.", - (ttyp == TRAPDOOR && !tseen) - ? "triggers and " : "", - (ttyp == TRAPDOOR) - ? "plugs a trap door" - : (ttyp == HOLE) ? "plugs a hole" - : "fills a pit"); + (ttyp == TRAPDOOR && !tseen) ? "triggers and " : "", + (ttyp == TRAPDOOR) ? "plugs a trap door" + : (ttyp == HOLE) ? "plugs a hole" + : "fills a pit"); } else { Soundeffect(se_boulder_drop, 100); You_hear("a boulder %s.", verb); @@ -253,10 +255,13 @@ flooreffects(struct obj *obj, coordxy x, coordxy y, const char *verb) * || mondied) -> mondead -> m_detach -> fill_pit. */ deletedwithboulder: - if ((t = t_at(x, y)) != 0) - deltrap(t); - if (u.utrap && u_at(x, y)) - reset_utrap(FALSE); + /* creating a pit in ice results in that ice being turned into + floor so we shouldn't need any special ice handing here */ + if ((t = t_at(x, y)) != 0) { + (void) delfloortrap(t); + if (u.utrap && u_at(x, y)) + reset_utrap(FALSE); + } useupf(obj, 1L); bury_objs(x, y); newsym(x, y); @@ -2312,6 +2317,7 @@ revive_corpse(struct obj *corpse, boolean moldy) fill_pit(mtmp->mx, mtmp->my); break; } + FALLTHROUGH; /*FALLTHRU*/ default: /* we should be able to handle the other cases... */ diff --git a/src/do_name.c b/src/do_name.c index 40c0c57093..3faebb13d1 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -442,6 +442,7 @@ objtyp_is_callable(int i) determine which one was the real one */ if (i == AMULET_OF_YENDOR || i == FAKE_AMULET_OF_YENDOR) break; /* return FALSE */ + FALLTHROUGH; /*FALLTHRU*/ case SCROLL_CLASS: case POTION_CLASS: @@ -787,12 +788,12 @@ rndghostname(void) * x_monnam is the generic monster-naming function. * seen unseen detected named * mon_nam: the newt it the invisible orc Fido - * noit_mon_nam:the newt (as if detected) the invisible orc Fido + * noit_mon_nam:your newt (as if detected) your invisible orc Fido * some_mon_nam:the newt someone the invisible orc Fido * or something * l_monnam: newt it invisible orc dog called Fido * Monnam: The newt It The invisible orc Fido - * noit_Monnam: The newt (as if detected) The invisible orc Fido + * noit_Monnam: Your newt (as if detected) Your invisible orc Fido * Some_Monnam: The newt Someone The invisible orc Fido * or Something * Adjmonnam: The poor newt It The poor invisible orc The poor Fido @@ -1057,14 +1058,15 @@ mon_nam(struct monst *mtmp) (has_mgivenname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE); } -/* print the name as if mon_nam() was called, but assume that the player - * can always see the monster--used for probing and for monsters aggravating - * the player with a cursed potion of invisibility - */ +/* print the name as if mon_nam() (y_monnam() if tame) was called, but + assume that the player can always see the monster--used for probing and + for monsters aggravating the player with a cursed potion of invisibility; + also used for pet moving "reluctantly" onto cursed object when that pet + can be seen either before or after it moves */ char * noit_mon_nam(struct monst *mtmp) { - return x_monnam(mtmp, ARTICLE_THE, (char *) 0, + return x_monnam(mtmp, ARTICLE_YOUR, (char *) 0, (has_mgivenname(mtmp) ? (SUPPRESS_SADDLE | SUPPRESS_IT) : SUPPRESS_IT), FALSE); diff --git a/src/do_wear.c b/src/do_wear.c index 41408724ce..72115cd4c1 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -28,7 +28,6 @@ staticfn int Cloak_on(void); staticfn int Helmet_on(void); staticfn int Shield_on(void); staticfn int Shirt_on(void); - staticfn void learnring(struct obj *, boolean); staticfn void adjust_attrib(struct obj *, int, int); staticfn void Ring_off_or_gone(struct obj *, boolean); @@ -82,6 +81,15 @@ off_msg(struct obj *otmp) staticfn void on_msg(struct obj *otmp) { + /* on_msg() for rings and amulets just shows add-to-invent feedback + [after caller calls setworn(), for suffix: "(on {left|right} hand)" + or "(being worn)"]; eyewear too unless giving verbose message below */ + if ((otmp->owornmask & (W_RING | W_AMUL)) != 0L + || ((otmp->owornmask & W_TOOL) != 0L && !flags.verbose)) { + prinv((char *) NULL, otmp, 0L); + return; + } + if (flags.verbose) { char how[BUFSZ]; /* call xname() before obj_is_pname(); formatting obj's name @@ -536,7 +544,8 @@ Helmet_on(void) useup(uarmh); } /* makeknown(HELM_OF_OPPOSITE_ALIGNMENT); -- below, after Tobjnam() */ - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ case DUNCE_CAP: if (uarmh && !uarmh->cursed) { if (Blind) @@ -931,7 +940,7 @@ dragon_armor_handling( switch (otmp->otyp) { /* grey: no extra effect */ /* silver: no extra effect */ - + case BLACK_DRAGON_SCALE_MAIL: if (puton) { @@ -1128,16 +1137,13 @@ Armor_gone(void) } void -Amulet_on(void) +Amulet_on(struct obj *amul) { - /* make sure amulet isn't wielded; can't use remove_worn_item() - here because it has already been set worn in amulet slot */ - if (uamul == uwep) - setuwep((struct obj *) 0); - else if (uamul == uswapwep) - setuswapwep((struct obj *) 0); - else if (uamul == uquiver) - setuqwep((struct obj *) 0); + boolean on_msg_done = FALSE; + + /* make sure amulet isn't wielded/alt-wielded/quivered, before wearing */ + remove_worn_item(amul, FALSE); + setworn(amul, W_AMUL); switch (uamul->otyp) { case AMULET_OF_ESP: @@ -1155,8 +1161,10 @@ Amulet_on(void) was_in_poison_gas = region_danger(); EMagical_breathing |= W_AMUL; if (was_in_poison_gas) { - You("are no longer bothered by the poison gas."); makeknown(AMULET_OF_MAGICAL_BREATHING); + on_msg(uamul); + on_msg_done = TRUE; + You("are no longer bothered by the poison gas."); } /* no need to check for becoming able to breathe underwater; if we are underwater, we already can or we would have drowned */ @@ -1167,46 +1175,58 @@ Amulet_on(void) make_slimed(0L, (char *) 0); break; case AMULET_OF_CHANGE: { + boolean call_it = FALSE; int new_sex, orig_sex = poly_gender(); - if (Unchanging) - break; - change_sex(); + /* in normal play it's not possible to put on an amulet of change + while already wearing an amulet of unchanging, but in wizard + mode the Unchanging attribute can be set via #wizintrinsic */ + if (!Unchanging) + change_sex(); + new_sex = poly_gender(); + if (new_sex != orig_sex) + makeknown(AMULET_OF_CHANGE); + on_msg(uamul); /* show 'z - amulet of change (being worn)' */ + on_msg_done = TRUE; + /* Don't use same message as polymorph */ if (new_sex != orig_sex) { - makeknown(AMULET_OF_CHANGE); + newsym(u.ux, u.uy); /* glyphmon flag and tile have changed */ + disp.botl = TRUE; /* role name or rank title might have changed */ You("are suddenly very %s!", flags.female ? "feminine" : "masculine"); - disp.botl = TRUE; - newsym(u.ux, u.uy); /* glyphmon flag and tile may have gone - * from male to female or vice versa */ } else { /* already polymorphed into single-gender monster; only changed the character's base sex */ You("don't feel like yourself."); + /* checking dknown is redundant--amulets always have dknown set */ + call_it = (uamul->dknown != 0); } livelog_newform(FALSE, orig_sex, new_sex); pline_The("amulet disintegrates!"); - if (orig_sex == poly_gender() && uamul->dknown) + if (call_it) trycall(uamul); useup(uamul); break; } case AMULET_OF_STRANGULATION: - if (can_be_strangled(&gy.youmonst)) { + /* note: might already be Strangled (via #wizintrinsic) */ + if (can_be_strangled(&gy.youmonst) && !Strangled) { makeknown(AMULET_OF_STRANGULATION); Strangled = 6L; disp.botl = TRUE; + on_msg(uamul); + on_msg_done = TRUE; pline("It constricts your throat!"); } break; case AMULET_OF_RESTFUL_SLEEP: { - long newnap = (long) rnd(100), oldnap = (HSleepy & TIMEOUT); + long newnap = (long) rnd(98) + 2L, oldnap = (HSleepy & TIMEOUT); - /* avoid clobbering FROMOUTSIDE bit, which might have - gotten set by previously eating one of these amulets */ if (newnap < oldnap || oldnap == 0L) + /* avoid clobbering FROMOUTSIDE bit, which might have + gotten set by previously eating one of these amulets */ HSleepy = (HSleepy & ~TIMEOUT) | newnap; break; } @@ -1224,6 +1244,8 @@ Amulet_on(void) if (!already_flying) { makeknown(AMULET_OF_FLYING); + on_msg(uamul); + on_msg_done = TRUE; disp.botl = TRUE; /* status: 'Fly' On */ You("are now in flight."); } @@ -1237,19 +1259,28 @@ Amulet_on(void) case AMULET_OF_YENDOR: break; } + + if (!on_msg_done) + on_msg(uamul); } void Amulet_off(void) { + struct obj *amul = uamul; /* for off_msg() after setworn(NULL,W_AMUL) */ + boolean mkn = FALSE, early_off_msg = FALSE; + svc.context.takeoff.mask &= ~W_AMUL; switch (uamul->otyp) { case AMULET_OF_ESP: /* need to update ability before calling see_monsters() */ setworn((struct obj *) 0, W_AMUL); + off_msg(amul); + early_off_msg = TRUE; + see_monsters(); - return; + break; case AMULET_OF_LIFE_SAVING: case AMULET_VERSUS_POISON: case AMULET_OF_REFLECTION: @@ -1258,21 +1289,31 @@ Amulet_off(void) case FAKE_AMULET_OF_YENDOR: break; case AMULET_OF_MAGICAL_BREATHING: + /* amulet is currently still on; take it off before calling drown() + and region_danger(); call off_msg() before specific messages */ + setworn((struct obj *) 0, W_AMUL); + off_msg(amul); /* 'uamul' has been set to Null */ + early_off_msg = TRUE; + if (Underwater) { - /* HMagical_breathing must be set off before calling drown() */ - setworn((struct obj *) 0, W_AMUL); if (!cant_drown(gy.youmonst.data) && !Swimming) { You("suddenly inhale an unhealthy amount of %s!", hliquid("water")); + mkn = TRUE; /* in case of life-saving */ (void) drown(); } - return; } - /* - * FIXME: we need a poison gas region check here - */ + if (region_danger()) { + /* "breathing": wouldn't get here otherwise */ + You("are breathing poison gas!"); + mkn = TRUE; + } break; case AMULET_OF_STRANGULATION: + setworn((struct obj *) 0, W_AMUL); + off_msg(amul); + early_off_msg = TRUE; + if (Strangled) { Strangled = 0L; disp.botl = TRUE; @@ -1280,6 +1321,7 @@ Amulet_off(void) Your("%s is no longer constricted!", body_part(NECK)); else You("can breathe more easily!"); + mkn = TRUE; } break; case AMULET_OF_RESTFUL_SLEEP: @@ -1287,20 +1329,24 @@ Amulet_off(void) /* HSleepy = 0L; -- avoid clobbering FROMOUTSIDE bit */ if (!ESleepy && !(HSleepy & ~TIMEOUT)) HSleepy &= ~TIMEOUT; /* clear timeout bits */ - return; + break; case AMULET_OF_FLYING: { boolean was_flying = !!Flying; - /* remove amulet 'early' to determine whether Flying changes */ + /* remove amulet 'early' to determine whether Flying changes; + also in case spoteffects() does something with the amulet */ setworn((struct obj *) 0, W_AMUL); + off_msg(amul); + early_off_msg = TRUE; + float_vs_flight(); /* probably not needed here */ if (was_flying && !Flying) { - makeknown(AMULET_OF_FLYING); disp.botl = TRUE; /* status: 'Fly' Off */ You("%s.", (is_pool_or_lava(u.ux, u.uy) || Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) ? "stop flying" : "land"); + mkn = TRUE; /* makeknown(AMULET_OF_FLYING) */ spoteffects(TRUE); } break; @@ -1311,7 +1357,12 @@ Amulet_off(void) case AMULET_OF_YENDOR: break; } + setworn((struct obj *) 0, W_AMUL); + if (!early_off_msg) + off_msg(amul); /* (not 'uamul'; it's Null now) */ + if (mkn) + makeknown(amul->otyp); return; } @@ -1401,7 +1452,9 @@ Ring_on(struct obj *obj) case RIN_FREE_ACTION: case RIN_SLOW_DIGESTION: case RIN_SUSTAIN_ABILITY: + break; case MEAT_RING: + /* wearing a meat ring does not affect vegan conduct */ break; case RIN_CARRYING: /* with inventory weights available, this is trivial to identify if it's @@ -1597,10 +1650,11 @@ Ring_off_or_gone(struct obj *obj, boolean gone) find_ac(); /* updates botl */ break; case RIN_PROTECTION_FROM_SHAPE_CHAN: - /* If you're no longer protected, let the chameleons - * change shape again -dgk - */ - restartcham(); + /* if you're no longer protected, let the chameleons change + shape again; however, might still be protected if wearing + 2nd ring of this type (or via #wizintrinsic) */ + if (!Protection_from_shape_changers) + restartcham(); break; case RIN_SLEEPING: /* Copied from Amulet of Restful Sleep */ @@ -1634,8 +1688,7 @@ Blindf_on(struct obj *otmp) boolean already_blind = Blind, changed = FALSE; /* blindfold might be wielded; release it for wearing */ - if (otmp->owornmask & W_WEAPONS) - remove_worn_item(otmp, FALSE); + remove_worn_item(otmp, FALSE); setworn(otmp, W_TOOL); on_msg(otmp); @@ -1720,7 +1773,7 @@ set_wear( if (!obj ? uleft != 0 : (obj == uleft)) (void) Ring_on(uleft); if (!obj ? uamul != 0 : (obj == uamul)) - (void) Amulet_on(); + (void) Amulet_on(uamul); if (!obj ? uarmu != 0 : (obj == uarmu)) (void) Shirt_on(); @@ -1857,8 +1910,8 @@ cancel_don(void) /* called by steal() during theft from hero; interrupt donning/doffing */ int -stop_donning(struct obj *stolenobj) /* no message if stolenobj is already - being doffing */ +stop_donning( + struct obj *stolenobj) /* no mesg if stolenobj is already being doffed */ { char buf[BUFSZ]; struct obj *otmp; @@ -1902,8 +1955,9 @@ static NEARDATA int Narmorpieces, Naccessories; /* assign values to Narmorpieces and Naccessories */ staticfn void -count_worn_stuff(struct obj **which, /* caller wants this when count is 1 */ - boolean accessorizing) +count_worn_stuff( + struct obj **which, /* caller wants this when count is 1 */ + boolean accessorizing) { struct obj *otmp; @@ -1987,12 +2041,12 @@ armor_or_accessory_off(struct obj *obj) off_msg(obj); Ring_off(obj); } else if (obj == uamul) { - Amulet_off(); - off_msg(obj); + Amulet_off(); /* does its own off_msg */ } else if (obj == ublindf) { Blindf_off(obj); /* does its own off_msg */ } else { - impossible("removing strange accessory?"); + impossible("removing strange accessory: %s", + safe_typename(obj->otyp)); if (obj->owornmask) remove_worn_item(obj, FALSE); } @@ -2265,12 +2319,12 @@ canwearobj(struct obj *otmp, long *mask, boolean noisy) You("have no feet..."); /* not body_part(FOOT) */ err++; } else if (Upolyd && gy.youmonst.data->mlet == S_CENTAUR) { - /* break_armor() pushes boots off for centaurs, - so don't let dowear() put them back on... */ + /* break_armor() pushes boots off for centaurs, so don't let + dowear() put them back on; + makeplural(body_part(FOOT)) would yield "rear hooves" here, + which sounds odd, so use hard-coded "hooves" */ if (noisy) - You("have too many hooves to wear %s.", - c_boots); /* makeplural(body_part(FOOT)) yields - "rear hooves" which sounds odd */ + You("have too many hooves to wear %s.", c_boots); err++; } else if (GreasedFeet || GreasedBoots) { /* prevent slippery feet from transferring to booted feet */ @@ -2372,7 +2426,7 @@ staticfn int accessory_or_armor_on(struct obj *obj) { long mask = 0L; - boolean armor, ring, eyewear; + boolean armor, ring, amulet, eyewear; if (obj->owornmask & (W_ACCESSORY | W_ARMOR)) { already_wearing(c_that_); @@ -2380,6 +2434,7 @@ accessory_or_armor_on(struct obj *obj) } armor = (obj->oclass == ARMOR_CLASS); ring = (obj->oclass == RING_CLASS || obj->otyp == MEAT_RING); + amulet = (obj->oclass == AMULET_CLASS); eyewear = (obj->otyp == BLINDFOLD || obj->otyp == LENSES); /* checks which are performed prior to actually touching the item */ if (armor) { @@ -2476,7 +2531,7 @@ accessory_or_armor_on(struct obj *obj) return res ? ECMD_TIME : ECMD_OK; } } - } else if (obj->oclass == AMULET_CLASS) { + } else if (amulet) { if (uamul) { already_wearing("an amulet"); return ECMD_OK; @@ -2560,26 +2615,24 @@ accessory_or_armor_on(struct obj *obj) } svc.context.takeoff.mask = svc.context.takeoff.what = 0L; } else { /* not armor */ - boolean give_feedback = FALSE; - - /* [releasing wielded accessory handled in Xxx_on()] */ if (ring) { + /* Ring_on() expects ring to already be worn as uleft or uright */ setworn(obj, mask); Ring_on(obj); - give_feedback = TRUE; - } else if (obj->oclass == AMULET_CLASS) { - setworn(obj, W_AMUL); - Amulet_on(); - /* no feedback here if amulet of change got used up */ - give_feedback = (uamul != 0); + /* is_worn(): 'obj' will always be worn here except when putting + on a ring of levitation while at a sink location */ + if (is_worn(obj)) + on_msg(obj); + } else if (amulet) { + /* setworn() and on_msg() handled by Amulet_on() */ + Amulet_on(obj); } else if (eyewear) { - /* setworn() handled by Blindf_on() */ + /* setworn() and on_msg() handled by Blindf_on() */ Blindf_on(obj); - /* message handled by Blindf_on(); leave give_feedback False */ + } else { + impossible("putting on unexpected type of accessory: %s", + safe_typename(obj->otyp)); } - /* feedback for ring or for amulet other than 'change' */ - if (give_feedback && is_worn(obj)) - prinv((char *) 0, obj, 0L); } return ECMD_TIME; } diff --git a/src/dog.c b/src/dog.c index f27e1db9b7..d7f9e064de 100644 --- a/src/dog.c +++ b/src/dog.c @@ -452,6 +452,12 @@ mon_arrive(struct monst *mtmp, int when) fromdlev.dnum = mtmp->mtrack[2].x; fromdlev.dlevel = mtmp->mtrack[2].y; mon_track_clear(mtmp); + /* in case Protection_from_shape_changers is different now from when + 'mtmp' went onto the migrating monsters list; that's handled in + getlev() when returning to a previously visited level and by the + special level code for monsters specified in the level, but needed + here for monsters migrating to a newly created level */ + restore_cham(mtmp); if (mtmp == u.usteed) return; /* don't place steed on the map */ @@ -552,7 +558,9 @@ mon_arrive(struct monst *mtmp, int when) } else if (!(u.uevent.qexpelled && (Is_qstart(&u.uz0) || Is_qstart(&u.uz)))) { impossible("mon_arrive: no corresponding portal?"); - } /*FALLTHRU*/ + } + FALLTHROUGH; + /*FALLTHRU*/ default: case MIGR_RANDOM: xlocale = ylocale = 0; @@ -1170,6 +1178,9 @@ dogfood(struct monst *mon, struct obj *obj) && obj->oclass != BALL_CLASS && obj->oclass != CHAIN_CLASS) return APPORT; + FALLTHROUGH; + /*FALLTHRU*/ + case ROCK_CLASS: return UNDEF; } } @@ -1313,6 +1324,8 @@ tamedog(struct monst *mtmp, struct obj *obj, boolean givemsg) Hallucination ? "approachable" : "friendly"); newsym(mtmp->mx, mtmp->my); + if (mtmp->wormno) + redraw_worm(mtmp); if (attacktype(mtmp->data, AT_WEAP)) { mtmp->weapon_check = NEED_HTH_WEAPON; (void) mon_wield_item(mtmp); @@ -1421,8 +1434,12 @@ abuse_dog(struct monst *mtmp) else growl(mtmp); /* give them a moment's worry */ - if (!mtmp->mtame) + if (!mtmp->mtame) { newsym(mtmp->mx, mtmp->my); + if (mtmp->wormno) { + redraw_worm(mtmp); + } + } } } diff --git a/src/dogmove.c b/src/dogmove.c index 5ffca3f0cf..37477ae662 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -90,6 +90,7 @@ droppables(struct monst *mon) if (pickaxe && pickaxe->otyp == PICK_AXE && pickaxe != wep && (!pickaxe->oartifact || obj->oartifact)) return pickaxe; /* drop the one we earlier decided to keep */ + FALLTHROUGH; /*FALLTHRU*/ case PICK_AXE: if (!pickaxe || (obj->oartifact && !pickaxe->oartifact)) { @@ -118,12 +119,14 @@ droppables(struct monst *mon) if (key && key->otyp == LOCK_PICK && (!key->oartifact || obj->oartifact)) return key; /* drop the one we earlier decided to keep */ + FALLTHROUGH; /*FALLTHRU*/ case LOCK_PICK: /* keep lock-pick in preference to credit card */ if (key && key->otyp == CREDIT_CARD && (!key->oartifact || obj->oartifact)) return key; + FALLTHROUGH; /*FALLTHRU*/ case CREDIT_CARD: if (!key || (obj->oartifact && !key->oartifact)) { diff --git a/src/dokick.c b/src/dokick.c index 49e92c6d30..6a18fc2996 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1504,6 +1504,7 @@ dokick(void) pline("%s burps loudly.", Monnam(u.ustuck)); break; } + FALLTHROUGH; /*FALLTHRU*/ default: Your("feeble kick has no effect."); @@ -1657,6 +1658,7 @@ drop_to(coord *cc, schar loc, coordxy x, coordxy y) cc->y = cc->x = 0; break; } + FALLTHROUGH; /*FALLTHRU*/ case MIGR_STAIRS_UP: case MIGR_LADDER_UP: @@ -1973,6 +1975,7 @@ obj_delivery(boolean near_hero) switch (where) { case MIGR_LADDER_UP: isladder = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case MIGR_STAIRS_UP: case MIGR_SSTAIRS: diff --git a/src/dothrow.c b/src/dothrow.c index 56137fb349..7c657d750a 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -68,6 +68,7 @@ multishot_class_bonus( case PM_NINJA: if (skill == -P_SHURIKEN || skill == -P_DART) multishot++; + FALLTHROUGH; /*FALLTHRU*/ case PM_SAMURAI: /* role-specific launcher and its ammo */ @@ -180,6 +181,7 @@ throw_obj(struct obj *obj, int shotlimit) switch (P_SKILL(weapon_type(obj))) { case P_EXPERT: multishot++; + FALLTHROUGH; /*FALLTHRU*/ case P_SKILLED: if (!weakmultishot) @@ -687,14 +689,15 @@ walk_path( if (dx < 0) { x_change = -1; dx = -dx; - } else + } else { x_change = 1; + } if (dy < 0) { y_change = -1; dy = -dy; - } else + } else { y_change = 1; - + } i = err = 0; if (dx < dy) { while (i++ < dy) { @@ -778,7 +781,8 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y) struct monst *mon; boolean may_pass = TRUE, via_jumping, stopping_short; struct trap *ttmp; - int dmg = 0; + struct rm *lev; + int ltyp, dmg = 0; if (!isok(x, y)) { You_feel("the spirits holding you back."); @@ -790,69 +794,52 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y) } via_jumping = (EWwalking & I_SPECIAL) != 0L; stopping_short = (via_jumping && *range < 2); + lev = &levl[x][y]; + ltyp = lev->typ; if (!Passes_walls || !(may_pass = may_passwall(x, y))) { - boolean odoor_diag = (IS_DOOR(levl[x][y].typ) - && (levl[x][y].doormask & D_ISOPEN) - && (u.ux - x) && (u.uy - y)); - - if (IS_OBSTRUCTED(levl[x][y].typ) || closed_door(x, y) || odoor_diag) { - const char *s; - + const char *why = NULL; + boolean diagonal = (u.ux - x) != 0 && (u.uy - y) != 0, + open_door = IS_DOOR(ltyp) && (lev->doormask & D_ISOPEN) != 0, + odoor_diag = open_door && diagonal; + + if (IS_OBSTRUCTED(levl[x][y].typ) + || closed_door(x, y) || odoor_diag) { + why = IS_TREE(ltyp) ? "bumping into a tree" + : IS_OBSTRUCTED(ltyp) ? "bumping into a wall" + : odoor_diag ? "bumping into a door frame" + : "bumping into a closed door"; if (odoor_diag) - You("hit the door edge!"); + You("hit the door frame!"); pline("Ouch!"); - if (IS_TREE(levl[x][y].typ)) - s = "bumping into a tree"; - else if (IS_OBSTRUCTED(levl[x][y].typ)) - s = "bumping into a wall"; - else - s = "bumping into a door"; - dmg = rnd(2 + *range); - losehp(Maybe_Half_Phys(dmg), s, KILLED_BY); - wake_nearto(x,y, 10); - return FALSE; - } - if (levl[x][y].typ == IRONBARS) { + } else if (ltyp == IRONBARS) { + why = "crashing into iron bars"; You("crash into some iron bars. Ouch!"); - dmg = rnd(2 + *range); - losehp(Maybe_Half_Phys(dmg), "crashing into iron bars", - KILLED_BY); - wake_nearto(x,y, 20); - return FALSE; - } - if ((obj = sobj_at(BOULDER, x, y)) != 0) { + } else if ((obj = sobj_at(BOULDER, x, y)) != 0) { + why = "bumping into a boulder"; You("bump into a %s. Ouch!", xname(obj)); - dmg = rnd(2 + *range); - losehp(Maybe_Half_Phys(dmg), "bumping into a boulder", KILLED_BY); - wake_nearto(x,y, 10); - return FALSE; - } - if (!may_pass) { + } else if (!may_pass) { /* did we hit a no-dig non-wall position? */ + why = "touching the edge of the universe"; You("smack into something!"); - dmg = rnd(2 + *range); - losehp(Maybe_Half_Phys(dmg), "touching the edge of the universe", - KILLED_BY); - wake_nearto(x,y, 10); - return FALSE; - } - if ((u.ux - x) && (u.uy - y) && bad_rock(gy.youmonst.data, u.ux, y) - && bad_rock(gy.youmonst.data, x, u.uy)) { + } else if (diagonal + && bad_rock(gy.youmonst.data, u.ux, y) + && bad_rock(gy.youmonst.data, x, u.uy)) { boolean too_much = (gi.invent && (inv_weight() + weight_cap() > 600)); - /* Move at a diagonal. */ if (bigmonst(gy.youmonst.data) || too_much) { + why = "wedging into a narrow crevice"; You("%sget forcefully wedged into a crevice.", too_much ? "and all your belongings " : ""); - dmg = rnd(2 + *range); - losehp(Maybe_Half_Phys(dmg), "wedging into a narrow crevice", - KILLED_BY); - wake_nearto(x,y, 10); - return FALSE; } } + if (why) { + dmg = rnd(2 + *range); + losehp(Maybe_Half_Phys(dmg), why, KILLED_BY); + wake_nearto(x, y, 10); + return FALSE; + } } if ((mon = m_at(x, y)) != 0 @@ -929,7 +916,7 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y) /* if terrain type changes, levitation or flying might become blocked or unblocked; might issue message, so do this after map+vision has been updated for new location instead of right after u_on_newpos() */ - if (levl[u.ux][u.uy].typ != levl[ox][oy].typ) + if (ltyp != levl[ox][oy].typ) switch_terrain(); /* might be entering a special room (treasure zoo, thrown room, &c) that @@ -968,8 +955,7 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y) dotrap(ttmp, NO_TRAP_FLAGS); /* doesn't print messages */ } else if (ttmp->ttyp == FIRE_TRAP || ttmp->ttyp == COLD_TRAP) { dotrap(ttmp, NO_TRAP_FLAGS); - } else if ((is_pit(ttmp->ttyp) || is_hole(ttmp->ttyp)) - && Sokoban) { + } else if ((is_pit(ttmp->ttyp) || is_hole(ttmp->ttyp)) && Sokoban) { /* air currents overcome the recoil in Sokoban; when jumping, caller performs last step and enters trap */ if (!via_jumping) @@ -1325,6 +1311,7 @@ toss_up(struct obj *obj, boolean hitsroof) Your("%s fails to protect you.", helm_simple_name(uarmh)); goto petrify; } + FALLTHROUGH; /*FALLTHRU*/ case CREAM_PIE: case BLINDING_VENOM: @@ -2806,12 +2793,14 @@ breakmsg(struct obj *obj, boolean in_view) default: /* glass or crystal wand */ if (obj->oclass != WAND_CLASS) impossible("breaking odd object (%d)?", obj->otyp); + FALLTHROUGH; /*FALLTHRU*/ case LENSES: case MIRROR: case CRYSTAL_BALL: case EXPENSIVE_CAMERA: to_pieces = " into a thousand pieces"; + FALLTHROUGH; /*FALLTHRU*/ case POT_WATER: /* really, all potions */ if (!in_view) diff --git a/src/dungeon.c b/src/dungeon.c index 032013eb80..613fa2cc95 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -3006,6 +3006,7 @@ count_feat_lastseentyp( } if (is_drawbridge_wall(x, y) < 0) break; + FALLTHROUGH; /*FALLTHRU*/ case DBWALL: case DRAWBRIDGE_DOWN: diff --git a/src/eat.c b/src/eat.c index 12031c1b2e..dc7cfc8a56 100644 --- a/src/eat.c +++ b/src/eat.c @@ -22,6 +22,7 @@ staticfn void cprefx(int); staticfn void givit(int, struct permonst *); staticfn void eye_of_newt_buzz(void); staticfn void cpostfx(int); +staticfn void use_up_tin(struct obj *) NONNULLARG1; staticfn void consume_tin(const char *); staticfn void start_tin(struct obj *); staticfn int eatcorpse(struct obj *); @@ -830,6 +831,10 @@ cprefx(int pm) if (!Stone_resistance && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { + /* if food was a tin, use it up early to keep it out of bones */ + if (svc.context.tin.tin) + use_up_tin(svc.context.tin.tin); + Sprintf(svk.killer.name, "tasting %s meat", mons[pm].pmnames[NEUTRAL]); svk.killer.format = KILLED_BY; @@ -885,6 +890,7 @@ cprefx(int pm) make_slimed(10L, (char *) 0); delayed_killer(SLIMED, KILLED_BY_AN, ""); } + FALLTHROUGH; /* Fall through */ default: if (acidic(&mons[pm]) && Stoned) @@ -1292,10 +1298,12 @@ cpostfx(int pm) } newsym(u.ux, u.uy); } + FALLTHROUGH; /*FALLTHRU*/ case PM_YELLOW_LIGHT: case PM_GIANT_BAT: make_stunned((HStun & TIMEOUT) + 30L, FALSE); + FALLTHROUGH; /*FALLTHRU*/ case PM_BAT: make_stunned((HStun & TIMEOUT) + 30L, FALSE); @@ -1305,12 +1313,15 @@ cpostfx(int pm) break; case PM_GIANT_MIMIC: tmp += 10; + FALLTHROUGH; /*FALLTHRU*/ case PM_LARGE_MIMIC: tmp += 20; + FALLTHROUGH; /*FALLTHRU*/ case PM_KILLER_MIMIC: tmp += 20; + FALLTHROUGH; /*FALLTHRU*/ case PM_SMALL_MIMIC: tmp += 20; @@ -1371,6 +1382,14 @@ cpostfx(int pm) if (Unchanging) { You_feel("momentarily different."); /* same as poly trap */ } else { + /* polyself() is potentially fatal; if food is a tin, use it up + early to keep it out of bones */ + if (svc.context.tin.tin) { + use_up_tin(svc.context.tin.tin); + /* most tin effects end up being skipped */ + lesshungry(200 + (metallivorous(gy.youmonst.data) ? 5 : 0)); + } + You("%s.", (pm == PM_GENETIC_ENGINEER) ? "undergo a freakish metamorphosis" : "feel a change coming over you"); @@ -1409,7 +1428,8 @@ cpostfx(int pm) } else { pline("For some reason, that tasted bland."); } - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ default: check_intrinsics = TRUE; break; @@ -1642,18 +1662,34 @@ tin_variety( return r; } +/* finish consume_tin(); also potentially used by cprefx() and cpostfx() */ +staticfn void +use_up_tin(struct obj *tin) +{ + if (carried(tin)) + useup(tin); + else + useupf(tin, 1L); + /* reset tin context */ + svc.context.tin.tin = (struct obj *) NULL; + svc.context.tin.o_id = 0; +} + staticfn void consume_tin(const char *mesg) { const char *what; - int which, mnum, r; + int which, mnum, r, nutamt; + /* if you've eaten tin itself, chance to not eat contents gets bypassed */ + boolean always_eat = metallivorous(gy.youmonst.data); struct obj *tin = svc.context.tin.tin; r = tin_variety(tin, FALSE); if (tin->otrapped || (tin->cursed && r != HOMEMADE_TIN && !rn2(8))) { b_trapped("tin", NO_PART); tin = costly_tin(COST_DSTROY); - goto use_up_tin; + use_up_tin(tin); + return; } pline1(mesg); /* "You succeed in opening the tin." */ @@ -1664,7 +1700,10 @@ consume_tin(const char *mesg) pline("It turns out to be empty."); tin->dknown = tin->known = 1; tin = costly_tin(COST_OPEN); - goto use_up_tin; + use_up_tin(tin); + if (always_eat) + lesshungry(5); /* metallivorous hero ate the tin itself */ + return; } which = 0; /* 0=>plural, 1=>as-is, 2=>"the" prefix */ @@ -1687,14 +1726,17 @@ consume_tin(const char *mesg) else if (which == 2) what = the(what); - pline("It smells like %s.", what); - if (y_n("Eat it?") == 'n') { - if (flags.verbose) - You("discard the open tin."); - if (!Hallucination) - tin->dknown = tin->known = 1; - tin = costly_tin(COST_OPEN); - goto use_up_tin; + if (!always_eat) { + pline("It smells like %s.", what); + if (y_n("Eat it?") == 'n') { + if (flags.verbose) + You("discard the open tin."); + if (!Hallucination) + tin->dknown = tin->known = 1; + tin = costly_tin(COST_OPEN); + use_up_tin(tin); + return; + } } /* in case stop_occupation() was called on previous meal */ @@ -1705,31 +1747,44 @@ consume_tin(const char *mesg) eating_conducts(&mons[mnum]); tin->dknown = tin->known = 1; - cprefx(mnum); - cpostfx(mnum); - /* charge for one at pre-eating cost */ - tin = costly_tin(COST_OPEN); + tin = svc.context.tin.tin = costly_tin(COST_OPEN); + + /* cprefx() or cpostfx() might use up tin to keep it out of bones */ + cprefx(mnum); + if (svc.context.tin.tin) + cpostfx(mnum); + if (!svc.context.tin.tin) + return; if (tintxts[r].nut < 0) { /* rotten */ make_vomiting((long) rn1(15, 10), FALSE); } else { - int nutamt = tintxts[r].nut; - + nutamt = tintxts[r].nut; /* nutrition from a homemade tin (made from a single corpse) shouldn't be more than nutrition from the corresponding corpse; other tinning modes might use more than one corpse or add extra ingredients so aren't similarly restricted */ if (r == HOMEMADE_TIN && nutamt > mons[mnum].cnutrit) nutamt = mons[mnum].cnutrit; + if (always_eat) + nutamt += 5; /* metallivorous hero ate the tin itself */ + /* use up tin now; lesshungry() could be fatal and produce bones */ + use_up_tin(tin), tin = NULL; lesshungry(nutamt); } if (tintxts[r].greasy) { - /* Assume !Glib, because you can't open tins when Glib. */ - make_glib(rn1(11, 5)); /* 5..15 */ - pline("Eating %s food made your %s very slippery.", - tintxts[r].txt, fingers_or_gloves(TRUE)); + /* normal hero is !Glib, because you can't open tins when Glib, + but one poly'd into metallivorous form might already be Glib; + it's debatable whether a rock mole should have its paws made + slippery when eating a greasy tin, but we'll go with that... */ + int alreadyglib = (int) (Glib & TIMEOUT); + + make_glib(alreadyglib + rn1(11, 5)); /* 5..15 */ + pline("Eating %s food made your %s %s slippery.", + tintxts[r].txt, fingers_or_gloves(TRUE), + alreadyglib ? "even more" : "very"); } } else { /* spinach... */ @@ -1741,11 +1796,12 @@ consume_tin(const char *mesg) tin->dknown = tin->known = 1; } - if (y_n("Eat it?") == 'n') { + if (!always_eat && y_n("Eat it?") == 'n') { if (flags.verbose) You("discard the open tin."); tin = costly_tin(COST_OPEN); - goto use_up_tin; + use_up_tin(tin); + return; } /* @@ -1769,19 +1825,19 @@ consume_tin(const char *mesg) : (flags.female ? "Olive Oyl" : "Bluto")); gainstr(tin, 0, FALSE); - tin = costly_tin(COST_OPEN); - lesshungry(tin->blessed ? 600 /* blessed */ - : !tin->cursed ? (400 + rnd(200)) /* uncursed */ - : (200 + rnd(400))); /* cursed */ + tin = svc.context.tin.tin = costly_tin(COST_OPEN); + nutamt = (tin->blessed ? 600 /* blessed */ + : !tin->cursed ? (400 + rnd(200)) /* uncursed */ + : (200 + rnd(400))); /* cursed */ + if (always_eat) + nutamt += 5; /* metallivorous hero also eats the tin itself */ + /* use up tin first; lesshungry() could be fatal and produce bones */ + use_up_tin(tin), tin = NULL; + lesshungry(nutamt); } - - use_up_tin: - if (carried(tin)) - useup(tin); - else - useupf(tin, 1L); - svc.context.tin.tin = (struct obj *) 0; - svc.context.tin.o_id = 0; + if (tin) + use_up_tin(tin); + return; } /* called during each move whilst opening a tin */ @@ -2263,7 +2319,7 @@ fprefx(struct obj *otmp) } else if (maybe_polyd(is_dwarf(gy.youmonst.data), Race_if(PM_DWARF))) { pline("Hrm... cram."); break; - } + } #if 0 /* No hobbit race yet */ else if (maybe_polyd(is_hobbit(gy.youmonst.data), Race_if(PM_HOBBIT))) { pline("You'd prefer a bit of plain bread and a mug of ale, but this will do."); @@ -2285,6 +2341,7 @@ fprefx(struct obj *otmp) break; } iter_mons(garlic_breath); + FALLTHROUGH; /*FALLTHRU*/ default: if (otmp->otyp == SLIME_MOLD && !otmp->cursed diff --git a/src/engrave.c b/src/engrave.c index dee04f980d..b4988a0055 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -706,6 +706,7 @@ doengrave_sfx_item_WAN(struct _doengrave_ctx *de) de->postknown = TRUE; if (!de->oep || (de->oep->engr_type != BURN)) break; + FALLTHROUGH; /*FALLTHRU*/ case WAN_CANCELLATION: case WAN_MAKE_INVISIBLE: @@ -830,6 +831,7 @@ doengrave_sfx_item(struct _doengrave_ctx *de) de->type = DUST; break; } + FALLTHROUGH; /*FALLTHRU*/ /* Objects too large to engrave with */ case BALL_CLASS: diff --git a/src/fountain.c b/src/fountain.c index 3da8a2b97c..b6c1af7310 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -839,6 +839,7 @@ drinkfountain(void) dofindgem(); break; } + FALLTHROUGH; /*FALLTHRU*/ case 28: /* Water Nymph */ dowaternymph(); @@ -978,6 +979,7 @@ dipfountain(struct obj *obj) dofindgem(); break; } + FALLTHROUGH; /*FALLTHRU*/ case 25: /* Water gushes forth */ dogushforth(FALSE); @@ -1260,6 +1262,7 @@ drinksink(void) pline("From the murky drain, a hand reaches up... --oops--"); break; } + FALLTHROUGH; /*FALLTHRU*/ default: You("take a sip of %s %s.", @@ -1331,6 +1334,7 @@ dipsink(struct obj *obj) try_call = TRUE; break; } + FALLTHROUGH; /* FALLTHRU */ case POT_GAIN_LEVEL: case POT_GAIN_ENERGY: diff --git a/src/getpos.c b/src/getpos.c index 0152fba53b..36e9d95ea2 100644 --- a/src/getpos.c +++ b/src/getpos.c @@ -465,6 +465,7 @@ gather_locs_interesting(coordxy x, coordxy y, int gloc) case GLOC_VALID: if (getpos_getvalid) return (*getpos_getvalid)(x, y); + FALLTHROUGH; /*FALLTHRU*/ case GLOC_INTERESTING: return (gather_locs_interesting(x, y, GLOC_DOOR) diff --git a/src/hack.c b/src/hack.c index 0163ef1f3d..ae2d30ac4c 100644 --- a/src/hack.c +++ b/src/hack.c @@ -575,6 +575,7 @@ moverock_core(coordxy sx, coordxy sy) dopush(sx, sy, rx, ry, otmp, costly); continue; } + FALLTHROUGH; /*FALLTHRU*/ case TELEP_TRAP: rock_disappear_msg(otmp); @@ -1799,9 +1800,14 @@ u_locomotion(const char *def) { boolean capitalize = (*def == highc(*def)); + /* regular locomotion() takes a monster type rather than a specific + monster, so can't tell whether it is operating on hero; + its is_flyer() and is_floater() tests wouldn't work on hero except + when hero is polymorphed and not wearing an amulet of flying + or boots/ring/spell of levitation */ return Levitation ? (capitalize ? "Float" : "float") - : Flying ? (capitalize ? "Fly" : "fly") - : locomotion(gy.youmonst.data, def); + : Flying ? (capitalize ? "Fly" : "fly") + : locomotion(gy.youmonst.data, def); } /* Return a simplified floor solid/liquid state based on hero's state */ @@ -1863,10 +1869,9 @@ staticfn boolean swim_move_danger(coordxy x, coordxy y) { schar newtyp = u_simple_floortyp(x, y); - boolean liquid_wall = IS_WATERWALL(newtyp) - || newtyp == LAVAWALL; + boolean liquid_wall = IS_WATERWALL(newtyp) || newtyp == LAVAWALL; boolean dangerous_puddle = is_puddle(x, y) && tiny_groundedmon(gy.youmonst.data); - if (Underwater && (is_pool(x, y) || IS_WATERWALL(newtyp))) + if (Underwater && (is_pool(x,y) || IS_WATERWALL(newtyp))) return FALSE; if ((newtyp != u_simple_floortyp(u.ux, u.uy)) @@ -2610,6 +2615,7 @@ escape_from_sticky_mon(coordxy x, coordxy y) u.ustuck->mfrozen = 1; u.ustuck->msleeping = 0; } + FALLTHROUGH; /*FALLTHRU*/ default: if (u.ustuck->mtame && !Conflict && !u.ustuck->mconf) @@ -2776,7 +2782,7 @@ domove_core(void) char qbuf[QBUFSZ]; Snprintf(qbuf, sizeof qbuf, "%s into that %s cloud?", - locomotion(gy.youmonst.data, "step"), + u_locomotion("step"), (reg_damg(newreg) > 0) ? "poison gas" : "vapor"); if (!paranoid_query(ParanoidConfirm, upstart(qbuf))) { nomul(0); @@ -3190,8 +3196,8 @@ pooleffects( } /* check for entering water or lava */ - if (!u.ustuck && !Levitation && !Flying && - (is_pool_or_lava(u.ux, u.uy) + if (!u.ustuck && !Levitation && !Flying && + (is_pool_or_lava(u.ux, u.uy) || (shallow_water && tiny_groundedmon(gy.youmonst.data)))) { if (u.usteed && !grounded(u.usteed->data)) { /* floating or clinging steed keeps hero safe (is_flyer() test @@ -3251,7 +3257,7 @@ pooleffects( } if (verysmall(gy.youmonst.data)) water_damage_chain(gi.invent, FALSE); - + if (!u.usteed) { /* Only dryup puddle if something was damaged. */ if (!rn2(3) && water_damage(uarmf, "boots", TRUE)) @@ -3703,7 +3709,8 @@ check_special_room(boolean newlev) break; case TEMPLE: intemple(roomno + ROOMOFFSET); - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ default: msg_given = (rt == TEMPLE || rt >= SHOPBASE); rt = 0; @@ -4597,6 +4604,7 @@ spot_checks(coordxy x, coordxy y, schar old_typ) switch (old_typ) { case DRAWBRIDGE_UP: db_ice_now = ((levl[x][y].drawbridgemask & DB_UNDER) == DB_ICE); + FALLTHROUGH; /*FALLTHRU*/ case ICE: if ((new_typ != old_typ) diff --git a/src/insight.c b/src/insight.c index 8425933a68..e230cafc6e 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1675,6 +1675,9 @@ attributes_enlightenment( /*** Vision and senses ***/ if ((HBlinded || EBlinded) && BBlinded) /* blind w/ blindness blocked */ you_can("see", from_what(-BLINDED)); /* Eyes of the Overworld */ + if (Blnd_resist && !Blind) /* skip if no eyes or blindfolded */ + you_are("not subject to light-induced blindness", + from_what(BLND_RES)); if (See_invisible) { if (!Blind) enl_msg(You_, "see", "saw", " invisible", from_what(SEE_INVIS)); @@ -2148,6 +2151,8 @@ attributes_enlightenment( switch (u.umortality) { case 0: impossible("dead without dying?"); + FALLTHROUGH; + /* FALLTHRU */ case 1: break; /* just "are dead" */ default: @@ -2825,6 +2830,7 @@ vanqsort_cmp( res = uniq2 - uniq1; break; } /* else both unique or neither unique */ + FALLTHROUGH; /*FALLTHRU*/ case VANQ_ALPHA_MIX: name1 = mons[indx1].pmnames[NEUTRAL]; @@ -3579,7 +3585,7 @@ mstatusline(struct monst *mtmp) /* avoid "Status of the invisible newt ..., invisible" */ /* and unlike a normal mon_nam, use "saddled" even if it has a name */ - Strcpy(monnambuf, x_monnam(mtmp, ARTICLE_THE, (char *) 0, + Strcpy(monnambuf, x_monnam(mtmp, ARTICLE_YOUR, (char *) 0, (SUPPRESS_IT | SUPPRESS_INVISIBLE), FALSE)); pline("Status of %s (%s, %s): Level %d HP %d(%d) AC %d%s.", diff --git a/src/invent.c b/src/invent.c index ea478d1c2c..c1b2f8bc67 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2477,6 +2477,7 @@ askchain( switch (sym) { case 'a': allflag = 1; + FALLTHROUGH; /*FALLTHRU*/ case 'y': tmp = (*fn)(otmp); @@ -2495,10 +2496,13 @@ askchain( cnt += tmp; if (--mx == 0) goto ret; + FALLTHROUGH; /*FALLTHRU*/ case 'n': if (nodot) dud++; + FALLTHROUGH; + /*FALLTHRU*/ default: break; case 'q': @@ -3012,6 +3016,7 @@ itemactions_pushkeys(struct obj *otmp, int act) switch (act) { default: impossible("Unknown item action"); + break; case IA_NONE: break; case IA_UNWIELD: diff --git a/src/makemon.c b/src/makemon.c index 7f6d30b46a..116f21bfb0 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -376,26 +376,24 @@ m_initweap(struct monst *mtmp) case S_ANGEL: if (humanoid(ptr)) { - /* create minion stuff; can't use mongets; - weapon: long sword [rn2(5) > 1 == 60%] or mace [40%] */ - otmp = mksobj((rn2(5) > 1) ? LONG_SWORD : MACE, FALSE, FALSE); + /* create minion stuff; bypass mongets */ + int typ = rn2(3) ? LONG_SWORD : MACE; + const char *nam = (typ == LONG_SWORD) ? "Sunsword" : "Demonbane"; + + otmp = mksobj(typ, FALSE, FALSE); /* maybe promote weapon to an artifact */ if ((!rn2(20) || is_lord(ptr)) && sgn(mtmp->isminion ? EMIN(mtmp)->min_align - : ptr->maligntyp) == A_LAWFUL) { - /* Sunsword and Demonbane both used to be long swords and - Angels always got a long sword, so might get either of - the two artifacts; Demonbane has been changed to be a - mace; this deliberately makes an independent choice of - which artifact and if it picks the wrong name for 'otmp's - type, then 'otmp' won't be upgraded into an artifact */ - otmp = oname(otmp, artiname((rn2(5) > 1) ? ART_SUNSWORD - : ART_DEMONBANE), - ONAME_RANDOM); /* randomly created */ - } + : ptr->maligntyp) == A_LAWFUL) + otmp = oname(otmp, nam, ONAME_RANDOM); /* randomly created */ + /* enhance the weapon */ bless(otmp); otmp->oerodeproof = TRUE; - otmp->spe = rn2(4) + rnd(5); + /* make long sword be +0 to +3, mace be +3 to +6 to compensate + for being significantly weaker against large opponents */ + otmp->spe = rn2(4); + if (typ == MACE) + otmp->spe += 3; (void) mpickobj(mtmp, otmp); otmp = mksobj(!rn2(4) || is_lord(ptr) ? SHIELD_OF_REFLECTION @@ -642,6 +640,7 @@ m_initweap(struct monst *mtmp) */ if (!is_demon(ptr)) break; + FALLTHROUGH; /*FALLTHRU*/ default: catchgnomes: @@ -826,12 +825,15 @@ m_initinv(struct monst *mtmp) /* MAJOR fall through ... */ case 0: (void) mongets(mtmp, WAN_MAGIC_MISSILE); + FALLTHROUGH; /*FALLTHRU*/ case 1: (void) mongets(mtmp, POT_EXTRA_HEALING); + FALLTHROUGH; /*FALLTHRU*/ case 2: (void) mongets(mtmp, POT_HEALING); + FALLTHROUGH; /*FALLTHRU*/ case 3: (void) mongets(mtmp, WAN_SLEEP); @@ -839,20 +841,23 @@ m_initinv(struct monst *mtmp) /* MAJOR fall through ... */ switch (rnd(4)) { - case 1: + case 1: (void) mongets(mtmp, POT_REFLECTION); + FALLTHROUGH; /*FALLTHRU*/ - case 2: + case 2: (void) mongets(mtmp, POT_EXTRA_HEALING); + FALLTHROUGH; /*FALLTHRU*/ - case 3: + case 3: (void) mongets(mtmp, SCR_TELEPORTATION); + FALLTHROUGH; /*FALLTHRU*/ - case 4: + case 4: (void) mongets(mtmp, WAN_TELEPORTATION); + FALLTHROUGH; /*FALLTHRU*/ - } - + } } else if (ptr->msound == MS_PRIEST || quest_mon_represents_role(ptr, PM_CLERIC)) { (void) mongets(mtmp, rn2(7) ? ROBE @@ -2350,7 +2355,7 @@ mongets(struct monst *mtmp, int otyp) return (struct obj *) 0; /* Anyone can be an undead slayer when you are a vampire! */ - if (Race_if(PM_VAMPIRE) && level_difficulty() > 8 + if (Race_if(PM_VAMPIRE) && level_difficulty() > 8 && !mon_hates_silver(mtmp) && !rn2(10)) { switch (otyp) { case DAGGER: diff --git a/src/mcastu.c b/src/mcastu.c index fc0c9ae503..a51dfc6b79 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -114,6 +114,7 @@ choose_magic_spell(struct monst* caster, int spellval) if (Antimagic || Hallucination) return MGC_PSI_BOLT; } + FALLTHROUGH; /*FALLTHRU*/ case 22: case 21: @@ -197,6 +198,7 @@ choose_clerical_spell(struct monst* caster, int spellnum) case 14: if (rn2(3)) return CLC_OPEN_WOUNDS; + FALLTHROUGH; /*FALLTHRU*/ case 13: return CLC_GEYSER; @@ -639,7 +641,7 @@ m_destroy_armor(struct monst *caster, struct monst *mdef) If you modify either of these, be sure to change is_undirected_spell() and spell_would_be_useless(). */ -staticfn int +staticfn int cast_wizard_spell( struct monst *caster, /* caster */ struct monst *mdef, /* target */ diff --git a/src/mhitm.c b/src/mhitm.c index ea4843dafd..aad5795715 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhitm.c $NHDT-Date: 1698939796 2023/11/02 15:43:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ */ +/* NetHack 3.7 mhitm.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.253 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -454,6 +454,7 @@ mattackm( mswingsm(magr, mdef, mwep); tmp += hitval(mwep, mdef); } + FALLTHROUGH; /*FALLTHRU*/ case AT_CLAW: case AT_KICK: @@ -805,6 +806,7 @@ hitmm( Snprintf(buf, sizeof buf, "%s squeezes", magr_name); break; } + FALLTHROUGH; /*FALLTHRU*/ default: if (!weaponhit || !mwep || !mwep->oartifact) @@ -1344,6 +1346,12 @@ paralyze_monst(struct monst *mon, int amt) int sleep_monst(struct monst *mon, int amt, int how) { + /* reveal mimic unless already asleep or paralyzed (won't be 'busy') */ + if (how >= 0 && !mon->msleeping && !mon->mfrozen + && mon->data->mlet == S_MIMIC && (M_AP_TYPE(mon) == M_AP_FURNITURE + || M_AP_TYPE(mon) == M_AP_OBJECT)) + seemimic(mon); + if ((resists_sleep(mon) || defended(mon, AD_SLEE) || (how >= 0 && resist(mon, (char) how, 0, NOTELL))) /* Cerberus can be put to sleep by tools */ diff --git a/src/mkmaze.c b/src/mkmaze.c index 661ddf5c5b..4ed52067ae 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -78,19 +78,22 @@ set_levltyp(coordxy x, coordxy y, schar newtyp) if (isok(x, y) && newtyp >= STONE && newtyp < MAX_TYPE) { if (CAN_OVERWRITE_TERRAIN(levl[x][y].typ)) { schar oldtyp = levl[x][y].typ; - boolean was_ice = (levl[x][y].typ == ICE); + /* typ==ICE || (typ==DRAWBRIDGE_UP && drawbridgemask==DB_ICE) */ + boolean was_ice = is_ice(x, y); levl[x][y].typ = newtyp; /* TODO? * if oldtyp used flags or horizontal differently from - * from the way newtyp will use them, clear them. + * the way newtyp will use them, clear them. */ - if (IS_LAVA(newtyp)) + if (IS_LAVA(newtyp)) /* [what about IS_LAVA(oldtyp)=>.lit = 0?] */ levl[x][y].lit = 1; - - if (was_ice && newtyp != ICE) + if (was_ice && newtyp != ICE) { + /* frozen corpses resume rotting, no more ice to melt away */ + obj_ice_effects(x, y, TRUE); spot_stop_timers(x, y, MELT_ICE_AWAY); + } if ((IS_FOUNTAIN(oldtyp) != IS_FOUNTAIN(newtyp)) || (IS_SINK(oldtyp) != IS_SINK(newtyp)) || (IS_TOILET(oldtyp) != IS_TOILET(newtyp)) @@ -590,6 +593,7 @@ fixup_special(void) sp = find_level(r->rname.str); lev = sp->dlevel; } + FALLTHROUGH; /*FALLTHRU*/ case LR_UPSTAIR: @@ -2075,6 +2079,7 @@ mv_bubble(struct bubble *b, coordxy dx, coordxy dy, boolean ini) break; case 3: b->dy = -b->dy; + FALLTHROUGH; /*FALLTHRU*/ case 2: b->dx = -b->dx; diff --git a/src/mkobj.c b/src/mkobj.c index afd11b5df2..8993e72f5f 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -359,6 +359,7 @@ mkbox_cnts(struct obj *box) n = 0; break; } + FALLTHROUGH; /*FALLTHRU*/ case BAG_OF_HOLDING: n = 1; @@ -1050,6 +1051,7 @@ mksobj_init(struct obj *otmp, boolean artif) case LARGE_BOX: otmp->olocked = !!(rn2(5)); otmp->otrapped = !(rn2(10)); + FALLTHROUGH; /*FALLTHRU*/ case ICE_BOX: case SACK: @@ -1281,6 +1283,7 @@ mksobj(int otyp, boolean init, boolean artif) if (svm.mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE | G_GONE)) otmp->corpsenm = gu.urole.mnum; } + FALLTHROUGH; /*FALLTHRU*/ case STATUE: case FIGURINE: @@ -1294,6 +1297,7 @@ mksobj(int otyp, boolean init, boolean artif) : is_male(ptr) ? CORPSTAT_MALE : rn2(2) ? CORPSTAT_FEMALE : CORPSTAT_MALE); } + FALLTHROUGH; /*FALLTHRU*/ case EGG: /* case TIN: */ @@ -1307,6 +1311,7 @@ mksobj(int otyp, boolean init, boolean artif) break; case POT_OIL: otmp->age = MAX_OIL_IN_FLASK; /* amount of oil */ + FALLTHROUGH; /*FALLTHRU*/ case POT_WATER: /* POTION_CLASS */ otmp->fromsink = 0; /* overloads corpsenm, which was set to NON_PM */ @@ -3186,6 +3191,7 @@ objlist_sanity(struct obj *objlist, int wheretype, const char *mesg) /* note: ball and chain can also be OBJ_FREE, but not across turns so this sanity check shouldn't encounter that */ bc_ok = TRUE; + FALLTHROUGH; /*FALLTHRU*/ default: if ((obj != uchain && obj != uball) || !bc_ok) { diff --git a/src/mon.c b/src/mon.c index 02b869cbde..0d0fbec2a2 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1211,7 +1211,8 @@ make_corpse(struct monst *mtmp, unsigned int corpseflags) case PM_KING_OF_GAMES: case PM_DAL_ZETHIRE: case PM_DUELIST: - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ #else default: #endif @@ -2458,7 +2459,7 @@ can_touch_safely(struct monst *mtmp, struct obj *otmp) * * to support the new pet behavior, this now returns the max # of objects * that a given monster could pick up from a pile. frequently this will be - * otmp->quan, but special cases for 'only one' now exist so. + * otmp->quan, but special cases for 'only one' now exist. * * this will probably cause very amusing behavior with pets and gold coins. * @@ -3379,15 +3380,20 @@ lifesaved_monster(struct monst *mtmp) } /* when a shape-shifted vampire is killed, it reverts to base form instead - of dying; moved into separate routine to unclutter mondead() */ + of dying; returns True if mtmp successfully revives, False otherwise; + "successfully revived" vampire might be killed by a booby trapped door */ staticfn boolean vamprises(struct monst *mtmp) { int mndx = mtmp->cham; + /* + * Protection from shape changers protects against this because + * the vampire will always be in normal form instead of shifted. + * So there's no need to check for that attribute being active. + */ if (ismnum(mndx) && mndx != monsndx(mtmp->data) && !(svm.mvitals[mndx].mvflags & G_GENOD)) { - coord new_xy; char action[BUFSZ]; /* alternate message phrasing for some monster types */ boolean spec_mon = (nonliving(mtmp->data) @@ -3400,30 +3406,28 @@ vamprises(struct monst *mtmp) /* construct a 'before' argument to pass to pline(); this used to construct a dynamic format string but that's overkill */ - Snprintf(action, sizeof action, "%s suddenly %s and rises as", + Snprintf(action, sizeof action, "%s%s %s%s and rises as", + Unaware ? "you dream that " : "", x_monnam(mtmp, ARTICLE_THE, spec_mon ? (char *) 0 : "seemingly dead", (SUPPRESS_INVISIBLE | AUGMENT_IT), FALSE), + Unaware ? "" : "suddenly ", spec_death ? "reconstitutes" : "transforms"); mtmp->mcanmove = 1; mtmp->mfrozen = 0; set_mon_min_mhpmax(mtmp, 10); /* mtmp->mhpmax=max(m_lev+1,10) */ mtmp->mhp = mtmp->mhpmax; - /* mtmp==u.ustuck can happen if previously a fog cloud - or poly'd hero is hugging a vampire bat */ + /* mtmp==u.ustuck can happen if previously a fog cloud or if + poly'd hero is hugging a vampire bat */ if (mtmp == u.ustuck) { if (u.uswallow) expels(mtmp, mtmp->data, FALSE); else uunstick(); } - /* if fog cloud is on a closed door space, move it to a more - appropriate spot for its intended new form */ - if (amorphous(mtmp->data) && closed_door(mtmp->mx, mtmp->my)) { - if (enexto(&new_xy, mtmp->mx, mtmp->my, &mons[mndx])) - rloc_to(mtmp, new_xy.x, new_xy.y); - } - (void) newcham(mtmp, &mons[mndx], NO_NC_FLAGS); + + if (!newcham(mtmp, &mons[mndx], NO_NC_FLAGS)) + return !DEADMONSTER(mtmp); mtmp->cham = (mtmp->data == &mons[mndx]) ? NON_PM : mndx; if (canspotmon(mtmp)) { @@ -3436,6 +3440,42 @@ vamprises(struct monst *mtmp) FALSE)); gv.vamp_rise_msg = TRUE; } + /* revived vampire is in normal shape, so can't be amorphous; if on + a closed door spot, destroy the door and if trapped, blow it up */ + if (closed_door(x, y)) { + static const char + door_smashed[] = "a door being smashed", + door_go_boom[] = "a door exploding"; + struct rm *door = &levl[x][y]; + boolean trapped = (door->doormask & D_TRAPPED) != 0, + seeit = cansee(x, y); + + set_msg_xy(x, y); /* You()/pline() will reset this */ + if (!seeit) + You_hear("%s.", trapped ? "an explosion" : door_smashed); + else if (!canspotmon(mtmp)) + You_see("%s.", trapped ? door_go_boom : door_smashed); + else if (!Unaware) + pline_The("door is smashed%s", + trapped ? " and it explodes!" : "."); + set_msg_xy(0, 0); /* in case none of the messages was delivered */ + + door->doormask = D_NODOOR; + unblock_point(x, y); + if (trapped) { + boolean trap_killed, save_verbose = flags.verbose; + + flags.verbose = FALSE; /* suppress mb_trapped() messages + * (that makes the 'seeit' arg moot) */ + trap_killed = mb_trapped(mtmp, seeit); + flags.verbose = save_verbose; + /* if the booby trap has killed the monster, mondied() will + have been called but no message about its death given yet; + mtmp was a vampire so use unconditional "destroyed" */ + if (trap_killed && canspotmon(mtmp) && !Unaware) + pline_mon(mtmp, "%s is destroyed!", Monnam(mtmp)); + } + } newsym(x, y); return TRUE; } @@ -3456,7 +3496,7 @@ logdeadmon(struct monst *mtmp, int mndx) if (mtmp->msummoned) return; - + if (mndx == PM_MEDUSA && howmany == 1) { record_achievement(ACH_MEDU); /* also generates a livelog event */ } else if (mndx == PM_CERBERUS && howmany == 1) { @@ -3626,7 +3666,8 @@ mondead(struct monst *mtmp) (void) makemon(mtmp->data, stway->sx, stway->sy, NO_MM_FLAGS); break; } - /* fall-through */ + FALLTHROUGH; + /* FALLTHRU */ case 2: /* randomly */ (void) makemon(mtmp->data, 0, 0, NO_MM_FLAGS); break; @@ -5310,7 +5351,7 @@ get_iter_mons_xy( /* force all chameleons and mimics to become themselves and werecreatures to revert to human form; called when Protection_from_shape_changers gets - activated via wearing or eating ring or wizintrinsics */ + activated via wearing or eating ring or via #wizintrinsic */ void rescham(void) { @@ -5491,6 +5532,7 @@ hideunder(struct monst *mtmp) if (undetected && seenmon && seenobj) { if (!locomo) locomo = locomotion(mtmp->data, "hide"); + set_msg_xy(mtmp->mx, mtmp->my); /* pline() will reset this */ You_see("%s %s under %s.", seenmon, locomo, seenobj); iflags.last_msg = PLNMSG_HIDE_UNDER; gl.last_hider = mtmp->m_id; @@ -5652,13 +5694,15 @@ pickvampshape(struct monst *mon) if (mon_has_special(mon)) break; /* leave mndx as is */ wolfchance = 3; - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ /* Vlad can become wolf */ if (!rn2(wolfchance) && !uppercase_only) { mndx = PM_WOLF; break; } - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ /* Vlad can become fog or bat */ mndx = (!rn2(4) && !uppercase_only) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT; break; @@ -5761,6 +5805,7 @@ validvamp(struct monst *mon, int *mndx_p, int monclass) *mndx_p = PM_WOLF; break; } + FALLTHROUGH; /*FALLTHRU*/ default: *mndx_p = NON_PM; diff --git a/src/mondata.c b/src/mondata.c index 37fc8d5adc..50edbaf411 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -183,7 +183,15 @@ resists_blnd(struct monst *mon) if (dmgtype_fromattack(ptr, AD_BLND, AT_EXPL) || dmgtype_fromattack(ptr, AD_BLND, AT_GAZE)) return TRUE; - return resists_blnd_by_arti(mon); + /* Sunsword */ + if (resists_blnd_by_arti(mon)) + return TRUE; + /* catchall */ + if (is_you && Blnd_resist) { + impossible("'Blnd_resist' but not resists_blnd()?"); + return TRUE; + } + return FALSE; } /* True iff monster is resistant to light-induced blindness due to worn diff --git a/src/monmove.c b/src/monmove.c index d9571b0164..eda22b2fbd 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -974,6 +974,7 @@ dochug(struct monst *mtmp) * Monsters should never attack while scared or fleeing. */ if (scared) panicattk = FALSE; + FALLTHROUGH; /*FALLTHRU*/ case MMOVE_NOTHING: /* no movement, but it can still attack you */ case MMOVE_DONE: /* absolutely no movement */ @@ -1585,9 +1586,9 @@ postmov( && amorphous(ptr)) { if (flags.verbose && canseemon(mtmp)) pline_mon(mtmp, "%s %s under the door.", YMonnam(mtmp), - (ptr == &mons[PM_FOG_CLOUD] - || ptr->mlet == S_LIGHT) ? "flows" : "oozes"); - } else if (here->doormask & D_LOCKED && can_unlock) { + (ptr == &mons[PM_FOG_CLOUD] + || ptr->mlet == S_LIGHT) ? "flows" : "oozes"); + } else if ((here->doormask & D_LOCKED) != 0 && can_unlock) { /* like the vampshift hack, there are sequencing issues when the monster is moved to the door's spot first then door handling plus feedback comes after */ @@ -1626,7 +1627,7 @@ postmov( } } } - } else if (here->doormask & (D_LOCKED | D_CLOSED)) { + } else if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0) { /* mfndpos guarantees this must be a doorbuster */ unsigned mask; @@ -1861,6 +1862,7 @@ m_move(struct monst *mtmp, int after) break; default: impossible("unknown shk/gd/pri_move return value (%d)", xm); + FALLTHROUGH; /*FALLTHRU*/ case 0: case 1: diff --git a/src/mthrowu.c b/src/mthrowu.c index 4ab0001f0d..bf1c29e20a 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -711,6 +711,7 @@ m_throw( hitu = 0; break; } + FALLTHROUGH; /*FALLTHRU*/ case CREAM_PIE: case BLINDING_VENOM: @@ -927,6 +928,7 @@ spitmm(struct monst *mtmp, struct attack *mattk, struct monst *mtarg) break; default: impossible("bad attack type in spitmm"); + FALLTHROUGH; /*FALLTHRU*/ case AD_ACID: otmp = mksobj(ACID_VENOM, TRUE, FALSE); diff --git a/src/muse.c b/src/muse.c index 45123f2579..d72254079b 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1442,6 +1442,7 @@ rnd_defensive_item(struct monst *mtmp) goto try_again; if (!rn2(3)) return WAN_TELEPORTATION; + FALLTHROUGH; /*FALLTHRU*/ case 0: case 1: @@ -1450,6 +1451,7 @@ rnd_defensive_item(struct monst *mtmp) case 10: if (!rn2(3)) return WAN_CREATE_MONSTER; + FALLTHROUGH; /*FALLTHRU*/ case 2: return SCR_CREATE_MONSTER; @@ -2471,7 +2473,9 @@ rnd_offensive_item(struct monst *mtmp) if (hard_helmet(mtmp_helmet) || amorphous(pm) || passes_walls(pm) || noncorporeal(pm) || unsolid(pm)) return SCR_EARTH; - } /* fall through */ + } + FALLTHROUGH; + /* FALLTHRU */ case 1: return WAN_STRIKING; case 2: diff --git a/src/music.c b/src/music.c index bb57f0eadd..f79dc494ab 100644 --- a/src/music.c +++ b/src/music.c @@ -447,6 +447,7 @@ do_earthquake(int force) unblock_point(x, y); if (cansee(x, y)) pline("A secret corridor is revealed."); + FALLTHROUGH; /*FALLTHRU*/ case CORR: case ROOM: @@ -456,6 +457,7 @@ do_earthquake(int force) cvt_sdoor_to_door(&levl[x][y]); /* .typ = DOOR */ if (cansee(x, y)) pline("A secret door is revealed."); + FALLTHROUGH; /*FALLTHRU*/ case DOOR: /* make the door collapse */ /* if already doorless, treat like room or corridor */ diff --git a/src/nhlua.c b/src/nhlua.c index b671193282..87aef8ad96 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -2031,6 +2031,8 @@ nhl_pcall_handle(lua_State *L, int nargs, int nresults, const char *name, case NHLpa_panic: panic("Lua error %d:%s %s", nud->sid, nud->name ? nud->name : "(unknown)", lua_tostring(L, -1)); + /*NOTREACHED*/ + break; case NHLpa_impossible: impossible("Lua error: %d:%s %s", nud->sid, nud->name ? nud->name : "(unknown)", diff --git a/src/objnam.c b/src/objnam.c index 2ff7b826c7..a7e8034e9f 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1711809641 2024/03/30 14:40:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.427 $ */ +/* NetHack 3.7 objnam.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.439 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -769,6 +769,7 @@ xname_flags( case WEAPON_CLASS: if (is_poisonable(obj) && obj->opoisoned) Strcpy(buf, "poisoned "); + FALLTHROUGH; /*FALLTHRU*/ case VENOM_CLASS: case TOOL_CLASS: @@ -806,6 +807,7 @@ xname_flags( break; } else if (is_boots(obj) || is_gloves(obj)) { Strcpy(buf, "pair of "); + FALLTHROUGH; /*FALLTHRU*/ } else if (is_shield(obj) && !dknown) { if (obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD) { @@ -1529,6 +1531,7 @@ doname_base( ConcatF1(bp, 1, ", %s lit)", arti_light_description(obj)); } } + FALLTHROUGH; /*FALLTHRU*/ case WEAPON_CLASS: if (ispoisoned) @@ -2625,7 +2628,7 @@ static const char wrpsym[] = { /* return form of the verb (input plural) if xname(otmp) were the subject */ char * -otense(struct obj* otmp,const char * verb) +otense(struct obj *otmp, const char *verb) { char *buf; @@ -5308,7 +5311,8 @@ readobjnam(char *bp, struct obj *no_wish) break; case SLIME_MOLD: d.otmp->spe = d.ftype; - /* Fall through */ + FALLTHROUGH; + /* FALLTHRU */ case SKELETON_KEY: case CHEST: case LARGE_BOX: @@ -5341,7 +5345,8 @@ readobjnam(char *bp, struct obj *no_wish) /* scroll of mail: 0: delivered in-game via external event (or randomly for fake mail); 1: from bones or wishing; 2: written with marker */ case SCR_MAIL: - /*FALLTHRU*/ + d.otmp->spe = 1; + break; #endif /* splash of venom: 0: normal, and transitory; 1: wishing */ case ACID_VENOM: @@ -5353,6 +5358,7 @@ readobjnam(char *bp, struct obj *no_wish) d.otmp->spe = (rn2(10) ? -1 : 0); break; } + FALLTHROUGH; /*FALLTHRU*/ default: d.otmp->spe = d.spe; diff --git a/src/options.c b/src/options.c index f8485df9f2..36af37d9d7 100644 --- a/src/options.c +++ b/src/options.c @@ -3,17 +3,17 @@ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ -#ifdef OPTION_LISTS_ONLY /* (AMIGA) external program for opt lists */ +#ifndef OPTION_LISTS_ONLY +#include "hack.h" +#include "tcap.h" +#else /* OPTION_LISTS_ONLY: (AMIGA) external program for opt lists */ #include "config.h" #include "objclass.h" #include "flag.h" NEARDATA struct flag flags; /* provide linkage */ NEARDATA struct instance_flags iflags; /* provide linkage */ +NEARDATA struct accessibility_data a11y; #define static -#else -#include "hack.h" -#include "tcap.h" -#include #endif #define BACKWARD_COMPAT @@ -3634,6 +3634,7 @@ optfn_scores( allopt[optidx].name); return optn_silenterr; } + FALLTHROUGH; /*FALLTHRU*/ default: config_error_add("Unknown %s parameter '%s'", @@ -5307,6 +5308,9 @@ optfn_boolean( case opt_rest_on_space: update_rest_on_space(); break; + case opt_accessiblemsg: + a11y.msg_loc.x = a11y.msg_loc.y = 0; + break; default: break; } @@ -6961,7 +6965,7 @@ initoptions_init(void) int i; boolean have_branch = (nomakedefs.git_branch && *nomakedefs.git_branch); - go.opt_phase = builtin_opt; // Did I need to move this here? + go.opt_phase = builtin_opt; /* Did I need to move this here? */ memcpy(allopt, allopt_init, sizeof(allopt)); determine_ambiguities(); diff --git a/src/pager.c b/src/pager.c index 15723342a5..539ad84148 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pager.c $NHDT-Date: 1724094301 2024/08/19 19:05:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.279 $ */ +/* NetHack 3.7 pager.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.282 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -288,7 +288,10 @@ mhidden_description( /* extracted from lookat(); also used by namefloorobj() */ boolean -object_from_map(int glyph, coordxy x, coordxy y, struct obj **obj_p) +object_from_map( + int glyph, + coordxy x, coordxy y, + struct obj **obj_p) { boolean fakeobj = FALSE, mimic_obj = FALSE; struct monst *mtmp; @@ -313,8 +316,10 @@ object_from_map(int glyph, coordxy x, coordxy y, struct obj **obj_p) if (!otmp || otmp->otyp != glyphotyp) { /* this used to exclude STRANGE_OBJECT; now caller deals with it */ otmp = mksobj(glyphotyp, FALSE, FALSE); - if (!otmp) - return FALSE; + /* even though we pass False for mksobj()'s 'init' arg, corpse-rot, + egg-hatch, and figurine-transform timers get initialized */ + if (otmp->timed) + obj_stop_timers(otmp); fakeobj = TRUE; if (otmp->oclass == COIN_CLASS) otmp->quan = 2L; /* to force pluralization */ @@ -859,6 +864,7 @@ lookat(coordxy x, coordxy y, char *buf, char *monbuf) Strcpy(buf, "stone"); break; } + FALLTHROUGH; /*FALLTHRU*/ default: Strcpy(buf, defsyms[symidx].explanation); diff --git a/src/pickup.c b/src/pickup.c index 6483d41580..664b1cab65 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -486,7 +486,9 @@ add_valid_menu_class(int c) switch (c) { case 'B': case 'U': - case 'C': /*FALLTHRU*/ + case 'C': + FALLTHROUGH; + /*FALLTHRU*/ case 'X': gb.bucx_filter = TRUE; break; @@ -870,6 +872,7 @@ pickup(int what) /* should be a long */ lcount = (long) yn_number; if (lcount > obj->quan) lcount = obj->quan; + FALLTHROUGH; /*FALLTHRU*/ default: /* 'y' */ break; @@ -1481,6 +1484,7 @@ query_category( /* assert( n == 1 ); */ break; /* from switch */ } + FALLTHROUGH; /*FALLTHRU*/ case 'q': default: diff --git a/src/pline.c b/src/pline.c index 2b6f284b88..93d3a93c7b 100644 --- a/src/pline.c +++ b/src/pline.c @@ -77,6 +77,23 @@ putmesg(const char *line) SoundSpeak(line); } +/* set the direction where next message happens */ +void +set_msg_dir(int dir) +{ + dtoxy(&a11y.msg_loc, dir); + a11y.msg_loc.x += u.ux; + a11y.msg_loc.y += u.uy; +} + +/* set the coordinate where next message happens */ +void +set_msg_xy(coordxy x, coordxy y) +{ + a11y.msg_loc.x = x; + a11y.msg_loc.y = y; +} + staticfn void vpline(const char *, va_list); DISABLE_WARNING_FORMAT_NONLITERAL @@ -127,23 +144,6 @@ pline_mon(struct monst *mtmp, const char *line, ...) va_end(the_args); } -/* set the direction where next message happens */ -void -set_msg_dir(int dir) -{ - dtoxy(&a11y.msg_loc, dir); - a11y.msg_loc.x += u.ux; - a11y.msg_loc.y += u.uy; -} - -/* set the coordinate where next message happens */ -void -set_msg_xy(coordxy x, coordxy y) -{ - a11y.msg_loc.x = x; - a11y.msg_loc.y = y; -} - staticfn void vpline(const char *line, va_list the_args) { @@ -152,6 +152,11 @@ vpline(const char *line, va_list the_args) int ln; int msgtyp; boolean no_repeat; + coord a11y_mesgxy; + + a11y_mesgxy = a11y.msg_loc; /* save a11y.msg_loc before reseting it */ + /* always reset a11y.msg_loc whether we end up using it or not */ + a11y.msg_loc.x = a11y.msg_loc.y = 0; if (!line || !*line) return; @@ -162,16 +167,15 @@ vpline(const char *line, va_list the_args) if (program_state.wizkit_wishing) return; - if (a11y.accessiblemsg && isok(a11y.msg_loc.x,a11y.msg_loc.y)) { - char *tmp; - char *dirstr; - static char dirstrbuf[BUFSZ]; - int g = (iflags.getpos_coords == GPCOORDS_NONE) - ? GPCOORDS_COMFULL : iflags.getpos_coords; + /* when accessiblemsg is set and a11y.msg_loc is nonzero, use the latter + to insert a location prefix in front of current message */ + if (a11y.accessiblemsg && isok(a11y_mesgxy.x, a11y_mesgxy.y)) { + char *tmp, *dirstr, dirstrbuf[QBUFSZ]; - dirstr = coord_desc(a11y.msg_loc.x, a11y.msg_loc.y, dirstrbuf, g); - a11y.msg_loc.x = a11y.msg_loc.y = 0; - tmp = (char *)alloc(strlen(line) + sizeof ": " + strlen(dirstr)); + dirstr = coord_desc(a11y_mesgxy.x, a11y_mesgxy.y, dirstrbuf, + ((iflags.getpos_coords == GPCOORDS_NONE) + ? GPCOORDS_COMFULL : iflags.getpos_coords)); + tmp = (char *) alloc(strlen(line) + sizeof ": " + strlen(dirstr)); Strcpy(tmp, dirstr); Strcat(tmp, ": "); Strcat(tmp, line); diff --git a/src/polyself.c b/src/polyself.c index a8e1cab7ac..e96ae7bd07 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -103,6 +103,8 @@ set_uasmon(void) PROPSET(REGENERATION, regenerates(mdat)); PROPSET(REFLECTING, (mdat == &mons[PM_SILVER_DRAGON])); PROPSET(BLINDED, !haseyes(mdat)); + PROPSET(BLND_RES, (dmgtype_fromattack(mdat, AD_BLND, AT_EXPL) + || dmgtype_fromattack(mdat, AD_BLND, AT_GAZE))); #undef PROPSET /* whether the player is flying/floating depends on their steed, @@ -1476,6 +1478,7 @@ dospit(void) break; default: impossible("bad attack type in dospit"); + FALLTHROUGH; /*FALLTHRU*/ case AD_ACID: otmp = mksobj(ACID_VENOM, TRUE, FALSE); diff --git a/src/potion.c b/src/potion.c index 8c7e55cb3d..d08cf80d15 100644 --- a/src/potion.c +++ b/src/potion.c @@ -766,7 +766,7 @@ dodrink(void) if (y_n("Drink the water underneath you?") == 'y') { pline("Do you know what lives in that water?"); return ECMD_TIME; - } else if ((Underwater + } else if ((Underwater || (is_puddle(u.ux, u.uy) && verysmall(gy.youmonst.data))) && !u.uswallow) { if (y_n("Drink the water around you?") == 'y') { @@ -1061,7 +1061,7 @@ peffect_see_invisible(struct obj *otmp) ? "This tastes like 10%% real %s%s all-natural beverage." : "This tastes like %s%s.", otmp->odiluted ? "reconstituted " : "", fruitname(TRUE)); - + /* Auto-ID by process of elimination */ if (otmp->otyp == POT_FRUIT_JUICE && objects[POT_SEE_INVISIBLE].oc_name_known) @@ -1069,7 +1069,7 @@ peffect_see_invisible(struct obj *otmp) else if (otmp->otyp == POT_SEE_INVISIBLE && objects[POT_FRUIT_JUICE].oc_name_known) makeknown(POT_SEE_INVISIBLE); - + if (otmp->otyp == POT_FRUIT_JUICE) { u.uhunger += (otmp->odiluted ? 5 : 10) * (2 + bcsign(otmp)); newuhs(FALSE); @@ -2175,16 +2175,19 @@ potionhit(struct monst *mon, struct obj *obj, int how) switch (obj->otyp) { case POT_FULL_HEALING: cureblind = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case POT_EXTRA_HEALING: if (!obj->cursed) cureblind = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case POT_HEALING: if (obj->blessed) cureblind = TRUE; if (mon->data == &mons[PM_PESTILENCE]) goto do_illness; + FALLTHROUGH; /*FALLTHRU*/ case POT_RESTORE_ABILITY: case POT_GAIN_ABILITY: @@ -2481,6 +2484,7 @@ potionbreathe(struct obj *obj) if (u.uhp < u.uhpmax) u.uhp++, disp.botl = TRUE; cureblind = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case POT_EXTRA_HEALING: if (Upolyd && u.mh < u.mhmax) @@ -2489,6 +2493,7 @@ potionbreathe(struct obj *obj) u.uhp++, disp.botl = TRUE; if (!obj->cursed) cureblind = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case POT_HEALING: if (Upolyd && u.mh < u.mhmax) @@ -3097,7 +3102,7 @@ dodip(void) useup(obj); if (IS_PUDDLE(here) && !rn2(3)) dryup_puddle(u.ux, u.uy, "dries up"); - + } return ECMD_TIME; } @@ -3233,7 +3238,7 @@ potion_dip(struct obj *obj, struct obj *potion) /* Scrolls of amnesia make potions forget what they were */ struct obj *singlescroll = (obj->quan > 1L ? splitobj(obj, 1L) : obj); - Your("%s fade%s.", xname(potion), + Your("%s fade%s.", xname(potion), potion->quan > 1L ? "" : "s"); makeknown(SCR_AMNESIA); diff --git a/src/pray.c b/src/pray.c index 9b254de76e..9679996750 100644 --- a/src/pray.c +++ b/src/pray.c @@ -29,6 +29,7 @@ staticfn void offer_different_alignment_altar(struct obj *, aligntyp); staticfn void sacrifice_your_race(struct obj *, boolean, aligntyp); staticfn int bestow_artifact(void); staticfn int sacrifice_value(struct obj *); +staticfn int eval_offering(struct obj *, aligntyp); staticfn void offer_corpse(struct obj *, boolean, aligntyp); staticfn boolean pray_revive(void); staticfn boolean water_prayer(boolean); @@ -423,7 +424,8 @@ fix_worst_trouble(int trouble) break; case TROUBLE_STARVING: /* temporarily lost strength recovery now handled by init_uhunger() */ - /*FALLTHRU*/ + FALLTHROUGH; + /* FALLTHRU*/ case TROUBLE_HUNGRY: Your("%s feels content.", body_part(STOMACH)); init_uhunger(); @@ -779,7 +781,9 @@ angrygods(aligntyp resp_god) gods_angry(resp_god); punish((struct obj *) 0); break; - } /* else fall thru */ + } + FALLTHROUGH; + /* FALLTHRU */ case 4: case 5: gods_angry(resp_god); @@ -1286,6 +1290,7 @@ pleased(aligntyp g_align) switch (min(action, 5)) { case 5: pat_on_head = 1; + FALLTHROUGH; /*FALLTHRU*/ case 4: do @@ -1294,9 +1299,12 @@ pleased(aligntyp g_align) break; case 3: + /* up to 10 troubles */ fix_worst_trouble(trouble); - case 2: - /* arbitrary number of tries */ + FALLTHROUGH; + /*FALLTHRU*/ + case 2: + /* up to 9 troubles */ while ((trouble = in_trouble()) > 0 && (++tryct < 10)) fix_worst_trouble(trouble); break; @@ -1304,6 +1312,7 @@ pleased(aligntyp g_align) case 1: if (trouble > 0) fix_worst_trouble(trouble); + break; case 0: break; /* your god blows you off, too bad */ } @@ -1391,7 +1400,8 @@ pleased(aligntyp g_align) break; } } - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ case 2: if (!Blind) You("are surrounded by %s glow.", an(hcolor(NH_GOLDEN))); @@ -1489,7 +1499,8 @@ pleased(aligntyp g_align) gcrownu(); break; } - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ case 6: /* Cave dwellers don't mess around with spells, so do nothing */ if (!primary_spellcaster()) @@ -2094,7 +2105,7 @@ bestow_artifact(void) } } } - + return FALSE; @@ -2203,6 +2214,66 @@ dosacrifice(void) return ECMD_TIME; } +staticfn int +eval_offering(struct obj *otmp, aligntyp altaralign) +{ + struct permonst *ptr; + int value; + + value = sacrifice_value(otmp); + + if (!value) + return 0; + + ptr = &mons[otmp->corpsenm]; + + if (is_undead(ptr)) { /* Not demons--no demon corpses */ + /* most undead that leave a corpse yield 'human' (or other race) + corpse so won't get here; the exception is wraith; give the + bonus for wraith to chaotics too because they are sacrificing + something valuable (unless hero refuses to eat such things) */ + if (u.ualign.type != A_CHAOTIC + /* reaching this side of the 'or' means hero is chaotic */ + || (ptr == &mons[PM_WRAITH] && u.uconduct.unvegetarian)) + value += 1; + } else if (is_unicorn(ptr)) { + int unicalign = sgn(ptr->maligntyp); + + if (unicalign == altaralign) { + /* When same as altar, always a very bad action. + */ + pline("Such an action is an insult to %s!", + (unicalign == A_CHAOTIC) ? "chaos" + : unicalign ? "law" : "balance"); + (void) adjattrib(A_WIS, -1, TRUE); + return -1; + } else if (u.ualign.type == altaralign) { + /* When different from altar, and altar is same as yours, + * it's a very good action. + */ + if (u.ualign.record < ALIGNLIM) + You_feel("appropriately %s.", align_str(u.ualign.type)); + else + You_feel("you are thoroughly on the right path."); + adjalign(5); + value += 3; + } else if (unicalign == u.ualign.type) { + /* When sacrificing unicorn of your alignment to altar not of + * your alignment, your god gets angry and it's a conversion. + */ + u.ualign.record = -1; + value = 1; + } else { + /* Otherwise, unicorn's alignment is different from yours + * and different from the altar's. It's an ordinary (well, + * with a bonus) sacrifice on a cross-aligned altar. + */ + value += 3; + } + } + return value; +} + staticfn void offer_corpse(struct obj *otmp, boolean highaltar, aligntyp altaralign) { @@ -2221,8 +2292,6 @@ offer_corpse(struct obj *otmp, boolean highaltar, aligntyp altaralign) */ #define MAXVALUE 24 /* Highest corpse value (besides Wiz) */ - ptr = &mons[otmp->corpsenm]; - /* KMH, conduct */ if (!u.uconduct.gnostic++) livelog_printf(LL_CONDUCT, "rejected atheism" @@ -2236,7 +2305,7 @@ offer_corpse(struct obj *otmp, boolean highaltar, aligntyp altaralign) if (rider_corpse_revival(otmp, FALSE)) return; - value = sacrifice_value(otmp); + ptr = &mons[otmp->corpsenm]; /* same race or former pet results apply even if the corpse is too old (value==0) */ @@ -2255,55 +2324,16 @@ offer_corpse(struct obj *otmp, boolean highaltar, aligntyp altaralign) offer_negative_valued(highaltar, altaralign); return; } - if (!value) { + + value = eval_offering(otmp, altaralign); + if (value == 0) { /* too old; don't give undead or unicorn bonus or penalty */ pline1(nothing_happens); return; } - if (is_undead(ptr)) { /* Not demons--no demon corpses */ - /* most undead that leave a corpse yield 'human' (or other race) - corpse so won't get here; the exception is wraith; give the - bonus for wraith to chaotics too because they are sacrificing - something valuable (unless hero refuses to eat such things) */ - if (u.ualign.type != A_CHAOTIC - /* reaching this side of the 'or' means hero is chaotic */ - || (ptr == &mons[PM_WRAITH] && u.uconduct.unvegetarian)) - value += 1; - } else if (is_unicorn(ptr)) { - int unicalign = sgn(ptr->maligntyp); - - if (unicalign == altaralign) { - /* When same as altar, always a very bad action. - */ - pline("Such an action is an insult to %s!", - (unicalign == A_CHAOTIC) ? "chaos" - : unicalign ? "law" : "balance"); - (void) adjattrib(A_WIS, -1, TRUE); - offer_negative_valued(highaltar, altaralign); - return; - } else if (u.ualign.type == altaralign) { - /* When different from altar, and altar is same as yours, - * it's a very good action. - */ - if (u.ualign.record < ALIGNLIM) - You_feel("appropriately %s.", align_str(u.ualign.type)); - else - You_feel("you are thoroughly on the right path."); - adjalign(5); - value += 3; - } else if (unicalign == u.ualign.type) { - /* When sacrificing unicorn of your alignment to altar not of - * your alignment, your god gets angry and it's a conversion. - */ - u.ualign.record = -1; - value = 1; - } else { - /* Otherwise, unicorn's alignment is different from yours - * and different from the altar's. It's an ordinary (well, - * with a bonus) sacrifice on a cross-aligned altar. - */ - value += 3; - } + if (value < 0) { + offer_negative_valued(highaltar, altaralign); + return; } if (altaralign != u.ualign.type && highaltar) { @@ -2692,18 +2722,23 @@ maybe_turn_mon_iter(struct monst *mtmp) case S_LICH: case PM_ALHOON: xlev += 2; + FALLTHROUGH; /*FALLTHRU*/ case S_GHOST: xlev += 2; + FALLTHROUGH; /*FALLTHRU*/ case S_VAMPIRE: xlev += 2; + FALLTHROUGH; /*FALLTHRU*/ case S_WRAITH: xlev += 2; + FALLTHROUGH; /*FALLTHRU*/ case S_MUMMY: xlev += 2; + FALLTHROUGH; /*FALLTHRU*/ case S_ZOMBIE: if (u.ulevel >= xlev && !resist(mtmp, '\0', 0, NOTELL)) { @@ -2715,6 +2750,7 @@ maybe_turn_mon_iter(struct monst *mtmp) } break; } /* else flee */ + FALLTHROUGH; /*FALLTHRU*/ default: monflee(mtmp, 0, FALSE, TRUE); @@ -3018,6 +3054,7 @@ blocked_boulder(int dx, int dy) /* this is only approximate since multiple boulders might sink */ if (is_pool_or_lava(nx, ny)) /* does its own isok() check */ break; /* still need Sokoban check below */ + FALLTHROUGH; /*FALLTHRU*/ default: /* more than one boulder--blocked after they push the top one; diff --git a/src/questpgr.c b/src/questpgr.c index 29ef494c8a..707846e90c 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -374,6 +374,7 @@ convert_line(char *in_line, char *out_line) /* pluralize */ case 'P': gc.cvt_buf[0] = highc(gc.cvt_buf[0]); + FALLTHROUGH; /*FALLTHRU*/ case 'p': Strcpy(gc.cvt_buf, makeplural(gc.cvt_buf)); @@ -382,6 +383,7 @@ convert_line(char *in_line, char *out_line) /* append possessive suffix */ case 'S': gc.cvt_buf[0] = highc(gc.cvt_buf[0]); + FALLTHROUGH; /*FALLTHRU*/ case 's': Strcpy(gc.cvt_buf, s_suffix(gc.cvt_buf)); @@ -403,8 +405,9 @@ convert_line(char *in_line, char *out_line) Strcat(cc, gc.cvt_buf); cc += strlen(gc.cvt_buf); break; - } /* else fall through */ - + } + FALLTHROUGH; + /* FALLTHRU */ default: *cc++ = *c; break; diff --git a/src/read.c b/src/read.c index b16862ba28..9cb5ae0494 100644 --- a/src/read.c +++ b/src/read.c @@ -885,7 +885,7 @@ recharge(struct obj *obj, int curse_bless) } obj->spe += s; /* update the accessory while it's off */ if (is_on) - setworn(obj, mask), isring ? Ring_on(obj) : Amulet_on(); + setworn(obj, mask), isring ? Ring_on(obj) : Amulet_on(obj); /* oartifact: if a touch-sensitive artifact ring is ever created the above will need to be revised */ /* update shop bill to reflect new higher price */ diff --git a/src/report.c b/src/report.c index db36f57c3d..2e9adb19d5 100644 --- a/src/report.c +++ b/src/report.c @@ -220,7 +220,7 @@ crashreport_bidshow(void) mark = uend; \ if (utmp >= urem) \ goto full; \ - memcpy(uend, str, utmp); \ + memcpy(uend, str, utmp); \ uend += utmp; urem -= utmp; \ *uend = '\0'; diff --git a/src/role.c b/src/role.c index ac059dc38f..915d66bb90 100644 --- a/src/role.c +++ b/src/role.c @@ -1436,6 +1436,7 @@ clearrolefilter(int which) switch (which) { case RS_filter: gr.rfilter.mask = 0; /* clear race, gender, and alignment filters */ + FALLTHROUGH; /*FALLTHRU*/ case RS_ROLE: for (i = 0; i < SIZE(roles) - 1; ++i) @@ -2254,7 +2255,7 @@ genl_player_selection(void) /*NOTREACHED*/ } -#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) +#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) || defined(SHIM_GRAPHICS) /* ['#else' far below] */ staticfn boolean reset_role_filtering(void); diff --git a/src/rumors.c b/src/rumors.c index b3a7d5ac42..60850b5591 100644 --- a/src/rumors.c +++ b/src/rumors.c @@ -563,6 +563,7 @@ outrumor( return; case BY_COOKIE: pline(fortune_msg); + FALLTHROUGH; /* FALLTHRU */ case BY_PAPER: pline("It reads:"); diff --git a/src/selvar.c b/src/selvar.c index 1951edfb84..5d08ca95e5 100644 --- a/src/selvar.c +++ b/src/selvar.c @@ -582,6 +582,7 @@ selection_do_gradient( switch (gtyp) { default: impossible("Unrecognized gradient type! Defaulting to radial..."); + FALLTHROUGH; /* FALLTHRU */ case SEL_GRADIENT_RADIAL: { for (dx = 0; dx < COLNO; dx++) diff --git a/src/shk.c b/src/shk.c index ed367c1773..7cfbb1c501 100644 --- a/src/shk.c +++ b/src/shk.c @@ -4090,6 +4090,7 @@ sellobj( switch (gs.sell_response ? gs.sell_response : nyaq(qbuf)) { case 'q': gs.sell_response = 'n'; + FALLTHROUGH; /*FALLTHRU*/ case 'n': if (container) @@ -4100,6 +4101,7 @@ sellobj( break; case 'a': gs.sell_response = 'y'; + FALLTHROUGH; /*FALLTHRU*/ case 'y': if (container) diff --git a/src/sit.c b/src/sit.c index 857b89a0ff..13e48e39f1 100644 --- a/src/sit.c +++ b/src/sit.c @@ -171,6 +171,7 @@ throne_sit_effect(void) default: case 2: /* more than 1 eye */ eye = makeplural(eye); + FALLTHROUGH; /*FALLTHRU*/ case 1: /* one eye (Cyclops, floating eye) */ Your("%s %s...", eye, vtense(eye, "tingle")); @@ -676,6 +677,7 @@ attrcurse(void) ret = FIRE_RES; break; } + FALLTHROUGH; /*FALLTHRU*/ case 2: if (HTeleportation & INTRINSIC) { @@ -684,6 +686,7 @@ attrcurse(void) ret = TELEPORT; break; } + FALLTHROUGH; /*FALLTHRU*/ case 3: if (HPoison_resistance) { @@ -694,6 +697,7 @@ attrcurse(void) ret = POISON_RES; break; } + FALLTHROUGH; /*FALLTHRU*/ case 4: if (HTelepat & INTRINSIC) { @@ -704,6 +708,7 @@ attrcurse(void) ret = TELEPAT; break; } + FALLTHROUGH; /*FALLTHRU*/ case 5: if (HCold_resistance) { @@ -714,6 +719,7 @@ attrcurse(void) ret = COLD_RES; break; } + FALLTHROUGH; /*FALLTHRU*/ case 6: if (HInvis & INTRINSIC) { @@ -722,6 +728,7 @@ attrcurse(void) ret = INVIS; break; } + FALLTHROUGH; /*FALLTHRU*/ case 7: if (HSee_invisible & INTRINSIC) { @@ -737,6 +744,7 @@ attrcurse(void) ret = SEE_INVIS; break; } + FALLTHROUGH; /*FALLTHRU*/ case 8: if (HFast & INTRINSIC) { @@ -745,6 +753,7 @@ attrcurse(void) ret = FAST; break; } + FALLTHROUGH; /*FALLTHRU*/ case 9: if (HStealth & INTRINSIC) { @@ -753,6 +762,7 @@ attrcurse(void) ret = STEALTH; break; } + FALLTHROUGH; /*FALLTHRU*/ case 10: /* intrinsic protection is just disabled, not set back to 0 */ @@ -762,6 +772,7 @@ attrcurse(void) ret = PROTECTION; break; } + FALLTHROUGH; /*FALLTHRU*/ case 11: if (HAggravate_monster & INTRINSIC) { @@ -770,6 +781,7 @@ attrcurse(void) ret = AGGRAVATE_MONSTER; break; } + FALLTHROUGH; /*FALLTHRU*/ case 12: if (HSleep_resistance) { diff --git a/src/sounds.c b/src/sounds.c index 0a9df9e96b..bfcc67567b 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -306,6 +306,7 @@ dosounds(void) break; } } + FALLTHROUGH; /*FALLTHRU*/ case 0: Soundeffect(se_guards_footsteps, 30); @@ -683,7 +684,6 @@ cry_sound(struct monst *mtmp) ret = "hiss"; break; case MS_ROAR: /* baby dragons; have them growl instead of roar */ - /*FALLTHRU*/ case MS_GROWL: /* (none) */ ret = "growl"; break; @@ -925,6 +925,7 @@ domonnoise(struct monst *mtmp) } break; } + FALLTHROUGH; /*FALLTHRU*/ case MS_GROWL: Soundeffect((mtmp->mpeaceful ? se_snarl : se_growl), 80); @@ -1097,6 +1098,7 @@ domonnoise(struct monst *mtmp) } break; } + FALLTHROUGH; /*FALLTHRU*/ case MS_HUMANOID: if (!mtmp->mpeaceful) { @@ -1251,7 +1253,8 @@ domonnoise(struct monst *mtmp) (void) demon_talk(mtmp); break; } - /* fall through */ + FALLTHROUGH; + /* FALLTHRU */ case MS_CUSS: if (!mtmp->mpeaceful) cuss(mtmp); diff --git a/src/spell.c b/src/spell.c index 86553590c4..96f7597a23 100644 --- a/src/spell.c +++ b/src/spell.c @@ -445,7 +445,7 @@ learn(void) faded_to_blank = TRUE; /* reset spestudied as if polymorph had taken place */ book->spestudied = rn2(book->spestudied); - + } else { Your("knowledge of %s is %s.", splname, spellknow(i) ? "keener" : "restored"); @@ -1511,12 +1511,14 @@ spelleffects(int spell_otyp, boolean atme, boolean force) * magical energy */ u.uen += Role_if(PM_CARTOMANCER) ? 0 : rnd(energy / 2 + 1); } + FALLTHROUGH; /*FALLTHRU*/ /* these spells are all duplicates of wand effects */ case SPE_FORCE_BOLT: physical_damage = TRUE; - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ case SPE_SLEEP: case SPE_MAGIC_MISSILE: case SPE_KNOCK: @@ -1582,7 +1584,8 @@ spelleffects(int spell_otyp, boolean atme, boolean force) /* high skill yields effect equivalent to blessed scroll */ if (role_skill >= P_SKILLED) pseudo->blessed = 1; - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ case SPE_MAGIC_MAPPING: case SPE_CREATE_MONSTER: (void) seffects(pseudo); @@ -1597,7 +1600,8 @@ spelleffects(int spell_otyp, boolean atme, boolean force) /* high skill yields effect equivalent to blessed potion */ if (role_skill >= P_SKILLED) pseudo->blessed = 1; - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ case SPE_INVISIBILITY: (void) peffects(pseudo); break; diff --git a/src/steed.c b/src/steed.c index 816597ce66..7a7902f47a 100644 --- a/src/steed.c +++ b/src/steed.c @@ -591,6 +591,7 @@ dismount_steed( switch (reason) { case DISMOUNT_THROWN: verb = "are thrown"; + FALLTHROUGH; /*FALLTHRU*/ case DISMOUNT_KNOCKED: case DISMOUNT_FELL: diff --git a/src/timeout.c b/src/timeout.c index 178e99f475..99639f5b60 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -82,6 +82,7 @@ const struct propname { { SICK_RES, "sickness resistance" }, { ANTIMAGIC, "magic resistance" }, { HALLUC_RES, "hallucination resistance" }, + { BLND_RES, "light-induced blindness resistance" }, { FUMBLING, "fumbling" }, { HUNGER, "voracious hunger" }, { TELEPAT, "telepathic" }, @@ -220,7 +221,8 @@ vomiting_dialogue(void) make_stunned((HStun & TIMEOUT) + (long) d(2, 4), FALSE); if (!Popeye(VOMITING)) stop_occupation(); - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ case 9: make_confused((HConfusion & TIMEOUT) + (long) d(2, 4), FALSE); if (gm.multi > 0) @@ -1160,7 +1162,8 @@ nh_timeout(void) break; case PROT_FROM_SHAPE_CHANGERS: /* No message */ - restartcham(); + if (!Protection_from_shape_changers) + restartcham(); break; case REFLECTING: if (!Blind) { @@ -1688,6 +1691,7 @@ burn_object(anything *arg, long timeout) switch (obj->where) { case OBJ_INVENT: need_invupdate = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case OBJ_MINVENT: pline("%spotion of oil has burnt away.", whose); @@ -1751,6 +1755,7 @@ burn_object(anything *arg, long timeout) switch (obj->where) { case OBJ_INVENT: need_invupdate = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case OBJ_MINVENT: if (obj->otyp == BRASS_LANTERN) @@ -1830,6 +1835,7 @@ burn_object(anything *arg, long timeout) switch (obj->where) { case OBJ_INVENT: need_invupdate = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case OBJ_MINVENT: pline("%scandelabrum's flame%s.", whose, @@ -1845,7 +1851,8 @@ burn_object(anything *arg, long timeout) case OBJ_INVENT: /* no need_invupdate for update_inventory() necessary; useupall() -> freeinv() handles it */ - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ case OBJ_MINVENT: pline("%s %s consumed!", Yname2(obj), many ? "are" : "is"); @@ -1914,6 +1921,7 @@ burn_object(anything *arg, long timeout) switch (obj->where) { case OBJ_INVENT: need_invupdate = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case OBJ_MINVENT: pline("%sholographic card stops glowing.", whose); diff --git a/src/topten.c b/src/topten.c index 28f63668c1..c82e0b3ab7 100644 --- a/src/topten.c +++ b/src/topten.c @@ -110,11 +110,13 @@ formatkiller( switch (svk.killer.format) { default: impossible("bad killer format? (%d)", svk.killer.format); + FALLTHROUGH; /*FALLTHRU*/ case NO_KILLER_PREFIX: break; case KILLED_BY_AN: kname = an(kname); + FALLTHROUGH; /*FALLTHRU*/ case KILLED_BY: (void) strncat(buf, killed_by_prefix[how], siz - 1); diff --git a/src/trap.c b/src/trap.c index 8dfbd35c7b..bc2385b8d4 100644 --- a/src/trap.c +++ b/src/trap.c @@ -477,7 +477,7 @@ struct trap * maketrap(coordxy x, coordxy y, int typ) { static union vlaunchinfo zero_vl; - boolean oldplace; + boolean oldplace, was_ice, clear_flags; struct trap *ttmp; struct rm *lev = &levl[x][y]; @@ -495,10 +495,10 @@ maketrap(coordxy x, coordxy y, int typ) || (u.utraptype == TT_LAVA && !is_lava(x, y)))) reset_utrap(FALSE); /* old remain valid */ - } else if (!CAN_OVERWRITE_TERRAIN(lev->typ) - || (IS_FURNITURE(lev->typ) - && (typ != PIT && typ != HOLE)) + } else if (!CAN_OVERWRITE_TERRAIN(lev->typ) /* stairs */ || is_pool_or_lava(x, y) + || (IS_FURNITURE(lev->typ) && (typ != PIT && typ != HOLE)) + || (lev->typ == DRAWBRIDGE_UP && typ == MAGIC_PORTAL) || (IS_AIR(lev->typ) && typ != MAGIC_PORTAL) || (is_puddle(x, y) && typ == WEB) || (typ == LEVEL_TELEP && single_level_branch(&u.uz))) { @@ -588,6 +588,7 @@ maketrap(coordxy x, coordxy y, int typ) case PIT: case SPIKED_PIT: ttmp->conjoined = 0; + FALLTHROUGH; /*FALLTHRU*/ case HOLE: case TRAPDOOR: @@ -597,22 +598,41 @@ maketrap(coordxy x, coordxy y, int typ) && (is_hole(typ) || IS_DOOR(lev->typ) || IS_WALL(lev->typ))) add_damage(x, y, /* schedule repair */ ((IS_DOOR(lev->typ) || IS_WALL(lev->typ)) - && !svc.context.mon_moving) - ? SHOP_HOLE_COST - : 0L); - lev->doormask = 0; /* subsumes altarmask, icedpool... */ - if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */ + && !svc.context.mon_moving) ? SHOP_HOLE_COST : 0L); + + clear_flags = TRUE; /* assume lev->flags needs to be reset */ + /* DRAWBRIDGE_UP passes the IS_ROOM() test so check it first; + it also needs to retain lev->drawbridgemask */ + if (lev->typ == DRAWBRIDGE_UP) { + /* bridge is closed and we're putting a hole or pit at the span + spot; this trap will be deleted if/when the bridge is opened; + terrain becomes room floor even if it was moat, lava, or ice */ + clear_flags = FALSE; /* keep lev->drawbridgemask */ + was_ice = (lev->drawbridgemask & DB_UNDER) == DB_ICE; + lev->drawbridgemask &= ~DB_UNDER; + lev->drawbridgemask |= DB_FLOOR; + if (was_ice) { + /* subset of set_levltyp() after changing ice to floor; + frozen corpses resume rotting, no more ice to melt away */ + obj_ice_effects(x, y, TRUE); + spot_stop_timers(x, y, MELT_ICE_AWAY); + } + } else if (IS_ROOM(lev->typ)) { (void) set_levltyp(x, y, ROOM); + /* * some cases which can happen when digging * down while phazing thru solid areas */ - else if (lev->typ == STONE || lev->typ == SCORR) + } else if (lev->typ == STONE || lev->typ == SCORR) { (void) set_levltyp(x, y, CORR); - else if (IS_WALL(lev->typ) || lev->typ == SDOOR) + } else if (IS_WALL(lev->typ) || lev->typ == SDOOR) { (void) set_levltyp(x, y, svl.level.flags.is_maze_lev ? ROOM : svl.level.flags.is_cavernous_lev ? CORR : DOOR); + } + if (clear_flags) + lev->flags = 0; /* set_levltyp doesn't take care of this [yet?] */ unearth_objs(x, y); break; @@ -1192,10 +1212,13 @@ m_harmless_trap(struct monst *mtmp, struct trap *ttmp) case COLD_TRAP: break; /* Affects cold resistant monsters too */ case PIT: + FALLTHROUGH; /*FALLTHRU*/ case SPIKED_PIT: + FALLTHROUGH; /*FALLTHRU*/ case HOLE: + FALLTHROUGH; /*FALLTHRU*/ case TRAPDOOR: if (is_clinger(mdat) && !Sokoban) @@ -2712,6 +2735,7 @@ trapeffect_web( mtmp->mtrapped = 1; break; } + FALLTHROUGH; /*FALLTHRU*/ default: if (mptr->mlet == S_GIANT @@ -3385,6 +3409,7 @@ immune_to_trap(struct monst *mon, unsigned ttype) if (pm->msize <= MZ_SMALL || amorphous(pm) || is_whirly(pm) || unsolid(pm)) return TRAP_CLEARLY_IMMUNE; + FALLTHROUGH; /*FALLTHRU*/ case SQKY_BOARD: case LANDMINE: @@ -3486,6 +3511,7 @@ immune_to_trap(struct monst *mon, unsigned ttype) for monsters, only replicates fire trap, so fall through */ if (is_you) return TRAP_NOT_IMMUNE; + FALLTHROUGH; /*FALLTHRU*/ case FIRE_TRAP: /* can always destroy items being carried */ /* harmful if not resistant or if carrying anything that could burn */ @@ -3961,10 +3987,12 @@ launch_obj( /* use otrapped as a flag to ohitmon */ singleobj->otrapped = 1; style &= ~LAUNCH_KNOWN; + FALLTHROUGH; /*FALLTHRU*/ case ROLL: roll: delaycnt = 2; + FALLTHROUGH; /*FALLTHRU*/ default: if (!delaycnt) @@ -4072,6 +4100,7 @@ launch_obj( /* if trap doesn't work, skip "disappears" message */ if (newlev == depth(&u.uz)) break; + FALLTHROUGH; /*FALLTHRU*/ case TELEP_TRAP: if (cansee(x, y)) @@ -4770,6 +4799,7 @@ float_down( case TRAPDOOR: if (!Can_fall_thru(&u.uz) || u.ustuck) break; + FALLTHROUGH; /*FALLTHRU*/ default: if (!u.utrap) /* not already in the trap */ diff --git a/src/uhitm.c b/src/uhitm.c index 227b7f9c90..d9dcefe84c 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 uhitm.c $NHDT-Date: 1713334817 2024/04/17 06:20:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.444 $ */ +/* NetHack 3.7 uhitm.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.451 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -4539,6 +4539,7 @@ mhitm_ad_deth( mhm->damage = 0; return; } + FALLTHROUGH; /*FALLTHRU*/ default: /* case 16: ... case 5: */ You_feel("your life force draining away..."); @@ -6615,10 +6616,12 @@ hmonas(struct monst *mon) case AT_CLAW: if (uwep && !cantwield(gy.youmonst.data) && !weapon_used) goto use_weapon; + FALLTHROUGH; /*FALLTHRU*/ case AT_TUCH: if (uwep && gy.youmonst.data->mlet == S_LICH && !weapon_used) goto use_weapon; + FALLTHROUGH; /*FALLTHRU*/ case AT_BITE: /* [ALI] Vampires are also smart. They avoid biting @@ -6884,6 +6887,7 @@ hmonas(struct monst *mon) || gy.youmonst.data->mlet == S_ORC || gy.youmonst.data->mlet == S_GNOME) && !weapon_used) goto use_weapon; + FALLTHROUGH; /*FALLTHRU*/ case AT_NONE: @@ -7406,6 +7410,8 @@ passive_obj( obj->oerodeproof = 0; break; } + FALLTHROUGH; + /* FALLTHRU */ default: break; } @@ -7418,8 +7424,11 @@ DISABLE_WARNING_FORMAT_NONLITERAL void stumble_onto_mimic(struct monst *mtmp) { - const char *fmt = "Wait! That's %s!", *generic = "a monster", *what = 0; + static char generic[] = "a monster"; + char fmt[QBUFSZ]; + const char *what = NULL; + Strcpy(fmt, "Wait! That's %s!"); if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK) /* must be adjacent; attack via polearm could be from farther away */ && m_next2u(mtmp)) @@ -7433,16 +7442,39 @@ stumble_onto_mimic(struct monst *mtmp) } else { int glyph = levl[u.ux + u.dx][u.uy + u.dy].glyph; - if (glyph_is_cmap(glyph) && (glyph_to_cmap(glyph) == S_hcdoor - || glyph_to_cmap(glyph) == S_vcdoor)) - fmt = "The door actually was %s!"; - else if (glyph_is_object(glyph) && glyph_to_obj(glyph) == GOLD_PIECE) - fmt = "That gold was %s!"; + if (glyph_is_cmap(glyph)) { + Sprintf(fmt, "%s %s actually is %%s!", + is_cmap_stairs(glyph) ? "Those" : "That", + defsyms[mtmp->mappearance].explanation); + /* BUG: this will misclassify a paralyzed mimic as sleeping */ + what = x_monnam(mtmp, ARTICLE_A, "sleeping", 0, FALSE); + } else if (glyph_is_object(glyph)) { + boolean fakeobj; + const char *otmp_name; + struct obj *otmp = NULL; + + fakeobj = object_from_map(glyph, mtmp->mx, mtmp->my, &otmp); + otmp_name = (otmp && otmp->otyp != STRANGE_OBJECT) + ? simpleonames(otmp) : "strange object"; + Sprintf(fmt, "%s %s %s %%s!", + otmp && is_plural(otmp) ? "Those" : "That", + otmp_name, otmp ? otense(otmp, "are") : "is"); + if (fakeobj && otmp) { + otmp->where = OBJ_FREE; /* object_from_map set to OBJ_FLOOR */ + dealloc_obj(otmp); + } + } /* cloned Wiz starts out mimicking some other monster and might make himself invisible before being revealed */ if (mtmp->minvis && !See_invisible) what = generic; + else if (mtmp->data->mlet == S_MIMIC + && (M_AP_TYPE(mtmp) == M_AP_OBJECT + || M_AP_TYPE(mtmp) == M_AP_FURNITURE) + && (mtmp->msleeping || mtmp->mfrozen)) + /* BUG: this will misclassify a paralyzed mimic as sleeping */ + what = x_monnam(mtmp, ARTICLE_A, "sleeping", 0, FALSE); else what = a_monnam(mtmp); } diff --git a/src/weapon.c b/src/weapon.c index c5c72debb2..98cad2d248 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1825,7 +1825,9 @@ weapon_hit_bonus(struct obj *weapon) } else if (type <= P_LAST_WEAPON) { switch (P_SKILL(type)) { default: - impossible(bad_skill, P_SKILL(type)); /* fall through */ + impossible(bad_skill, P_SKILL(type)); + FALLTHROUGH; + /* FALLTHRU */ case P_ISRESTRICTED: case P_UNSKILLED: bonus = -4; @@ -1849,7 +1851,9 @@ weapon_hit_bonus(struct obj *weapon) skill = P_SKILL(wep_type); switch (skill) { default: - impossible(bad_skill, skill); /* fall through */ + impossible(bad_skill, skill); + FALLTHROUGH; + /* FALLTHRU */ case P_ISRESTRICTED: case P_UNSKILLED: bonus = -9; @@ -1923,7 +1927,8 @@ weapon_dam_bonus(struct obj *weapon) switch (P_SKILL(type)) { default: impossible("weapon_dam_bonus: bad skill %d", P_SKILL(type)); - /* fall through */ + FALLTHROUGH; + /* FALLTHRU */ case P_ISRESTRICTED: case P_UNSKILLED: bonus = -2; diff --git a/src/windows.c b/src/windows.c index 323e1f7cef..508d7c7b28 100644 --- a/src/windows.c +++ b/src/windows.c @@ -1876,6 +1876,7 @@ dump_status_update( break; case BL_GOLD: text = decode_mixed(goldbuf, text); + FALLTHROUGH; /*FALLTHRU*/ default: attrmask = (color >> 8) & 0x00FF; diff --git a/src/wizard.c b/src/wizard.c index 729256a6d8..663599d864 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -286,8 +286,8 @@ strategy(struct monst *mtmp) case 1: /* the wiz is less cautious */ if (mtmp->data != &mons[PM_WIZARD_OF_YENDOR]) return (unsigned long) STRAT_HEAL; - /* else fall through */ - + FALLTHROUGH; + /* FALLTHRU */ case 2: dstrat = STRAT_HEAL; break; @@ -401,6 +401,7 @@ tactics(struct monst *mtmp) mtmp->mhp += rnd(8); return 1; } + FALLTHROUGH; /*FALLTHRU*/ case STRAT_NONE: /* harass */ diff --git a/src/wizcmds.c b/src/wizcmds.c index 8607e9fab6..9854bb6b16 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1079,6 +1079,7 @@ wiz_intrinsic(void) so needs more than simple incr_itimeout() but we want the pline() issued with that */ make_glib((int) newtimeout); + FALLTHROUGH; /*FALLTHRU*/ default: def_feedback: diff --git a/src/worm.c b/src/worm.c index 317fcc4a13..fe1bfac909 100644 --- a/src/worm.c +++ b/src/worm.c @@ -993,4 +993,15 @@ flip_worm_segs_horizontal(struct monst *worm, int minx, int maxx) } } +void +redraw_worm(struct monst *worm) +{ + struct wseg *curr = wtails[worm->wormno]; + + while (curr) { + newsym(curr->wx, curr->wy); + curr = curr->nseg; + } +} + /*worm.c*/ diff --git a/src/zap.c b/src/zap.c index 46a3cdba1f..10e700b910 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 zap.c $NHDT-Date: 1723946858 2024/08/18 02:07:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.542 $ */ +/* NetHack 3.7 zap.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.551 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -153,7 +153,11 @@ learnwand(struct obj *obj) } } -/* Routines for IMMEDIATE wands and spells. */ +/* + * Routines for IMMEDIATE wands and spells. + * Also RAY or NODIR for wands that are being broken rather than zapped. + */ + /* bhitm: monster mtmp was hit by the effect of wand or spell otmp */ int bhitm(struct monst *mtmp, struct obj *otmp) @@ -181,7 +185,8 @@ bhitm(struct monst *mtmp, struct obj *otmp) switch (otyp) { case WAN_STRIKING: zap_type_text = "wand"; - /*FALLTHRU*/ + FALLTHROUGH; + /*FALLTHRU*/ case SPE_FORCE_BOLT: reveal_invis = TRUE; if (disguised_mimic) @@ -432,6 +437,10 @@ bhitm(struct monst *mtmp, struct obj *otmp) } case WAN_LOCKING: case SPE_WIZARD_LOCK: + /* can't use Is_box() here */ + if (disguised_mimic && (is_obj_mappear(mtmp, CHEST) + || is_obj_mappear(mtmp, LARGE_BOX))) + seemimic(mtmp); wake = closeholdingtrap(mtmp, &learn_it); break; case WAN_PROBING: @@ -442,6 +451,9 @@ bhitm(struct monst *mtmp, struct obj *otmp) break; case WAN_OPENING: case SPE_KNOCK: + if (disguised_mimic && (is_obj_mappear(mtmp, CHEST) + || is_obj_mappear(mtmp, LARGE_BOX))) + seemimic(mtmp); wake = FALSE; /* don't want immediate counterattack */ if (mtmp == u.ustuck) { if (otyp == SPE_KNOCK) { @@ -576,7 +588,8 @@ bhitm(struct monst *mtmp, struct obj *otmp) break; case WAN_SLEEP: /* (broken wand) */ /* [wakeup() doesn't rouse victims of temporary sleep, - so it's okay to leave `wake' set to TRUE here] */ + so it's okay to leave `wake' set to TRUE here; + revealing concealed mimic is handled by sleep_monst()] */ reveal_invis = TRUE; if (sleep_monst(mtmp, d(1 + otmp->spe, 12), WAND_CLASS)) slept_monst(mtmp); @@ -584,6 +597,8 @@ bhitm(struct monst *mtmp, struct obj *otmp) learn_it = TRUE; break; case SPE_STONE_TO_FLESH: + /* FIXME: mimics disguished as stone furniture or stone object + should be taken out of concealment. */ if (monsndx(mtmp->data) == PM_STONE_GOLEM) { char *name = Monnam(mtmp); @@ -1052,7 +1067,7 @@ revive(struct obj *corpse, boolean by_hero) x = xy.x, y = xy.y; } - if (corpse->norevive || (mons[montype].mlet == S_EEL + if (corpse->norevive || (mons[montype].mlet == S_EEL && !(IS_POOL(levl[x][y].typ) || IS_PUDDLE(levl[x][y].typ)))) { if (cansee(x, y)) pline("%s twitches feebly.", @@ -1214,6 +1229,7 @@ revive(struct obj *corpse, boolean by_hero) obfree(corpse, (struct obj *) 0); break; } + FALLTHROUGH; /*FALLTHRU*/ case OBJ_FREE: case OBJ_MIGRATING: @@ -2265,6 +2281,7 @@ stone_to_flesh_obj(struct obj *obj) /* nonnull */ smell = TRUE; break; case WEAPON_CLASS: /* crysknife */ + FALLTHROUGH; /*FALLTHRU*/ default: res = 0; @@ -3280,6 +3297,7 @@ zapyourself(struct obj *obj, boolean ordinary) case WAN_LIGHT: /* (broken wand) */ /* assert( !ordinary ); */ damage = d(obj->spe, 25); + FALLTHROUGH; /*FALLTHRU*/ case EXPENSIVE_CAMERA: if (!damage) @@ -3848,6 +3866,7 @@ zap_updown(struct obj *obj) /* wand or spell, nonnull */ case WAN_STRIKING: case SPE_FORCE_BOLT: striking = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case WAN_LOCKING: case SPE_WIZARD_LOCK: @@ -4158,7 +4177,8 @@ exclam(int force) } void -hit(const char *str, /* zap text or missile name */ +hit( + const char *str, /* zap text or missile name */ struct monst *mtmp, /* target; for missile, might be hero */ const char *force) /* usually either "." or "!" via exclam() */ { @@ -4167,11 +4187,8 @@ hit(const char *str, /* zap text or missile name */ && (cansee(gb.bhitpos.x, gb.bhitpos.y) || canspotmon(mtmp) || engulfing_u(mtmp)))); - if (!verbosely) - pline("%s %s it.", The(str), vtense(str, "hit")); - else - pline("%s %s %s%s", The(str), vtense(str, "hit"), - mon_nam(mtmp), force); + pline("%s %s %s%s", The(str), vtense(str, "hit"), + verbosely ? mon_nam(mtmp) : "it", force); } void @@ -4541,7 +4558,7 @@ bhit( ((!(weapon == KICKED_WEAPON || weapon == THROWN_WEAPON) && obj->otyp == SPE_FIRE_BOLT))) { if (cansee(gb.bhitpos.x, gb.bhitpos.y)) - pline("Steam billows from the %s.", + pline("Steam billows from the %s.", explain_terrain(gb.bhitpos.x, gb.bhitpos.y)); if (typ == FOUNTAIN) dryup(gb.bhitpos.x, gb.bhitpos.y, TRUE); @@ -4968,7 +4985,8 @@ zhitm( tmp += destroy_items(mon, AD_COLD, orig_dmg); break; case ZT_SLEEP: - /* possibly resistance and shield effect handled by sleep_monst() */ + /* resistance and shield effect and revealing concealed mimic are + handled by sleep_monst() */ tmp = 0; (void) sleep_monst(mon, d(nd, 25), type == ZT_WAND(ZT_SLEEP) ? WAND_CLASS : '\0'); @@ -5947,6 +5965,7 @@ dobuzz( switch (bounce) { case 0: dx = -dx; + FALLTHROUGH; /*FALLTHRU*/ case 1: dy = -dy; @@ -6321,6 +6340,7 @@ zap_over_floor( break; case ZT_LIGHTNING: + FALLTHROUGH; /*FALLTHRU*/ case ZT_ACID: if (lev->typ == IRONBARS) { diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 41e461f110..f1644247ca 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 libnhmain.c $NHDT-Date: 1693359589 2023/08/30 01:39:49 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 3.7 libnhmain.c $NHDT-Date: 1693359589 2023/08/30 01:39:49 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.106 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -12,6 +12,7 @@ #include #include #include +#include #ifndef O_RDONLY #include #endif @@ -103,8 +104,8 @@ nhmain(int argc, char *argv[]) exit(EXIT_SUCCESS); #ifdef CRASHREPORT - if (argcheck(argc, argv, ARG_BIDSHOW)) - exit(EXIT_SUCCESS); + if (argcheck(argc, argv, ARG_BIDSHOW)) + exit(EXIT_SUCCESS); #endif if (argcheck(argc, argv, ARG_SHOWPATHS) == 2) { @@ -174,6 +175,12 @@ nhmain(int argc, char *argv[]) chdirx(dir, 1); #endif +#ifdef __EMSCRIPTEN__ + js_helpers_init(); + js_constants_init(); + js_globals_init(); +#endif + #ifdef _M_UNIX check_sco_console(); #endif @@ -201,11 +208,6 @@ nhmain(int argc, char *argv[]) process_options(argc, argv); /* command line options */ #ifdef WINCHAIN commit_windowchain(); -#endif -#ifdef __EMSCRIPTEN__ - js_helpers_init(); - js_constants_init(); - js_globals_init(); #endif init_nhwindows(&argc, argv); /* now we can set up window system */ #ifdef _M_UNIX @@ -781,9 +783,9 @@ EM_JS(void, js_helpers_init, (), { globalThis.nethackGlobal = globalThis.nethackGlobal || {}; globalThis.nethackGlobal.helpers = globalThis.nethackGlobal.helpers || {}; - installHelper(displayInventory); - installHelper(getPointerValue); - installHelper(setPointerValue); + installHelper(displayInventory, "displayInventory"); + installHelper(getPointerValue, "getPointerValue"); + installHelper(setPointerValue, "setPointerValue"); // used by update_inventory function displayInventory() { @@ -804,6 +806,8 @@ EM_JS(void, js_helpers_init, (), { return getValue(ptr, "*"); case "c": // char return String.fromCharCode(getValue(ptr, "i8")); + case "b": + return getValue(ptr, "i8") == 1; case "0": /* 2^0 = 1 byte */ return getValue(ptr, "i8"); case "1": /* 2^1 = 2 bytes */ @@ -816,8 +820,8 @@ EM_JS(void, js_helpers_init, (), { return getValue(ptr, "float"); case "d": // double return getValue(ptr, "double"); - case "o": // overloaded: multiple types - return ptr; + case "v": // void + return undefined; default: throw new TypeError ("unknown type:" + type); } @@ -828,7 +832,8 @@ EM_JS(void, js_helpers_init, (), { // console.log("setPointerValue", name, "0x" + ptr.toString(16), type, value); switch (type) { case "p": - throw new Error("not implemented"); + setValue(ptr, value, "*"); + break; case "s": if(typeof value !== "string") throw new TypeError(`expected ${name} return type to be string`); @@ -841,6 +846,11 @@ EM_JS(void, js_helpers_init, (), { throw new TypeError(`expected ${name} return type to be integer`); setValue(ptr, value, "i32"); break; + case "1": + if(typeof value !== "number" || !Number.isInteger(value)) + throw new TypeError(`expected ${name} return type to be integer`); + setValue(ptr, value, "i16"); + break; case "c": if(typeof value !== "number" || value < 0 || value > 128) throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); @@ -857,6 +867,10 @@ EM_JS(void, js_helpers_init, (), { throw new TypeError(`expected ${name} return type to be double`); setValue(ptr, value, "double"); break; + case "b": + if (typeof value !== "boolean") + throw new TypeError(`expected ${name} return type to be boolean`); + setValue(ptr, value ? 1 : 0, "i8"); case "v": break; default: @@ -896,11 +910,19 @@ EM_JS(void, set_const_str, (char *scope_str, char *name_str, char *input_str), { globalThis.nethackGlobal.constants[scope] = globalThis.nethackGlobal.constants[scope] || {}; globalThis.nethackGlobal.constants[scope][name] = str; }); +#define SET_POINTER(name) set_const_ptr(#name, (void *)&name); +EM_JS(void, set_const_ptr, (char *name_str, void* ptr), { + let name = UTF8ToString(name_str); + + globalThis.nethackGlobal.pointers = globalThis.nethackGlobal.pointers || {}; + globalThis.nethackGlobal.pointers[name] = ptr; +}); void js_constants_init() { EM_ASM({ globalThis.nethackGlobal = globalThis.nethackGlobal || {}; globalThis.nethackGlobal.constants = globalThis.nethackGlobal.constants || {}; + globalThis.nethackGlobal.pointers = globalThis.nethackGlobal.pointers || {}; }); // create_nhwindow @@ -989,8 +1011,7 @@ void js_constants_init() { // copyright SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_A); SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_B); - // XXX: not set for cross-compile - //SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_C); + set_const_str("COPYRIGHT", "COPYRIGHT_BANNER_C", (char*) COPYRIGHT_BANNER_C); SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_D); // glyphs @@ -1042,6 +1063,119 @@ void js_constants_init() { SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_BLINK); SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_INVERSE); SET_CONSTANT("COLOR_ATTR", BL_ATTCLR_MAX); + + SET_CONSTANT("BL_MASK", BL_MASK_BAREH); + SET_CONSTANT("BL_MASK", BL_MASK_BLIND); + SET_CONSTANT("BL_MASK", BL_MASK_BUSY); + SET_CONSTANT("BL_MASK", BL_MASK_CONF); + SET_CONSTANT("BL_MASK", BL_MASK_DEAF); + SET_CONSTANT("BL_MASK", BL_MASK_ELF_IRON); + SET_CONSTANT("BL_MASK", BL_MASK_FLY); + SET_CONSTANT("BL_MASK", BL_MASK_FOODPOIS); + SET_CONSTANT("BL_MASK", BL_MASK_GLOWHANDS); + SET_CONSTANT("BL_MASK", BL_MASK_GRAB); + SET_CONSTANT("BL_MASK", BL_MASK_HALLU); + SET_CONSTANT("BL_MASK", BL_MASK_HELD); + SET_CONSTANT("BL_MASK", BL_MASK_ICY); + SET_CONSTANT("BL_MASK", BL_MASK_INLAVA); + SET_CONSTANT("BL_MASK", BL_MASK_LEV); + SET_CONSTANT("BL_MASK", BL_MASK_PARLYZ); + SET_CONSTANT("BL_MASK", BL_MASK_RIDE); + SET_CONSTANT("BL_MASK", BL_MASK_SLEEPING); + SET_CONSTANT("BL_MASK", BL_MASK_SLIME); + SET_CONSTANT("BL_MASK", BL_MASK_SLIPPERY); + SET_CONSTANT("BL_MASK", BL_MASK_STONE); + SET_CONSTANT("BL_MASK", BL_MASK_STRNGL); + SET_CONSTANT("BL_MASK", BL_MASK_STUN); + SET_CONSTANT("BL_MASK", BL_MASK_SUBMERGED); + SET_CONSTANT("BL_MASK", BL_MASK_TERMILL); + SET_CONSTANT("BL_MASK", BL_MASK_TETHERED); + SET_CONSTANT("BL_MASK", BL_MASK_TRAPPED); + SET_CONSTANT("BL_MASK", BL_MASK_UNCONSC); + SET_CONSTANT("BL_MASK", BL_MASK_WOUNDEDL); + SET_CONSTANT("BL_MASK", BL_MASK_HOLDING); + + SET_CONSTANT("ROLE_RACEMASK", MH_HUMAN); + SET_CONSTANT("ROLE_RACEMASK", MH_ELF); + SET_CONSTANT("ROLE_RACEMASK", MH_DWARF); + SET_CONSTANT("ROLE_RACEMASK", MH_GNOME); + SET_CONSTANT("ROLE_RACEMASK", MH_ORC); + + SET_CONSTANT("ROLE_GENDMASK", ROLE_MALE); + SET_CONSTANT("ROLE_GENDMASK", ROLE_FEMALE); + SET_CONSTANT("ROLE_GENDMASK", ROLE_NEUTER); + + SET_CONSTANT("ROLE_ALIGNMASK", ROLE_LAWFUL); + SET_CONSTANT("ROLE_ALIGNMASK", ROLE_NEUTRAL); + SET_CONSTANT("ROLE_ALIGNMASK", ROLE_CHAOTIC); + + SET_CONSTANT("blconditions", bl_bareh); + SET_CONSTANT("blconditions", bl_blind); + SET_CONSTANT("blconditions", bl_busy); + SET_CONSTANT("blconditions", bl_conf); + SET_CONSTANT("blconditions", bl_deaf); + SET_CONSTANT("blconditions", bl_elf_iron); + SET_CONSTANT("blconditions", bl_fly); + SET_CONSTANT("blconditions", bl_foodpois); + SET_CONSTANT("blconditions", bl_glowhands); + SET_CONSTANT("blconditions", bl_grab); + SET_CONSTANT("blconditions", bl_hallu); + SET_CONSTANT("blconditions", bl_held); + SET_CONSTANT("blconditions", bl_icy); + SET_CONSTANT("blconditions", bl_inlava); + SET_CONSTANT("blconditions", bl_lev); + SET_CONSTANT("blconditions", bl_parlyz); + SET_CONSTANT("blconditions", bl_ride); + SET_CONSTANT("blconditions", bl_sleeping); + SET_CONSTANT("blconditions", bl_slime); + SET_CONSTANT("blconditions", bl_slippery); + SET_CONSTANT("blconditions", bl_stone); + SET_CONSTANT("blconditions", bl_strngl); + SET_CONSTANT("blconditions", bl_stun); + SET_CONSTANT("blconditions", bl_submerged); + SET_CONSTANT("blconditions", bl_termill); + SET_CONSTANT("blconditions", bl_tethered); + SET_CONSTANT("blconditions", bl_trapped); + SET_CONSTANT("blconditions", bl_unconsc); + SET_CONSTANT("blconditions", bl_woundedl); + SET_CONSTANT("blconditions", bl_holding); + SET_CONSTANT("blconditions", CONDITION_COUNT); + + SET_CONSTANT("HL", HL_UNDEF); + SET_CONSTANT("HL", HL_NONE); + SET_CONSTANT("HL", HL_BOLD); + SET_CONSTANT("HL", HL_DIM); + SET_CONSTANT("HL", HL_ITALIC); + SET_CONSTANT("HL", HL_ULINE); + SET_CONSTANT("HL", HL_BLINK); + SET_CONSTANT("HL", HL_INVERSE); + + SET_CONSTANT("MG", MG_HERO); + SET_CONSTANT("MG", MG_CORPSE); + SET_CONSTANT("MG", MG_INVIS); + SET_CONSTANT("MG", MG_DETECT); + SET_CONSTANT("MG", MG_PET); + SET_CONSTANT("MG", MG_RIDDEN); + SET_CONSTANT("MG", MG_STATUE); + SET_CONSTANT("MG", MG_OBJPILE); + SET_CONSTANT("MG", MG_BW_LAVA); + SET_CONSTANT("MG", MG_BW_ICE); + SET_CONSTANT("MG", MG_BW_SINK); + SET_CONSTANT("MG", MG_BW_ENGR); + SET_CONSTANT("MG", MG_NOTHING); + SET_CONSTANT("MG", MG_UNEXPL); + SET_CONSTANT("MG", MG_MALE); + SET_CONSTANT("MG", MG_FEMALE); + + SET_POINTER(extcmdlist); + SET_POINTER(conditions); + SET_POINTER(condtests); + + /* roles/races/genders/alignments */ + SET_POINTER(roles); + SET_POINTER(races); + SET_POINTER(genders); + SET_POINTER(aligns); } /*** @@ -1073,6 +1207,20 @@ void js_globals_init() { CREATE_GLOBAL(WIN_MESSAGE, "i"); CREATE_GLOBAL(WIN_INVEN, "i"); CREATE_GLOBAL(WIN_STATUS, "i"); + + /* instance flags */ + CREATE_GLOBAL(iflags.window_inited, "b"); + CREATE_GLOBAL(iflags.wc2_hitpointbar, "b"); + CREATE_GLOBAL(iflags.wc_hilite_pet, "b"); + CREATE_GLOBAL(iflags.hilite_pile, "b"); + + /* flags */ + CREATE_GLOBAL(flags.initrole, "i"); + CREATE_GLOBAL(flags.initrace, "i"); + CREATE_GLOBAL(flags.initgend, "i"); + CREATE_GLOBAL(flags.initalign, "i"); + CREATE_GLOBAL(flags.showexp, "b"); + CREATE_GLOBAL(flags.time, "b"); } EM_JS(void, create_global, (char *name_str, void *ptr, char *type_str), { diff --git a/sys/msdos/video.c b/sys/msdos/video.c index e172513ee5..6397fa8d85 100644 --- a/sys/msdos/video.c +++ b/sys/msdos/video.c @@ -293,6 +293,7 @@ term_end_attr(int attr) switch (attr) { case ATR_INVERSE: inversed = 0; + FALLTHROUGH; /*FALLTHRU*/ case ATR_ULINE: case ATR_BOLD: @@ -341,6 +342,7 @@ term_start_attr(int attr) break; case ATR_INVERSE: inversed = 1; + FALLTHROUGH; /*FALLTHRU*/ default: g_attribute = iflags.grmode ? attrib_gr_normal : attrib_text_normal; diff --git a/sys/share/cppregex.cpp b/sys/share/cppregex.cpp index 4d45928c7c..9835a1f5ca 100644 --- a/sys/share/cppregex.cpp +++ b/sys/share/cppregex.cpp @@ -10,7 +10,7 @@ extern "C" { #include "config.h" #define CPPREGEX_C -//#include "extern.h" +#include "nhregex.h" } // extern "C" diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 2290c2fbc6..7d08cc4cf2 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -157,6 +157,8 @@ DAT = $(DATNODLB) $(DATDLB) # $(CHGRP) $(GAMEGRP) $(INSTDIR)/sysconf && \ # chmod $(VARFILEPERM) $(INSTDIR)/sysconf; fi ); +RECOVERBIN = recover + # Lua LUAHEADERS = lib/lua-$(LUA_VERSION)/src LUATESTTARGET = $(LUAHEADERS)/lua.h @@ -322,7 +324,7 @@ package: $(GAME) recover $(VARDAT) spec_levs # recover can be used when INSURANCE is defined in include/config.h # and the checkpoint option is true recover: $(GAME) - ( cd util ; $(MAKE) recover ) + ( cd util ; $(MAKE) $(RECOVERBIN) ) dofiles: target=`sed -n \ diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index c2b40bd876..ebe974cc10 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -200,7 +200,7 @@ HACKLIBOBJ = $(OBJDIR)/hacklib.o panic.o MAKEOBJS = makedefs.o $(OMONOBJ) $(ODATE) $(OALLOC) # object files for recovery utility -RECOVOBJS = $(TARGETPFX)recover.o +RECOVOBJS = recover.o # object files for the data librarian DLBOBJS = dlb_main.o $(OBJDIR)/dlb.o $(OALLOC) @@ -277,12 +277,12 @@ lintdgn: # dependencies for recover # -$(TARGETPFX)recover: $(RECOVOBJS) $(TARGETPFX)$(HACKLIB) - $(TARGET_CLINK) $(TARGET_LFLAGS) -o recover \ - $(RECOVOBJS) $(TARGETPFX)$(HACKLIB) $(LIBS) +recover: $(RECOVOBJS) $(HACKLIB) + $(CLINK) $(LFLAGS) -o recover \ + $(RECOVOBJS) $(HACKLIB) $(LIBS) -$(TARGETPFX)recover.o: recover.c $(CONFIG_H) - $(TARGET_CC) $(TARGET_CFLAGS) $(CSTD) -c recover.c -o $@ +recover.o: recover.c $(CONFIG_H) + $(CC) $(CFLAGS) $(CSTD) -c recover.c -o $@ # dependencies for dlb @@ -441,7 +441,10 @@ clean-fixup: clean: clean-fixup -rm -f *.o +# obsolete dgn_comp and lev_comp could be left around from 3.6.x spotless: clean -rm -f makedefs recover dlb $(HACKLIB) -rm -f gif2txt txt2ppm tile2x11 tile2img.ttp xpm2img.ttp \ tilemap tileedit tile2bmp uudecode + -rm -f dgn_comp* dgn_lex.c dgn_yacc.c ../include/dgn_comp.h \ + lev_comp* lev_lex.c lev_yacc.c ../include/lev_comp.h diff --git a/sys/unix/hints/include/compiler.370 b/sys/unix/hints/include/compiler.370 index 49ec119f7e..1605818a61 100755 --- a/sys/unix/hints/include/compiler.370 +++ b/sys/unix/hints/include/compiler.370 @@ -78,20 +78,28 @@ CXX=g++ -std=gnu++11 GCCGTEQ9 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 9) GCCGTEQ11 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 11) GCCGTEQ12 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 12) +GCCGTEQ14 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 14) ifeq "$(GCCGTEQ9)" "1" # flags present in gcc version greater than or equal to 9 can go here CFLAGS+=-Wformat-overflow CFLAGS+=-Wmissing-parameter-type endif # GCC greater than or equal to 9 #ifeq "$(GCCGTEQ11)" "1" +CFLAGS+=-Wimplicit-fallthrough #endif #ifeq "$(GCCGTEQ12)" "1" #endif +#ifeq "$(GCCGTEQ14)" "1" +#endif # end of gcc-specific else # gcc or clang? CXX=clang++ -std=gnu++11 # clang-specific follows +CLANGGTEQ12 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 12) CLANGGTEQ14 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 14) +ifeq "$(CLANGGTEQ12)" "1" +CFLAGS+=-Wimplicit-fallthrough +endif ifeq "$(CLANGGTEQ14)" "1" ifneq "$(VIEWDEPRECATIONS)" "1" CFLAGS+=-Wno-deprecated-declarations @@ -119,6 +127,7 @@ CCXX=g++ -std=gnu++11 GPPGTEQ9 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 9) GPPGTEQ11 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 11) GPPGTEQ12 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 12) +GPPGTEQ14 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 14) ifeq "$(GPPGTEQ9)" "1" CCXXFLAGS+=-Wformat-overflow ifdef CPLUSPLUS_NEED_DEPSUPPRESS @@ -135,7 +144,7 @@ CFLAGS+=-fPIC endif # g++ version greater than or equal to 11 ifdef CPLUSPLUS_NEED17 ifeq "$(GPPGTEQ12)" "1" -CCXX=g++ -std=c++20 +CCXX=g++ -std=c++17 else # g++ version greater than or equal to 12? (no follows) CCXX=g++ -std=c++17 endif # g++ version greater than or equal to 12 @@ -149,6 +158,7 @@ CCXX=clang++ -std=c++11 CLANGPPGTEQ9 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 9) CLANGPPGTEQ11 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 11) CLANGPPGTEQ14 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 14) +CLANGPPGTEQ16 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 16) CLANGPPGTEQ17 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 17) ifeq "$(CLANGPPGTEQ9)" "1" #CCXXFLAGS+=-Wformat-overflow @@ -170,7 +180,7 @@ ifeq "$(CLANGPPGTEQ14)" "1" CCXX=clang++ -std=c++17 endif # clang++ greater than or equal to 14 ifeq "$(CLANGPPGTEQ17)" "1" -CCXX=clang++ -std=c++20 +CCXX=clang++ -std=c++17 endif # clang++ greater than or equal to 17 endif # CPLUSPLUS_NEED17 endif # end of clang++-specific section diff --git a/sys/unix/hints/include/cross-post.370 b/sys/unix/hints/include/cross-post.370 index aff9363a2c..1d1200b6af 100644 --- a/sys/unix/hints/include/cross-post.370 +++ b/sys/unix/hints/include/cross-post.370 @@ -42,7 +42,7 @@ $(DOSFONT)/ter-u28b.psf: $(FONTTOP)/ter-u28b.bdf $(DOSFONT)/nh-u28b.bdf $(DOSFON $(DOSFONT)/ter-u32b.psf: $(FONTTOP)/ter-u32b.bdf $(DOSFONT)/nh-u32b.bdf $(DOSFONT)/makefont.lua $(LUABIN) $(LUABIN) $(DOSFONT)/makefont.lua $(FONTTOP)/ter-u32b.bdf $(DOSFONT)/nh-u32b.bdf $@ # -.PHONY: dodata dospkg dosfonts recover +.PHONY: dodata dospkg dosfonts dosfonts: $(FONTTARGETS) dospkg: dodata dosfonts $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp $(TARGET_STUBEDIT) $(GAMEBIN) minstack=2048K @@ -107,12 +107,17 @@ $(TARGETPFX)unixtty.o : ../sys/share/unixtty.c $(HACK_H) $(TARGETPFX)winshim.o : ../win/shim/winshim.c $(HACK_H) $(TARGETPFX)libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) endif # CROSS_TO_WASM + # ifdef CROSS_TO_MIPS -$(MIPS_TARGET): pregame $(TARGETPFX)date.o $(HOSTOBJ) $(HOBJ) $(LUACROSSLIB) $(MIPS_DATA_DIR) +$(MIPS_TARGET): pregame $(TARGETPFX)date.o $(HOSTOBJ) $(HOBJ) $(LUACROSSLIB) \ + $(TARGETPFX)ncurses/lib/libncurses.a \ + $(MIPS_DATA_DIR) -rm $@ - $(TARGET_CC) $(TARGET_LFLAGS) $(TARGET_CFLAGS) -o $@ \ - $(HOBJ) $(TARGETPFX)date.o $(TARGET_LIBS) + $(TARGET_LINK) $(TARGET_LFLAGS) -o $@ \ + $(HOBJ) $(TARGETPFX)date.o $(TARGETPFX)$(HACKLIB) \ + $(TARGETPFX)ncurses/lib/libncurses.a \ + $(TARGET_LIBS) $(MIPS_DATA_DIR): $(MIPS_DATA_DIR)/nhdat touch $(MIPS_DATA_DIR)/perm @@ -131,9 +136,28 @@ $(TARGETPFX)unixres.o : ../sys/unix/unixres.c $(HACK_H) $(TARGETPFX)unixunix.o : ../sys/unix/unixunix.c $(HACK_H) $(TARGETPFX)ioctl.o : ../sys/share/ioctl.c $(HACK_H) $(TARGETPFX)unixtty.o : ../sys/share/unixtty.c $(HACK_H) -endif # CROSS_TO_MIPS -# +$(LUABIN): + ( cd .. && make luabin && cd src) +dodata: + ( cd .. && make dlb && cd src) + +mipsrecover: $(TARGETPFX)recover +.PHONY: mipspkg +mipspkg: dodata $(GAMEBIN) $(TARGETPFX)recover + mkdir -p $(TARGETPFX)pkg + cp $(GAMEBIN) $(TARGETPFX)pkg/nethack + cp $(TARGETPFX)recover $(TARGETPFX)pkg/recover + cp ../dat/nhdat $(TARGETPFX)pkg/nhdat + cp ../dat/license $(TARGETPFX)pkg/license + cp ../dat/symbols $(TARGETPFX)pkg/symbols + cp ../sys/share/NetHack.cnf $(TARGETPFX)pkg/.nethackrc + cp ../sys/msdos/sysconf $(TARGETPFX)pkg/sysconf + cp ../doc/nethack.txt $(TARGETPFX)pkg/nethack.txt + -touch $(TARGETPFX)pkg/record + cd $(TARGETPFX)pkg ; zip -9 ../nh370mips.zip * ; cd ../../.. + @echo MIPS package zip file $(TARGETPFX)nh370mips.zip +endif # CROSS_TO_MIPS ifdef CROSS_SHARED # shared file dependencies @@ -144,16 +168,26 @@ $(TARGETPFX)pcunix.o : ../sys/share/pcunix.c $(HACK_H) $(TARGETPFX)tileset.o : ../win/share/tileset.c $(TARGETPFX)bmptiles.o : ../win/share/bmptiles.c $(TARGETPFX)giftiles.o : ../win/share/giftiles.c -$(TARGETPFX)recover.o : ../util/recover.c endif # CROSS_SHARED # ifdef CROSS $(TARGETPFX)hacklib.a: $(TARGETPFX)hacklib.o $(TARGET_AR) $(TARGET_ARFLAGS) $@ $(TARGETPFX)hacklib.o +ifdef MAKEFILE_UTL +$(TARGETPFX)recover.o: recover.c $(CONFIG_H) + $(TARGET_CC) $(TARGET_CFLAGS) $(CSTD) -c recover.c -o $@ +ifdef CROSS_TO_MSDOS $(TARGETPFX)recover.exe : $(TARGETPFX)recover.o $(TARGETPFX)hacklib.a $(TARGET_LINK) $(TARGET_LFLAGS) \ $(TARGETPFX)recover.o $(TARGETPFX)hacklib.a -o $@ +else +$(TARGETPFX)recover : $(TARGETPFX)recover.o $(TARGETPFX)hacklib.a + $(TARGET_LINK) $(TARGET_LFLAGS) \ + $(TARGETPFX)recover.o $(TARGETPFX)hacklib.a -o $@ endif +endif # MAKEFILE_UTL +endif # CROSS + ifdef BUILD_TARGET_LUA # Lua lib $(LUACROSSLIB): $(LUALIBOBJS) diff --git a/sys/unix/hints/include/cross-pre2.370 b/sys/unix/hints/include/cross-pre2.370 index c8f2603883..2cad202b50 100644 --- a/sys/unix/hints/include/cross-pre2.370 +++ b/sys/unix/hints/include/cross-pre2.370 @@ -84,8 +84,6 @@ PDCOBJS = $(TARGETPFX)pdcclip.o $(TARGETPFX)pdcdisp.o \ $(TARGETPFX)pdcscrn.o $(TARGETPFX)pdcsetsc.o \ $(TARGETPFX)pdcutil.o override TARGET_LIBS += $(PDCLIB) -ifdef CROSS_TO_MSDOS -endif override BUILDMORE += $(PDCLIB) override CLEANMORE += rm -f $(PDCLIB) ; else #WANT_WIN_CURSES @@ -142,6 +140,7 @@ MSDOS_TARGET_CFLAGS = -c -O -I../include -I../sys/msdos -I../win/share \ -Wall -Wextra -Wno-missing-field-initializers -Wreturn-type -Wunused \ -Wformat -Wswitch -Wshadow -Wwrite-strings \ -Wimplicit -Wimplicit-function-declaration -Wimplicit-int \ + -Wimplicit-fallthrough \ -Wmissing-parameter-type -Wold-style-definition -Wstrict-prototypes MSDOS_TARGET_CXXFLAGS = -c -O -I../include -I../sys/msdos -I../win/share \ $(LUAINCL) -DDLB $(PDCURSESDEF) \ @@ -191,7 +190,8 @@ override WINLIB= override LUALIB= override LUALIBS= override TOPLUALIB= -override GAMEBIN = $(TARGETPFX)NerfHack.exe +override GAMEBIN = $(TARGETPFX)nerfhack.exe +override RECOVERBIN = $(TARGETPFX)recover.exe override PACKAGE = dospkg override PREGAME += mkdir -p $(TARGETDIR) ; make $(TARGETPFX)exceptn.o ; override CLEANMORE += rm -f -r $(TARGETDIR) ; rm -f -r $(FONTTARGETS) ; @@ -216,7 +216,7 @@ ifdef CROSS_TO_WASM # originally from https://github.com/NetHack/NetHack/pull/385 #===============-================================================= # -WASM_DEBUG = 1 +#WASM_DEBUG = 1 WASM_DATA_DIR = $(TARGETPFX)wasm-data WASM_TARGET = $(TARGETPFX)nethack.js EMCC_LFLAGS = @@ -227,10 +227,13 @@ EMCC_LFLAGS += -s ALLOW_TABLE_GROWTH EMCC_LFLAGS += -s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]' EMCC_LFLAGS += -O3 EMCC_LFLAGS += -s MODULARIZE -EMCC_LFLAGS += -s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback", "_display_inventory"]' +EMCC_LFLAGS += -s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback", "_display_inventory", "_malloc"]' EMCC_LFLAGS += -s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", \ - "removeFunction", "UTF8ToString", "getValue", "setValue"]' + "removeFunction", "UTF8ToString", "stringToUTF8", "getValue", \ + "setValue", "ENV", "FS", "IDBFS"]' EMCC_LFLAGS += -s ERROR_ON_UNDEFINED_SYMBOLS=0 +EMCC_LFLAGS += -s EXPORT_ES6=1 +EMCC_LFLAGS += -lidbfs.js # XXX: the "@/" at the end of "--embed-file" tells emscripten to embed the files # in the root directory, otherwise they will end up in the $(WASM_DATA_DIR) path EMCC_LFLAGS += --embed-file $(WASM_DATA_DIR)@/ @@ -355,6 +358,7 @@ CFLAGS += -DCROSSCOMPILE override TARGET_CC = mipsel-linux-gnu-gcc override TARGET_CXX = CXX=mipsel-linux-gnu-g++ override TARGET_AR = mipsel-linux-gnu-ar +MIPS_TARGET = $(TARGETPFX)nethack #override TARGET_LINK = mipsel-linux-gnu-ld MIPS_TARGET_CFLAGS = -c -O -I../include -I../sys/unix -I../win/share \ $(LUAINCL) -DDLB \ @@ -386,8 +390,9 @@ override WINLIB = $(NCURSESLIB) override LUALIB= override LUALIBS= override TOPLUALIB= -#override GAMEBIN= -#override PACKAGE= +override GAMEBIN=$(MIPS_TARGET) +override RECOVERBIN = $(TARGETPFX)recover +override PACKAGE = mipspkg override PREGAME += mkdir -p $(TARGETDIR) ; override CLEANMORE += rm -f -r $(TARGETDIR) ; # Rule for file in sys/unix diff --git a/sys/unix/hints/linux.370 b/sys/unix/hints/linux.370 index c0c9b42f38..c610a8d7f5 100755 --- a/sys/unix/hints/linux.370 +++ b/sys/unix/hints/linux.370 @@ -74,6 +74,9 @@ endif # WANT_WIN_QT5 ifdef WANT_WIN_QT6 #if your Qt6 is elsewhere, change this to match QTDIR=/usr/local/qt6 +ifeq "$(GPPGTEQ14)" "1" +CCXXFLAGS += -Wno-template-id-cdtor +endif # g++ greater than or equal to 14 endif # WANT_WIN_QT6 endif # WANT_WIN_QT diff --git a/sys/unix/hints/macOS.370 b/sys/unix/hints/macOS.370 index a8c462d803..306c9d2826 100755 --- a/sys/unix/hints/macOS.370 +++ b/sys/unix/hints/macOS.370 @@ -87,6 +87,13 @@ endif # HAVE_MACPORTS endif # QTDIR endif # WANT_WIN_QT +ifdef WANT_WIN_QT +ifeq "$(CLANGPPGTEQ16)" "1" +CXX=clang++ --std=c++17 +CCXXFLAGS +=-Wno-c++20-attribute-extensions +endif +endif + # misc.370 must come after compiler.370 # and after QTDIR is defined diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 9153364b80..1533eac409 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -644,15 +644,15 @@ early_options(int *argc_p, char ***argv_p, char **hackdir_p) ++arg; switch (arg[1]) { /* char after leading dash */ - case 'b': + case 'b': #ifdef CRASHREPORT - // --bidshow - if (argcheck(argc, argv, ARG_BIDSHOW) == 2){ + // --bidshow + if (argcheck(argc, argv, ARG_BIDSHOW) == 2){ opt_terminate(); /*NOTREACHED*/ - } + } #endif - break; + break; case 'd': if (argcheck(argc, argv, ARG_DEBUG) == 1) { consume_arg(ndx, argc_p, argv_p), consumed = 1; diff --git a/sys/vms/vmsunix.c b/sys/vms/vmsunix.c index deb890ac4c..b1bd0813ef 100644 --- a/sys/vms/vmsunix.c +++ b/sys/vms/vmsunix.c @@ -241,6 +241,7 @@ vms_define(const char *name, const char *value, int flag) switch (flag) { case ENV_JOB: /* job logical name */ tbl_dsc.len = strlen(tbl_dsc.adr = "LNM$JOB"); + FALLTHROUGH; /*FALLTHRU*/ case ENV_SUP: /* supervisor-mode process logical name */ result = lib$set_logical(&nam_dsc, &val_dsc, &tbl_dsc); diff --git a/sys/windows/Makefile.mingw32 b/sys/windows/Makefile.mingw32 index 11b5d87d8a..0a0d54abca 100644 --- a/sys/windows/Makefile.mingw32 +++ b/sys/windows/Makefile.mingw32 @@ -334,15 +334,19 @@ else DLBFLG = endif + ifeq "$(GCC_EXTRA_WARNINGS)" "Y" # # These match the warnings enabled on the linux.370 and macOS.370 hints builds # -CFLAGSXTRA = -Wall -Wextra -Wno-missing-field-initializers -Wreturn-type \ - -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -pedantic \ - -Wmissing-declarations -Wformat-nonliteral -Wunreachable-code \ - -Wimplicit -Wimplicit-function-declaration -Wimplicit-int \ - -Wmissing-prototypes -Wold-style-definition -Wstrict-prototypes +CFLAGSXTRA = -Wall -Wextra -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow \ + -Wwrite-strings -pedantic -Wmissing-declarations \ + -Wformat-nonliteral -Wunreachable-code -Wimplicit \ + -Wimplicit-function-declaration -Wimplicit-int \ + -Wmissing-prototypes -Wold-style-definition \ + -Wstrict-prototypes -Wnonnull -Wformat-overflow \ + -Wmissing-parameter-type -Wimplicit-fallthrough + CPPFLAGSXTRA = -Wall -Wextra -Wno-missing-field-initializers -Wreturn-type \ -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -pedantic \ -Wmissing-declarations -Wformat-nonliteral -Wunreachable-code diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index ba5d096f20..ec5f878957 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -9,7 +9,7 @@ # # Visual Studio Compilers Tested: # - Microsoft Visual Studio 2019 Community Edition v 16.11.42 -# - Microsoft Visual Studio 2022 Community Edition v 17.12.0 +# - Microsoft Visual Studio 2022 Community Edition v 17.12.2 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -231,6 +231,13 @@ WANT_CURSES=Y WANT_CURSES=Y !ENDIF +!IF "$(CURSES_CONSOLE)" != "Y" +!IF "$(CURSES_GRAPHICAL)" != "Y" +WANT_CURSES=N +ADD_CURSES=N +!ENDIF +!ENDIF + # Now, pdcursesmod !IF "$(WANT_CURSES)" == "Y" PDCDIST=pdcursesmod @@ -459,8 +466,12 @@ PDCURSES_CURSES_H = $(PDCURSES_TOP)\curses.h PDCURSES_CURSPRIV_H = $(PDCURSES_TOP)\curspriv.h PDCURSES_HEADERS = $(PDCURSES_CURSES_H) $(PDCURSES_CURSPRIV_H) PDCSRC = $(PDCURSES_TOP)\pdcurses +!IF "$(CURSES_CONSOLE)" == "Y" PDCWINCON = $(PDCURSES_TOP)\wincon +!ENDIF +!IF "$(CURSES_GRAPHICAL)" == "Y" PDCWINGUI = $(PDCURSES_TOP)\wingui +!ENDIF PDCDEP = $(PDCURSES_TOP)\curses.h PDCCOMMONOBJS = $(OPDC)addch.o $(OPDC)addchstr.o $(OPDC)addstr.o $(OPDC)attr.o $(OPDC)beep.o \ @@ -474,17 +485,25 @@ PDCCOMMONOBJS = $(OPDC)addch.o $(OPDC)addchstr.o $(OPDC)addstr.o $(OPDC)attr.o $ $(OPDC)scroll.o $(OPDC)slk.o $(OPDC)termattr.o $(OPDC)touch.o \ $(OPDC)util.o $(OPDC)window.o +PDCINCL = /I$(PDCURSES_TOP) /I$(PDCSRC) +!IF "$(CURSES_CONSOLE)" == "Y" +PDCINCLCON = /I$(PDCWINCON) PDCWINCONOBJS = $(OPDCC)pdcclip.o $(OPDCC)pdcdisp.o $(OPDCC)pdcgetsc.o \ $(OPDCC)pdckbd.o $(OPDCC)pdcscrn.o $(OPDCC)pdcsetsc.o $(OPDCC)pdcutil.o - +!ENDIF +!IF "$(CURSES_GRAPHICAL)" == "Y" PDCWINGUIOBJS = $(OPDCG)pdcclip.o $(OPDCG)pdcdisp.o $(OPDCG)pdcgetsc.o \ $(OPDCG)pdckbd.o $(OPDCG)pdcscrn.o $(OPDCG)pdcsetsc.o $(OPDCG)pdcutil.o - -PDCINCL = /I$(PDCURSES_TOP) /I$(PDCSRC) PDCINCLGUI = /I$(PDCWINCON) -PDCINCLCON = /I$(PDCWINGUI) +!ENDIF !ELSE -PDCDEP = +PDCDEP= +PDCCOMMONOBJS= +PDCWINCONOBJS= +PDCWINGUIOBJS= +PDCINCL= +PDINCLGUI= +PDCINCLCON= !ENDIF @@ -795,19 +814,20 @@ CURSESOBJ= $(OTTY)cursdial.o $(OTTY)cursinit.o $(OTTY)cursinvt.o \ !IF "$(CURSES_CONSOLE)" == "Y" CURSESWINCONOBJS = $(CURSESOBJ) PDCWINCONLIB = $(LIBDIR)\$(PDCDIST)-wincon-$(TARGET_CPU)-static.lib -CURSESDEF1=-D"CURSES_GRAPHICS" -DPDC_NCMOUSE +CURSESCONDEF1=-D"CURSES_GRAPHICS" -DPDC_NCMOUSE #CURSESDEF2=-D"CURSES_BRIEF_INCLUDE" -DCHTYPE_32 CURSESDEF2=-DCURSES_UNICODE $(PDCURSESFLAGS) !ENDIF !IF "$(CURSES_GRAPHICAL)" == "Y" CURSESWINGUIOBJS = $(CURSESOBJ) $(OGUI)guitty.o PDCWINGUILIB = $(LIBDIR)\$(PDCDIST)-wingui-$(TARGET_CPU)-static.lib -CURSESDEF1=-D"CURSES_GRAPHICS" -DPDC_NCMOUSE +CURSESGUIDEF1=-D"CURSES_GRAPHICS" -DPDC_NCMOUSE #CURSESDEF2=-D"CURSES_BRIEF_INCLUDE" -DCHTYPE_32 CURSESDEF2=-DCURSES_UNICODE $(PDCURSESFLAGS) !ENDIF !ELSE -!UNDEF CURSDEF +!UNDEF CURSDEF1 +!UNDEF CURSDEF2 !UNDEF CURSESLIB !UNDEF CURSESOBJ !UNDEF CURSESWINCONOBJS @@ -828,7 +848,7 @@ OGUIHACKLIB = $(OGUI)hacklib-$(TARGET_CPU)-static.lib # - TTY # -TTYDEF= -D"_CONSOLE" -DWIN32CON $(CURSESDEF1) +TTYDEF= -D"_CONSOLE" -DWIN32CON $(CURSESCONDEF1) $(CURSESGUIDEF1) RANDOMTTY = $(OTTY)random.o MDLIBTTY = $(OTTY)mdlib.o @@ -887,7 +907,7 @@ ALLOBJTTY = $(SOBJTTY) $(DLBOBJTTY) $(OBJSTTY) $(VVOBJTTY) $(LUAOBJTTY) # - GUI # -GUIDEF= -DTILES -DMSWIN_GRAPHICS -DNOTTYGRAPHICS $(CURSESDEF1) +GUIDEF= -DTILES -DMSWIN_GRAPHICS -DNOTTYGRAPHICS $(CURSESGUIDEF1) ALL_GUIHDR = $(MSWIN)\mhaskyn.h $(MSWIN)\mhdlg.h $(MSWIN)\mhfont.h \ $(MSWIN)\mhinput.h $(MSWIN)\mhmain.h $(MSWIN)\mhmap.h $(MSWIN)\mhmenu.h \ @@ -1170,7 +1190,7 @@ rc=Rc.exe # # Recently tested versions: TESTEDVS2019 = 14.29.30157.0 -TESTEDVS2022 = 14.42.34433.0 +TESTEDVS2022 = 14.42.34435.0 VS2019CUR = $(TESTEDVS2019:.=) VS2022CUR = $(TESTEDVS2022:.=) @@ -1292,10 +1312,18 @@ scall = # 4777 format string requires an argument of type 'type', # but variadic argument 'position' has type 'type' # 4820 padding in struct +# 5262 enable fallthrough warnings that lack [[fallthrough]] +# ctmpflags = $(ctmpflags:-W3=-W4) -wd4100 -wd4244 -wd4245 -wd4310 -wd4706 -w44777 -wd4820 !IF ($(VSVER) >= 2019) ctmpflags = $(ctmpflags) -w44774 !ENDIF +!IF ($(VSVER) >= 2022) +!IF ($(MAKEVERSION) >= 1440338120) +# warning 5262 became available starting in Visual Studio 2022 version 17.4. +ctmpflags = $(ctmpflags) -w45262 /std:clatest +!ENDIF +!ENDIF !ENDIF #More verbose warning output options below @@ -1479,33 +1507,38 @@ DLB = #========================================== # Rules for files in win\curses #========================================== - {$(WCURSES)}.c{$(OBJTTY)}.o: - $(Q)$(CC) $(PDCINCL) $(CFLAGS) $(CURSESDEF1) $(CURSESDEF2) $(TTYDEF) $(GUIDEF) $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< + $(Q)$(CC) $(PDCINCL) $(CFLAGS) $(CURSESCONDEF1) $(CURSESGUIDEF1) $(CURSESDEF2) $(TTYDEF) $(GUIDEF) $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< #========================================== # Rules for files in PDCurses #========================================== # +!IF "$(ADD_CURSES)" == "Y" {$(PDCURSES_TOP)}.c{$(OBJPDC)}.o: - $(Q)$(CC) /wd4244 $(PDCINCL) $(CFLAGS) $(CURSESDEF2) $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< + $(Q)$(CC) /wd4244 $(PDCINCL) $(CFLAGS) $(CURSESDEF2) /wd5262 $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< {$(PDCSRC)}.c{$(OBJPDC)}.o: - $(Q)$(CC) /wd4244 /wd4267 /wd4774 $(PDCINCL) $(CFLAGS:-w44774= ) $(CURSESDEF2) $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< + $(Q)$(CC) /wd4244 /wd4267 /wd4774 $(PDCINCL) $(CFLAGS:-w44774= ) $(CURSESDEF2) /wd5262 $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< +!IF "$(CURSES_CONSOLE)" == "Y" {$(PDCWINCON)}.c{$(OBJPDCC)}.o: - $(Q)$(CC) /wd4244 /wd4267 /wd4774 $(PDCINCL) $(PDCINCLCON) $(CFLAGS) $(CURSESDEF2) $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< + $(Q)$(CC) /wd4244 /wd4267 /wd4774 $(PDCINCL) $(PDCINCLCON) $(CFLAGS) $(CURSESDEF2) /wd5262 $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< +!ENDIF +!IF "$(CURSES_GRAPHICAL)" == "Y" {$(PDCWINGUI)}.c{$(OBJPDCG)}.o: - $(Q)$(CC) /wd4244 /wd4267 /wd4774 $(PDCINCL) $(PDCINCLGUI) $(CFLAGS) $(CURSESDEF2) $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< + $(Q)$(CC) /wd4244 /wd4267 /wd4774 $(PDCINCL) $(PDCINCLGUI) $(CFLAGS) $(CURSESDEF2) /wd5262 $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< +!ENDIF +!ENDIF #========================================== # Rules for LUA files #========================================== {$(LUASRC)}.c{$(OBJLUA)}.o: - $(Q)$(CC) $(CFLAGS) -wd4701 -wd4702 -wd4774 -wd4324 $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< + $(Q)$(CC) $(CFLAGS) -wd4701 -wd4702 -wd4774 -wd4324 -wd5262 $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ $< #=============================================================================== # Rules for integrated sound files in sound/wav @@ -1556,11 +1589,12 @@ $(LUASRC)\lua.h: # git submodule update --remote ../submodules/lua # #aka PDCDEP +!IF "$(ADD_CURSES)" == "Y" $(PDCURSES_TOP)\curses.h: git submodule init ../submodules/$(PDCDIST) git submodule update ../submodules/$(PDCDIST) # git submodule update --remote ../submodules/$(PDCDIST) - +!ENDIF !ELSE # GIT_AVAILABLE no CURLLUASRC=https://www.lua.org/ftp/lua-5.4.6.tar.gz CURLLUADST=lua-5.4.6.tar.gz @@ -1575,6 +1609,7 @@ $(LUASRC)\lua.h: curl -L $(CURLLUASRC) -o $(CURLLUADST) tar -xvf $(CURLLUADST) cd ..\src +!IF "$(ADD_CURSES)" == "Y" $(PDCURSES_TOP)\curses.h: @if not exist $(LIBDIR)\*.* mkdir $(LIBDIR) cd $(LIBDIR) @@ -1582,10 +1617,13 @@ $(PDCURSES_TOP)\curses.h: if not exist $(PDCDIST)\*.* mkdir $(PDCDIST) tar -C $(PDCDIST) --strip-components=1 -xvf $(CURLPDCDST) cd ..\src +!ENDIF # ADD_CURSES !ENDIF # GIT_AVAILABLE !ELSE # INTERNET_AVAILABLE $(LUASRC)\lua.h: +!IF "$(ADD_CURSES)" == "Y" $(PDCURSES_TOP)\curses.h: +!ENDIF !ENDIF # INTERNET_AVAILABLE #========================================== @@ -1950,8 +1988,11 @@ pkgdir.tag: envchk.tag: cpu.tag !IFDEF TTYOBJ @echo tty window support included -! IF "$(ADD_CURSES)"=="Y" - @echo curses window support also included +! IF "$(CURSES_CONSOLE)" == "Y" + @echo curses console window support also included +! ENDIF +! IF "$(CURSES_GRAPHICAL)" == "Y" + @echo curses graphical window support also included ! ENDIF !ENDIF ! IF "$(CL)"!="" @@ -1986,6 +2027,7 @@ fetch-actual-Lua: cd ..\src @echo Lua has been fetched into $(LIBDIR)\lua-$(LUAVER) +!IF "$(ADD_CURSES)" == "Y" fetch-pdcurses: @if not exist $(LIBDIR)\*.* mkdir $(LIBDIR) cd $(LIBDIR) @@ -1999,6 +2041,7 @@ fetch-pdcurses: if exist .\$(PDCDIST).zip del .\$(PDCDIST).zip cd ..\src @echo $(PDCDIST) has been fetched into $(LIBDIR)\$(PDCDIST) +!ENDIF #========================================== # DLB utility and nhdatNNN file creation @@ -2204,14 +2247,18 @@ $(SRC)\x11tiles: $(U)tile2x11.exe $(WSHR)\monsters.txt $(WSHR)\objects.txt \ #=============================================================================== # PDCurses #=============================================================================== - +!IF "$(ADD_CURSES)" == "Y" +!IF "$(CURSES_CONSOLE)" == "Y" $(PDCWINCONLIB) : $(PDCCOMMONOBJS) $(PDCWINCONOBJS) @echo Building library $@ from $** @$(librarian) -nologo /out:$@ $(PDCCOMMONOBJS) $(PDCWINCONOBJS) +!ENDIF +!IF "$(CURSES_GRAPHICAL)" == "Y" $(PDCWINGUILIB) : $(PDCCOMMONOBJS) $(PDCWINGUIOBJS) @echo Building library $@ from $** @$(librarian) -nologo /out:$@ $(PDCCOMMONOBJS) $(PDCWINGUIOBJS) - +!ENDIF +!ENDIF $(OGUI)guitty.o: $(MSWSYS)\guitty.c $(WINDHDR) $(HACK_H) $(TILE_H) #=============================================================================== @@ -3022,6 +3069,8 @@ $(OTTY)sfstruct.o: sfstruct.c $(HACK_H) $(OTTY)shk.o: shk.c $(HACK_H) $(OTTY)shknam.o: shknam.c $(HACK_H) $(OTTY)sit.o: sit.c $(HACK_H) $(INCL)\artifact.h + $(Q)$(CC) $(CFLAGS) /EP $(@B).c > $(OTTY)$(@B).c.preproc + $(Q)$(CC) $(CFLAGS) -Fo$@ $(@B).c $(OTTY)sounds.o: sounds.c $(HACK_H) $(OTTY)sp_lev.o: sp_lev.c $(HACK_H) $(INCL)\sp_lev.h $(OTTY)spell.o: spell.c $(HACK_H) diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 3a960d8ec5..35bedebbad 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -98,7 +98,7 @@ cell_t undefined_cell = { CONSOLE_UNDEFINED_CHARACTER, CONSOLE_UNDEFINED_ATTRIBUTE }; #else /* VIRTUAL_TERMINAL_SEQUENCES */ cell_t clear_cell = { { CONSOLE_CLEAR_CHARACTER, 0, 0, 0, 0, 0, 0 }, - CONSOLE_CLEAR_CHARACTER, 0, 0L, 0, "\x1b[0m" }; + CONSOLE_CLEAR_CHARACTER, 0, 0L, 0, "\x1b[0m", 0 }; cell_t undefined_cell = { { CONSOLE_UNDEFINED_CHARACTER, 0, 0, 0, 0, 0, 0 }, CONSOLE_UNDEFINED_CHARACTER, 0, 0L, 0, (const char *) 0 }; static const uint8 empty_utf8str[MAX_UTF8_SEQUENCE] = { 0 }; @@ -300,7 +300,7 @@ static INPUT_RECORD bogus_key; /* Windows console palette: Color Name Console Legacy RGB Values New Default RGB Values -BLACK 0,0,0 12,12,12 +BLACK 0,0,0 12,12,12 DARK_BLUE 0,0,128 0,55,218 DARK_GREEN 0,128,0 19,161,14 DARK_CYAN 0,128,128 58,150,221 @@ -1087,6 +1087,7 @@ CtrlHandler(DWORD ctrltype) /* case CTRL_C_EVENT: */ case CTRL_BREAK_EVENT: term_clear_screen(); + FALLTHROUGH; case CTRL_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: @@ -1335,7 +1336,8 @@ xputc_core(int ch) case '\n': if (console.cursor.Y < console.height - 1) console.cursor.Y++; - /* fall through */ + FALLTHROUGH; + /* FALLTHRU */ case '\r': console.cursor.X = 1; break; @@ -1879,6 +1881,7 @@ toggle_mouse_support(void) #endif /* VIRTUAL_TERMINAL_SEQUENCES */ break; case 0: + FALLTHROUGH; /*FALLTHRU*/ default: #ifndef VIRTUAL_TERMINAL_SEQUENCES diff --git a/sys/windows/vs/NetHack.sln b/sys/windows/vs/NetHack.sln index 19a8202492..da3bd77172 100644 --- a/sys/windows/vs/NetHack.sln +++ b/sys/windows/vs/NetHack.sln @@ -12,6 +12,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NerfHackW", "NetHackW\NetHa {63F9B82B-F589-4082-ABE5-D4F0682050AB} = {63F9B82B-F589-4082-ABE5-D4F0682050AB} {642BC75D-ABAF-403E-8224-7C725FD4CB42} = {642BC75D-ABAF-403E-8224-7C725FD4CB42} {93F10526-209E-41D7-BBEA-775787876895} = {93F10526-209E-41D7-BBEA-775787876895} + {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037} = {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dlb", "dlb\dlb.vcxproj", "{0303A585-3F83-4BB7-AF6B-1E12C8FB54AC}" @@ -60,6 +61,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NerfHack", "NetHack\NetHack {096FD6BB-256A-4E68-9B09-2ACA7C606FF3} = {096FD6BB-256A-4E68-9B09-2ACA7C606FF3} {503AE687-C33A-45ED-93AA-83967E176D67} = {503AE687-C33A-45ED-93AA-83967E176D67} {63F9B82B-F589-4082-ABE5-D4F0682050AB} = {63F9B82B-F589-4082-ABE5-D4F0682050AB} + {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037} = {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037} {BAA70D0F-3EC7-4D10-91F0-974F1F49308B} = {BAA70D0F-3EC7-4D10-91F0-974F1F49308B} EndProjectSection EndProject @@ -101,6 +103,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "package\package. {CEC5D360-8804-454F-8591-002184C23499} = {CEC5D360-8804-454F-8591-002184C23499} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lualib", "lualib\lualib.vcxproj", "{B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037}" + ProjectSection(ProjectDependencies) = postProject + {503AE687-C33A-45ED-93AA-83967E176D67} = {503AE687-C33A-45ED-93AA-83967E176D67} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -213,6 +220,14 @@ Global {0B53AF9B-E1A4-478B-9246-43A39E8B4027}.Release|Win32.Build.0 = Release|Win32 {0B53AF9B-E1A4-478B-9246-43A39E8B4027}.Release|x64.ActiveCfg = Release|x64 {0B53AF9B-E1A4-478B-9246-43A39E8B4027}.Release|x64.Build.0 = Release|x64 + {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037}.Debug|Win32.ActiveCfg = Debug|Win32 + {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037}.Debug|Win32.Build.0 = Debug|Win32 + {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037}.Debug|x64.ActiveCfg = Debug|x64 + {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037}.Debug|x64.Build.0 = Debug|x64 + {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037}.Release|Win32.ActiveCfg = Release|Win32 + {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037}.Release|Win32.Build.0 = Release|Win32 + {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037}.Release|x64.ActiveCfg = Release|x64 + {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/sys/windows/vs/NetHack/NetHack.vcxproj b/sys/windows/vs/NetHack/NetHack.vcxproj index c7f5b166c8..74dcc09789 100644 --- a/sys/windows/vs/NetHack/NetHack.vcxproj +++ b/sys/windows/vs/NetHack/NetHack.vcxproj @@ -40,16 +40,24 @@ - /Gs /Oi- /w44774 %(AdditionalOptions) + /Gs /Oi- /w44774 /w45262 %(AdditionalOptions) Disabled Default Speed true $(WinWin32Dir);$(IncDir);$(SysWindDir);$(SysShareDir);$(WinShareDir);$(LuaDir);%(AdditionalIncludeDirectories) WIN32CON;NO_TILE_C;DLB;SAFEPROCS;SND_LIB_WINDSOUND;USER_SOUNDS;_LIB;HAS_STDINT_H;%(PreprocessorDefinitions) + stdclatest + stdclatest + stdclatest + stdclatest + /Gs /Oi- /w44774 /w45262 %(AdditionalOptions) + /Gs /Oi- /w44774 /w45262 %(AdditionalOptions) + /Gs /Oi- /w44774 /w45262 %(AdditionalOptions) + /Gs /Oi- /w44774 /w45262 %(AdditionalOptions) - hacklib.lib;kernel32.lib;dbghelp.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;Winmm.lib;bcrypt.lib;%(AdditionalDependencies) + hacklib.lib;lualib.lib;kernel32.lib;dbghelp.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;Winmm.lib;bcrypt.lib;%(AdditionalDependencies) $(SndWavDir);%(AdditionalIncludeDirectories) @@ -65,12 +73,6 @@ - - 4701;4702;4244;4310;4774 - %(AdditionalOptions) /wd4774 - 4701;4702;4244;4310;4774;4324 - 4701;4702;4244;4310;4774;4324 - @@ -243,6 +245,8 @@ + + @@ -308,4 +312,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/NetHackW/NetHackW.vcxproj b/sys/windows/vs/NetHackW/NetHackW.vcxproj index 7629fb22c8..1f75f50937 100644 --- a/sys/windows/vs/NetHackW/NetHackW.vcxproj +++ b/sys/windows/vs/NetHackW/NetHackW.vcxproj @@ -53,6 +53,14 @@ true $(WinWin32Dir);$(IncDir);$(SysWindDir);$(SysShareDir);$(WinShareDir);$(LuaDir);%(AdditionalIncludeDirectories) TILES;_WINDOWS;DLB;MSWIN_GRAPHICS;SAFEPROCS;NOTTYGRAPHICS;SND_LIB_WINDSOUND;USER_SOUNDS;HAS_STDINT_H;PDC_WIDE;%(PreprocessorDefinitions) + stdclatest + stdclatest + stdclatest + stdclatest + /Gs /Oi- /w44774 /w45262 %(AdditionalOptions) + /Gs /Oi- /w44774 /w45262 %(AdditionalOptions) + /Gs /Oi- /w44774 /w45262 %(AdditionalOptions) + /Gs /Oi- /w44774 /w45262 %(AdditionalOptions) 4820;4706;4244;4245;4100;4310;6001 4820;4706;4244;4245;4100;4310 @@ -66,7 +74,7 @@ Windows - hacklib.lib;dbghelp.lib;comctl32.lib;winmm.lib;bcrypt.lib;%(AdditionalDependencies) + hacklib.lib;lualib.lib;dbghelp.lib;comctl32.lib;winmm.lib;bcrypt.lib;%(AdditionalDependencies) $(WinWin32Dir)NerfHackW.exe.manifest;%(AdditionalManifestFiles) @@ -74,12 +82,6 @@ - - 4701;4702;4244;4310;4774 - %(AdditionalOptions) /wd4774 - 4701;4702;4244;4310;4774;4324;6011;6297;6305;6385;6386;6387;28182 - 4701;4702;4244;4310;4774;4324 - @@ -372,4 +374,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/dlb/dlb.vcxproj b/sys/windows/vs/dlb/dlb.vcxproj index d54510ff0b..71b96d8236 100644 --- a/sys/windows/vs/dlb/dlb.vcxproj +++ b/sys/windows/vs/dlb/dlb.vcxproj @@ -28,6 +28,10 @@ $(IncDir);$(SysWindDir);$(SysShareDir);$(LuaDir);%(AdditionalIncludeDirectories) WIN32CON;DLB;MSWIN_GRAPHICS;HAS_STDINT_H;%(PreprocessorDefinitions) + stdclatest + stdclatest + stdclatest + stdclatest $(ToolsDir);%(AdditionalLibraryDirectories) @@ -64,4 +68,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/hacklib/hacklib.vcxproj b/sys/windows/vs/hacklib/hacklib.vcxproj index b43c429ea2..4ec744f5c9 100644 --- a/sys/windows/vs/hacklib/hacklib.vcxproj +++ b/sys/windows/vs/hacklib/hacklib.vcxproj @@ -54,13 +54,13 @@ StaticLibrary true - v143 + $(DefaultPlatformToolset) Unicode StaticLibrary false - v143 + $(DefaultPlatformToolset) true Unicode @@ -102,7 +102,9 @@ WIN32;_DEBUG;_LIB;WIN32CON;DLB;MSWIN_GRAPHICS;ENUM_PM;HAS_STDINT_H;%(PreprocessorDefinitions) true $(IncDir);$(SysWindDir);$(LuaDir);%(AdditionalIncludeDirectories) - + stdclatest + /w45262 %(AdditionalOptions) + @@ -118,6 +120,8 @@ WIN32;NDEBUG;_LIB;WIN32CON;DLB;MSWIN_GRAPHICS;ENUM_PM;HAS_STDINT_H;%(PreprocessorDefinitions) true $(IncDir);$(SysWindDir);$(LuaDir);%(AdditionalIncludeDirectories) + stdclatest + /w45262 %(AdditionalOptions) @@ -134,6 +138,8 @@ _DEBUG;_LIB;WIN32CON;DLB;MSWIN_GRAPHICS;ENUM_PM;HAS_STDINT_H;%(PreprocessorDefinitions) true $(IncDir);$(SysWindDir);$(LuaDir);%(AdditionalIncludeDirectories) + stdclatest + /w45262 %(AdditionalOptions) @@ -150,6 +156,8 @@ NDEBUG;_LIB;WIN32CON;DLB;MSWIN_GRAPHICS;ENUM_PM;HAS_STDINT_H;%(PreprocessorDefinitions) true $(IncDir);$(SysWindDir);$(LuaDir);%(AdditionalIncludeDirectories) + stdclatest + /w45262 %(AdditionalOptions) @@ -171,4 +179,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/lualib/lualib.vcxproj b/sys/windows/vs/lualib/lualib.vcxproj new file mode 100644 index 0000000000..52d96e5cb9 --- /dev/null +++ b/sys/windows/vs/lualib/lualib.vcxproj @@ -0,0 +1,483 @@ + + + + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + 4701;4702;4244;4310;4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + %(AdditionalOptions) /wd4774 + + + + + + 17.0 + Win32Proj + {B6B3CC8A-75FD-479C-AB1C-D80FFF0F5037} + lualib + 10.0 + + + + StaticLibrary + true + $(DefaultPlatformToolset) + Unicode + + + StaticLibrary + false + $(DefaultPlatformToolset) + true + Unicode + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_LIB;WIN32CON;DLB;MSWIN_GRAPHICS;ENUM_PM;HAS_STDINT_H;%(PreprocessorDefinitions) + true + $(IncDir);$(SysWindDir);$(LuaDir);%(AdditionalIncludeDirectories) + /Gs /Oi- /w44774 %(AdditionalOptions) + + + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_LIB;WIN32CON;DLB;MSWIN_GRAPHICS;ENUM_PM;HAS_STDINT_H;%(PreprocessorDefinitions) + true + $(IncDir);$(SysWindDir);$(LuaDir);%(AdditionalIncludeDirectories) + /Gs /Oi- /w44774 %(AdditionalOptions) + + + + + true + true + true + + + + + Level3 + true + _DEBUG;_LIB;WIN32CON;DLB;MSWIN_GRAPHICS;ENUM_PM;HAS_STDINT_H;%(PreprocessorDefinitions) + true + $(IncDir);$(SysWindDir);$(LuaDir);%(AdditionalIncludeDirectories) + /Gs /Oi- /w44774 %(AdditionalOptions) + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;WIN32CON;DLB;MSWIN_GRAPHICS;ENUM_PM;HAS_STDINT_H;%(PreprocessorDefinitions) + true + $(IncDir);$(SysWindDir);$(LuaDir);%(AdditionalIncludeDirectories) + /Gs /Oi- /w44774 %(AdditionalOptions) + + + + + true + true + true + + + + + + + + + + + + + + + diff --git a/sys/windows/vs/makedefs/makedefs.vcxproj b/sys/windows/vs/makedefs/makedefs.vcxproj index 9c3abce145..c5bd6c0ddc 100644 --- a/sys/windows/vs/makedefs/makedefs.vcxproj +++ b/sys/windows/vs/makedefs/makedefs.vcxproj @@ -28,13 +28,12 @@ $(IncDir);$(SysWindDir);$(LuaDir);%(AdditionalIncludeDirectories) WIN32CON;DLB;MSWIN_GRAPHICS;ENUM_PM;HAS_STDINT_H;%(PreprocessorDefinitions) + stdclatest + /w45262 %(AdditionalOptions) - $(ToolsDir);%(AdditionalLibraryDirectories) + $(ToolsDir);%(AdditionalLibraryDirectories) hacklib.lib;%(AdditionalDependencies) - $(ToolsDir);%(AdditionalLibraryDirectories) - $(ToolsDir);%(AdditionalLibraryDirectories) - $(ToolsDir);%(AdditionalLibraryDirectories) @@ -69,4 +68,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/recover/recover.vcxproj b/sys/windows/vs/recover/recover.vcxproj index 1e108fcfcd..66fd134d0c 100644 --- a/sys/windows/vs/recover/recover.vcxproj +++ b/sys/windows/vs/recover/recover.vcxproj @@ -20,6 +20,8 @@ $(IncDir);$(SysWindDir);$(LuaDir);%(AdditionalIncludeDirectories) WIN32CON;DLB;MSWIN_GRAPHICS;HAS_STDINT_H;%(PreprocessorDefinitions) + stdclatest + /w45262 %(AdditionalOptions) $(ToolsDir);%(AdditionalLibraryDirectories) diff --git a/sys/windows/vs/tile2bmp/tile2bmp.vcxproj b/sys/windows/vs/tile2bmp/tile2bmp.vcxproj index 113567b865..8207ebceb4 100644 --- a/sys/windows/vs/tile2bmp/tile2bmp.vcxproj +++ b/sys/windows/vs/tile2bmp/tile2bmp.vcxproj @@ -28,23 +28,13 @@ $(IncDir);$(SysWindDir);$(SysShareDir);$(LuaDir);%(AdditionalIncludeDirectories) WIN32CON;DLB;MSWIN_GRAPHICS;HAS_STDINT_H;%(PreprocessorDefinitions) + stdclatest + /w45262 %(AdditionalOptions) - $(ToolsDir);%(AdditionalLibraryDirectories) - hacklib.lib;%(AdditionalDependencies) - - - $(ToolsDir);%(AdditionalLibraryDirectories) - hacklib.lib;%(AdditionalDependencies) - - - $(ToolsDir);%(AdditionalLibraryDirectories) - hacklib.lib;%(AdditionalDependencies) - - - $(ToolsDir);%(AdditionalLibraryDirectories) - hacklib.lib;%(AdditionalDependencies) - + $(ToolsDir);%(AdditionalLibraryDirectories) + hacklib.lib;%(AdditionalDependencies) + @@ -66,4 +56,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/tilemap/tilemap.vcxproj b/sys/windows/vs/tilemap/tilemap.vcxproj index ee79ffc685..aa34626e5a 100644 --- a/sys/windows/vs/tilemap/tilemap.vcxproj +++ b/sys/windows/vs/tilemap/tilemap.vcxproj @@ -30,22 +30,12 @@ $(IncDir);$(SysWindDir);$(SysShareDir);$(LuaDir);%(AdditionalIncludeDirectories) WIN32CON;DLB;MSWIN_GRAPHICS;HAS_STDINT_H;%(PreprocessorDefinitions) + stdclatest + /w45262 %(AdditionalOptions) - $(ToolsDir);%(AdditionalLibraryDirectories) - hacklib.lib;%(AdditionalDependencies) - - - $(ToolsDir);%(AdditionalLibraryDirectories) - hacklib.lib;%(AdditionalDependencies) - - - $(ToolsDir);%(AdditionalLibraryDirectories) - hacklib.lib;%(AdditionalDependencies) - - - $(ToolsDir);%(AdditionalLibraryDirectories) - hacklib.lib;%(AdditionalDependencies) + $(ToolsDir);%(AdditionalLibraryDirectories) + hacklib.lib;%(AdditionalDependencies) @@ -105,4 +95,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/uudecode/uudecode.vcxproj b/sys/windows/vs/uudecode/uudecode.vcxproj index f99aa84b17..5b85f9979e 100644 --- a/sys/windows/vs/uudecode/uudecode.vcxproj +++ b/sys/windows/vs/uudecode/uudecode.vcxproj @@ -31,10 +31,7 @@ - 4820;4702;4706;4244;4245;4100;4310 - 4820;4702;4706;4244;4245;4100;4310 - 4820;4702;4706;4244;4245;4100;4310 - 4820;4702;4706;4244;4245;4100;4310 + 4820;4702;4706;4244;4245;4100;4310 @@ -47,4 +44,4 @@ - \ No newline at end of file + diff --git a/sys/windows/win10.h b/sys/windows/win10.h index 22a4c0f12e..cc8a0bf48d 100644 --- a/sys/windows/win10.h +++ b/sys/windows/win10.h @@ -1,5 +1,5 @@ /* NetHack 3.7 win10.h $NHDT-Date: 1596498319 2020/08/03 23:45:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ */ -/* Copyright (C) 2018 by Bart House */ +/* Copyright (C) 2018 by Bart House */ /* NetHack may be freely redistributed. See license for details. */ #ifndef WIN10_H diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 2c0dd21d15..6bb686e67e 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -69,7 +69,7 @@ void windows_nhbell(void); int windows_nh_poskey(int *, int *, int *); void windows_raw_print(const char *); char windows_yn_function(const char *, const char *, char); -static void windows_getlin(const char *, char *); +/* static void windows_getlin(const char *, char *); */ #ifdef WIN32CON extern int windows_console_custom_nhgetch(void); @@ -116,6 +116,11 @@ void copy_sysconf_content(void); void copy_config_content(void); void copy_hack_content(void); void copy_symbols_content(void); +void copy_file(const char *, const char *, + const char *, const char *, boolean); +void update_file(const char *, const char *, + const char *, const char *, BOOL); +void windows_raw_print_bold(const char *); #ifdef PORT_HELP void port_help(void); @@ -150,6 +155,7 @@ DISABLE_WARNING_UNREACHABLE_CODE #if defined(MSWIN_GRAPHICS) #define MAIN nethackw_main +int nethackw_main(int, char **); #else #define MAIN main #endif @@ -369,7 +375,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ (void) fname_encode( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.", '%', fnamebuf, encodedfnamebuf, BUFSZ); - Sprintf(gl.lock, "%s", encodedfnamebuf); + Snprintf(gl.lock, sizeof gl.lock, "%s", encodedfnamebuf); /* regularize(lock); */ /* we encode now, rather than substitute */ if ((getlock_result = getlock()) == 0) nethack_exit(EXIT_SUCCESS); @@ -630,7 +636,8 @@ process_options(int argc, char * argv[]) break; } else raw_printf("\nUnknown switch: %s", argv[0]); - /* FALL THROUGH */ + FALLTHROUGH; + /* FALLTHRU */ case '?': nhusage(); nethack_exit(EXIT_SUCCESS); @@ -989,6 +996,7 @@ copy_symbols_content(void) copy_file(gf.fqn_prefix[SYSCONFPREFIX], SYMBOLS, gf.fqn_prefix[SYSCONFPREFIX], SYMBOLS_TEMPLATE, TRUE); } + nhUse(no_template); } void @@ -1107,10 +1115,10 @@ boolean fakeconsole(void) { if (!hStdOut) { - HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); - HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); + HANDLE fkhStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + HANDLE fkhStdIn = GetStdHandle(STD_INPUT_HANDLE); - if (!hStdOut && !hStdIn) { + if (!fkhStdOut && !fkhStdIn) { /* Bool rval; */ AllocConsole(); AttachConsole(GetCurrentProcessId()); @@ -1277,11 +1285,13 @@ windows_yn_function(const char *query UNUSED, const char *resp UNUSED, } /*ARGSUSED*/ +#if 0 static void windows_getlin(const char *prompt UNUSED, char *outbuf) { Strcpy(outbuf, "\033"); } +#endif #ifdef PC_LOCKING static int diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index a4e721f189..9023a2d7d1 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -799,7 +799,7 @@ struct CRctxt *ctxp = &ctxp_; // XXX should this now be in gc.* ? #define win32err(fn) errname = fn; goto error int -win32_cr_helper(char cmd, struct CRctxt *ctxp, void *p, int d){ +win32_cr_helper(char cmd, struct CRctxt *contextp, void *p, int d){ char *errname = "unknown"; switch (cmd) { default: @@ -815,77 +815,77 @@ win32_cr_helper(char cmd, struct CRctxt *ctxp, void *p, int d){ return MessageBoxW(NULL, lbidstr, L"bidshow", MB_SETFOREGROUND); } break; - case 'i': /* HASH_INIT(ctxp) */ + case 'i': /* HASH_INIT(contextp) */ if (!IsWindowsVistaOrGreater()) return 1; // CNG not available. - ctxp->bah = NULL; - ctxp->bhh = NULL; - ctxp->pbhashobj = NULL; - ctxp->cbhashobj = 0; - ctxp->cbhash = 0; - ctxp->cbdata = 0; - ctxp->pbhash = NULL; - ctxp->st = 0; + contextp->bah = NULL; + contextp->bhh = NULL; + contextp->pbhashobj = NULL; + contextp->cbhashobj = 0; + contextp->cbhash = 0; + contextp->cbdata = 0; + contextp->pbhash = NULL; + contextp->st = 0; // win32err("test"); // TESTING - FAKE AN ERROR - if (0 > (ctxp->st = BCryptOpenAlgorithmProvider( - &ctxp->bah, BCRYPT_MD4_ALGORITHM, NULL, 0))) { + if (0 > (contextp->st = BCryptOpenAlgorithmProvider( + &contextp->bah, BCRYPT_MD4_ALGORITHM, NULL, 0))) { win32err("BCryptOpenAlgorithmProvider"); }; - if (0 > (ctxp->st = - BCryptGetProperty(ctxp->bah, BCRYPT_OBJECT_LENGTH, - (unsigned char *) &ctxp->cbhashobj, - sizeof(DWORD), &ctxp->cbdata, 0))) { + if (0 > (contextp->st = + BCryptGetProperty(contextp->bah, BCRYPT_OBJECT_LENGTH, + (unsigned char *) &contextp->cbhashobj, + sizeof(DWORD), &contextp->cbdata, 0))) { win32err("BCryptGetProperty1"); }; if (0 - == (ctxp->pbhashobj = - HeapAlloc(GetProcessHeap(), 0, ctxp->cbhashobj))) { + == (contextp->pbhashobj = + HeapAlloc(GetProcessHeap(), 0, contextp->cbhashobj))) { win32err("HeapAlloc1"); }; - if (0 > (ctxp->st = BCryptGetProperty( - ctxp->bah, BCRYPT_HASH_LENGTH, (PBYTE) &ctxp->cbhash, - sizeof(DWORD), &ctxp->cbdata, 0))) { + if (0 > (contextp->st = BCryptGetProperty( + contextp->bah, BCRYPT_HASH_LENGTH, (PBYTE) &contextp->cbhash, + sizeof(DWORD), &contextp->cbdata, 0))) { win32err("BCryptGetProperty2"); } if (0 - == (ctxp->pbhash = - HeapAlloc(GetProcessHeap(), 0, ctxp->cbhash))) { + == (contextp->pbhash = + HeapAlloc(GetProcessHeap(), 0, contextp->cbhash))) { win32err("HeapAlloc2\n"); } - if (0 > BCryptCreateHash(ctxp->bah, &ctxp->bhh, ctxp->pbhashobj, - ctxp->cbhashobj, NULL, 0, 0)) { + if (0 > BCryptCreateHash(contextp->bah, &contextp->bhh, contextp->pbhashobj, + contextp->cbhashobj, NULL, 0, 0)) { win32err("BCryptCreateHash"); } break; - case 'u': /* HASH_UPDATE(ctxp, ptr, len) */ - if (0 > (ctxp->st = BCryptHashData(ctxp->bhh, p, d, 0))) { + case 'u': /* HASH_UPDATE(contextp, ptr, len) */ + if (0 > (contextp->st = BCryptHashData(contextp->bhh, p, d, 0))) { win32err("BCryptHashData"); } break; - case 'f': /* HASH_FINISH(ctxp) */ - if (0 > BCryptFinishHash(ctxp->bhh, ctxp->pbhash, ctxp->cbhash, 0)) { + case 'f': /* HASH_FINISH(contextp) */ + if (0 > BCryptFinishHash(contextp->bhh, contextp->pbhash, contextp->cbhash, 0)) { win32err("BCryptFinishHash"); } break; - case 'c': /* HASH_CLEANUP(ctxp) */ - if (ctxp->bah) { - BCryptCloseAlgorithmProvider(ctxp->bah, 0); + case 'c': /* HASH_CLEANUP(contextp) */ + if (contextp->bah) { + BCryptCloseAlgorithmProvider(contextp->bah, 0); } - if (ctxp->bhh) { - BCryptDestroyHash(ctxp->bhh); + if (contextp->bhh) { + BCryptDestroyHash(contextp->bhh); } - if (ctxp->pbhashobj) { - HeapFree(GetProcessHeap(), 0, ctxp->pbhashobj); + if (contextp->pbhashobj) { + HeapFree(GetProcessHeap(), 0, contextp->pbhashobj); } - if (ctxp->pbhash) { - HeapFree(GetProcessHeap(), 0, ctxp->pbhash); + if (contextp->pbhash) { + HeapFree(GetProcessHeap(), 0, contextp->pbhash); } break; - case 's': /* HASH_RESULT_SIZE(ctxp) */ - return ctxp->cbhash; - case 'r': /* HASH_RESULT(ctxp, resp) */ - *(unsigned char **)p = ctxp->pbhash; + case 's': /* HASH_RESULT_SIZE(contextp) */ + return contextp->cbhash; + case 'r': /* HASH_RESULT(contextp, resp) */ + *(unsigned char **)p = contextp->pbhash; break; case 'b': /* HASH_BINFILE(NULL,&binfile,0) */ // XXX This buffer should be allocated, not static (and freed in @@ -906,7 +906,7 @@ win32_cr_helper(char cmd, struct CRctxt *ctxp, void *p, int d){ return 0; /* ok */ error: raw_printf("WIN32 function %s failed: status=%" PRIx64 "\n", - errname, (uint64)ctxp->st); + errname, (uint64)contextp->st); return 1; /* fail */ } #undef win32err diff --git a/util/makedefs.c b/util/makedefs.c index bbf1b7ffa4..f09a2ceb1f 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -846,7 +846,8 @@ do_grep_control(char *buf) break; case '!': /* if not ID */ isif = 0; - /* FALLTHROUGH */ + FALLTHROUGH; + /* FALLTHRU */ case '?': /* if ID */ if (grep_sp == GREP_STACK_SIZE - 2) { Fprintf(stderr, "stack overflow at line %d.", grep_lineno); @@ -2303,6 +2304,7 @@ do_objs(void) n_glass_gems++; break; } + FALLTHROUGH; /*FALLTHRU*/ case VENOM_CLASS: /* fall-through from gem class is ok; objects[] used to have @@ -2312,6 +2314,7 @@ do_objs(void) so strip the extra "splash of " off to keep same macros */ if (!strncmp(objnam, "SPLASH_OF_", 10)) objnam += 10; + FALLTHROUGH; /*FALLTHRU*/ default: Fprintf(ofp, "#define\t"); diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 0f29c42841..6623848c18 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -70,6 +70,8 @@ static struct key_macro_rec { { 0, 0U, (const char *) 0, (const char *) 0 } }; +static QPen *pen = (QPen *) 0; + NetHackQtBind::NetHackQtBind(int& argc, char** argv) : #ifdef KDE KApplication(argc,argv) @@ -269,6 +271,7 @@ void NetHackQtBind::qt_askname() // success; handle plname[] verification below prior to returning break; } + FALLTHROUGH; /*FALLTHRU*/ case -2: // Quit @@ -578,6 +581,45 @@ void NetHackQtBind::qt_raw_print_bold(const char *str) qt_raw_print(str); } +const QPen NetHackQtBind::nhcolor_to_pen(uint32_t c) +{ + if (!pen) { + pen = new QPen[17]; + + pen[ 0] = QColor(64, 64, 64); // black + pen[ 1] = QColor(Qt::red); + pen[ 2] = QColor(0, 191, 0); // green + pen[ 3] = QColor(127, 127, 0); // brownish + pen[ 4] = QColor(Qt::blue); + pen[ 5] = QColor(Qt::magenta); + pen[ 6] = QColor(Qt::cyan); + pen[ 7] = QColor(Qt::gray); + // on tty, "light" variations are "bright" instead; here they're paler + pen[ 8] = QColor(Qt::white); // no color + pen[ 9] = QColor(255, 127, 0); // orange + pen[10] = QColor(127, 255, 127); // light green + pen[11] = QColor(Qt::yellow); + pen[12] = QColor(127, 127, 255); // light blue + pen[13] = QColor(255, 127, 255); // light magenta + pen[14] = QColor(127, 255, 255); // light cyan + pen[15] = QColor(Qt::white); + // ? out of range for 0..15 + pen[16] = QColor(Qt::black); + } + +#ifdef ENHANCED_SYMBOLS + if (c & 0x80000000) { + return QColor( + (c >> 16) & 0xFF, + (c >> 8) & 0xFF, + (c >> 0) & 0xFF); + } else +#endif + { + return pen[c]; + } +} + int NetHackQtBind::qt_nhgetch() { if (main) @@ -685,6 +727,7 @@ char NetHackQtBind::qt_more() switch (ch) { case '\0': // hypothetical ch = '\033'; + FALLTHROUGH; /*FALLTHRU*/ case ' ': case '\n': @@ -901,6 +944,28 @@ void NetHackQtBind::qt_delay_output() #endif } +#ifdef CHANGE_COLOR +void NetHackQtBind::qt_change_color(int color, long rgb, int reverse UNUSED) +{ + int r, g, b; + + r = (rgb >> 16) & 0xFF; + g = (rgb >> 8) & 0xFF; + b = rgb & 0xFF; + if (!pen) { + (void) NetHackQtBind::nhcolor_to_pen(0); /* init pen[] */ + } + pen[color % 16] = QColor(r, g, b); +} + +char * +NetHackQtBind::qt_get_color_string(void) +{ + return (char *) 0; +} + +#endif + void NetHackQtBind::qt_start_screen() { // Ignore. @@ -1158,11 +1223,13 @@ struct window_procs Qt_procs = { nethack_qt_::NetHackQtBind::qt_get_ext_cmd, nethack_qt_::NetHackQtBind::qt_number_pad, nethack_qt_::NetHackQtBind::qt_delay_output, -#ifdef CHANGE_COLOR /* only a Mac option currently */ - donull, - donull, +#ifdef CHANGE_COLOR + nethack_qt_::NetHackQtBind::qt_change_color, +#ifdef MAC /* old OS 9, not OSX */ donull, donull, +#endif + nethack_qt_::NetHackQtBind::qt_get_color_string, #endif /* other defs that really should go away (they're tty specific) */ nethack_qt_::NetHackQtBind::qt_start_screen, diff --git a/win/Qt/qt_bind.h b/win/Qt/qt_bind.h index b0b9f4f3a4..6535e637b8 100644 --- a/win/Qt/qt_bind.h +++ b/win/Qt/qt_bind.h @@ -71,6 +71,9 @@ class NetHackQtBind : NetHackQtBindBase { const glyph_info *bkglyphinfo); static void qt_raw_print(const char *str); static void qt_raw_print_bold(const char *str); + static const QPen nhcolor_to_pen(uint32_t c); + static void qt_change_color(int color, long rgb, int reverse UNUSED); + static char *qt_get_color_string(void); static int qt_nhgetch(); static int qt_nh_poskey(coordxy *x, coordxy *y, int *mod); static void qt_nhbell(); diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index e05ff84332..90836d7464 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -77,47 +77,6 @@ extern int qt_compact_mode; namespace nethack_qt_ { -static const QPen nhcolor_to_pen(uint32_t c) -{ - static QPen *pen = (QPen *) 0; - if (!pen) { - pen = new QPen[17]; - // - // FIXME: these are duplicated in qt_menu.cpp - // - pen[ 0] = QColor(64, 64, 64); // black - pen[ 1] = QColor(Qt::red); - pen[ 2] = QColor(0, 191, 0); // green - pen[ 3] = QColor(127, 127, 0); // brownish - pen[ 4] = QColor(Qt::blue); - pen[ 5] = QColor(Qt::magenta); - pen[ 6] = QColor(Qt::cyan); - pen[ 7] = QColor(Qt::gray); - // on tty, "light" variations are "bright" instead; here they're paler - pen[ 8] = QColor(Qt::white); // no color - pen[ 9] = QColor(255, 127, 0); // orange - pen[10] = QColor(127, 255, 127); // light green - pen[11] = QColor(Qt::yellow); - pen[12] = QColor(127, 127, 255); // light blue - pen[13] = QColor(255, 127, 255); // light magenta - pen[14] = QColor(127, 255, 255); // light cyan - pen[15] = QColor(Qt::white); - // ? out of range for 0..15 - pen[16] = QColor(Qt::black); - } - -#ifdef ENHANCED_SYMBOLS - if (c & 0x80000000) { - return QColor( - (c >> 16) & 0xFF, - (c >> 8) & 0xFF, - (c >> 0) & 0xFF); - } else -#endif - { - return pen[c]; - } -} NetHackQtMapViewport::NetHackQtMapViewport(NetHackQtClickBuffer& click_sink) : QWidget(NULL), @@ -202,7 +161,7 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) ch = cp437(ch); } color = Glyphcolor(i, j); - painter.setPen(nhcolor_to_pen(color)); + painter.setPen(NetHackQtBind::nhcolor_to_pen(color)); if (!DrawWalls(painter, i * gW, j * gH, gW, gH, ch)) { ushort utf16[3]; if (ch < 0x10000) { @@ -226,7 +185,7 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) } framecolor = GlyphFramecolor(i, j); if (framecolor != NO_COLOR) { - painter.setPen(nhcolor_to_pen(framecolor)); + painter.setPen(NetHackQtBind::nhcolor_to_pen(framecolor)); painter.drawRect(i * qt_settings->glyphs().width(), j * qt_settings->glyphs().height(), qt_settings->glyphs().width() - 1, @@ -255,7 +214,7 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) } framecolor = GlyphFramecolor(i, j); if (framecolor != NO_COLOR) { - painter.setPen(nhcolor_to_pen(framecolor)); + painter.setPen(NetHackQtBind::nhcolor_to_pen(framecolor)); painter.drawRect(i * qt_settings->glyphs().width(), j * qt_settings->glyphs().height(), qt_settings->glyphs().width() - 1, diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 3d1cc3aa68..b2d66c32f8 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -483,69 +483,11 @@ void NetHackQtMenuWindow::UpdateCountColumn(long newcount) table->repaint(); } -struct qcolor { - QColor q; - const char *nm; -}; -// these match the tty colors, or better versions of same; -// [0] is used for black, and [8] (the first white) corresponds to "no color" -static const struct qcolor colors[] = { - { QColor(64, 64, 64), "64,64,64" }, // black - { QColor(Qt::red), "red" }, - { QColor(0, 191, 0), "0,191,0" }, // green - { QColor(127, 127, 0), "127,127,0" }, // brownish - { QColor(Qt::blue), "blue" }, - { QColor(Qt::magenta), "magenta" }, - { QColor(Qt::cyan), "cyan" }, - { QColor(Qt::gray), "gray" }, - // on tty, the "light" variations are "bright" instead; here they're paler - { QColor(Qt::white), "white" }, // no-color, so not rendered - { QColor(255, 127, 0), "255,127,0" }, // orange - { QColor(127, 255, 127), "127,255,127" }, // light green - { QColor(Qt::yellow), "yellow" }, - { QColor(127, 127, 255), "127,127,255" }, // light blue - { QColor(255, 127, 255), "255,127,255" }, // light magenta - { QColor(127, 255, 255), "127,255,255" }, // light cyan - { QColor(Qt::white), "white" }, -}; - -#if 0 /* available for debugging */ -static const char *color_name(const QColor q) -{ - for (int i = 0; i < SIZE(colors); ++i) - if (q == colors[i].q) - return colors[i].nm; - // these are all the enum GlobalColor values ; - // black and white have been moved in front of color0 and color1 here - const char *nm = (q == Qt::black) ? "black" - : (q == Qt::white) ? "white" - : (q == Qt::color0) ? "color0" // doesn't duplicate white? - : (q == Qt::color1) ? "color1" // does duplicate black - : (q == Qt::darkGray) ? "darkGray" - : (q == Qt::gray) ? "gray" - : (q == Qt::lightGray) ? "lightGray" - : (q == Qt::red) ? "red" - : (q == Qt::green) ? "green" - : (q == Qt::blue) ? "blue" - : (q == Qt::cyan) ? "cyan" - : (q == Qt::magenta) ? "magenta" - : (q == Qt::yellow) ? "yellow" - : (q == Qt::darkRed) ? "darkRed" - : (q == Qt::darkGreen) ? "darkGreen" - : (q == Qt::darkBlue) ? "darkBlue" - : (q == Qt::darkCyan) ? "darkCyan" - : (q == Qt::darkMagenta) ? "darkMagenta" - : (q == Qt::darkYellow) ? "darkYellow" - : (q == Qt::transparent) ? "transparent" - : "other"; - return nm; -} -#endif - void NetHackQtMenuWindow::SetTwiAttr(QTableWidgetItem *twi, int color, int attr) { if (color != NO_COLOR) { - twi->setForeground(colors[color].q); + const QPen qp = NetHackQtBind::nhcolor_to_pen(color); + twi->setForeground(qp.color()); } if (attr != ATR_NONE) { @@ -1161,7 +1103,7 @@ void NetHackQtTextWindow::Display(bool block UNUSED) rip.show(); } else { /* h+=ok.height()*2 + 7; */ - (void) ok.height(); + (void) ok.height(); ok.show(); search.show(); rip.hide(); diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 1df8980e5b..3ce2b65fcd 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -1556,6 +1556,7 @@ menu_get_selections(WINDOW *win, nhmenu *menu, int how) break; } } + FALLTHROUGH; /*FALLTHRU*/ default: if (curletter > 0 && curletter < 256 diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index a04de5c085..49378348cb 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -122,6 +122,7 @@ curses_create_main_windows(void) case 3: noperminv_borders = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case 1: /* On */ borders = TRUE; @@ -129,6 +130,7 @@ curses_create_main_windows(void) case 4: noperminv_borders = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case 2: /* Auto */ borders = (term_cols >= 80 + 2 && term_rows >= 24 + 2); diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index 0b8d18b5e0..4afa9509a2 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -1078,11 +1078,12 @@ curses_putmsghistory(const char *msg, boolean restoring_msghist) however, we aren't only called when restoring history; core uses putmsghistory() for other stuff during play and those messages should have a normal turn value */ - if (last_mesg) /* appease static analyzer */ + if (last_mesg) { /* appease static analyzer */ last_mesg->turn = restoring_msghist ? (1L << 3) : gh.hero_seq; #ifdef DUMPLOG_CORE - dumplogmsg(last_mesg->str); + dumplogmsg(last_mesg->str); #endif + } } else if (stash_count) { nhprev_mesg *mesg; long mesg_turn; diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 73a939f2a9..71b9f31f69 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -291,7 +291,7 @@ curses_break_str(const char *str, int width, int line_num) char *retstr; int curline = 0; int strsize = (int) strlen(str) + 1; -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) && !defined(_MSC_VER) char substr[strsize]; char curstr[strsize]; char tmpstr[strsize]; @@ -363,7 +363,7 @@ curses_str_remainder(const char *str, int width, int line_num) char *retstr; int curline = 0; int strsize = strlen(str) + 1; -#if __STDC_VERSION__ >= 199901L +#if (__STDC_VERSION__ >= 199901L) && !defined(_MSC_VER) char substr[strsize]; char tmpstr[strsize]; @@ -801,6 +801,7 @@ curses_convert_keys(int key) a value for ^H greater than 255 is passed back to core's readchar() and stripping the value down to 0..255 yields ^G! */ ret = C('H'); + FALLTHROUGH; /*FALLTHRU*/ default: if (modifiers_available) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 8990a08fe9..d52f317673 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -417,6 +417,7 @@ draw_horizontal(boolean border) w -= (t - 30); /* '+= strlen()' below will add 't'; * functional result being 'w += 30' */ } + FALLTHROUGH; /*FALLTHRU*/ case BL_ALIGN: case BL_LEVELDESC: @@ -1234,6 +1235,7 @@ curs_vert_status_vals(int win_width) if (fld_width < hp_width + 3) /* +3: " " gap and "("...")" */ Sprintf(leadingspace, "%*s", (hp_width + 3) - fld_width, " "); + FALLTHROUGH; /*FALLTHRU*/ case BL_VERS: case BL_EXP: diff --git a/win/curses/curswins.c b/win/curses/curswins.c index fa99b58c42..19c6c380af 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -98,6 +98,7 @@ curses_create_window(int wid, int width, int height, orient orientation) switch (orientation) { default: impossible("curses_create_window: Bad orientation"); + FALLTHROUGH; /*FALLTHRU*/ case CENTER: startx = (term_cols / 2) - (width / 2); diff --git a/win/shim/winshim.c b/win/shim/winshim.c index d83c62a45c..dbc3ef5d7e 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -115,7 +115,7 @@ void name fn_args { \ #endif /* __EMSCRIPTEN__ */ VDECLCB(shim_init_nhwindows,(int *argcp, char **argv), "vpp", P2V argcp, P2V argv) -VDECLCB(shim_player_selection,(void), "v") +DECLCB(boolean, shim_player_selection_or_tty,(void), "b") VDECLCB(shim_askname,(void), "v") VDECLCB(shim_get_nh_event,(void), "v") VDECLCB(shim_exit_nhwindows,(const char *str), "vs", P2V str) @@ -123,33 +123,33 @@ VDECLCB(shim_suspend_nhwindows,(const char *str), "vs", P2V str) VDECLCB(shim_resume_nhwindows,(void), "v") DECLCB(winid, shim_create_nhwindow, (int type), "ii", A2P type) VDECLCB(shim_clear_nhwindow,(winid window), "vi", A2P window) -VDECLCB(shim_display_nhwindow,(winid window, boolean blocking), "vii", A2P window, A2P blocking) +VDECLCB(shim_display_nhwindow,(winid window, boolean blocking), "vib", A2P window, A2P blocking) VDECLCB(shim_destroy_nhwindow,(winid window), "vi", A2P window) VDECLCB(shim_curs,(winid a, int x, int y), "viii", A2P a, A2P x, A2P y) VDECLCB(shim_putstr,(winid w, int attr, const char *str), "viis", A2P w, A2P attr, P2V str) -VDECLCB(shim_display_file,(const char *name, boolean complain), "vsi", P2V name, A2P complain) +VDECLCB(shim_display_file,(const char *name, boolean complain), "vsb", P2V name, A2P complain) VDECLCB(shim_start_menu,(winid window, unsigned long mbehavior), "vii", A2P window, A2P mbehavior) VDECLCB(shim_add_menu, (winid window, const glyph_info *glyphinfo, const ANY_P *identifier, char ch, char gch, int attr, int clr, const char *str, unsigned int itemflags), - "vippiiiisi", + "vipi00iisi", A2P window, P2V glyphinfo, P2V identifier, A2P ch, A2P gch, A2P attr, A2P clr, P2V str, A2P itemflags) VDECLCB(shim_end_menu,(winid window, const char *prompt), "vis", A2P window, P2V prompt) /* XXX: shim_select_menu menu_list is an output */ -DECLCB(int, shim_select_menu,(winid window, int how, MENU_ITEM_P **menu_list), "iiio", A2P window, A2P how, P2V menu_list) +DECLCB(int, shim_select_menu,(winid window, int how, MENU_ITEM_P **menu_list), "iiip", A2P window, A2P how, P2V menu_list) DECLCB(char, shim_message_menu,(char let, int how, const char *mesg), "ciis", A2P let, A2P how, P2V mesg) VDECLCB(shim_mark_synch,(void), "v") VDECLCB(shim_wait_synch,(void), "v") VDECLCB(shim_cliparound,(int x, int y), "vii", A2P x, A2P y) -VDECLCB(shim_update_positionbar,(char *posbar), "vp", P2V posbar) -VDECLCB(shim_print_glyph,(winid w, coordxy x, coordxy y, const glyph_info *glyphinfo, const glyph_info *bkglyphinfo), "viiipp", A2P w, A2P x, A2P y, P2V glyphinfo, P2V bkglyphinfo) +VDECLCB(shim_update_positionbar,(char *posbar), "vs", P2V posbar) +VDECLCB(shim_print_glyph,(winid w, coordxy x, coordxy y, const glyph_info *glyphinfo, const glyph_info *bkglyphinfo), "vi11pp", A2P w, A2P x, A2P y, P2V glyphinfo, P2V bkglyphinfo) VDECLCB(shim_raw_print,(const char *str), "vs", P2V str) VDECLCB(shim_raw_print_bold,(const char *str), "vs", P2V str) DECLCB(int, shim_nhgetch,(void), "i") -DECLCB(int, shim_nh_poskey,(coordxy *x, coordxy *y, int *mod), "iooo", P2V x, P2V y, P2V mod) +DECLCB(int, shim_nh_poskey,(coordxy *x, coordxy *y, int *mod), "ippp", P2V x, P2V y, P2V mod) VDECLCB(shim_nhbell,(void), "v") DECLCB(int, shim_doprev_message,(void),"iv") -DECLCB(char, shim_yn_function,(const char *query, const char *resp, char def), "cssi", P2V query, P2V resp, A2P def) -VDECLCB(shim_getlin,(const char *query, char *bufp), "vso", P2V query, P2V bufp) +DECLCB(char, shim_yn_function,(const char *query, const char *resp, char def), "css0", P2V query, P2V resp, A2P def) +VDECLCB(shim_getlin,(const char *query, char *bufp), "vsp", P2V query, P2V bufp) DECLCB(int,shim_get_ext_cmd,(void),"iv") VDECLCB(shim_number_pad,(int state), "vi", A2P state) VDECLCB(shim_delay_output,(void), "v") @@ -162,17 +162,17 @@ DECLCB(char *,shim_get_color_string,(void),"sv") VDECLCB(shim_start_screen, (void), "v") VDECLCB(shim_end_screen, (void), "v") VDECLCB(shim_preference_update, (const char *pref), "vp", P2V pref) -DECLCB(char *,shim_getmsghistory, (boolean init), "si", A2P init) -VDECLCB(shim_putmsghistory, (const char *msg, boolean restoring_msghist), "vsi", P2V msg, A2P restoring_msghist) +DECLCB(char *,shim_getmsghistory, (boolean init), "sb", A2P init) +VDECLCB(shim_putmsghistory, (const char *msg, boolean restoring_msghist), "vsb", P2V msg, A2P restoring_msghist) VDECLCB(shim_status_init, (void), "v") VDECLCB(shim_status_enablefield, (int fieldidx, const char *nm, const char *fmt, boolean enable), - "vippi", + "vippb", A2P fieldidx, P2V nm, P2V fmt, A2P enable) /* XXX: the second argument to shim_status_update is sometimes an integer and sometimes a pointer */ VDECLCB(shim_status_update, (int fldidx, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks), - "vioiiip", + "vipiiip", A2P fldidx, P2V ptr, A2P chg, A2P percent, A2P color, P2V colormasks) #ifdef __EMSCRIPTEN__ @@ -183,6 +183,14 @@ void shim_update_inventory(int a1 UNUSED) { display_inventory(NULL, FALSE); } } + +void shim_player_selection() { + boolean do_genl_player_setup = shim_player_selection_or_tty(); + if (do_genl_player_setup) { + genl_player_setup(80); + } +} + win_request_info * shim_ctrl_nhwindow( winid window UNUSED, @@ -203,6 +211,7 @@ struct window_procs shim_procs = { WPID(shim), (0 | WC_ASCII_MAP + | WC_MOUSE_SUPPORT | WC_COLOR | WC_HILITE_PET | WC_INVERSE | WC_EIGHT_BIT_IN), (0 #if defined(SELECTSAVED) @@ -262,7 +271,7 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r // unrolling and it crashes. Thus we use Asyncify.handleSleep() and wakeUp() to make sure that async doesn't break // Asyncify. For details, see: https://emscripten.org/docs/porting/asyncify.html#optimizing Asyncify.handleSleep(wakeUp => { - // convert callback arguments to proper JavaScript varaidic arguments + // convert callback arguments to proper JavaScript variadic arguments let name = UTF8ToString(shim_name); let fmt = UTF8ToString(fmt_str); let cbName = UTF8ToString(cb_name); @@ -287,40 +296,25 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r // do the callback let userCallback = globalThis[cbName]; - runJsEventLoop(() => userCallback.call(this, name, ... jsArgs)).then((retVal) => { + userCallback.call(this, name, ... jsArgs).then((retVal) => { // save the return value setPointerValue(name, ret_ptr, retType, retVal); - // return - setTimeout(() => { - reentryMutexUnlock(); + reentryMutexUnlock(); + try { wakeUp(); - }, 0); + } catch (e) { + + } }); function getArg(name, ptr, type) { - return (type === "o")?ptr:getPointerValue(name, getValue(ptr, "*"), type); - } - - // setTimeout() with value of '0' is similar to setImmediate() (but setImmediate isn't standard) - // this lets the JS loop run for a tick so that other events can occur - // XXX: I also tried replacing the for(;;) in allmain.c:moveloop() with emscripten_set_main_loop() - // unfortunately that won't work -- if the simulate_infinite_loop arg is false, it falls through - // and the program ends; - // if is true, it throws an exception to break out of main(), but doesn't get caught because - // the stack isn't running under main() anymore... - // I think this is suboptimal, but we will have to live with it (for now?) - async function runJsEventLoop(cb) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(cb()); - }, 0); - }); + return (type === "p") ? getValue(ptr, "*") : getPointerValue(name, getValue(ptr, "*"), type); } function reentryMutexLock(name) { globalThis.nethackGlobal = globalThis.nethackGlobal || {}; if(globalThis.nethackGlobal.shimFunctionRunning) { - throw new Error(`'${name}' attempting second call to 'local_callback' before '${globalThis.nethackGlobal.shimFunctionRunning}' has finished, will crash emscripten Asyncify. For details see: emscripten.org/docs/porting/asyncify.html#reentrancy`); + console.error(`'${name}' attempting second call to 'local_callback' before '${globalThis.nethackGlobal.shimFunctionRunning}' has finished, will crash emscripten Asyncify. For details see: emscripten.org/docs/porting/asyncify.html#reentrancy`); } globalThis.nethackGlobal.shimFunctionRunning = name; } diff --git a/win/tty/termcap.c b/win/tty/termcap.c index 5abe6f23a2..be060aa12a 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -403,8 +403,14 @@ tty_decgraphics_termcap_fixup(void) * Do not select NA ASCII as the primary font since people may * reasonably be using the UK character set. */ - if (SYMHANDLING(H_DEC)) + if (SYMHANDLING(H_DEC)) { xputs("\033)0"); /* "\e)0" load line drawing chars as secondary set */ + /* TI doesn't necessarily do this; explicitly switch to primary + font in case previous program (either before starting nethack + or during a shell escape) left the alternate font active */ + xputs(AE); + } + #ifdef PC9800 init_hilite(); #endif @@ -658,7 +664,7 @@ void term_clear_screen(void) { /* note: if CL is null, then termcap initialization failed, - so don't attempt screen-oriented I/O during final cleanup. + * so don't attempt screen-oriented I/O during final cleanup. */ if (CL) { xputs(CL); @@ -877,7 +883,7 @@ cl_eos(void) /* free after Robert Viduya */ about reconstructing them after the header file inclusion. */ #undef TRUE #undef FALSE -#define m_move curses_m_move /* Some curses.h decl m_move(), not used here */ +#define m_move curses_m_move /* some curses.h decl m_move(), not used here */ #include @@ -935,7 +941,7 @@ init_hilite(void) iflags.colorcount = colors; int md_len = 0; - if (colors < 8 || (MD == NULL) || (strlen(MD) == 0) + if (colors < 8 || !MD || !*MD || ((setf = tgetstr(nhStr("AF"), (char **) 0)) == (char *) 0 && (setf = tgetstr(nhStr("Sf"), (char **) 0)) == (char *) 0)) { /* Fallback when colors not available @@ -963,23 +969,16 @@ init_hilite(void) if (colors >= 16) { for (c = 0; c < SIZE(ti_map); c++) { - char *work; - /* system colors */ scratch = tparm(setf, ti_map[c].nh_color); - work = (char *) alloc(strlen(scratch) + 1); - Strcpy(work, scratch); - hilites[ti_map[c].nh_color] = work; - + hilites[ti_map[c].nh_color] = dupstr(scratch); /* bright colors */ scratch = tparm(setf, ti_map[c].nh_bright_color); - work = (char *) alloc(strlen(scratch) + 1); - Strcpy(work, scratch); - hilites[ti_map[c].nh_bright_color] = work; + hilites[ti_map[c].nh_bright_color] = dupstr(scratch); } } else { /* 8 system colors */ - md_len = strlen(MD); + md_len = (int) strlen(MD); c = 6; while (c--) { @@ -996,9 +995,8 @@ init_hilite(void) } if (colors >= 16) { - scratch = tparm(setf, COLOR_WHITE|BRIGHT); - hilites[CLR_WHITE] = (char *) alloc(strlen(scratch) + 1); - Strcpy(hilites[CLR_WHITE], scratch); + scratch = tparm(setf, COLOR_WHITE | BRIGHT); + hilites[CLR_WHITE] = dupstr(scratch); } else { scratch = tparm(setf, COLOR_WHITE); hilites[CLR_WHITE] = (char *) alloc(strlen(scratch) + md_len + 1); @@ -1012,8 +1010,7 @@ init_hilite(void) if (iflags.wc2_darkgray) { if (colors >= 16) { scratch = tparm(setf, COLOR_BLACK|BRIGHT); - hilites[CLR_BLACK] = (char *) alloc(strlen(scratch) + 1); - Strcpy(hilites[CLR_BLACK], scratch); + hilites[CLR_BLACK] = dupstr(scratch); } else { /* On many terminals, esp. those using classic PC CGA/EGA/VGA * textmode, specifying "hilight" and "black" simultaneously @@ -1043,9 +1040,11 @@ kill_hilite(void) if (hilites[CLR_BLACK] == nh_HI) return; + /* hilites[] will be set to NULL below, whether freed here or not */ + if (hilites[CLR_BLACK]) { if (hilites[CLR_BLACK] != hilites[CLR_BLUE]) - free(hilites[CLR_BLACK]); + free(hilites[CLR_BLACK]), hilites[CLR_BLACK] = NULL; } if (tgetnum(nhStr("Co")) >= 16) { if (hilites[CLR_BLUE]) @@ -1086,7 +1085,7 @@ kill_hilite(void) free(hilites[CLR_WHITE]); for (c = 0; c < CLR_MAX; c++) - hilites[c] = 0; + hilites[c] = NULL; } #else /* UNIX && TERMINFO */ @@ -1150,7 +1149,7 @@ analyze_seq(char *str, int *fg, int *bg) /* * Sets up highlighting sequences, using ANSI escape sequences (highlight code - * found in print.c). The nh_HI and nh_HE sequences (usually from SO) are + * found in wintty.c). The nh_HI and nh_HE sequences (usually from SO) are * scanned to find foreground and background colors. */ @@ -1173,6 +1172,7 @@ init_hilite(void) hilites[0] = NOCOL; for (c = 1; c < SIZE(hilites); c++) { char *foo; + foo = (char *) alloc(sizeof "\033b0"); if (tos_numcolors > 4) Sprintf(foo, "\033b%c", (c & ~BRIGHT) + '0'); @@ -1216,9 +1216,9 @@ init_hilite(void) if (c == CLR_BLUE) continue; #endif - if (c == foreg) + if (c == foreg) { hilites[c] = (char *) 0; - else if (c != hi_foreg || backg != hi_backg) { + } else if (c != hi_foreg || backg != hi_backg) { hilites[c] = (char *) alloc(sizeof "\033[%d;3%d;4%dm"); Sprintf(hilites[c], "\033[%d", !!(c & BRIGHT)); if ((c | BRIGHT) != (foreg | BRIGHT)) @@ -1341,6 +1341,7 @@ s_atr2str(int n) /* if italic isn't available, fall through to underline */ if (ZH && *ZH) return ZH; + FALLTHROUGH; /*FALLTHRU*/ case ATR_BLINK: case ATR_ULINE: @@ -1351,6 +1352,7 @@ s_atr2str(int n) if (nh_US && *nh_US) return nh_US; } + FALLTHROUGH; /*FALLTHRU*/ case ATR_BOLD: if (MD && *MD) @@ -1378,15 +1380,18 @@ e_atr2str(int n) /* send ZR unless we didn't have ZH and substituted US */ if (ZR && *ZR && ZH && *ZH) return ZR; + FALLTHROUGH; /*FALLTHRU*/ case ATR_ULINE: if (nh_UE && *nh_UE) return nh_UE; + FALLTHROUGH; /*FALLTHRU*/ case ATR_BOLD: case ATR_BLINK: if (nh_HE && *nh_HE) return nh_HE; + FALLTHROUGH; /*FALLTHRU*/ case ATR_DIM: case ATR_INVERSE: diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 85c552d442..658c3ef52e 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -665,6 +665,7 @@ tty_askname(void) case -1: bail("Until next time then..."); /* quit */ /*NOTREACHED*/ + break; case 0: break; /* no game chosen; start new game */ case 1: @@ -1084,6 +1085,7 @@ tty_clear_nhwindow(winid window) case NHW_MAP: /* cheap -- clear the whole thing and tell nethack to redraw botl */ disp.botlx = TRUE; + FALLTHROUGH; /*FALLTHRU*/ case NHW_BASE: /* if erasing_tty_screen is True, calling sequence is @@ -1721,6 +1723,7 @@ process_menu_window(winid window, struct WinDesc *cw) break; case MENU_EXPLICIT_CHOICE: morc = really_morc; + FALLTHROUGH; /*FALLTHRU*/ default: if (cw->how == PICK_NONE || !strchr(resp, morc)) { @@ -1878,12 +1881,14 @@ tty_display_nhwindow( tty_display_nhwindow(WIN_MESSAGE, TRUE); return; } + FALLTHROUGH; /*FALLTHRU*/ case NHW_BASE: (void) fflush(stdout); break; case NHW_TEXT: cw->maxcol = ttyDisplay->cols; /* force full-screen mode */ + FALLTHROUGH; /*FALLTHRU*/ case NHW_MENU: cw->active = 1; @@ -1951,6 +1956,7 @@ tty_dismiss_nhwindow(winid window) if (ttyDisplay->toplin != TOPLINE_EMPTY) tty_display_nhwindow(WIN_MESSAGE, TRUE); nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); + FALLTHROUGH; /*FALLTHRU*/ case NHW_STATUS: case NHW_BASE: @@ -4448,6 +4454,7 @@ tty_status_update( switch (fldidx) { case BL_RESET: reset_state = FORCE_RESET; + FALLTHROUGH; /*FALLTHRU*/ case BL_FLUSH: if (make_things_fit(reset_state) || truncation_expected) { @@ -4468,6 +4475,7 @@ tty_status_update( break; case BL_GOLD: text = decode_mixed(goldbuf, text); + FALLTHROUGH; /*FALLTHRU*/ default: attrmask = (color >> 8) & 0x00FF; @@ -4516,6 +4524,7 @@ tty_status_update( break; case BL_LEVELDESC: dlvl_shrinklvl = 0; /* caller is passing full length string */ + FALLTHROUGH; /*FALLTHRU*/ case BL_HUNGER: /* The core sends trailing blanks for some fields. diff --git a/win/win32/mhdlg.c b/win/win32/mhdlg.c index afa55c1c9d..f190f000d2 100644 --- a/win/win32/mhdlg.c +++ b/win/win32/mhdlg.c @@ -146,7 +146,8 @@ GetlinDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) (WPARAM) sizeof(wbuf2), (LPARAM) wbuf2); NH_W2A(wbuf2, data->result, data->result_size); - /* Fall through. */ + FALLTHROUGH; + /* FALLTHRU */ /* cancel button was pressed */ case IDCANCEL: @@ -246,7 +247,8 @@ ExtCmdDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) hWnd, IDC_EXTCMD_LIST, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0); if (*data->selection == LB_ERR) *data->selection = -1; - /* Fall through. */ + FALLTHROUGH; + /* FALLTHRU */ /* CANCEL button ws clicked */ case IDCANCEL: diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index 46a71b7d40..053324db88 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -1022,7 +1022,8 @@ onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) pFile = _tfopen(filename, TEXT("wt+,ccs=UTF-8")); if (!pFile) { TCHAR buf[4096]; - _stprintf(buf, TEXT("Cannot open %s for writing!"), filename); + nh_stprintf(buf, sizeof buf, + TEXT("Cannot open %s for writing!"), filename); NHMessageBox(hWnd, buf, MB_OK | MB_ICONERROR); if (text) free(text); diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index 41442cc691..0899bc7477 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -1188,10 +1188,12 @@ onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam) && data->menui.menu.items[lpdis->itemID].count != 0 && item->glyphinfo.glyph != NO_GLYPH) { if (data->menui.menu.items[lpdis->itemID].count == -1) { - _stprintf(wbuf, TEXT("Count: All")); + nh_stprintf(wbuf, sizeof wbuf, + TEXT("Count: All")); } else { - _stprintf(wbuf, TEXT("Count: %d"), - data->menui.menu.items[lpdis->itemID].count); + nh_stprintf(wbuf, sizeof wbuf, + TEXT("Count: %d"), + data->menui.menu.items[lpdis->itemID].count); } /* TODO: add blinking for blink text */ diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 930ffd23b7..c82ad4d742 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -1061,8 +1061,9 @@ mswin_display_file(const char *filename, boolean must_exist) if (!f) { if (must_exist) { TCHAR message[90]; - _stprintf(message, TEXT("Warning! Could not find file: %s\n"), - NH_A2W(filename, wbuf, sizeof(wbuf))); + nh_stprintf(message, sizeof message, + TEXT("Warning! Could not find file: %s\n"), + NH_A2W(filename, wbuf, sizeof(wbuf))); NHMessageBox(GetNHApp()->hMainWnd, message, MB_OK | MB_ICONEXCLAMATION); } diff --git a/win/win32/winMS.h b/win/win32/winMS.h index 1cb26aed2a..ed7e24e8f6 100644 --- a/win/win32/winMS.h +++ b/win/win32/winMS.h @@ -249,12 +249,14 @@ extern COLORREF message_fg_color; /* unicode stuff */ #define NH_CODEPAGE (SYMHANDLING(H_IBM) ? GetOEMCP() : GetACP()) #ifdef _UNICODE +#define nh_stprintf swprintf #define NH_W2A(w, a, cb) \ (WideCharToMultiByte(NH_CODEPAGE, 0, (w), -1, (a), (cb), NULL, NULL), (a)) #define NH_A2W(a, w, cb) \ (MultiByteToWideChar(NH_CODEPAGE, 0, (a), -1, (w), (cb)), (w)) #else +#define nh_stprintf snprintf #define NH_W2A(w, a, cb) (strncpy((a), (w), (cb))) #define NH_A2W(a, w, cb) (strncpy((w), (a), (cb)))