From 8f5cca8e3d9c2fdf9cece17103eaed2d38457fa8 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 24 Nov 2019 17:56:01 -0800 Subject: [PATCH 1/2] 3.7 build cleanup Unix Makefile.utl wasn't aware of the dependency of makedefs.o on src/mdlib.c so didn't rebuild makedefs when it should have. Eliminate several warnings: mdlib.c - #if inside the arguments to macro Sprintf(); nhlua.c - nhl_error() ends with a call to lua_error() which doesn't return, but neither of them were declared that way; nhlsel.c - because of the previous, the 'else error' case of l_selection_ellipse() led to complaints about uninitialized variables; sp_lev.c - missing 'const'. I did minimal testing which went ok, but revisiting a couple of levels gave me un-freed memory allocated by restore.c line 1337. (I haven't looked at that at all.) --- include/extern.h | 4 +- src/mdlib.c | 18 +++--- src/nhlsel.c | 141 +++++++++++++++++++----------------------- src/nhlua.c | 7 ++- src/sp_lev.c | 6 +- sys/unix/Makefile.utl | 6 +- 6 files changed, 84 insertions(+), 98 deletions(-) diff --git a/include/extern.h b/include/extern.h index 08ca0b29a..a191b9acf 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1573940539 2019/11/16 21:42:19 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.741 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1574646942 2019/11/25 01:55:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.759 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1674,7 +1674,7 @@ E int FDECL(l_selection_register, (lua_State *)); E lua_State * NDECL(nhl_init); E boolean FDECL(nhl_loadlua, (lua_State *, const char *)); E boolean FDECL(load_lua, (const char *)); -E void FDECL(nhl_error, (lua_State *, const char *)); +E void FDECL(nhl_error, (lua_State *, const char *)) NORETURN; E void FDECL(lcheck_param_table, (lua_State *)); E schar FDECL(get_table_mapchr, (lua_State *, const char *)); E schar FDECL(get_table_mapchr_opt, (lua_State *, const char *, SCHAR_P)); diff --git a/src/mdlib.c b/src/mdlib.c index 6d3dcdd5d..ea134e67f 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mdlib.c $NHDT-Date: 1562180226 2019/07/03 18:57:06 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.149 $ */ +/* NetHack 3.7 mdlib.c $NHDT-Date: 1574646946 2019/11/25 01:55:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ @@ -560,25 +560,21 @@ build_options() opttext[idxopttext] = strdup(optbuf); if (idxopttext < (MAXOPT - 1)) idxopttext++; - Sprintf(optbuf, - "%sNetHack version %d.%d.%d%s\n", - opt_indent, - VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) #if (NH_DEVEL_STATUS == NH_STATUS_BETA) - " [beta]" +#define STATUS_ARG " [beta]" #else - " [work-in-progress]" +#define STATUS_ARG " [work-in-progress]" #endif #else - "" +#define STATUS_ARG "" #endif /* NH_DEVEL_STATUS == NH_STATUS_RELEASED */ - ); + Sprintf(optbuf, "%sNetHack version %d.%d.%d%s\n", + opt_indent, VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, STATUS_ARG); opttext[idxopttext] = strdup(optbuf); if (idxopttext < (MAXOPT - 1)) idxopttext++; - Sprintf(optbuf, - "Options compiled into this edition:"); + Sprintf(optbuf, "Options compiled into this edition:"); opttext[idxopttext] = strdup(optbuf); if (idxopttext < (MAXOPT - 1)) idxopttext++; diff --git a/src/nhlsel.c b/src/nhlsel.c index 9fe66047c..50e328e8a 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 nhlua.c $NHDT-Date: 1524287226 2018/04/21 05:07:06 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.98 $ */ +/* NetHack 3.6 nhlua.c $NHDT-Date: 1574646948 2019/11/25 01:55:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ */ /* Copyright (c) 2018 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ @@ -41,7 +41,6 @@ static int FDECL(l_selection_iterate, (lua_State *)); static int FDECL(l_selection_add, (lua_State *)); static int FDECL(l_selection_sub, (lua_State *)); static int FDECL(l_selection_ipairs, (lua_State *)); -/* this prototype was missing but function body was below */ static struct selectionvar *FDECL(l_selection_to, (lua_State *, int)); #endif @@ -69,16 +68,19 @@ lua_State *L; return 0; } +#if 0 static struct selectionvar * l_selection_to(L, index) lua_State *L; int index; { struct selectionvar *sel = (struct selectionvar *)lua_touserdata(L, index); + if (!sel) nhl_error(L, "Selection error"); return sel; } +#endif static struct selectionvar * l_selection_push(L) @@ -137,11 +139,10 @@ l_selection_setpoint(L) lua_State *L; { struct selectionvar *sel = (struct selectionvar *) 0; - /* REVIEW: initializer added */ schar x = -1, y = -1; int val = 1; int argc = lua_gettop(L); - long coord; + long coord = 0L; if (argc == 0) { (void) l_selection_new(L); @@ -162,6 +163,7 @@ lua_State *L; if (!sel || !sel->map) { nhl_error(L, "Selection setpoint error"); + /*NOTREACHED*/ return 0; } @@ -169,7 +171,8 @@ lua_State *L; coord = SP_COORD_PACK_RANDOM(0); else coord = SP_COORD_PACK(x,y); - get_location_coord(&x, &y, ANY_LOC, g.coder ? g.coder->croom : NULL, coord); + get_location_coord(&x, &y, ANY_LOC, + g.coder ? g.coder->croom : NULL, coord); selection_setpoint(x, y, sel, val); lua_settop(L, 1); return 1; @@ -451,7 +454,6 @@ lua_State *L; { int argc = lua_gettop(L); struct selectionvar *sel = (struct selectionvar *) 0; - /* REVIEW: initializer added */ schar x1, y1, x2, y2; int roughness = 7; @@ -473,10 +475,12 @@ lua_State *L; sel = l_selection_check(L, 1); } - get_location_coord(&x1, &y1, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x1,y1)); - get_location_coord(&x2, &y2, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x2,y2)); + get_location_coord(&x1, &y1, ANY_LOC, + g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x1, y1)); + get_location_coord(&x2, &y2, ANY_LOC, + g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x2, y2)); - selection_do_randline(x1,y1, x2,y2, roughness, 12, sel); + selection_do_randline(x1, y1, x2, y2, roughness, 12, sel); lua_settop(L, 1); return 1; } @@ -533,7 +537,6 @@ lua_State *L; { int argc = lua_gettop(L); struct selectionvar *sel = (struct selectionvar *) 0; - /* REVIEW: initializer added */ schar x, y; if (argc == 3) { @@ -548,11 +551,13 @@ lua_State *L; sel = l_selection_check(L, 1); } else { nhl_error(L, "wrong parameters"); + /*NOTREACHED*/ } - get_location_coord(&x, &y, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x,y)); + get_location_coord(&x, &y, ANY_LOC, + g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x, y)); - if (isok(x,y)) { + if (isok(x, y)) { set_floodfillchk_match_under(levl[x][y].typ); selection_floodfill(sel, x, y, FALSE); } @@ -571,9 +576,8 @@ lua_State *L; { int argc = lua_gettop(L); struct selectionvar *sel = (struct selectionvar *) 0; - /* REVIEW: initializer added */ - schar x, y; - int r, filled = 0; + schar x = 0, y = 0; + int r = 0, filled = 0; if (argc == 3) { x = (schar) luaL_checkinteger(L, 1); @@ -599,22 +603,13 @@ lua_State *L; filled = (int) luaL_optinteger(L, 5, 0); /* TODO: boolean */ } else { nhl_error(L, "wrong parameters"); - /* - * FIXME: OSX compiler is issuing a complaint - * about r being passed to selection_do_ellipse() - * below without ever having been initialized - * to something when this else clause is encountered. - * I could have added an initializer to r at the - * top, but I didn't know what it should be initialized - * to in order for selection_do_ellipse() to not - * misbehave. The parameters passed in previous versions - * were related to xaxis and yaxis. - */ + /*NOTREACHED*/ } - get_location_coord(&x, &y, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x,y)); + get_location_coord(&x, &y, ANY_LOC, + g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x, y)); - selection_do_ellipse(sel, x,y, r,r, !filled); + selection_do_ellipse(sel, x, y, r, r, !filled); lua_settop(L, 1); return 1; @@ -630,9 +625,8 @@ lua_State *L; { int argc = lua_gettop(L); struct selectionvar *sel = (struct selectionvar *) 0; - /* REVIEW: initializer added */ - schar x, y; - int r1, r2, filled = 0; + schar x = 0, y = 0; + int r1 = 0, r2 = 0, filled = 0; if (argc == 4) { x = (schar) luaL_checkinteger(L, 1); @@ -661,22 +655,13 @@ lua_State *L; filled = (int) luaL_optinteger(L, 6, 0); /* TODO: boolean */ } else { nhl_error(L, "wrong parameters"); - /* - * FIXME: OSX compiler is issuing a complaint - * about r1 and r2 being passed to selection_do_ellipse() - * below without ever having been initialized - * to something when this else clause is encountered. - * I could have added an initializer to r1,r2 at the - * top, but I didn't know what they should be initialized - * to in order for selection_do_ellipse() to not - * misbehave. The parameters passed in previous versions - * were related to xaxis and yaxis. - */ + /*NOTREACHED*/ } - get_location_coord(&x, &y, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x,y)); + get_location_coord(&x, &y, ANY_LOC, + g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x, y)); - selection_do_ellipse(sel, x,y, r1,r2, !filled); + selection_do_ellipse(sel, x, y, r1, r2, !filled); lua_settop(L, 1); return 1; @@ -684,43 +669,43 @@ lua_State *L; static const struct luaL_Reg l_selection_methods[] = { - { "new", l_selection_new }, - { "clone", l_selection_clone }, - { "get", l_selection_getpoint }, - { "set", l_selection_setpoint }, - { "negate", l_selection_not }, - { "percentage", l_selection_filter_percent }, - { "rndcoord", l_selection_rndcoord }, - { "line", l_selection_line }, - { "randline", l_selection_randline }, - { "rect", l_selection_rect }, - { "fillrect", l_selection_fillrect }, - { "area", l_selection_fillrect }, - { "grow", l_selection_grow }, - { "filter_mapchar", l_selection_filter_mapchar }, - { "floodfill", l_selection_flood }, - { "circle", l_selection_circle }, - { "ellipse", l_selection_ellipse }, - /* TODO: - { "gradient", l_selection_gradient }, - { "iterate", l_selection_iterate }, - */ - { NULL, NULL } + { "new", l_selection_new }, + { "clone", l_selection_clone }, + { "get", l_selection_getpoint }, + { "set", l_selection_setpoint }, + { "negate", l_selection_not }, + { "percentage", l_selection_filter_percent }, + { "rndcoord", l_selection_rndcoord }, + { "line", l_selection_line }, + { "randline", l_selection_randline }, + { "rect", l_selection_rect }, + { "fillrect", l_selection_fillrect }, + { "area", l_selection_fillrect }, + { "grow", l_selection_grow }, + { "filter_mapchar", l_selection_filter_mapchar }, + { "floodfill", l_selection_flood }, + { "circle", l_selection_circle }, + { "ellipse", l_selection_ellipse }, + /* TODO: + { "gradient", l_selection_gradient }, + { "iterate", l_selection_iterate }, + */ + { NULL, NULL } }; static const luaL_Reg l_selection_meta[] = { - { "__gc", l_selection_gc }, - { "__unm", l_selection_not }, - { "__band", l_selection_and }, - { "__bor", l_selection_or }, - { "__bxor", l_selection_xor }, - { "__bnot", l_selection_not }, - /* TODO: http://lua-users.org/wiki/MetatableEvents - { "__add", l_selection_add }, - { "__sub", l_selection_sub }, - { "__ipairs", l_selection_ipairs }, - */ - { NULL, NULL } + { "__gc", l_selection_gc }, + { "__unm", l_selection_not }, + { "__band", l_selection_and }, + { "__bor", l_selection_or }, + { "__bxor", l_selection_xor }, + { "__bnot", l_selection_not }, + /* TODO: http://lua-users.org/wiki/MetatableEvents + { "__add", l_selection_add }, + { "__sub", l_selection_sub }, + { "__ipairs", l_selection_ipairs }, + */ + { NULL, NULL } }; int diff --git a/src/nhlua.c b/src/nhlua.c index 494b1d265..73431fc7f 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 nhlua.c $NHDT-Date: 1524287226 2018/04/21 05:07:06 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.98 $ */ +/* NetHack 3.6 nhlua.c $NHDT-Date: 1574646949 2019/11/25 01:55:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ */ /* Copyright (c) 2018 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ @@ -37,13 +37,16 @@ nhl_error(L, msg) lua_State *L; const char *msg; { + extern int FDECL(lua_error, (lua_State *)) NORETURN; lua_Debug ar; char buf[BUFSZ]; + lua_getstack(L, 1, &ar); lua_getinfo(L, "lS", &ar); Sprintf(buf, "%s (line %i%s)", msg, ar.currentline, ar.source); lua_pushstring(L, buf); - lua_error(L); + (void) lua_error(L); + /*NOTREACHED*/ } /* Check that parameters are nothing but single table, diff --git a/src/sp_lev.c b/src/sp_lev.c index cb35286ed..c759dd318 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 sp_lev.c $NHDT-Date: 1567805254 2019/09/06 21:27:34 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.117 $ */ +/* NetHack 3.6 sp_lev.c $NHDT-Date: 1574646949 2019/11/25 01:55:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.141 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -3336,8 +3336,10 @@ const char *name; int defval; { char *trapstr = get_table_str_opt(L, name, emptystr); + if (trapstr && *trapstr) { int i; + for (i = 0; trap_types[i].name; i++) if (!strcmpi(trapstr, trap_types[i].name)) { Free(trapstr); @@ -3350,7 +3352,7 @@ int defval; int get_traptype_byname(trapname) -char *trapname; +const char *trapname; { int i; diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index 64dccf570..30676b7e7 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -1,5 +1,5 @@ # Makefile for NetHack's utility programs. -# NetHack 3.6 Makefile.utl $NHDT-Date: 1539968067 2018/10/19 16:54:27 $ $NHDT-Branch: keni-makedefsm $:$NHDT-Revision: 1.38 $ +# NetHack 3.6 Makefile.utl $NHDT-Date: 1574646950 2019/11/25 01:55:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.44 $ # Copyright (c) 2018 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. @@ -185,7 +185,7 @@ CONFIG_H = ../src/config.h-t HACK_H = ../src/hack.h-t # utility .c files -MAKESRC = makedefs.c +MAKESRC = makedefs.c ../src/mdlib.c RECOVSRC = recover.c DLBSRC = dlb_main.c UTILSRCS = $(MAKESRC) panic.c $(DGNCOMPSRC) $(RECOVSRC) $(DLBSRC) @@ -231,7 +231,7 @@ YACCDIST = makedefs: $(MAKEOBJS) mdgrep.h $(CC) $(LFLAGS) -o makedefs $(MAKEOBJS) -makedefs.o: makedefs.c $(CONFIG_H) ../include/permonst.h \ +makedefs.o: makedefs.c ../src/mdlib.c $(CONFIG_H) ../include/permonst.h \ ../include/objclass.h ../include/monsym.h \ ../include/artilist.h ../include/dungeon.h ../include/obj.h \ ../include/monst.h ../include/you.h ../include/flag.h \ From 9adeff5e27f0a56af84429c39b5b739fc3ffd9b2 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 24 Nov 2019 18:29:14 -0800 Subject: [PATCH 2/2] 3.7: fix #9397 - pronouns when hallucinating Developed for 3.6 but deferred to 3.7. Most of the testing was with the earlier incarnation. Report was that pronouns were accurate for the underlying monsters when hallucination was describing something random, and also that the gender prefix flag from bogusmon.txt wasn't being used. The latter is still the case, but pronouns are now chosen at random while under the influence of hallucination. One of the choices is plural and an attempt is made to make the monster name and verb fit that usage. |The homunculus picks up a wand of speed monster. |The large cats zap themselves with a wand of speed monster! |The blue dragon is suddenly moving faster. There is no attempt to match gender for the singular cases; you might get |The succubus zaps himself [...] or |The incubus zaps herself [...] --- include/extern.h | 6 ++++-- include/you.h | 21 ++++++++++++++------- src/apply.c | 12 +++++++----- src/do_name.c | 40 ++++++++++++++++++++++++++++++++++++++-- src/mondata.c | 17 ++++++++++++----- src/muse.c | 17 ++++++++++++----- src/objnam.c | 38 ++++++++++++++++++++++++++++++++++++-- src/role.c | 6 ++++-- src/steed.c | 8 +++++--- 9 files changed, 132 insertions(+), 33 deletions(-) diff --git a/include/extern.h b/include/extern.h index a191b9acf..48c5db522 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1574646942 2019/11/25 01:55:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.759 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1574648937 2019/11/25 02:28:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.760 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -452,6 +452,8 @@ E char *FDECL(Amonnam, (struct monst *)); E char *FDECL(a_monnam, (struct monst *)); E char *FDECL(distant_monnam, (struct monst *, int, char *)); E char *FDECL(mon_nam_too, (struct monst *, struct monst *)); +E char *FDECL(monverbself, (struct monst *, char *, + const char *, const char *)); E char *FDECL(minimal_monnam, (struct monst *, BOOLEAN_P)); E char *FDECL(rndmonnam, (char *)); E const char *FDECL(hcolor, (const char *)); @@ -1511,7 +1513,7 @@ E int FDECL(monsndx, (struct permonst *)); E int FDECL(name_to_mon, (const char *)); E int FDECL(name_to_monclass, (const char *, int *)); E int FDECL(gender, (struct monst *)); -E int FDECL(pronoun_gender, (struct monst *, BOOLEAN_P)); +E int FDECL(pronoun_gender, (struct monst *, unsigned)); E boolean FDECL(levl_follower, (struct monst *)); E int FDECL(little_to_big, (int)); E int FDECL(big_to_little, (int)); diff --git a/include/you.h b/include/you.h index 657b9c3e7..611fcf3b1 100644 --- a/include/you.h +++ b/include/you.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 you.h $NHDT-Date: 1547514642 2019/01/15 01:10:42 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.35 $ */ +/* NetHack 3.6 you.h $NHDT-Date: 1574648937 2019/11/25 02:28:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -237,14 +237,21 @@ extern const struct Gender genders[]; /* table of available genders */ #define uhe() (genders[flags.female ? 1 : 0].he) #define uhim() (genders[flags.female ? 1 : 0].him) #define uhis() (genders[flags.female ? 1 : 0].his) +/* pronoun_gender() flag masks */ +#define PRONOUN_NORMAL 0 /* none of the below */ +#define PRONOUN_NO_IT 1 +#define PRONOUN_HALLU 2 /* corresponding pronouns for monsters; yields "it" when mtmp can't be seen */ -#define mhe(mtmp) (genders[pronoun_gender(mtmp, FALSE)].he) -#define mhim(mtmp) (genders[pronoun_gender(mtmp, FALSE)].him) -#define mhis(mtmp) (genders[pronoun_gender(mtmp, FALSE)].his) +#define mhe(mtmp) (genders[pronoun_gender(mtmp, PRONOUN_HALLU)].he) +#define mhim(mtmp) (genders[pronoun_gender(mtmp, PRONOUN_HALLU)].him) +#define mhis(mtmp) (genders[pronoun_gender(mtmp, PRONOUN_HALLU)].his) /* override "it" if reason is lack of visibility rather than neuter species */ -#define noit_mhe(mtmp) (genders[pronoun_gender(mtmp, TRUE)].he) -#define noit_mhim(mtmp) (genders[pronoun_gender(mtmp, TRUE)].him) -#define noit_mhis(mtmp) (genders[pronoun_gender(mtmp, TRUE)].his) +#define noit_mhe(mtmp) \ + (genders[pronoun_gender(mtmp, (PRONOUN_NO_IT | PRONOUN_HALLU))].he) +#define noit_mhim(mtmp) \ + (genders[pronoun_gender(mtmp, (PRONOUN_NO_IT | PRONOUN_HALLU))].him) +#define noit_mhis(mtmp) \ + (genders[pronoun_gender(mtmp, (PRONOUN_NO_IT | PRONOUN_HALLU))].his) /*** Unified structure specifying alignment information ***/ struct Align { diff --git a/src/apply.c b/src/apply.c index ecaccb741..6451187e9 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 apply.c $NHDT-Date: 1573778560 2019/11/15 00:42:40 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.284 $ */ +/* NetHack 3.6 apply.c $NHDT-Date: 1574648938 2019/11/25 02:28:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.301 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -212,7 +212,7 @@ int rx, ry, *resp; if (mtmp) { mptr = mtmp->data = &mons[mtmp->mnum]; /* TRUE: override visibility check--it's not on the map */ - gndr = pronoun_gender(mtmp, TRUE); + gndr = pronoun_gender(mtmp, PRONOUN_NO_IT); } else { mptr = &mons[corpse->corpsenm]; if (is_female(mptr)) @@ -934,8 +934,9 @@ struct obj *obj; /* infravision doesn't produce an image in the mirror */ } else if ((how_seen & SEENMON) == MONSEEN_INFRAVIS) { if (vis) /* (redundant) */ - pline("%s is too far away to see %sself in the dark.", - Monnam(mtmp), mhim(mtmp)); + pline("%s in the dark.", + monverbself(mtmp, Monnam(mtmp), "are", + "too far away to see")); /* some monsters do special things */ } else if (mlet == S_VAMPIRE || mlet == S_GHOST || is_vampshifter(mtmp)) { if (vis) @@ -965,7 +966,8 @@ struct obj *obj; if (vis) { char buf[BUFSZ]; /* "She" or "He" */ - pline("%s admires %sself in your %s.", Monnam(mtmp), mhim(mtmp), + pline("%s in your %s.", /* " admires self in your mirror " */ + monverbself(mtmp, Monnam(mtmp), "admire", (char *) 0), mirror); pline("%s takes it!", upstart(strcpy(buf, mhe(mtmp)))); } else diff --git a/src/do_name.c b/src/do_name.c index 02ea4230b..cf812daa3 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_name.c $NHDT-Date: 1574419578 2019/11/22 10:46:18 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.152 $ */ +/* NetHack 3.6 do_name.c $NHDT-Date: 1574648939 2019/11/25 02:28:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.167 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1959,7 +1959,7 @@ struct monst *mon, *other_mon; outbuf = mon_nam(mon); } else { outbuf = nextmbuf(); - switch (pronoun_gender(mon, FALSE)) { + switch (pronoun_gender(mon, PRONOUN_HALLU)) { case 0: Strcpy(outbuf, "himself"); break; @@ -1967,13 +1967,49 @@ struct monst *mon, *other_mon; Strcpy(outbuf, "herself"); break; default: + case 2: Strcpy(outbuf, "itself"); break; + case 3: /* could happen when hallucinating */ + Strcpy(outbuf, "themselves"); + break; } } return outbuf; } +/* construct " {him|her|it}self" which might + be distorted by Hallu; if that's plural, adjust monnamtext and verb */ +char * +monverbself(mon, monnamtext, verb, othertext) +struct monst *mon; +char *monnamtext; /* modifiable 'mbuf' with adequare room at end */ +const char *verb, *othertext; +{ + char *verbs, selfbuf[40]; /* sizeof "themselves" suffices */ + + /* "himself"/"herself"/"itself", maybe "themselves" if hallucinating */ + Strcpy(selfbuf, mon_nam_too(mon, mon)); + /* verb starts plural; this will yield singular except for "themselves" */ + verbs = vtense(selfbuf, verb); + if (!strcmp(verb, verbs)) { /* a match indicates that it stayed plural */ + monnamtext = makeplural(monnamtext); + /* for "it", makeplural() produces "them" but we want "they" */ + if (!strcmpi(monnamtext, genders[3].he)) { + boolean capitaliz = (monnamtext[0] == highc(monnamtext[0])); + + Strcpy(monnamtext, genders[3].him); + if (capitaliz) + monnamtext[0] = highc(monnamtext[0]); + } + } + Strcat(strcat(monnamtext, " "), verbs); + if (othertext && *othertext) + Strcat(strcat(monnamtext, " "), othertext); + Strcat(strcat(monnamtext, " "), selfbuf); + return monnamtext; +} + /* for debugging messages, where data might be suspect and we aren't taking what the hero does or doesn't know into consideration */ char * diff --git a/src/mondata.c b/src/mondata.c index f510afcfd..ba5b27d0a 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mondata.c $NHDT-Date: 1550525093 2019/02/18 21:24:53 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.72 $ */ +/* NetHack 3.6 mondata.c $NHDT-Date: 1574648940 2019/11/25 02:29:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -910,13 +910,20 @@ register struct monst *mtmp; return mtmp->female; } -/* Like gender(), but lower animals and such are still "it". - This is the one we want to use when printing messages. */ +/* Like gender(), but unseen humanoids are "it" rather than "he" or "she" + and lower animals and such are "it" even when seen; hallucination might + yield "they". This is the one we want to use when printing messages. */ int -pronoun_gender(mtmp, override_vis) +pronoun_gender(mtmp, pg_flags) register struct monst *mtmp; -boolean override_vis; /* if True then 'no it' unless neuter */ +unsigned pg_flags; /* flags&1: 'no it' unless neuter, + * flags&2: random if hallucinating */ { + boolean override_vis = (pg_flags & PRONOUN_NO_IT) ? TRUE : FALSE, + hallu_rand = (pg_flags & PRONOUN_HALLU) ? TRUE : FALSE; + + if (hallu_rand && Hallucination) + return rn2(4); /* 0..3 */ if (!override_vis && !canspotmon(mtmp)) return 2; if (is_neuter(mtmp->data)) diff --git a/src/muse.c b/src/muse.c index 770e6b60d..25e29ed91 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 muse.c $NHDT-Date: 1560161807 2019/06/10 10:16:47 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.96 $ */ +/* NetHack 3.6 muse.c $NHDT-Date: 1574648940 2019/11/25 02:29:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.115 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -161,7 +161,8 @@ boolean self; ? "nearby" : "distant"); otmp->known = 0; } else if (self) { - pline("%s zaps %sself with %s!", Monnam(mtmp), mhim(mtmp), + pline("%s with %s!", + monverbself(mtmp, Monnam(mtmp), "zap", (char *) 0), doname(otmp)); } else { pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp))); @@ -186,9 +187,15 @@ boolean self; ? "nearby" : "in the distance"); otmp->known = 0; /* hero doesn't know how many charges are left */ } else { + char *objnamp, objbuf[BUFSZ]; + otmp->dknown = 1; - pline("%s plays a %s directed at %s!", Monnam(mtmp), xname(otmp), - self ? mon_nam_too(mtmp, mtmp) : (char *) "you"); + objnamp = xname(otmp); + if (strlen(objnamp) >= QBUFSZ) + objnamp = simpleonames(otmp); + Sprintf(objbuf, "a %s directed at", objnamp); + /* " plays a directed at himself!" */ + pline("%s!", monverbself(mtmp, Monnam(mtmp), "play", objbuf)); makeknown(otmp->otyp); /* (wands handle this slightly differently) */ if (!self) stop_occupation(); @@ -2461,7 +2468,7 @@ boolean by_you; /* true: if mon kills itself, hero gets credit/blame */ } else if (otyp == STRANGE_OBJECT) { /* monster is using fire breath on self */ if (vis) - pline("%s breathes fire on %sself.", Monnam(mon), mhim(mon)); + pline("%s.", monverbself(mon, Monnam(mon), "breath", "fire on")); if (!rn2(3)) mon->mspec_used = rn1(10, 5); /* -21 => monster's fire breath; 1 => # of damage dice */ diff --git a/src/objnam.c b/src/objnam.c index 7aba0526c..64f8b473f 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1573290418 2019/11/09 09:06:58 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.248 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1574648942 2019/11/25 02:29:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.271 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2310,7 +2310,7 @@ const char *oldstr; register char *spot; char lo_c, *str = nextobuf(); const char *excess = (char *) 0; - int len; + int len, i; if (oldstr) while (*oldstr == ' ') @@ -2320,6 +2320,26 @@ const char *oldstr; Strcpy(str, "s"); return str; } + /* makeplural() is sometimes used on monsters rather than objects + and sometimes pronouns are used for monsters, so check those; + unfortunately, "her" (which matches genders[1].him and [1].his) + and "it" (which matches genders[2].he and [2].him) are ambiguous; + we'll live with that; caller can fix things up if necessary */ + *str = '\0'; + for (i = 0; i <= 2; ++i) { + if (!strcmpi(genders[i].he, oldstr)) + Strcpy(str, genders[3].he); /* "they" */ + else if (!strcmpi(genders[i].him, oldstr)) + Strcpy(str, genders[3].him); /* "them" */ + else if (!strcmpi(genders[i].his, oldstr)) + Strcpy(str, genders[3].his); /* "their" */ + if (*str) { + if (oldstr[0] == highc(oldstr[0])) + str[0] = highc(str[0]); + return str; + } + } + Strcpy(str, oldstr); /* @@ -2498,6 +2518,20 @@ const char *oldstr; str[0] = '\0'; return str; } + /* makeplural() of pronouns isn't reversible but at least we can + force a singular value */ + *str = '\0'; + if (!strcmpi(genders[3].he, oldstr)) /* "they" */ + Strcpy(str, genders[2].he); /* "it" */ + else if (!strcmpi(genders[3].him, oldstr)) /* "them" */ + Strcpy(str, genders[2].him); /* also "it" */ + else if (!strcmpi(genders[3].his, oldstr)) /* "their" */ + Strcpy(str, genders[2].his); /* "its" */ + if (*str) { + if (oldstr[0] == highc(oldstr[0])) + str[0] = highc(str[0]); + return str; + } bp = strcpy(str, oldstr); diff --git a/src/role.c b/src/role.c index 349c736b8..a62d042a7 100644 --- a/src/role.c +++ b/src/role.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 role.c $NHDT-Date: 1547086250 2019/01/10 02:10:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.56 $ */ +/* NetHack 3.6 role.c $NHDT-Date: 1574648943 2019/11/25 02:29:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -701,7 +701,9 @@ const struct Race races[] = { const struct Gender genders[] = { { "male", "he", "him", "his", "Mal", ROLE_MALE }, { "female", "she", "her", "her", "Fem", ROLE_FEMALE }, - { "neuter", "it", "it", "its", "Ntr", ROLE_NEUTER } + { "neuter", "it", "it", "its", "Ntr", ROLE_NEUTER }, + /* used by pronoun_gender() when hallucinating */ + { "group", "they", "them", "their", "Grp", 0 }, }; /* Table of all alignments */ diff --git a/src/steed.c b/src/steed.c index cc0c165cd..c145b09a1 100644 --- a/src/steed.c +++ b/src/steed.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 steed.c $NHDT-Date: 1573940541 2019/11/16 21:42:21 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 3.6 steed.c $NHDT-Date: 1574648944 2019/11/25 02:29:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ /* Copyright (c) Kevin Hugo, 1998-1999. */ /* NetHack may be freely redistributed. See license for details. */ @@ -377,7 +377,7 @@ exercise_steed() void kick_steed() { - char He[4]; + char He[BUFSZ]; /* monverbself() appends to the "He"/"She"/"It" value */ if (!u.usteed) return; @@ -400,7 +400,9 @@ kick_steed() if (u.usteed->msleeping || !u.usteed->mcanmove) pline("%s stirs.", He); else - pline("%s rouses %sself!", He, mhim(u.usteed)); + /* if hallucinating, might yield "He rouses herself" or + "She rouses himself" */ + pline("%s!", monverbself(u.usteed, He, "rouse", (char *) 0)); } else pline("%s does not respond.", He); return;