From 33cd6befe08d352aade908fae6f9007d7ced2b1f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 1 Feb 2020 18:29:55 +0200 Subject: [PATCH 01/16] Dehardcode minefill Instead of hardcoding the minefill levels in the core, allow defining fill levels for a dungeon branch in the dungeon.lua --- dat/dungeon.lua | 1 + include/dungeon.h | 1 + src/dungeon.c | 4 +++- src/mklev.c | 4 ++-- 4 files changed, 7 insertions(+), 3 deletions(-) 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/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/src/dungeon.c b/src/dungeon.c index f07f375f1..950504732 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -832,7 +832,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)) @@ -847,6 +847,7 @@ init_dungeons() 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); @@ -984,6 +985,7 @@ 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; 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]; From 70611afc4823e9e8e93fb05da70d696995bc7c6b Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 1 Feb 2020 08:59:19 -0800 Subject: [PATCH 02/16] splitting cmd.c, phase I Preparation for moving enlightenment and conduct into new source file insight.c. Right now it's a stub that shouldn't break anything whether included or omitted. Once makefiles and project files have been updated to compile and link it, the actual code will be moved. unix/Makefile.src has been updated; vms/Makefile.src and vmsbuild.com have been updated but not tested. --- sys/unix/Makefile.src | 7 +++++-- sys/vms/Makefile.src | 7 +++++-- sys/vms/vmsbuild.com | 47 +++++++++++++++++-------------------------- 3 files changed, 29 insertions(+), 32 deletions(-) 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 From 10b8356a15112d012a72be0a2d1ba3224e391ab8 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 1 Feb 2020 09:14:18 -0800 Subject: [PATCH 03/16] splitting cmd.c, phase 1B I neglected to use -f with 'git add' and the stub file didn't make it into the previous commit. --- src/insight.c | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/insight.c 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*/ From bb1925a95720655d00c636b736dfb537f2fdfa68 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 1 Feb 2020 20:18:56 +0200 Subject: [PATCH 04/16] Dehardcode wizard1 morgue secret door --- dat/wizard1.lua | 7 ++++--- src/mkmaze.c | 4 ---- 2 files changed, 4 insertions(+), 7 deletions(-) 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/src/mkmaze.c b/src/mkmaze.c index b287189a9..230f8facc 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); From dcdb8d437bc1e1d94b879258306efb9a75be5b7b Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 1 Feb 2020 21:30:50 +0200 Subject: [PATCH 05/16] Dehardcode sanctum temple secret door --- dat/sanctum.lua | 4 +++- src/mkmaze.c | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) 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/src/mkmaze.c b/src/mkmaze.c index 230f8facc..d37d1c08c 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -583,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; From f9b4ebae87748a8425570ea62fbb0b78deba7acc Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 1 Feb 2020 16:48:07 -0500 Subject: [PATCH 06/16] Remove code fragment causing compile error --- src/options.c | 5 ----- 1 file changed, 5 deletions(-) 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 From 1fb1967e4269416e1cf54a156e9a9822fda8f4f6 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 1 Feb 2020 16:48:37 -0500 Subject: [PATCH 07/16] Enable statue glyphs for cross compile --- sys/msdos/Makefile1.cross | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 #========================================== From 32f0520fe026bbfb88af77f589041dde301894cc Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 1 Feb 2020 15:44:42 -0800 Subject: [PATCH 08/16] sp_lev.c private variables Make a start at reducing the size of 'g' by removing some special level stuff that doesn't need to be there. --- include/decl.h | 16 ++----- include/hack.h | 5 +-- src/decl.c | 8 +--- src/sp_lev.c | 116 +++++++++++++++++++++++++++++-------------------- 4 files changed, 74 insertions(+), 71 deletions(-) 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/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/sp_lev.c b/src/sp_lev.c index 8b8dee95d..5c653a8b0 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: 1580600499 2020/02/01 23:41:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.151 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -142,12 +142,32 @@ 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. + */ +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 +175,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 +287,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 +1408,7 @@ struct mkroom *croom; if (m->has_invent) { discard_minvent(mtmp); - g.invent_carrying_monster = mtmp; + invent_carrying_monster = mtmp; } } } @@ -1502,9 +1522,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 +1536,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 +1555,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 +1638,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 +2182,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 +2207,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 +2272,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 +2292,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; } } @@ -2798,7 +2818,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 +2880,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 +2917,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)]; @@ -3192,7 +3212,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 +3271,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; @@ -4264,7 +4284,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" }); */ @@ -5006,7 +5026,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; } @@ -5336,8 +5356,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 +5395,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 +5463,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 +5484,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 +5530,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 +5541,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; } From 5d6b3b6f513ac7833e4592aa1583d1c03375b2a2 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 1 Feb 2020 17:33:50 -0800 Subject: [PATCH 09/16] get_table_str use Some cleanup when chasing a memory leak. get_table_str() and get_table_str_opt() return a value from dupstr() and it wasn't always being freed. I'm not sure that I found the problem--maybe it involved pointers turned over to Lua garbage collection--but did find a couple of suspicious things in dungeon setup. --- src/dungeon.c | 144 +++++++++++++++++++++++++++++++------------------- src/sp_lev.c | 40 ++++++-------- 2 files changed, 108 insertions(+), 76 deletions(-) diff --git a/src/dungeon.c b/src/dungeon.c index 950504732..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(); @@ -843,47 +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; @@ -897,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); @@ -922,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; @@ -960,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 @@ -989,8 +1023,9 @@ init_dungeons() 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); @@ -1100,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); @@ -1124,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)) @@ -1163,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/sp_lev.c b/src/sp_lev.c index 5c653a8b0..1e9bd75d0 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 sp_lev.c $NHDT-Date: 1580600499 2020/02/01 23:41:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.151 $ */ +/* NetHack 3.6 sp_lev.c $NHDT-Date: 1580607226 2020/02/02 01:33:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.152 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -2372,7 +2372,6 @@ lua_State *L; if (s && strlen(s) == 1) ret = (int) *s; Free(s); - return ret; } @@ -2797,11 +2796,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)) @@ -3045,16 +3044,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 }); */ @@ -3311,14 +3311,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; } @@ -3406,18 +3401,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 * @@ -4732,19 +4726,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} }); */ @@ -4840,7 +4834,6 @@ lua_State *L; tmplregion.rname.str = get_table_str_opt(L, "name", NULL); levregion_add(&tmplregion); - return 0; } @@ -5348,6 +5341,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) From 158ea1a23f96097548c345baf45193f8aff5c104 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 1 Feb 2020 17:53:07 -0800 Subject: [PATCH 10/16] failing level change messsage confusion While testing the changes to dungeon and special level handling, I got |A mysterious force prevents you from descending! |You materialize on a different level! The mystery force is handled by goto_level() so level_tele() doesn't know that the failure is going to happen when it sets up the message for deferred delivery. Suppress the message if you don't change levels. --- doc/fixes37.0 | 5 ++++- src/do.c | 7 ++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 337f1e3df..62e1aea52 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.85 $ $NHDT-Date: 1580608377 2020/02/02 01:52:57 $ General Fixes and Modified Features ----------------------------------- @@ -82,6 +82,9 @@ 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 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 */ From 76b7e63888a555988c411f5e9f0b5670bba2980b Mon Sep 17 00:00:00 2001 From: keni Date: Sat, 1 Feb 2020 21:17:49 -0500 Subject: [PATCH 11/16] Guidebook.tex: fix formatting typos --- doc/Guidebook.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index c10bf9bcb..7caa15d8f 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -1993,7 +1993,7 @@ than as 7 and 25, respectively, and total to 2 when both are at the same location). %.pg -The \{\tt nopickup} command prefix (default `\{\tt m}') can be +The {\tt nopickup} command prefix (default `{\tt m}') can be used before a movement direction to step on objects without attempting auto-pickup and without giving feedback about them. @@ -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. From 7bc799f06bd4166e57d0084c15ddc273ec23300f Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 1 Feb 2020 18:27:36 -0800 Subject: [PATCH 12/16] insert omitted 'static' for two sp_lev.c variables --- src/sp_lev.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/sp_lev.c b/src/sp_lev.c index 1e9bd75d0..efe71d17b 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 sp_lev.c $NHDT-Date: 1580607226 2020/02/02 01:33:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.152 $ */ +/* 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. */ @@ -150,14 +150,11 @@ int FDECL(lspo_wallify, (lua_State *)); 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. */ -boolean splev_init_present, - icedpools; +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 From 09d82164fc919c27a4529af93ca15ec45c95d757 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 1 Feb 2020 22:08:41 -0500 Subject: [PATCH 13/16] msdos fix from chasonr --- doc/fixes37.0 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 62e1aea52..686cd7b84 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -89,6 +89,8 @@ prevent "you materialize on a different level" after "a mysterious force 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 From bfd180a5ac7a6212d4b0f92cdb55d07992f7f085 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 1 Feb 2020 22:49:21 -0500 Subject: [PATCH 14/16] mention a pair of recent file additions in Cross-compiling [skip travis] --- Cross-compiling | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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, From 2ebbe61f533f1d3e08b06bea62763def95ab0139 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 2 Feb 2020 00:55:26 -0800 Subject: [PATCH 15/16] fix github issue #285 - spellcasting monster After casting a spell, a monster got a chance to make a regular attack despite the apparent attempt to set up a return value indicating that it wouldn't move. When looking over the return value situation, I noticed 'wormhitu()' for the first time. It gives worms additional attacks when the hero is adjacent to some of the tail, that only works if the head is within reach of a melee attack. The hidden tail segment at head's location always met that criterium so gave an extra attack that didn't make sense; change wormhitu() to skip that segment. Do some formatting in mcastu.c; no change in actual code there. Fixes #285 --- doc/fixes37.0 | 3 ++- include/extern.h | 4 ++-- src/mcastu.c | 22 ++++++++++------------ src/monmove.c | 28 +++++++++++++++++----------- src/worm.c | 14 ++++++++++---- 5 files changed, 41 insertions(+), 30 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 686cd7b84..58e243ac9 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.85 $ $NHDT-Date: 1580608377 2020/02/02 01:52:57 $ +$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 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/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/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/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() From b12ea03d110dd3cd55104e623510d5da0809b5cd Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 2 Feb 2020 11:04:08 +0200 Subject: [PATCH 16/16] Allow monsters to rummage through containers --- doc/fixes37.0 | 1 + src/muse.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 58e243ac9..c381d5156 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -140,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/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)