diff --git a/Cross-compiling b/Cross-compiling index b3dbba6f6..2fba66923 100644 --- a/Cross-compiling +++ b/Cross-compiling @@ -189,14 +189,14 @@ cross-compiling possible: Mac OS X are some examples of platforms that have cross-compilers for other targets available) - o Then, make the community, devteam, and otheres aware that you're starting + o Then, make the community, devteam, and others aware that you're starting a cross-compile of NetHack for XX-Platform. You might need to ask some "starting out" questions initially, and as you get deeper into it, you might need to ask some tougher questions. o Perhaps consider forking from NetHack on GitHub, and do the cross-compiler work there in your fork. Strive to get it to a point where - its ready to play-test on XX-Platform, or perhaps even use an emulator + it's ready to play-test on XX-Platform, or perhaps even use an emulator of XX-Platform if one is available. We live in a time where plenty do. Doing your work on a GitHub fork has the following advantages: @@ -364,16 +364,16 @@ Using the cross-compiler, build the following targets: 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/invent.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/mapglyph.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/o_init.c, - src/objects.c, src/objnam.c, src/options.c, - src/pager.c, src/pickup.c, src/pline.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/questpgr.c, src/random.c, src/read.c, src/rect.c, src/region.c, diff --git a/dat/dungeon.lua b/dat/dungeon.lua index 014d3dab3..be504fbd2 100644 --- a/dat/dungeon.lua +++ b/dat/dungeon.lua @@ -167,6 +167,7 @@ dungeon = { range = 2, alignment = "lawful", flags = { "mazelike" }, + lvlfill = "minefill", levels = { { name = "minetn", diff --git a/dat/sanctum.lua b/dat/sanctum.lua index bc669a7cd..45aa0b361 100644 --- a/dat/sanctum.lua +++ b/dat/sanctum.lua @@ -32,7 +32,9 @@ des.map([[ | ------------- ----- ------- | ---------------------------------------------------------------------------- ]]); -des.region({ region={15,07, 21,10}, lit=1, type="temple" }) +des.region({ region={15,07, 21,10}, lit=1, type="temple", contents = function() + des.door({ wall = "random", state = "secret" }); +end }) des.altar({ x=18, y=08, align="noalign", type="sanctum" }) des.region({ region={41,06, 48,11}, lit=0, type="morgue", prefilled=0, irregular=1 }) -- Non diggable walls diff --git a/dat/wizard1.lua b/dat/wizard1.lua index a34f20df5..26dfd5839 100644 --- a/dat/wizard1.lua +++ b/dat/wizard1.lua @@ -28,9 +28,10 @@ des.levregion({ type="stair-up", region={01,00,79,20}, region_islev=1, exclude={ des.levregion({ type="stair-down", region={01,00,79,20}, region_islev=1, exclude={0,0,28,12} }) des.levregion({ type="branch", region={01,00,79,20}, region_islev=1, exclude={0,0,28,12} }) des.teleport_region({ region={01,00,79,20}, region_islev=1, exclude={0,0,27,12} }) --- Make it a morgue for rm id in mkmaze.c --- for the purpose of random sdoor placement -des.region({ region={12,01, 20,09}, lit=0, type="morgue", prefilled=1 }) +des.region({ region={12,01, 20,09}, lit=0, type="morgue", prefilled=1, contents=function() + local sdwall = { "south", "west", "east" }; + des.door({ wall = sdwall[math.random(1, #sdwall)], state = "secret" }); +end }) -- another region to constrain monster arrival des.region({ region={01,01, 10,11}, lit=0, type="ordinary", prefilled=0 }) des.mazewalk(28,05,"east") diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index e7eaa2c2f..5fbf3251b 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -3911,7 +3911,7 @@ something pushes the old item into your alternate weapon slot (default off). Likewise for the `a' (apply) command if it causes the applied item to become wielded. Persistent. %.lp -\item[\ib{quick\verb+_+farsight}] +\item[\ib(quick\verb+_+farsight)] When set, usually prevents the ``you sense your surroundings'' message where play pauses to allow you to browse the map whenever clairvoyance randomly activates. diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 337f1e3df..c381d5156 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.84 $ $NHDT-Date: 1580504296 2020/01/31 20:58:16 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ $NHDT-Date: 1580633720 2020/02/02 08:55:20 $ General Fixes and Modified Features ----------------------------------- @@ -50,6 +50,7 @@ revamp achievement tracking for exploring Mine's End and Sokoban (by acquiring throttle long worm growth rate and HP accumulation poly'd hero was able to zap wands, apply tools, and #rub objects without having any hands +spellcasting monster got an extra move after casting Fixes to 3.7.0-x Problems that Were Exposed Via git Repository @@ -82,10 +83,15 @@ level teleporation's "You materialize on a different level!" could be given out of sequence with other arrival messages creating Mine Town variant 1 (Orcish Town) sometimes complained about being unable to place lregion type 1 and failed to have any staircase up +prevent "you materialize on a different level" after "a mysterious force + prevents you from descending" if you try to level teleport past the + stairs down from the quest home level before being granted access Platform- and/or Interface-Specific Fixes ----------------------------------------- +msdos: Add -DSTATUES_LOOK_LIKE_MONSTERS to Makefile1.cross so the VESA mode + can display statue glyphs. tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic @@ -134,6 +140,7 @@ when 'color' if Off and 'use_inverse' is On, draw ice on the map in inverse new 'mention_decor' option; when On, describe dungeon features being stepped on or floated/flown over even when they're not covered by objects applying royal jelly on an egg kills, revives, or changes the egg +intelligent monsters pick up and rummage through containers Platform- and/or Interface-Specific New Features diff --git a/include/decl.h b/include/decl.h index 5588377a3..335eaec92 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 decl.h $NHDT-Date: 1573869061 2019/11/16 01:51:01 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.165 $ */ +/* NetHack 3.6 decl.h $NHDT-Date: 1580600478 2020/02/01 23:41:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.221 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1110,27 +1110,19 @@ struct instance_globals { /* auto-response flag for/from "sell foo?" 'a' => 'y', 'q' => 'n' */ char sell_response; int sell_how; - /* can't just use sell_response='y' for auto_credit because the 'a' response + /* can't just use sell_response='y' for auto_credit because 'a' response shouldn't carry over from ordinary selling to credit selling */ boolean auto_credit; struct repo repo; - long int followmsg; /* last time of follow message */ - + long int followmsg; /* last time of follow message */ /* sp_lev.c */ char *lev_message; lev_region *lregions; int num_lregions; - /* positions touched by level elements explicitly defined in des-file */ - char SpLev_Map[COLNO][ROWNO]; struct sp_coder *coder; xchar xstart, ystart; - char xsize, ysize; - boolean splev_init_present; - boolean icedpools; - struct obj *container_obj[MAX_CONTAINMENT]; - int container_idx; - struct monst *invent_carrying_monster; + xchar xsize, ysize; /* spells.c */ int spl_sortmode; /* index into spl_sortchoices[] */ diff --git a/include/dungeon.h b/include/dungeon.h index c25494001..7a5677761 100644 --- a/include/dungeon.h +++ b/include/dungeon.h @@ -56,6 +56,7 @@ typedef struct dest_area { /* non-stairway level change identifier */ typedef struct dungeon { /* basic dungeon identifier */ char dname[24]; /* name of the dungeon (eg. "Hell") */ char proto[15]; /* name of prototype file (eg. "tower") */ + char fill_lvl[15]; /* name of "fill" level protype file */ char boneid; /* character to id dungeon in bones files */ d_flags flags; /* dungeon flags */ xchar entry_lev; /* entry level */ diff --git a/include/extern.h b/include/extern.h index ef9f64838..b43df085e 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1580044333 2020/01/26 13:12:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.786 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1580633720 2020/02/02 08:55:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.787 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3014,7 +3014,7 @@ E void FDECL(initworm, (struct monst *, int)); E void FDECL(worm_move, (struct monst *)); E void FDECL(worm_nomove, (struct monst *)); E void FDECL(wormgone, (struct monst *)); -E void FDECL(wormhitu, (struct monst *)); +E int FDECL(wormhitu, (struct monst *)); E void FDECL(cutworm, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P)); E void FDECL(see_wsegs, (struct monst *)); E void FDECL(detect_wsegs, (struct monst *, BOOLEAN_P)); diff --git a/include/hack.h b/include/hack.h index 4a987d9d9..eba5d7bb1 100644 --- a/include/hack.h +++ b/include/hack.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 hack.h $NHDT-Date: 1580252122 2020/01/28 22:55:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */ +/* NetHack 3.6 hack.h $NHDT-Date: 1580600495 2020/02/01 23:41:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -169,9 +169,6 @@ typedef struct strbuf { char buf[256]; } strbuf_t; -/* max. layers of object containment from sp_lev.h */ -#define MAX_CONTAINMENT 10 - /* str_or_len from sp_lev.h */ typedef union str_or_len { char *str; diff --git a/src/decl.c b/src/decl.c index 79cbd199a..6bf82e986 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 decl.c $NHDT-Date: 1573869062 2019/11/16 01:51:02 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.149 $ */ +/* NetHack 3.6 decl.c $NHDT-Date: 1580600496 2020/02/01 23:41:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.202 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -630,17 +630,11 @@ const struct instance_globals g_init = { NULL, /* lev_message */ NULL, /* lregions */ 0, /* num_lregions */ - UNDEFINED_VALUES, /* SpLev_Map */ NULL, /* coder */ UNDEFINED_VALUE, /* xstart */ UNDEFINED_VALUE, /* ystart */ UNDEFINED_VALUE, /* xsize */ UNDEFINED_VALUE, /* ysize */ - FALSE, /* splev_init_present */ - FALSE, /* icedpools */ - { UNDEFINED_PTR }, /* container_obj */ - 0, /* container_idx */ - NULL, /* invent_carrying_monster */ /* spells.c */ 0, /* spl_sortmode */ diff --git a/src/do.c b/src/do.c index 69734ed6c..d392cdbf3 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do.c $NHDT-Date: 1580254093 2020/01/28 23:28:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.221 $ */ +/* NetHack 3.6 do.c $NHDT-Date: 1580608377 2020/02/02 01:52:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.222 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1781,10 +1781,11 @@ void deferred_goto() { if (!on_level(&u.uz, &u.utolev)) { - d_level dest; + d_level dest, oldlev; int typmask = u.utotype; /* save it; goto_level zeroes u.utotype */ assign_level(&dest, &u.utolev); + assign_level(&oldlev, &u.uz); if (g.dfr_pre_msg) pline1(g.dfr_pre_msg); goto_level(&dest, !!(typmask & 1), !!(typmask & 2), !!(typmask & 4)); @@ -1796,7 +1797,7 @@ deferred_goto() newsym(u.ux, u.uy); } } - if (g.dfr_post_msg) + if (g.dfr_post_msg && !on_level(&u.uz, &oldlev)) pline1(g.dfr_post_msg); } u.utotype = 0; /* our caller keys off of this */ diff --git a/src/dungeon.c b/src/dungeon.c index f07f375f1..9546b7c3a 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dungeon.c $NHDT-Date: 1562187890 2019/07/03 21:04:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.105 $ */ +/* NetHack 3.6 dungeon.c $NHDT-Date: 1580607225 2020/02/02 01:33:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.124 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -693,7 +693,7 @@ struct proto_dungeon *pd; return FALSE; } -struct level_map { +static struct level_map { const char *lev_name; d_level *lev_spec; } level_map[] = { { "air", &air_level }, @@ -729,8 +729,10 @@ get_dgn_flags(L) lua_State *L; { int dgn_flags = 0; - const char *const flagstrs[] = { "town", "hellish", "mazelike", "roguelike", NULL}; - const int flagstrs2i[] = { TOWN, HELLISH, MAZELIKE, ROGUELIKE, 0 }; + static const char *const flagstrs[] = { + "town", "hellish", "mazelike", "roguelike", NULL + }; + static const int flagstrs2i[] = { TOWN, HELLISH, MAZELIKE, ROGUELIKE, 0 }; lua_getfield(L, -1, "flags"); if (lua_type(L, -1) == LUA_TTABLE) { @@ -740,10 +742,11 @@ lua_State *L; nflags = (int) lua_tointeger(L, -1); lua_pop(L, 1); for (f = 0; f < nflags; f++) { - lua_pushinteger(L, f+1); + lua_pushinteger(L, f + 1); lua_gettable(L, -2); if (lua_type(L, -1) == LUA_TSTRING) { - dgn_flags |= flagstrs2i[luaL_checkoption(L, -1, NULL, flagstrs)]; + dgn_flags |= flagstrs2i[luaL_checkoption(L, -1, NULL, + flagstrs)]; lua_pop(L, 1); } else impossible("flags[%i] is not a string", f); @@ -761,8 +764,13 @@ lua_State *L; void init_dungeons() { - const char *const dgnaligns[] = { "unaligned", "noalign", "lawful", "neutral", "chaotic", NULL}; - const int dgnaligns2i[] = { D_ALIGN_NONE, D_ALIGN_NONE, D_ALIGN_LAWFUL, D_ALIGN_NEUTRAL, D_ALIGN_CHAOTIC, D_ALIGN_NONE }; + static const char *const dgnaligns[] = { + "unaligned", "noalign", "lawful", "neutral", "chaotic", NULL + }; + static const int dgnaligns2i[] = { + D_ALIGN_NONE, D_ALIGN_NONE, D_ALIGN_LAWFUL, + D_ALIGN_NEUTRAL, D_ALIGN_CHAOTIC, D_ALIGN_NONE + }; lua_State *L; register int i, cl = 0; register s_level *x; @@ -770,7 +778,7 @@ init_dungeons() struct level_map *lev_map; int tidx; - (void) memset(&pd, 0, sizeof(struct proto_dungeon)); + (void) memset(&pd, 0, sizeof (struct proto_dungeon)); pd.n_levs = pd.n_brs = 0; L = nhl_init(); @@ -832,7 +840,7 @@ init_dungeons() lua_pushnil(L); /* first key */ i = 0; while (lua_next(L, tidx) != 0) { - char *dgn_name, *dgn_bonetag, *dgn_protoname; + char *dgn_name, *dgn_bonetag, *dgn_protoname, *dgn_fill; int dgn_base, dgn_range, dgn_align, dgn_entry, dgn_chance, dgn_flags; if (!lua_istable(L, -1)) @@ -843,46 +851,61 @@ init_dungeons() dgn_protoname = get_table_str_opt(L, "protofile", emptystr); dgn_base = get_table_int(L, "base"); dgn_range = get_table_int_opt(L, "range", 0); - dgn_align = dgnaligns2i[get_table_option(L, "alignment", "unaligned", dgnaligns)]; + dgn_align = dgnaligns2i[get_table_option(L, "alignment", + "unaligned", dgnaligns)]; dgn_entry = get_table_int_opt(L, "entry", 0); dgn_chance = get_table_int_opt(L, "chance", 100); dgn_flags = get_dgn_flags(L); + dgn_fill = get_table_str_opt(L, "lvlfill", emptystr); - debugpline4("DUNGEON[%i]: %s, base=(%i,%i)", i, dgn_name, dgn_base, dgn_range); + debugpline4("DUNGEON[%i]: %s, base=(%i,%i)", + i, dgn_name, dgn_base, dgn_range); if (!wizard && dgn_chance && (dgn_chance <= rn2(100))) { debugpline1("IGNORING %s", dgn_name); g.n_dgns--; lua_pop(L, 1); /* pop the dungeon table */ + free((genericptr_t) dgn_name); + free((genericptr_t) dgn_bonetag); + free((genericptr_t) dgn_protoname); + free((genericptr_t) dgn_fill); continue; } /* levels begin */ lua_getfield(L, -1, "levels"); if (lua_type(L, -1) == LUA_TTABLE) { - int f, nlevels; + char *lvl_name, *lvl_bonetag, *lvl_chain; + int lvl_base, lvl_range, lvl_nlevels, lvl_chance, + lvl_align, lvl_flags; + struct tmplevel *tmpl; + int bi, f, nlevels; lua_len(L, -1); nlevels = (int) lua_tointeger(L, -1); pd.tmpdungeon[i].levels = nlevels; lua_pop(L, 1); for (f = 0; f < nlevels; f++) { - lua_pushinteger(L, f+1); + lua_pushinteger(L, f + 1); lua_gettable(L, -2); if (lua_type(L, -1) == LUA_TTABLE) { - int bi; - char *lvl_name = get_table_str(L, "name"); - char *lvl_bonetag = get_table_str_opt(L, "bonetag", emptystr); - int lvl_base = get_table_int(L, "base"); - int lvl_range = get_table_int_opt(L, "range", 0); - int lvl_nlevels = get_table_int_opt(L, "nlevels", 0); - int lvl_chance = get_table_int_opt(L, "chance", 100); - char *lvl_chain = get_table_str_opt(L, "chainlevel", NULL); - int lvl_align = dgnaligns2i[get_table_option(L, "alignment", "unaligned", dgnaligns)]; - int lvl_flags = get_dgn_flags(L); - struct tmplevel *tmpl = &pd.tmplevel[pd.n_levs + f]; + lvl_name = get_table_str(L, "name"); + lvl_bonetag = get_table_str_opt(L, "bonetag", emptystr); + lvl_chain = get_table_str_opt(L, "chainlevel", NULL); + lvl_base = get_table_int(L, "base"); + lvl_range = get_table_int_opt(L, "range", 0); + lvl_nlevels = get_table_int_opt(L, "nlevels", 0); + lvl_chance = get_table_int_opt(L, "chance", 100); + lvl_align = dgnaligns2i[get_table_option(L, "alignment", + "unaligned", dgnaligns)]; + lvl_flags = get_dgn_flags(L); + /* array index is offset by cumulative number of levels + defined for preceding branches (iterations of 'while' + loop we're inside, not branch connections below) */ + tmpl = &pd.tmplevel[pd.n_levs + f]; - debugpline4("LEVEL[%i]:%s,(%i,%i)", f, lvl_name, lvl_base, lvl_range); + debugpline4("LEVEL[%i]:%s,(%i,%i)", + f, lvl_name, lvl_base, lvl_range); tmpl->name = lvl_name; tmpl->chainlvl = lvl_chain; tmpl->lev.base = lvl_base; @@ -896,15 +919,17 @@ init_dungeons() if (lvl_chain) { debugpline1("CHAINLEVEL: %s", lvl_chain); for (bi = 0; bi < pd.n_levs + f; bi++) { - debugpline2("checking(%i):%s", bi, pd.tmplevel[bi].name); + debugpline2("checking(%i):%s", + bi, pd.tmplevel[bi].name); if (!strcmp(pd.tmplevel[bi].name, lvl_chain)) { tmpl->chain = bi; break; } } if (tmpl->chain == -1) - panic("Could not chain level %s to %s", lvl_name, lvl_chain); - free(lvl_chain); + panic("Could not chain level %s to %s", + lvl_name, lvl_chain); + /* free(lvl_chain); -- recorded in pd.tmplevel[] */ } } else panic("dungeon[%i].levels[%i] is not a hash", i, f); @@ -921,30 +946,39 @@ init_dungeons() /* branches begin */ lua_getfield(L, -1, "branches"); if (lua_type(L, -1) == LUA_TTABLE) { - int f, nbranches; + static const char *const brdirstr[] = { "up", "down", 0 }; + static const int brdirstr2i[] = { TRUE, FALSE, FALSE }; + static const char *const brtypes[] = { + "stair", "portal", "no_down", "no_up", 0 + }; + static const int brtypes2i[] = { + TBR_STAIR, TBR_PORTAL, TBR_NO_DOWN, TBR_NO_UP, TBR_STAIR + }; + char *br_name, *br_chain; + int br_base, br_range, br_type, br_up; + struct tmpbranch *tmpb; + int bi, f, nbranches; lua_len(L, -1); nbranches = (int) lua_tointeger(L, -1); pd.tmpdungeon[i].branches = nbranches; lua_pop(L, 1); for (f = 0; f < nbranches; f++) { - lua_pushinteger(L, f+1); + lua_pushinteger(L, f + 1); lua_gettable(L, -2); if (lua_type(L, -1) == LUA_TTABLE) { - int bi; - const char *const brdirstr[] = { "up", "down", NULL }; - const int brdirstr2i[] = { TRUE, FALSE, FALSE }; - const char *const brtypes[] = { "stair", "portal", "no_down", "no_up", NULL }; - const int brtypes2i[] = { TBR_STAIR, TBR_PORTAL, TBR_NO_DOWN, TBR_NO_UP, TBR_STAIR }; - char *br_name = get_table_str(L, "name"); - int br_base = get_table_int(L, "base"); - int br_range = get_table_int_opt(L, "range", 0); - int br_type = brtypes2i[get_table_option(L, "branchtype", "stair", brtypes)]; - int br_up = brdirstr2i[get_table_option(L, "direction", "down", brdirstr)]; - char *br_chain = get_table_str_opt(L, "chainlevel", NULL); - struct tmpbranch *tmpb = &pd.tmpbranch[pd.n_brs + f]; + br_name = get_table_str(L, "name"); + br_chain = get_table_str_opt(L, "chainlevel", NULL); + br_base = get_table_int(L, "base"); + br_range = get_table_int_opt(L, "range", 0); + br_type = brtypes2i[get_table_option(L, "branchtype", + "stair", brtypes)]; + br_up = brdirstr2i[get_table_option(L, "direction", + "down", brdirstr)]; + tmpb = &pd.tmpbranch[pd.n_brs + f]; - debugpline4("BRANCH[%i]:%s,(%i,%i)", f, br_name, br_base, br_range); + debugpline4("BRANCH[%i]:%s,(%i,%i)", + f, br_name, br_base, br_range); tmpb->name = br_name; tmpb->lev.base = br_base; tmpb->lev.rand = br_range; @@ -959,7 +993,8 @@ init_dungeons() break; } if (tmpb->chain == -1) - panic("Could not chain branch %s to level %s", br_name, br_chain); + panic("Could not chain branch %s to level %s", + br_name, br_chain); free(br_chain); } } else @@ -984,11 +1019,13 @@ init_dungeons() pd.tmpdungeon[i].chance = dgn_chance; pd.tmpdungeon[i].entry_lev = dgn_entry; + Strcpy(g.dungeons[i].fill_lvl, dgn_fill); /* FIXME: fill_lvl len */ Strcpy(g.dungeons[i].dname, dgn_name); /* FIXME: dname length */ Strcpy(g.dungeons[i].proto, dgn_protoname); /* FIXME: proto length */ g.dungeons[i].boneid = *dgn_bonetag ? *dgn_bonetag : 0; - free(dgn_protoname); - free(dgn_bonetag); + free((genericptr) dgn_fill); + /* free((genericptr) dgn_protoname); -- stored in pd.tmpdungeon[] */ + free((genericptr) dgn_bonetag); if (dgn_range) g.dungeons[i].num_dunlevs = (xchar) rn1(dgn_range, dgn_base); @@ -1098,7 +1135,8 @@ init_dungeons() } lua_pop(L, 1); /* get rid of the dungeon global */ - debugpline2("init_dungeon lua DONE (n_levs=%i, n_brs=%i)", pd.n_levs, pd.n_brs); + debugpline2("init_dungeon lua DONE (n_levs=%i, n_brs=%i)", + pd.n_levs, pd.n_brs); for (i = 0; i < 5; i++) g.tune[i] = 'A' + rn2(7); @@ -1122,9 +1160,8 @@ init_dungeons() branch *br; /* * Kludge to allow floating Knox entrance. We - * specify a floating entrance by the fact that - * its entrance (end1) has a bogus dnum, namely - * n_dgns. + * specify a floating entrance by the fact that its + * entrance (end1) has a bogus dnum, namely n_dgns. */ for (br = g.branches; br; br = br->next) if (on_level(&br->end2, &knox_level)) @@ -1161,13 +1198,16 @@ init_dungeons() lua_close(L); for (i = 0; i < pd.n_brs; i++) { - free(pd.tmpbranch[i].name); + free((genericptr_t) pd.tmpbranch[i].name); } for (i = 0; i < pd.n_levs; i++) { - free(pd.tmplevel[i].name); + free((genericptr_t) pd.tmplevel[i].name); + if (pd.tmplevel[i].chainlvl) + free((genericptr_t) pd.tmplevel[i].chainlvl); } for (i = 0; i < g.n_dgns; i++) { - free(pd.tmpdungeon[i].name); + free((genericptr_t) pd.tmpdungeon[i].name); + free((genericptr_t) pd.tmpdungeon[i].protoname); } #ifdef DEBUG diff --git a/src/insight.c b/src/insight.c new file mode 100644 index 000000000..2d0b43cdd --- /dev/null +++ b/src/insight.c @@ -0,0 +1,10 @@ +/* NetHack 3.7 insight.c $NHDT-Date: 1580577249 2020/02/01 17:14:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ +/* NetHack may be freely redistributed. See license for details. */ + +#include "hack.h" + +/* temporary, until Makefiles and IDE project files are all updated */ +int insight_dummy = 0; + +/*insight.c*/ diff --git a/src/mcastu.c b/src/mcastu.c index ad00be361..baeb2d5fa 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mcastu.c $NHDT-Date: 1567418129 2019/09/02 09:55:29 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.55 $ */ +/* NetHack 3.6 mcastu.c $NHDT-Date: 1580633721 2020/02/02 08:55:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -82,8 +82,7 @@ static int choose_magic_spell(spellval) int spellval; { - /* for 3.4.3 and earlier, val greater than 22 selected the default spell - */ + /* for 3.4.3 and earlier, val greater than 22 selected default spell */ while (spellval > 24 && rn2(25)) spellval = rn2(spellval); @@ -232,7 +231,7 @@ boolean foundyou; /* monster unable to cast spells? */ if (mtmp->mcan || mtmp->mspec_used || !ml) { cursetxt(mtmp, is_undirected_spell(mattk->adtyp, spellnum)); - return (0); + return 0; } if (mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) { @@ -250,14 +249,14 @@ boolean foundyou; canseemon(mtmp) ? Monnam(mtmp) : "Something", levl[mtmp->mux][mtmp->muy].typ == WATER ? "empty water" : "thin air"); - return (0); + return 0; } nomul(0); if (rn2(ml * 10) < (mtmp->mconf ? 100 : 20)) { /* fumbled attack */ if (canseemon(mtmp) && !Deaf) pline_The("air crackles around %s.", mon_nam(mtmp)); - return (0); + return 0; } if (canspotmon(mtmp) || !is_undirected_spell(mattk->adtyp, spellnum)) { pline("%s casts a spell%s!", @@ -283,7 +282,7 @@ boolean foundyou; impossible( "%s casting non-hand-to-hand version of hand-to-hand spell %d?", Monnam(mtmp), mattk->adtyp); - return (0); + return 0; } } else if (mattk->damd) dmg = d((int) ((ml / 2) + mattk->damn), (int) mattk->damd); @@ -293,7 +292,6 @@ boolean foundyou; dmg = (dmg + 1) / 2; ret = 1; - switch (mattk->adtyp) { case AD_FIRE: pline("You're enveloped in flames."); @@ -334,7 +332,7 @@ boolean foundyou; } if (dmg) mdamageu(mtmp, dmg); - return (ret); + return ret; } static int @@ -845,11 +843,11 @@ register struct attack *mattk; /* don't print constant stream of curse messages for 'normal' spellcasting monsters at range */ if (mattk->adtyp > AD_SPC2) - return (0); + return 0; if (mtmp->mcan) { cursetxt(mtmp, FALSE); - return (0); + return 0; } if (lined_up(mtmp) && rn2(3)) { nomul(0); @@ -862,7 +860,7 @@ register struct attack *mattk; } else impossible("Monster spell %d cast", mattk->adtyp - 1); } - return (1); + return 1; } /*mcastu.c*/ diff --git a/src/mklev.c b/src/mklev.c index 41e2ae95d..965a4dca6 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -685,8 +685,8 @@ makelevel() } else if (g.dungeons[u.uz.dnum].proto[0]) { makemaz(""); return; - } else if (In_mines(&u.uz)) { - makemaz("minefill"); + } else if (g.dungeons[u.uz.dnum].fill_lvl[0]) { + makemaz(g.dungeons[u.uz.dnum].fill_lvl); return; } else if (In_quest(&u.uz)) { char fillname[9]; diff --git a/src/mkmaze.c b/src/mkmaze.c index b287189a9..d37d1c08c 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -565,10 +565,6 @@ fixup_special() set_corpsenm(otmp, rndmonnum()); } } - } else if (Is_wiz1_level(&u.uz)) { - croom = search_special(MORGUE); - - create_secret_door(croom, W_SOUTH | W_EAST | W_WEST); } else if (Is_knox(&u.uz)) { /* using an unfilled morgue for rm id */ croom = search_special(MORGUE); @@ -587,10 +583,6 @@ fixup_special() g.level.flags.graveyard = 1; } else if (Is_stronghold(&u.uz)) { g.level.flags.graveyard = 1; - } else if (Is_sanctum(&u.uz)) { - croom = search_special(TEMPLE); - - create_secret_door(croom, W_ANY); } else if (on_level(&u.uz, &orcus_level)) { struct monst *mtmp, *mtmp2; diff --git a/src/monmove.c b/src/monmove.c index 324eaeb05..4d18d2850 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 monmove.c $NHDT-Date: 1579616424 2020/01/21 14:20:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */ +/* NetHack 3.6 monmove.c $NHDT-Date: 1580633722 2020/02/02 08:55:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.129 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -631,22 +631,23 @@ register struct monst *mtmp; /* arbitrary distance restriction to keep monster far away from you from having cast dozens of sticks-to-snakes or similar spells by the time you reach it */ - if (dist2(mtmp->mx, mtmp->my, u.ux, u.uy) <= 49 - && !mtmp->mspec_used) { + if (!mtmp->mspec_used + && dist2(mtmp->mx, mtmp->my, u.ux, u.uy) <= 49) { struct attack *a; for (a = &mdat->mattk[0]; a < &mdat->mattk[NATTK]; a++) { if (a->aatyp == AT_MAGC && (a->adtyp == AD_SPEL || a->adtyp == AD_CLRC)) { if (castmu(mtmp, a, FALSE, FALSE)) { - tmp = 3; + tmp = 3; /* bypass m_move() */ break; } } } } - tmp = m_move(mtmp, 0); + if (!tmp) + tmp = m_move(mtmp, 0); if (tmp != 2) distfleeck(mtmp, &inrange, &nearby, &scared); /* recalc */ @@ -690,14 +691,18 @@ register struct monst *mtmp; /* Now, attack the player if possible - one attack set per monst */ - if (!mtmp->mpeaceful || (Conflict && !resist(mtmp, RING_CLASS, 0, 0))) { - if (inrange && !noattacks(mdat) - && (Upolyd ? u.mh : u.uhp) > 0 && !scared && tmp != 3) + if (tmp != 3 && (!mtmp->mpeaceful + || (Conflict && !resist(mtmp, RING_CLASS, 0, 0)))) { + if (inrange && !scared && !noattacks(mdat) + /* [is this hp check really needed?] */ + && (Upolyd ? u.mh : u.uhp) > 0) { if (mattacku(mtmp)) return 1; /* monster died (e.g. exploded) */ - - if (mtmp->wormno) - wormhitu(mtmp); + } + if (mtmp->wormno) { + if (wormhitu(mtmp)) + return 1; /* worm died (poly'd hero passive counter-attack) */ + } } /* special speeches for quest monsters */ if (!mtmp->msleeping && mtmp->mcanmove && nearby) @@ -707,6 +712,7 @@ register struct monst *mtmp; && couldsee(mtmp->mx, mtmp->my) && !mtmp->minvis && !rn2(5)) cuss(mtmp); + /* note: can't get here when tmp==2 so this always returns 0 */ return (tmp == 2); } diff --git a/src/muse.c b/src/muse.c index 44e711c6e..f31a7667f 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1614,6 +1614,7 @@ struct monst *mtmp; #define MUSE_WAN_SPEED_MONSTER 7 #define MUSE_BULLWHIP 8 #define MUSE_POT_POLYMORPH 9 +#define MUSE_BAG 10 boolean find_misc(mtmp) @@ -1738,6 +1739,13 @@ struct monst *mtmp; g.m.misc = obj; g.m.has_misc = MUSE_POT_POLYMORPH; } + nomore(MUSE_BAG); + if (Is_container(obj) && obj->otyp != BAG_OF_TRICKS && !rn2(5) + && !g.m.has_misc && Has_contents(obj) + && !obj->olocked && !obj->otrapped) { + g.m.misc = obj; + g.m.has_misc = MUSE_BAG; + } } return (boolean) !!g.m.has_misc; #undef nomore @@ -1875,6 +1883,29 @@ struct monst *mtmp; makeknown(POT_POLYMORPH); m_useup(mtmp, otmp); return 2; + case MUSE_BAG: + { + struct obj *xobj; + long count = 1; + + /* FIXME: handle cursed bag of holding */ + if (Is_mbag(otmp) && otmp->cursed) + return 0; + if (!Has_contents(otmp) || otmp->olocked) + return 0; + + for (xobj = otmp->cobj; xobj; xobj = xobj->nobj) count++; + count = rn2(count); + for (xobj = otmp->cobj; xobj && count; xobj = xobj->nobj) count--; + if (xobj && can_carry(mtmp, xobj)) { + if (vismon) + pline("%s rummages through something.", Monnam(mtmp)); + obj_extract_self(xobj); + (void) mpickobj(mtmp, xobj); + return 2; + } + } + return 0; case MUSE_POLY_TRAP: if (vismon) { const char *Mnam = Monnam(mtmp); @@ -2087,6 +2118,8 @@ struct obj *obj; return (boolean) (!obj->cursed && !is_unicorn(mon->data)); if (typ == FROST_HORN || typ == FIRE_HORN) return (obj->spe > 0 && can_blow(mon)); + if (Is_container(obj) && !(Is_mbag(obj) && obj->cursed)) + return TRUE; break; case FOOD_CLASS: if (typ == CORPSE) diff --git a/src/options.c b/src/options.c index cd2a60710..c95ce0731 100644 --- a/src/options.c +++ b/src/options.c @@ -3412,11 +3412,6 @@ boolean tinitial, tfrom_file; return retval; } #endif /* NO_TERMS */ - } else if ((opts = string_for_env_opt(fullname, opts, FALSE)) - == empty_optstr) { - return FALSE; - } - } #endif /* MSDOS */ /* WINCAP diff --git a/src/sp_lev.c b/src/sp_lev.c index 8b8dee95d..efe71d17b 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 sp_lev.c $NHDT-Date: 1580434524 2020/01/31 01:35:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.150 $ */ +/* NetHack 3.6 sp_lev.c $NHDT-Date: 1580610435 2020/02/02 02:27:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.153 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -142,11 +142,28 @@ int FDECL(lspo_wallify, (lua_State *)); #define XLIM 4 #define YLIM 3 -#define New(type) (type *) alloc(sizeof(type)) -#define NewTab(type, size) (type **) alloc(sizeof(type *) * (unsigned) size) -#define Free(ptr) if (ptr) free((genericptr_t) (ptr)) +#define New(type) (type *) alloc(sizeof (type)) +#define NewTab(type, size) (type **) alloc(sizeof (type *) * (unsigned) size) +#define Free(ptr) \ + do { \ + if (ptr) \ + free((genericptr_t) (ptr)); \ + } while (0) -extern struct engr *head_engr; + /* + * No need for 'struct instance_globals g' to contain these. + * sp_level_coder_init() always re-initializes them prior to use. + */ +static boolean splev_init_present, icedpools; +/* positions touched by level elements explicitly defined in the level */ +static char SpLev_Map[COLNO][ROWNO]; +#define MAX_CONTAINMENT 10 +static int container_idx = 0; /* next slot in container_obj[] to use */ +static struct obj *container_obj[MAX_CONTAINMENT]; +static struct monst *invent_carrying_monster = (struct monst *) 0; + /* + * end of no 'g.' + */ static void solidify_map() @@ -155,7 +172,7 @@ solidify_map() for (x = 0; x < COLNO; x++) for (y = 0; y < ROWNO; y++) - if (IS_STWALL(levl[x][y].typ) && !g.SpLev_Map[x][y]) + if (IS_STWALL(levl[x][y].typ) && !SpLev_Map[x][y]) levl[x][y].wall_info |= (W_NONDIGGABLE | W_NONPASSWALL); } @@ -267,7 +284,7 @@ remove_boundary_syms() if (has_bounds) { for (x = 0; x < g.x_maze_max; x++) for (y = 0; y < g.y_maze_max; y++) - if ((levl[x][y].typ == CROSSWALL) && g.SpLev_Map[x][y]) + if ((levl[x][y].typ == CROSSWALL) && SpLev_Map[x][y]) levl[x][y].typ = ROOM; } } @@ -1388,7 +1405,7 @@ struct mkroom *croom; if (m->has_invent) { discard_minvent(mtmp); - g.invent_carrying_monster = mtmp; + invent_carrying_monster = mtmp; } } } @@ -1502,9 +1519,9 @@ struct mkroom *croom; } /* contents (of a container or monster's inventory) */ - if (o->containment & SP_OBJ_CONTENT || g.invent_carrying_monster) { - if (!g.container_idx) { - if (!g.invent_carrying_monster) { + if (o->containment & SP_OBJ_CONTENT || invent_carrying_monster) { + if (!container_idx) { + if (!invent_carrying_monster) { /*impossible("create_object: no container");*/ /* don't complain, the monster may be gone legally (eg. unique demon already generated) @@ -1516,10 +1533,10 @@ struct mkroom *croom; ; /* ['otmp' remains on floor] */ } else { remove_object(otmp); - (void) mpickobj(g.invent_carrying_monster, otmp); + (void) mpickobj(invent_carrying_monster, otmp); } } else { - struct obj *cobj = g.container_obj[g.container_idx - 1]; + struct obj *cobj = container_obj[container_idx - 1]; remove_object(otmp); if (cobj) { @@ -1535,9 +1552,9 @@ struct mkroom *croom; /* container */ if (o->containment & SP_OBJ_CONTAINER) { delete_contents(otmp); - if (g.container_idx < MAX_CONTAINMENT) { - g.container_obj[g.container_idx] = otmp; - g.container_idx++; + if (container_idx < MAX_CONTAINMENT) { + container_obj[container_idx] = otmp; + container_idx++; } else impossible("create_object: too deeply nested containers."); } @@ -1618,8 +1635,8 @@ struct mkroom *croom; boolean dealloced; (void) bury_an_obj(otmp, &dealloced); - if (dealloced && g.container_idx) { - g.container_obj[g.container_idx - 1] = NULL; + if (dealloced && container_idx) { + container_obj[container_idx - 1] = NULL; } } } @@ -2162,7 +2179,7 @@ int humidity; y = rn1(g.y_maze_max - 3, 3); if (--tryct < 0) break; /* give up */ - } while (!(x % 2) || !(y % 2) || g.SpLev_Map[x][y] + } while (!(x % 2) || !(y % 2) || SpLev_Map[x][y] || !is_ok_location((schar) x, (schar) y, humidity)); m->x = (xchar) x, m->y = (xchar) y; @@ -2187,7 +2204,7 @@ fill_empty_maze() for (x = 2; x < g.x_maze_max; x++) for (y = 0; y < g.y_maze_max; y++) - if (g.SpLev_Map[x][y]) + if (SpLev_Map[x][y]) mapcount--; if ((mapcount > (int) (mapcountmax / 10))) { @@ -2252,7 +2269,7 @@ lev_init *linit; linit->lit = rn2(2); if (linit->filling > -1) lvlfill_solid(linit->filling, 0); - linit->icedpools = g.icedpools; + linit->icedpools = icedpools; mkmap(linit); break; } @@ -2272,18 +2289,18 @@ long curpos, jmpaddr; static void spo_end_moninvent() { - if (g.invent_carrying_monster) - m_dowear(g.invent_carrying_monster, TRUE); - g.invent_carrying_monster = NULL; + if (invent_carrying_monster) + m_dowear(invent_carrying_monster, TRUE); + invent_carrying_monster = NULL; } /*ARGUSED*/ static void spo_pop_container() { - if (g.container_idx > 0) { - g.container_idx--; - g.container_obj[g.container_idx] = NULL; + if (container_idx > 0) { + container_idx--; + container_obj[container_idx] = NULL; } } @@ -2352,7 +2369,6 @@ lua_State *L; if (s && strlen(s) == 1) ret = (int) *s; Free(s); - return ret; } @@ -2777,11 +2793,11 @@ lua_State *L; break; } } + free((genericptr_t) montype); if (pm) tmpobj.corpsenm = monsndx(pm); else nhl_error(L, "Unknown montype"); - free(montype); } if (tmpobj.id == STATUE) { if (get_table_boolean_opt(L, "historic", 0)) @@ -2798,7 +2814,7 @@ lua_State *L; quancnt = (tmpobj.id > STRANGE_OBJECT) ? tmpobj.quan : 0; - if (g.container_idx) + if (container_idx) tmpobj.containment |= SP_OBJ_CONTENT; if (maybe_contents) { @@ -2860,7 +2876,7 @@ lua_State *L; else if (!strcmpi(s, "graveyard")) g.level.flags.graveyard = 1; else if (!strcmpi(s, "icedpools")) - g.icedpools = 1; + icedpools = 1; else if (!strcmpi(s, "corrmaze")) g.level.flags.corrmaze = 1; else if (!strcmpi(s, "premapped")) @@ -2897,7 +2913,7 @@ lua_State *L; lcheck_param_table(L); - g.splev_init_present = TRUE; + splev_init_present = TRUE; init_lev.init_style = initstyles2i[get_table_option(L, "style", "solidfill", initstyles)]; @@ -3025,16 +3041,17 @@ const char *name; int defval; { char *roomstr = get_table_str_opt(L, name, emptystr); + int i, res = defval; + if (roomstr && *roomstr) { - int i; for (i = 0; room_types[i].name; i++) if (!strcmpi(roomstr, room_types[i].name)) { - Free(roomstr); - return room_types[i].type; + res = room_types[i].type; + break; } } Free(roomstr); - return defval; + return res; } /* room({ type="ordinary", lit=1, x=3,y=3, xalign="center",yalign="center", w=11,h=9 }); */ @@ -3192,7 +3209,7 @@ lua_State *L; if ((badtrap = t_at(x, y)) != 0) deltrap(badtrap); mkstairs(x, y, (char) up, g.coder->croom); - g.SpLev_Map[x][y] = 1; + SpLev_Map[x][y] = 1; return 0; } @@ -3251,7 +3268,7 @@ lua_State *L; if ((badtrap = t_at(x, y)) != 0) deltrap(badtrap); levl[x][y].typ = LADDER; - g.SpLev_Map[x][y] = 1; + SpLev_Map[x][y] = 1; if (up) { xupladder = x; yupladder = y; @@ -3291,14 +3308,9 @@ lua_State *L; if (isok(x, y) && !t_at(x, y)) { levl[x][y].typ = GRAVE; - if (txt) - make_grave(x, y, txt); - else - make_grave(x, y, NULL); + make_grave(x, y, txt); /* note: 'txt' might be Null */ } - Free(txt); - return 0; } @@ -3386,18 +3398,17 @@ const char *name; int defval; { char *trapstr = get_table_str_opt(L, name, emptystr); + int i, res = defval; if (trapstr && *trapstr) { - int i; - for (i = 0; trap_types[i].name; i++) if (!strcmpi(trapstr, trap_types[i].name)) { - Free(trapstr); - return trap_types[i].type; + res = trap_types[i].type; + break; } } Free(trapstr); - return defval; + return res; } const char * @@ -4264,7 +4275,7 @@ genericptr_t arg; } set_door_orientation(x, y); /* set/clear levl[x][y].horizontal */ levl[x][y].doormask = typ; - g.SpLev_Map[x][y] = 1; + SpLev_Map[x][y] = 1; } /* door({ x = 1, y = 1, state = "nodoor" }); */ @@ -4712,19 +4723,19 @@ lev_region *lregion; if (g.num_lregions) { /* realloc the lregion space to add the new one */ lev_region *newl = (lev_region *) alloc( - sizeof(lev_region) * (unsigned) (1 + g.num_lregions)); + sizeof (lev_region) * (unsigned) (1 + g.num_lregions)); (void) memcpy((genericptr_t) (newl), (genericptr_t) g.lregions, - sizeof(lev_region) * g.num_lregions); + sizeof (lev_region) * g.num_lregions); Free(g.lregions); g.num_lregions++; g.lregions = newl; } else { g.num_lregions = 1; - g.lregions = (lev_region *) alloc(sizeof(lev_region)); + g.lregions = (lev_region *) alloc(sizeof (lev_region)); } (void) memcpy(&g.lregions[g.num_lregions - 1], lregion, - sizeof(lev_region)); + sizeof (lev_region)); } /* teleport_region({ region = { x1,y1, x2,y2} }); */ @@ -4820,7 +4831,6 @@ lua_State *L; tmplregion.rname.str = get_table_str_opt(L, "name", NULL); levregion_add(&tmplregion); - return 0; } @@ -5006,7 +5016,7 @@ lua_State *L; db_open = !rn2(2); if (!create_drawbridge(x, y, dir, db_open ? TRUE : FALSE)) impossible("Cannot create drawbridge."); - g.SpLev_Map[x][y] = 1; + SpLev_Map[x][y] = 1; return 0; } @@ -5328,6 +5338,7 @@ TODO: g.coder->croom needs to be updated tmps = mapdata; while (tmps && *tmps) { char *s1 = index(tmps, '\n'); + if (maphei > MAP_Y_LIM) break; if (s1) @@ -5336,8 +5347,8 @@ TODO: g.coder->croom needs to be updated maphei++; } - /* keepregion restricts the coordinates of the commands coming after the map - into the map region */ + /* keepregion restricts the coordinates of the commands coming after + the map into the map region */ /* for keepregion */ tmpxsize = g.xsize; tmpysize = g.ysize; @@ -5375,7 +5386,7 @@ TODO: g.coder->croom needs to be updated /* place map starting at halign,valign */ switch (lr) { case LEFT: - g.xstart = g.splev_init_present ? 1 : 3; + g.xstart = splev_init_present ? 1 : 3; break; case H_LEFT: g.xstart = 2 + ((g.x_maze_max - 2 - g.xsize) / 4); @@ -5443,7 +5454,7 @@ TODO: g.coder->croom needs to be updated levl[x][y].horizontal = 0; levl[x][y].roomno = 0; levl[x][y].edge = 0; - g.SpLev_Map[x][y] = 1; + SpLev_Map[x][y] = 1; /* * Set secret doors to closed (why not trapped too?). Set * the horizontal bit. @@ -5464,8 +5475,8 @@ TODO: g.coder->croom needs to be updated levl[x][y].horizontal = 1; else if (levl[x][y].typ == LAVAPOOL) levl[x][y].lit = 1; - else if (g.splev_init_present && levl[x][y].typ == ICE) - levl[x][y].icedpool = g.icedpools ? ICED_POOL : ICED_MOAT; + else if (splev_init_present && levl[x][y].typ == ICE) + levl[x][y].icedpool = icedpools ? ICED_POOL : ICED_MOAT; } if (g.coder->lvl_is_joined) remove_rooms(g.xstart, g.ystart, @@ -5510,8 +5521,8 @@ sp_level_coder_init() coder->lvl_is_joined = 0; coder->room_stack = 0; - g.splev_init_present = FALSE; - g.icedpools = FALSE; + splev_init_present = FALSE; + icedpools = FALSE; for (tmpi = 0; tmpi <= MAX_NESTED_ROOMS; tmpi++) { coder->tmproomlist[tmpi] = (struct mkroom *) 0; @@ -5521,19 +5532,19 @@ sp_level_coder_init() update_croom(); for (tmpi = 0; tmpi < MAX_CONTAINMENT; tmpi++) - g.container_obj[tmpi] = NULL; - g.container_idx = 0; + container_obj[tmpi] = NULL; + container_idx = 0; - g.invent_carrying_monster = NULL; + invent_carrying_monster = NULL; - (void) memset((genericptr_t) &g.SpLev_Map[0][0], 0, sizeof g.SpLev_Map); + (void) memset((genericptr_t) SpLev_Map, 0, sizeof SpLev_Map); g.level.flags.is_maze_lev = 0; - g.xstart = 1; + g.xstart = 1; /* column [0] is off limits */ g.ystart = 0; - g.xsize = COLNO - 1; - g.ysize = ROWNO; + g.xsize = COLNO - 1; /* 1..COLNO-1 */ + g.ysize = ROWNO; /* 0..ROWNO-1 */ return coder; } diff --git a/src/worm.c b/src/worm.c index 920a2766f..28f47542d 100644 --- a/src/worm.c +++ b/src/worm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 worm.c $NHDT-Date: 1580043421 2020/01/26 12:57:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */ +/* NetHack 3.6 worm.c $NHDT-Date: 1580633722 2020/02/02 08:55:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -329,8 +329,10 @@ struct monst *worm; * Check for mon->wormno before calling this function! * * If the hero is near any part of the worm, the worm will try to attack. + * Returns 1 if the worm dies (poly'd hero with passive counter-attack) + * or 0 if it doesn't. */ -void +int wormhitu(worm) struct monst *worm; { @@ -341,11 +343,15 @@ struct monst *worm; * is out of range of the player. We might try to kludge, and bring * the head within range for a tiny moment, but this needs a bit more * looking at before we decide to do this. + * + * Head has already had a chance to attack, so the dummy tail segment + * sharing its location should be skipped. */ - for (seg = wtails[wnum]; seg; seg = seg->nseg) + for (seg = wtails[wnum]; seg != wheads[wnum]; seg = seg->nseg) if (distu(seg->wx, seg->wy) < 3) if (mattacku(worm)) - return; /* your passive ability killed the worm */ + return 1; /* your passive ability killed the worm */ + return 0; } /* cutworm() diff --git a/sys/msdos/Makefile1.cross b/sys/msdos/Makefile1.cross index e8bae64b9..9105341f4 100644 --- a/sys/msdos/Makefile1.cross +++ b/sys/msdos/Makefile1.cross @@ -439,7 +439,7 @@ $(U)tilemap: $(HOST_O)tilemap.o $(HOST_LINK) $(LFLAGS) -o$@ $(HOST_O)tilemap.o $(HOST_O)tilemap.o: $(WSHR)/tilemap.c $(HACK_H) $(TILE_H) - $(HOST_CC) $(cflags) -I$(WSHR) -I$(MSYS) -o$@ $(WSHR)/tilemap.c + $(HOST_CC) $(cflags) -I$(WSHR) -I$(MSYS) -DSTATUES_LOOK_LIKE_MONSTERS -o$@ $(WSHR)/tilemap.c #========================================== diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index fea1ec531..5293dd70a 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -445,7 +445,8 @@ HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ botl.c cmd.c dbridge.c decl.c detect.c dig.c display.c dlb.c do.c \ do_name.c do_wear.c dog.c dogmove.c dokick.c dothrow.c drawing.c \ dungeon.c eat.c end.c engrave.c exper.c explode.c extralev.c \ - files.c fountain.c hack.c hacklib.c invent.c isaac64.c light.c \ + files.c fountain.c hack.c hacklib.c \ + insight.c invent.c isaac64.c light.c \ lock.c mail.c makemon.c mapglyph.c mcastu.c mdlib.c mhitm.c \ mhitu.c minion.c mklev.c mkmap.c mkmaze.c mkobj.c mkroom.c mon.c \ mondata.c monmove.c monst.c mplayer.c mthrowu.c muse.c music.c \ @@ -512,7 +513,8 @@ HOBJ = $(FIRSTOBJ) allmain.o alloc.o apply.o artifact.o attrib.o ball.o \ bones.o botl.o cmd.o dbridge.o decl.o detect.o dig.o display.o dlb.o \ do.o do_name.o do_wear.o dog.o dogmove.o dokick.o dothrow.o \ drawing.o dungeon.o eat.o end.o engrave.o exper.o explode.o \ - extralev.o files.o fountain.o hack.o hacklib.o invent.o isaac64.o \ + extralev.o files.o fountain.o hack.o hacklib.o \ + insight.o invent.o isaac64.o \ light.o lock.o mail.o makemon.o mapglyph.o mcastu.o mdlib.o mhitm.o \ mhitu.o minion.o mklev.o mkmap.o mkmaze.o mkobj.o mkroom.o mon.o \ mondata.o monmove.o mplayer.o mthrowu.o muse.o music.o \ @@ -1073,6 +1075,7 @@ files.o: files.c $(HACK_H) ../include/dlb.h #zlib.h fountain.o: fountain.c $(HACK_H) hack.o: hack.c $(HACK_H) hacklib.o: hacklib.c $(HACK_H) +insight.o: insight.c $(HACK_H) invent.o: invent.c $(HACK_H) isaac64.o: isaac64.c $(CONFIG_H) ../include/isaac64.h light.o: light.c $(HACK_H) diff --git a/sys/vms/Makefile.src b/sys/vms/Makefile.src index 559f974c0..40ea87bdc 100644 --- a/sys/vms/Makefile.src +++ b/sys/vms/Makefile.src @@ -148,7 +148,8 @@ HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ botl.c cmd.c dbridge.c decl.c detect.c dig.c display.c dlb.c do.c \ do_name.c do_wear.c dog.c dogmove.c dokick.c dothrow.c drawing.c \ dungeon.c eat.c end.c engrave.c exper.c explode.c extralev.c \ - files.c fountain.c hack.c hacklib.c invent.c light.c lock.c \ + files.c fountain.c hack.c hacklib.c \ + insight.c invent.c light.c lock.c \ mail.c makemon.c mapglyph.c mcastu.c mhitm.c mhitu.c minion.c \ mklev.c mkmap.c \ mkmaze.c mkobj.c mkroom.c mon.c mondata.c monmove.c monst.c \ @@ -194,7 +195,8 @@ HOBJ1 = allmain.obj,alloc.obj,apply.obj,artifact.obj,attrib.obj, \ detect.obj,dig.obj,display.obj,dlb.obj,do.obj,do_name.obj,do_wear.obj HOBJ2 = dog.obj,dogmove.obj,dokick.obj,dothrow.obj,drawing.obj, \ dungeon.obj,eat.obj,end.obj,engrave.obj,exper.obj,explode.obj, \ - extralev.obj,files.obj,fountain.obj,hack.obj,hacklib.obj,invent.obj + extralev.obj,files.obj,fountain.obj,hack.obj,hacklib.obj, \ + insight.obj,invent.obj HOBJ3 = light.obj,lock.obj,mail.obj,makemon.obj,mapglyph.obj,mcastu.obj, \ mhitm.obj,mhitu.obj,minion.obj,mklev.obj,mkmap.obj,mkmaze.obj, \ mkobj.obj,mkroom.obj,mon.obj,mondata.obj,monmove.obj @@ -519,6 +521,7 @@ files.obj : files.c $(HACK_H) $(INC)dlb.h $(INC)wintty.h #zlib.h fountain.obj : fountain.c $(HACK_H) hack.obj : hack.c $(HACK_H) hacklib.obj : hacklib.c $(HACK_H) +insight.obj : insight.c $(HACK_H) invent.obj : invent.c $(HACK_H) light.obj : light.c $(HACK_H) lock.obj : lock.c $(HACK_H) diff --git a/sys/vms/vmsbuild.com b/sys/vms/vmsbuild.com index 0ab402d1a..9ef56da27 100755 --- a/sys/vms/vmsbuild.com +++ b/sys/vms/vmsbuild.com @@ -3,6 +3,10 @@ $ version_number = "3.7.0" $ ! $NHDT-Date: 1557701799 2019/05/12 22:56:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ $ ! Copyright (c) 2018 by Robert Patrick Rankin $ ! NetHack may be freely redistributed. See license for details. +$ +$!TODO: Separate the lua build and create an object library for it instead +$! of putting lua modules into nethack.olb. +$ $ ! $ ! usage: $ ! $ set default [.src] !or [-.-.src] if starting from [.sys.vms] @@ -61,13 +65,13 @@ $ copy sys$input: sys$error: !p1 usage or "DECC" -- use DEC C to compile everything or "GNUC" -- use GNU C to compile everything or "LINK" -- skip compilation, just relink nethack.exe - or "SPEC[IAL]" -- just compile and link lev_comp.exe + or "SPEC[IAL]" -- just compile and link dlb.exe and recover.exe or "" -- default operation (VAXC unless 'CC' is defined) Note: if a DCL symbol for CC is defined, "VAXC" and "GNUC" are no-ops. If the symbol value begins with "G" (or "g"), then the GNU C library will be included in all link operations. Do not rebuild - lev_comp with "SPECIAL" unless you have a CC symbol setup with + dlb+recover with "SPECIAL" unless you have a CC symbol setup with the proper options. $ abort $p1_ok: @@ -185,6 +189,7 @@ $ nethacklib = "[-.src]nethack.olb" $ create nethack.opt ! nethack.opt nethack.olb/Include=(vmsmain)/Library +![-.lib.lua]liblua.olb/Library ! lib$initialize is used to call a routine (before main()) in vmsunix.c that ! tries to check whether debugger support has been linked in, for PANICTRACE sys$library:starlet.olb/Include=(lib$initialize) @@ -238,7 +243,6 @@ $! $ if f$search("pmatchregex.c").eqs."" then copy [-.sys.share]pmatchregex.c []*.* $ if f$search("random.c").eqs."" then copy [-.sys.share]random.c []*.* $ if f$search("tclib.c") .eqs."" then copy [-.sys.share]tclib.c []*.* -$ if f$search("[-.util]lev_yacc.c").eqs."" then @[-.sys.vms]spec_lev.com $! $ p5 := 'p5' $ ttysrc = "[-.win.tty]getline,[-.win.tty]termcap" - @@ -251,7 +255,7 @@ $ interface = ttysrc !default $ if p5.eqs."CURSES" then interface = cursessrc $ if p5.eqs."TTY+CURSES" then interface = ttysrc + "," + cursessrc $ if p5.eqs."CURSES+TTY" then interface = cursessrc + "," + ttysrc - +$ $ if f$search("[-.include]nhlua.h").eqs."" $ then $ create [-.include]nhlua.h !empty @@ -300,14 +304,15 @@ $ c_list = "decl,version,[-.sys.vms]vmsmain,[-.sys.vms]vmsunix" - $ gosub compile_list $ c_list = interface !ttysrc or cursessrc or both $ gosub compile_list -$ c_list = "allmain,apply,artifact,attrib,ball,bones,botl,cmd,dbridge,detect" - - + ",dig,display,do,do_name,do_wear,dog,dogmove,dokick,dothrow,drawing" - - + ",dungeon,eat,end,engrave,exper,explode,extralev,files,fountain" +$ c_list = "allmain,apply,artifact,attrib,ball,bones,botl,cmd,dbridge" - + + ",dothrow,drawing,detect,dig,display,do,do_name,do_wear,dog" - + + ",dogmove,dokick,dungeon,eat,end,engrave,exper,explode" - + + ",extralev,files,fountain" $ gosub compile_list -$ c_list = "hack,hacklib,invent,light,lock,mail,makemon,mapglyph,mcastu" - - + ",mhitm,mhitu,minion,mklev,mkmap,mkmaze,mkobj,mkroom,mon,mondata" - - + ",monmove,mplayer,mthrowu,muse,music,o_init,objnam,options" - - + ",pager,pickup" +$ c_list = "hack,hacklib,insight,invent,light,lock,mail,makemon" - + + ",mapglyph,mcastu,mhitm,mhitu,minion,mklev,mkmap,mkmaze" - + + ",mkobj,mkroom,mon,mondata,monmove,mplayer,mthrowu,muse" - + + ",music,o_init,objnam,options,pager,pickup" $ gosub compile_list $ c_list = "pline,polyself,potion,pray,priest,quest,questpgr,read" - + ",rect,region,restore,rip,rnd,role,rumors,save,shk,shknam,sit" - @@ -320,7 +325,7 @@ $ gosub compile_list $! $! Files added in 3.7 $! -$ c_list = "sfstruct,nhlua,nhlsel" +$ c_list = "nhlua,nhlobj,nhlsel" !,sfstruct $ gosub compile_list $! $! 3.7 runtime LUA level parser/loader @@ -347,24 +352,10 @@ $ milestone "NetHack" $ if c_opt.eq.o_LINK then goto done !"LINK" only $special: $! -$! build special level and dungeon compilers +$! utilities only [dgn_comp and lev_comp are gone] $! $ set default [-.util] -$! c_list = "#panic,#lev_main,#lev_yacc,#dgn_main,#dgn_yacc" -$! if c_opt.eq.o_SPCL then c_list = "[-.sys.vms]vmsfiles," + c_list -$! gosub compile_list -$! c_list = "#lev_lex,#dgn_lex" -$! copy [-.sys.vms]lev_lex.h stdio.*/Prot=(s:rwd,o:rwd) -$! gosub compile_list -$! rename stdio.h lev_lex.* -$! link/exe=lev_comp.exe lev_main.obj,lev_yacc.obj,lev_lex.obj,- -$! panic.obj,'nethacklib'/Lib,[-.src]ident.opt/Opt,[-.src]crtl.opt/Opt -$! milestone "lev_comp" -$! link/exe=dgn_comp.exe dgn_main.obj,dgn_yacc.obj,dgn_lex.obj,- -$! panic.obj,'nethacklib'/Lib,[-.src]ident.opt/Opt,[-.src]crtl.opt/Opt -$! milestone "dgn_comp" -$! -$ c_list = "#dlb_main,#recover" +$ c_list = "#panic,#dlb_main,#recover" $ gosub compile_list $ link/exe=dlb.exe dlb_main.obj,- panic.obj,'nethacklib'/Lib,[-.src]ident.opt/Opt,[-.src]crtl.opt/Opt