From 71401a7db877a726dbd219aa4939181c26792dfd Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 5 Apr 2015 12:17:57 +0300 Subject: [PATCH 1/8] Add poison cloud glyph, fumaroles to fire plane. When a gas cloud that deals damage is created, it uses a poison cloud glyph instead of the cloud glyph. (A bright green '#', or a bright-green recolor of the cloud tile) The plane of fire has random "stinking clouds", or fumaroles, centered on lava pools. Also make poison cloud glyph override lava, pool and moat glyphs. --- include/extern.h | 1 + include/rm.h | 39 ++++++++++++++++++++------------------- src/allmain.c | 2 ++ src/display.c | 7 ++++++- src/do.c | 2 ++ src/drawing.c | 2 ++ src/mkmaze.c | 20 ++++++++++++++++++++ src/region.c | 2 +- win/share/other.txt | 19 +++++++++++++++++++ 9 files changed, 73 insertions(+), 21 deletions(-) diff --git a/include/extern.h b/include/extern.h index 28680c5fa..971971ea8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1158,6 +1158,7 @@ E boolean FDECL(bad_location, (XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P)) E void FDECL(place_lregion, (XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P, XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P, XCHAR_P,d_level *)); +E void NDECL(fumaroles); E void NDECL(movebubbles); E void NDECL(water_friction); E void FDECL(save_waterlevel, (int,int)); diff --git a/include/rm.h b/include/rm.h index 00f0bc4c5..cfc399300 100644 --- a/include/rm.h +++ b/include/rm.h @@ -189,34 +189,35 @@ #define S_ss2 72 #define S_ss3 73 #define S_ss4 74 +#define S_poisoncloud 75 /* The 8 swallow symbols. Do NOT separate. To change order or add, see */ /* the function swallow_to_glyph() in display.c. */ -#define S_sw_tl 75 /* swallow top left [1] */ -#define S_sw_tc 76 /* swallow top center [2] Order: */ -#define S_sw_tr 77 /* swallow top right [3] */ -#define S_sw_ml 78 /* swallow middle left [4] 1 2 3 */ -#define S_sw_mr 79 /* swallow middle right [6] 4 5 6 */ -#define S_sw_bl 80 /* swallow bottom left [7] 7 8 9 */ -#define S_sw_bc 81 /* swallow bottom center [8] */ -#define S_sw_br 82 /* swallow bottom right [9] */ +#define S_sw_tl 76 /* swallow top left [1] */ +#define S_sw_tc 77 /* swallow top center [2] Order: */ +#define S_sw_tr 78 /* swallow top right [3] */ +#define S_sw_ml 79 /* swallow middle left [4] 1 2 3 */ +#define S_sw_mr 80 /* swallow middle right [6] 4 5 6 */ +#define S_sw_bl 81 /* swallow bottom left [7] 7 8 9 */ +#define S_sw_bc 82 /* swallow bottom center [8] */ +#define S_sw_br 83 /* swallow bottom right [9] */ -#define S_explode1 83 /* explosion top left */ -#define S_explode2 84 /* explosion top center */ -#define S_explode3 85 /* explosion top right Ex. */ -#define S_explode4 86 /* explosion middle left */ -#define S_explode5 87 /* explosion middle center /-\ */ -#define S_explode6 88 /* explosion middle right |@| */ -#define S_explode7 89 /* explosion bottom left \-/ */ -#define S_explode8 90 /* explosion bottom center */ -#define S_explode9 91 /* explosion bottom right */ +#define S_explode1 84 /* explosion top left */ +#define S_explode2 85 /* explosion top center */ +#define S_explode3 86 /* explosion top right Ex. */ +#define S_explode4 87 /* explosion middle left */ +#define S_explode5 88 /* explosion middle center /-\ */ +#define S_explode6 89 /* explosion middle right |@| */ +#define S_explode7 90 /* explosion bottom left \-/ */ +#define S_explode8 91 /* explosion bottom center */ +#define S_explode9 92 /* explosion bottom right */ /* end effects */ -#define MAXPCHARS 92 /* maximum number of mapped characters */ +#define MAXPCHARS 93 /* maximum number of mapped characters */ #define MAXDCHARS 41 /* maximum of mapped dungeon characters */ #define MAXTCHARS 22 /* maximum of mapped trap characters */ -#define MAXECHARS 29 /* maximum of mapped effects characters */ +#define MAXECHARS 30 /* maximum of mapped effects characters */ #define MAXEXPCHARS 9 /* number of explosion characters */ struct symdef { diff --git a/src/allmain.c b/src/allmain.c index 5f5ab44c7..981358e77 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -294,6 +294,8 @@ boolean resuming; /* underwater and waterlevel vision are done here */ if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) movebubbles(); + else if (Is_firelevel(&u.uz)) + fumaroles(); else if (Underwater) under_water(0); /* vision while buried done here */ diff --git a/src/display.c b/src/display.c index 0e8b042a6..87658aefa 100644 --- a/src/display.c +++ b/src/display.c @@ -674,7 +674,12 @@ newsym(x,y) */ lev->waslit = (lev->lit!=0); /* remember lit condition */ - if (reg != NULL && ACCESSIBLE(lev->typ)) { + /* normal region shown only on accessible positions, but poison clouds + * also shown above lava, pools and moats. + */ + if (reg != NULL && (ACCESSIBLE(lev->typ) || + (reg->glyph == cmap_to_glyph(S_poisoncloud) && + (lev->typ == LAVAPOOL || lev->typ == POOL || lev->typ == MOAT)))) { show_region(reg,x,y); return; } diff --git a/src/do.c b/src/do.c index eae360425..acc241a90 100644 --- a/src/do.c +++ b/src/do.c @@ -1288,6 +1288,8 @@ boolean at_stairs, falling, portal; /* initial movement of bubbles just before vision_recalc */ if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) movebubbles(); + else if (Is_firelevel(&u.uz)) + fumaroles(); if (level_info[new_ledger].flags & FORGOTTEN) { forget_map(ALL_MAP); /* forget the map */ diff --git a/src/drawing.c b/src/drawing.c index a5cc10d46..a08a7acc5 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -211,6 +211,7 @@ const struct symdef defsyms[MAXPCHARS] = { {'#', "", C(HI_ZAP)}, {'@', "", C(HI_ZAP)}, {'*', "", C(HI_ZAP)}, + {'#', "poison cloud", C(CLR_BRIGHT_GREEN)}, /* [part of] a poison cloud */ {'/', "", C(CLR_GREEN)}, /* swallow top left */ {'-', "", C(CLR_GREEN)}, /* swallow top center */ {'\\', "", C(CLR_GREEN)}, /* swallow top right */ @@ -614,6 +615,7 @@ struct symparse loadsyms[] = { {SYM_PCHAR, S_hcdbridge, "S_hcdbridge"}, {SYM_PCHAR, S_air, "S_air"}, {SYM_PCHAR, S_cloud, "S_cloud"}, + {SYM_PCHAR, S_poisoncloud, "S_poisoncloud"}, {SYM_PCHAR, S_water, "S_water"}, {SYM_PCHAR, S_arrow_trap, "S_arrow_trap"}, {SYM_PCHAR, S_dart_trap, "S_dart_trap"}, diff --git a/src/mkmaze.c b/src/mkmaze.c index 8a5b9b793..d9515de2d 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -879,6 +879,26 @@ register xchar x, y, todnum, todlevel; return; } +void +fumaroles() +{ + xchar n; + boolean snd = FALSE, loud = FALSE; + for (n = rn2(3)+2; n; n--) { + xchar x = rn1(COLNO-4,3); + xchar y = rn1(ROWNO-4,3); + struct trap *ttmp = t_at(x,y); + if (levl[x][y].typ == LAVAPOOL) { + NhRegion *r = create_gas_cloud(x,y, 4+rn2(5), rn1(10,5)); + clear_heros_fault(r); + snd = TRUE; + if (distu(x,y) < 15) loud = TRUE; + } + } + if (snd && !Deaf) + Norep("You hear a %swhoosh!", loud ? "loud " : ""); +} + /* * Special waterlevel stuff in endgame (TH). * diff --git a/src/region.c b/src/region.c index 562747948..bd47b7949 100644 --- a/src/region.c +++ b/src/region.c @@ -996,7 +996,7 @@ int damage; cloud->arg = zeroany; cloud->arg.a_int = damage; cloud->visible = TRUE; - cloud->glyph = cmap_to_glyph(S_cloud); + cloud->glyph = cmap_to_glyph(damage ? S_poisoncloud : S_cloud); add_region(cloud); return cloud; } diff --git a/win/share/other.txt b/win/share/other.txt index 14ec940d5..61258f290 100644 --- a/win/share/other.txt +++ b/win/share/other.txt @@ -1439,6 +1439,25 @@ P = (108, 145, 182) MMMMMNNNNNMMMMMM MMMMMMMMMMMMMMMM } +# tile 75 (poison cloud) +{ + BBBBBBBBBBBBBBBB + BBBBBFFFFFFFBBBB + BBBFFFFFFFFFFBBB + BBFFFFFFFFFGFFBB + BBFFFFFFFFFFFFFB + BFFFFFFFFFFFFGFB + FFFGFFFFFFFFGFFF + FFFFFFFFFFGGFFFF + FFFFFFFFFFFFFGFF + FFGGFFFFFFFGGFFG + FFFFFGGGGGFFFFGG + BGFFFFFFFFFFGGGB + BBGGGFFFFGGGGGGB + BBBGGGGGGGGGGBBB + BBBBBBGGGGBBBBBB + BBBBBBBBBBBBBBBB +} # tile 75 (cmap 75) { AAAAAAADDDDDDAAA From 056565fe7529f595f8ee892dd7a12ce5bffdcd4c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 5 Apr 2015 12:47:27 +0300 Subject: [PATCH 2/8] Make all elementals breathless It makes no sense that air, fire and water elementals would choke in stinking cloud. --- src/monst.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/monst.c b/src/monst.c index d6b843b6c..2d2dbc5d1 100644 --- a/src/monst.c +++ b/src/monst.c @@ -1367,14 +1367,14 @@ NEARDATA struct permonst mons[] = { A(ATTK(AT_ENGL, AD_PHYS, 1, 10), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(0, 0, MS_SILENT, MZ_HUGE), MR_POISON|MR_STONE, 0, - M1_NOEYES|M1_NOLIMBS|M1_NOHEAD|M1_MINDLESS|M1_UNSOLID|M1_FLY, + M1_NOEYES|M1_NOLIMBS|M1_NOHEAD|M1_MINDLESS|M1_BREATHLESS|M1_UNSOLID|M1_FLY, M2_STRONG|M2_NEUTER, 0, CLR_CYAN), MON("fire elemental", S_ELEMENTAL, LVL(8, 12, 2, 30, 0), (G_NOCORPSE|1), A(ATTK(AT_CLAW, AD_FIRE, 3, 6), ATTK(AT_NONE, AD_FIRE, 0, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(0, 0, MS_SILENT, MZ_HUGE), MR_FIRE|MR_POISON|MR_STONE, 0, - M1_NOEYES|M1_NOLIMBS|M1_NOHEAD|M1_MINDLESS|M1_UNSOLID|M1_FLY|M1_NOTAKE, + M1_NOEYES|M1_NOLIMBS|M1_NOHEAD|M1_MINDLESS|M1_BREATHLESS|M1_UNSOLID|M1_FLY|M1_NOTAKE, M2_STRONG|M2_NEUTER, M3_INFRAVISIBLE, CLR_YELLOW), MON("earth elemental", S_ELEMENTAL, LVL(8, 6, 2, 30, 0), (G_NOCORPSE|1), @@ -1390,7 +1390,7 @@ NEARDATA struct permonst mons[] = { A(ATTK(AT_CLAW, AD_PHYS, 5, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(2500, 0, MS_SILENT, MZ_HUGE), MR_POISON|MR_STONE, 0, - M1_NOEYES|M1_NOLIMBS|M1_NOHEAD|M1_MINDLESS|M1_UNSOLID| + M1_NOEYES|M1_NOLIMBS|M1_NOHEAD|M1_MINDLESS|M1_BREATHLESS|M1_UNSOLID| M1_AMPHIBIOUS|M1_SWIM, M2_STRONG|M2_NEUTER, 0, CLR_BLUE), /* From 2643a5c3110d792b6d7f18db4f9403f8c0de7ce9 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 5 Apr 2015 13:47:59 +0300 Subject: [PATCH 3/8] Show stinking cloud valid positions --- doc/fixes35.0 | 4 ++-- src/display.c | 6 ++++-- src/read.c | 38 +++++++++++++++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 5fa64755d..4e81689ee 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -887,13 +887,13 @@ show object symbols in menu headings in menus where those object symbols act as menu accelerators, toggleable via "menu_objsyms" option show t-shirt text at end of game inventory disclose hitting with a polearm remembers the position of the last monster you hit -allow showing legal polearm positions when asked for location to hit add messages for trying to pick up some terrain features boomerang makes noise when hitting a sink non-pet rust monsters would eat rust-proofed non-digestibles but ignore those non-digestibles otherwise kicking a grave may topple the gravestone -allow showing legal jumping positions when asked for location to jump to +allow showing legal positions for stinking cloud, jumping and polearms + when asked for a location Platform- and/or Interface-Specific Fixes diff --git a/src/display.c b/src/display.c index 87658aefa..da5c194e7 100644 --- a/src/display.c +++ b/src/display.c @@ -829,8 +829,10 @@ shieldeff(x,y) * DISP_ALWAYS- Like DISP_FLASH, but vision is not taken into account. */ +#define TMP_AT_MAX_GLYPHS (COLNO*2) + static struct tmp_glyph { - coord saved[COLNO]; /* previously updated positions */ + coord saved[TMP_AT_MAX_GLYPHS]; /* previously updated positions */ int sidx; /* index of next unused slot in saved[] */ int style; /* either DISP_BEAM or DISP_FLASH or DISP_ALWAYS */ int glyph; /* glyph to use when printing */ @@ -900,7 +902,7 @@ tmp_at(x, y) default: /* do it */ if (tglyph->style == DISP_BEAM || tglyph->style == DISP_ALL) { if (tglyph->style != DISP_ALL && !cansee(x,y)) break; - if (tglyph->sidx >= COLNO) break; /* too many locations */ + if (tglyph->sidx >= TMP_AT_MAX_GLYPHS) break; /* too many locations */ /* save pos for later erasing */ tglyph->saved[tglyph->sidx].x = x; tglyph->saved[tglyph->sidx].y = y; diff --git a/src/read.c b/src/read.c index 7d35620bc..d20c25606 100644 --- a/src/read.c +++ b/src/read.c @@ -868,6 +868,39 @@ struct obj *sobj; return 0; } +boolean +is_valid_stinking_cloud_pos(x,y, showmsg) +int x,y; +boolean showmsg; +{ + if (!cansee(x, y) || !ACCESSIBLE(levl[x][y].typ) || distu(x, y) >= 32) { + if (showmsg) You("smell rotten eggs."); + return FALSE; + } + return TRUE; +} + +void +display_stinking_cloud_positions(state) + int state; +{ + if (state == 0) { + tmp_at(DISP_BEAM, cmap_to_glyph(S_flashbeam)); + } else if (state == 1) { + int x,y, dx, dy; + int dist = 6; + for (dx = -dist; dx <= dist; dx++) + for (dy = -dist; dy <= dist; dy++) { + x = u.ux + dx; + y = u.uy + dy; + if (isok(x,y) && is_valid_stinking_cloud_pos(x,y, FALSE)) + tmp_at(x,y); + } + } else { + tmp_at(DISP_END, 0); + } +} + /* scroll effects; return 1 if we use up the scroll and possibly make it become discovered, 0 if caller should take care of those side-effects */ int @@ -1613,14 +1646,13 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ already_known ? "stinking " : ""); cc.x = u.ux; cc.y = u.uy; + getpos_sethilite(display_stinking_cloud_positions); if (getpos(&cc, TRUE, "the desired position") < 0) { pline1(Never_mind); break; } - if (!cansee(cc.x, cc.y) || distu(cc.x, cc.y) >= 32) { - You("smell rotten eggs."); + if (!is_valid_stinking_cloud_pos(cc.x, cc.y, TRUE)) break; - } (void) create_gas_cloud(cc.x, cc.y, 3+bcsign(sobj), 8+4*bcsign(sobj)); break; From 2c8b088edf468ba8d894a7a70d15c89849eb6100 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 5 Apr 2015 15:15:49 +0300 Subject: [PATCH 4/8] Add S_poisoncloud to Guidebooks --- doc/Guidebook.mn | 1 + doc/Guidebook.tex | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 89dee0ae0..5b6cd229e 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -2837,6 +2837,7 @@ O S_ogre (ogre) o S_orc (orc) p S_piercer (piercer) ^ S_pit (pit) +# S_poisoncloud (poison cloud) ^ S_polymorph_trap (polymorph trap) } S_pool (water) ! S_potion (potion) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 67ca18cc1..4073ab71b 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -3412,6 +3412,7 @@ Default & Symbol Name & Description\\ \verb@o@ & S\_orc & (orc)\\ \verb@p@ & S\_piercer & (piercer)\\ \verb@^@ & S\_pit & (pit)\\ +\verb@#@ & S\_poisoncloud & (poison cloud)\\ \verb@^@ & S\_polymorph\_trap & (polymorph trap)\\ \verb@}@ & S\_pool & (water)\\ \verb@!@ & S\_potion & (potion)\\ From 660534389e47146752340720e23aa2671bced2ce Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 5 Apr 2015 09:26:01 -0400 Subject: [PATCH 5/8] a warning bout lc_error lev_comp.l(310) : warning C4013: 'lc_error' undefined; assuming extern returning int --- sys/share/lev_lex.c | 1 + util/lev_comp.l | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/share/lev_lex.c b/sys/share/lev_lex.c index 91f13e8f8..c5fdc4097 100644 --- a/sys/share/lev_lex.c +++ b/sys/share/lev_lex.c @@ -1175,6 +1175,7 @@ void FDECL(init_yyout, (FILE *)); long NDECL(handle_varstring_check); long FDECL(corefunc_str_check, (char *, long)); +extern void VDECL(lc_error, (const char *, ...)); extern struct lc_vardefs *FDECL(vardef_defined,(struct lc_vardefs *,char *, int)); extern struct lc_vardefs *variable_definitions; diff --git a/util/lev_comp.l b/util/lev_comp.l index bba52c270..202f3a7a8 100644 --- a/util/lev_comp.l +++ b/util/lev_comp.l @@ -1,5 +1,5 @@ %{ -/* NetHack 3.5 lev_comp.l $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 3.5 lev_comp.l $NHDT-Date: 1428240296 2015/04/05 13:24:56 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ */ /* NetHack 3.5 lev_comp.l $Date: 2009/05/06 10:54:31 $ $Revision: 1.9 $ */ /* SCCS Id: @(#)lev_lex.c 3.5 2002/03/27 */ /* Copyright (c) 1989 by Jean-Christophe Collet */ @@ -69,6 +69,7 @@ void FDECL(init_yyout, (FILE *)); long NDECL(handle_varstring_check); long FDECL(corefunc_str_check, (char *, long)); +extern void VDECL(lc_error, (const char *, ...)); extern struct lc_vardefs *FDECL(vardef_defined,(struct lc_vardefs *,char *, int)); extern struct lc_vardefs *variable_definitions; From d8a65cd150c84ec9f65a917a8c11804a30a03acb Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 5 Apr 2015 16:29:34 +0300 Subject: [PATCH 6/8] Add missing protos --- src/read.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/read.c b/src/read.c index d20c25606..8c42fcfbe 100644 --- a/src/read.c +++ b/src/read.c @@ -27,7 +27,8 @@ STATIC_DCL void FDECL(randomize,(int *, int)); STATIC_DCL void FDECL(forget_single_object, (int)); STATIC_DCL void FDECL(forget, (int)); STATIC_DCL int FDECL(maybe_tame, (struct monst *,struct obj *)); - +STATIC_DCL boolean FDECL(is_valid_stinking_cloud_pos, (int, int, BOOLEAN_P)); +STATIC_DCL void FDECL(display_stinking_cloud_positions, (int)); STATIC_PTR void FDECL(set_lit, (int,int,genericptr_t)); STATIC_OVL boolean From 3ab441b1a15d14c3df1435419ac9abb1fcadec71 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 6 Apr 2015 09:30:34 +0300 Subject: [PATCH 7/8] Quick band-aid to prevent PRNG prediction This is originally Derek's change from Spork, but sniping it so we can mark this done for now, and can move on with the nextversion. Better solution is to use something like the ISAAC PRNG, which cannot be predicted. --- src/hacklib.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/hacklib.c b/src/hacklib.c index a9c31d42d..1ad5028a9 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -603,24 +603,28 @@ STATIC_DCL struct tm *NDECL(getlt); void setrandom() { - time_t now = getnow(); /* time((TIME_type) 0) */ + unsigned long seed = getnow(); /* time((TIME_type) 0) */ +#ifdef UNIX + /* Quick dirty band-aid to prevent PRNG prediction */ + seed *= getpid(); +#endif /* the types are different enough here that sweeping the different * routine names into one via #defines is even more confusing */ #ifdef RANDOM /* srandom() from sys/share/random.c */ - srandom((unsigned int) now); + srandom((unsigned int) seed); #else # if defined(__APPLE__) || defined(BSD) || defined(LINUX) || defined(ULTRIX) || defined(CYGWIN32) /* system srandom() */ # if defined(BSD) && !defined(POSIX_TYPES) && defined(SUNOS4) (void) # endif - srandom((int) now); + srandom((int) seed); # else # ifdef UNIX /* system srand48() */ - srand48((long) now); + srand48((long) seed); # else /* poor quality system routine */ - srand((int) now); + srand((int) seed); # endif # endif #endif From 3d6fabf730cddc5a8062752a76050e3e657863c0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 6 Apr 2015 10:12:10 -0400 Subject: [PATCH 8/8] nhclose Changes to be committed: modified: include/extern.h modified: src/bones.c modified: src/do.c modified: src/files.c modified: src/music.c modified: src/restore.c modified: src/save.c modified: sys/share/pcmain.c modified: sys/share/pcsys.c modified: sys/share/pcunix.c In order to get level file locking correctly again post 3.4.3 with the newer compilers for windows, I had to funnel close() calls to an intercepting routine. I had two choices: 1. Surround every close() in at least 9 source files with messy: #ifdef WIN32 nhclose(fd); #else close(fd); #endif OR 2. Replace every close() with nhclose() and deal with the special code in the nhclose() version for windows, while just calling close() for other platforms (in files.c). It is also possible, although not done in this commit, to #define nhclose(fd) close(fd) in a header file for non-windows, rather than funnel though a real nhclose() function in files.c. --- include/extern.h | 1 + src/bones.c | 8 ++--- src/do.c | 4 +-- src/files.c | 77 +++++++++++++++++++++++++--------------------- src/music.c | 2 +- src/restore.c | 8 ++--- src/save.c | 18 +++++------ sys/share/pcmain.c | 2 +- sys/share/pcsys.c | 4 +-- sys/share/pcunix.c | 4 +-- 10 files changed, 68 insertions(+), 60 deletions(-) diff --git a/include/extern.h b/include/extern.h index 971971ea8..f36f0243b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -743,6 +743,7 @@ E boolean NDECL(recover_savefile); #ifdef SYSCF_FILE E void NDECL(assure_syscf_file); #endif +E int FDECL(nhclose, (int)); #ifdef HOLD_LOCKFILE_OPEN E void NDECL(really_close); #endif diff --git a/src/bones.c b/src/bones.c index f061316b4..d6c3b75e7 100644 --- a/src/bones.c +++ b/src/bones.c @@ -331,7 +331,7 @@ struct obj *corpse; clear_bypasses(); fd = open_bonesfile(&u.uz, &bonesid); if (fd >= 0) { - (void) close(fd); + (void) nhclose(fd); if (wizard) { if (yn("Bones file already exists. Replace it?") == 'y') { if (delete_bonesfile(&u.uz)) goto make_bones; @@ -504,7 +504,7 @@ struct obj *corpse; if (bytes_counted > freediskspace(bones)) { /* not enough room */ if (wizard) pline("Insufficient space to create bones file."); - (void) close(fd); + (void) nhclose(fd); cancel_bonesfile(); return; } @@ -551,7 +551,7 @@ getbones() ok = TRUE; if(wizard) { if(yn("Get bones?") == 'n') { - (void) close(fd); + (void) nhclose(fd); compress_bonesfile(); return(0); } @@ -595,7 +595,7 @@ getbones() resetobjs(level.buriedobjlist,TRUE); } } - (void) close(fd); + (void) nhclose(fd); sanitize_engravings(); u.uroleplay.numbones++; diff --git a/src/do.c b/src/do.c index acc241a90..8ba500501 100644 --- a/src/do.c +++ b/src/do.c @@ -945,7 +945,7 @@ currentlevel_rewrite() #ifdef MFLOPPY if (!savelev(fd, ledger_no(&u.uz), COUNT_SAVE)) { - (void) close(fd); + (void) nhclose(fd); delete_levelfile(ledger_no(&u.uz)); pline("NetHack is out of disk space for making levels!"); You("can save, quit, or continue playing."); @@ -1160,7 +1160,7 @@ boolean at_stairs, falling, portal; } minit(); /* ZEROCOMP */ getlev(fd, hackpid, new_ledger, FALSE); - (void) close(fd); + (void) nhclose(fd); oinit(); /* reassign level dependent obj probabilities */ } /* do this prior to level-change pline messages */ diff --git a/src/files.c b/src/files.c index f3b9eb610..b3820e361 100644 --- a/src/files.c +++ b/src/files.c @@ -641,12 +641,12 @@ really_close() lftrack.fd = -1; lftrack.oflag = 0; if (fd != -1) - (void)_close(fd); + (void)close(fd); return; } int -close(fd) +nhclose(fd) int fd; { if (lftrack.fd == fd) { @@ -655,10 +655,17 @@ int fd; lftrack.nethack_thinks_it_is_open = FALSE; return 0; } - return _close(fd); + return close(fd); +} +#else +int +nhclose(fd) +int fd; +{ + return close(fd); } #endif - + /* ---------- END LEVEL FILE HANDLING ----------- */ @@ -996,7 +1003,7 @@ restore_saved_game() if ((fd = open_savefile()) < 0) return fd; if (validate(fd, fq_save) != 0) { - (void) close(fd), fd = -1; + (void) nhclose(fd), fd = -1; (void) delete_savefile(); } return fd; @@ -1021,7 +1028,7 @@ const char* filename; get_plname_from_file(fd, tplname); result = dupstr(tplname); } - (void) close(fd); + (void) nhclose(fd); } nh_compress(SAVEF); @@ -1777,7 +1784,7 @@ const char *filename; if (unlink(lockname) < 0) HUP raw_printf("Can't unlink %s.", lockname); # ifdef NO_FILE_LINKS - (void) close(lockfd); + (void) nhclose(lockfd); # endif #endif /* UNIX || VMS */ @@ -2936,9 +2943,9 @@ const char *dir UNUSED_if_not_OS2_CODEVIEW; wait_synch(); } # endif - (void) close(fd); /* RECORD is accessible */ + (void) nhclose(fd); /* RECORD is accessible */ } else if ((fd = open(fq_record, O_CREAT|O_RDWR, FCMASK)) >= 0) { - (void) close(fd); /* RECORD newly created */ + (void) nhclose(fd); /* RECORD newly created */ # if defined(VMS) && !defined(SECURE) /* Re-protect RECORD with world:read+write+execute+delete access. */ (void) chmod(fq_record, FCMASK | 007); @@ -2978,9 +2985,9 @@ const char *dir UNUSED_if_not_OS2_CODEVIEW; raw_printf("Warning: cannot write record %s", tmp); wait_synch(); } else - (void) close(fd); + (void) nhclose(fd); } else /* open succeeded */ - (void) close(fd); + (void) nhclose(fd); #else /* MICRO || WIN32*/ # ifdef MAC @@ -3064,14 +3071,14 @@ recover_savefile() if (read(gfd, (genericptr_t) &hpid, sizeof hpid) != sizeof hpid) { raw_printf( "\nCheckpoint data incompletely written or subsequently clobbered. Recovery impossible."); - (void)close(gfd); + (void)nhclose(gfd); return FALSE; } if (read(gfd, (genericptr_t) &savelev, sizeof(savelev)) != sizeof(savelev)) { raw_printf("\nCheckpointing was not in effect for %s -- recovery impossible.\n", lock); - (void)close(gfd); + (void)nhclose(gfd); return FALSE; } if ((read(gfd, (genericptr_t) savename, sizeof savename) @@ -3085,7 +3092,7 @@ recover_savefile() (read(gfd, (genericptr_t) &tmpplbuf, pltmpsiz) != pltmpsiz)) { raw_printf("\nError reading %s -- can't recover.\n", lock); - (void)close(gfd); + (void)nhclose(gfd); return FALSE; } @@ -3101,15 +3108,15 @@ recover_savefile() sfd = create_savefile(); if (sfd < 0) { raw_printf("\nCannot recover savefile %s.\n", SAVEF); - (void)close(gfd); + (void)nhclose(gfd); return FALSE; } lfd = open_levelfile(savelev, errbuf); if (lfd < 0) { raw_printf("\n%s\n", errbuf); - (void)close(gfd); - (void)close(sfd); + (void)nhclose(gfd); + (void)nhclose(sfd); delete_savefile(); return FALSE; } @@ -3117,8 +3124,8 @@ recover_savefile() if (write(sfd, (genericptr_t) &version_data, sizeof version_data) != sizeof version_data) { raw_printf("\nError writing %s; recovery failed.", SAVEF); - (void)close(gfd); - (void)close(sfd); + (void)nhclose(gfd); + (void)nhclose(sfd); delete_savefile(); return FALSE; } @@ -3128,8 +3135,8 @@ recover_savefile() raw_printf( "\nError writing %s; recovery failed (savefile_info).\n", SAVEF); - (void)close(gfd); - (void)close(sfd); + (void)nhclose(gfd); + (void)nhclose(sfd); delete_savefile(); return FALSE; } @@ -3139,8 +3146,8 @@ recover_savefile() raw_printf( "Error writing %s; recovery failed (player name size).\n", SAVEF); - (void)close(gfd); - (void)close(sfd); + (void)nhclose(gfd); + (void)nhclose(sfd); delete_savefile(); return FALSE; } @@ -3150,28 +3157,28 @@ recover_savefile() raw_printf( "Error writing %s; recovery failed (player name).\n", SAVEF); - (void)close(gfd); - (void)close(sfd); + (void)nhclose(gfd); + (void)nhclose(sfd); delete_savefile(); return FALSE; } if (!copy_bytes(lfd, sfd)) { - (void) close(lfd); - (void) close(sfd); + (void) nhclose(lfd); + (void) nhclose(sfd); delete_savefile(); return FALSE; } - (void)close(lfd); + (void)nhclose(lfd); processed[savelev] = 1; if (!copy_bytes(gfd, sfd)) { - (void) close(lfd); - (void) close(sfd); + (void) nhclose(lfd); + (void) nhclose(sfd); delete_savefile(); return FALSE; } - (void)close(gfd); + (void)nhclose(gfd); processed[0] = 1; for (lev = 1; lev < 256; lev++) { @@ -3185,17 +3192,17 @@ recover_savefile() levc = (xchar) lev; write(sfd, (genericptr_t) &levc, sizeof(levc)); if (!copy_bytes(lfd, sfd)) { - (void) close(lfd); - (void) close(sfd); + (void) nhclose(lfd); + (void) nhclose(sfd); delete_savefile(); return FALSE; } - (void)close(lfd); + (void)nhclose(lfd); processed[lev] = 1; } } } - (void)close(sfd); + (void)nhclose(sfd); #ifdef HOLD_LOCKFILE_OPEN really_close(); diff --git a/src/music.c b/src/music.c index 0912d78cc..24a7b75bd 100644 --- a/src/music.c +++ b/src/music.c @@ -753,7 +753,7 @@ char *buf; break; } (void) write(fd, buf, strlen(buf)); - (void) close(fd); + (void) nhclose(fd); } } #endif /* UNIX386MUSIC */ diff --git a/src/restore.c b/src/restore.c index 4c4b049ce..d46adbb31 100644 --- a/src/restore.c +++ b/src/restore.c @@ -718,7 +718,7 @@ xchar ltmp; /* Remove levels and bones that may have been created. */ - (void) close(nfd); + (void) nhclose(nfd); # ifdef AMIGA clearlocks(); # else @@ -767,7 +767,7 @@ register int fd; if (!restgamestate(fd, &stuckid, &steedid)) { display_nhwindow(WIN_MESSAGE, TRUE); savelev(-1, 0, FREE_SAVE); /* discard current level */ - (void) close(fd); + (void) nhclose(fd); (void) delete_savefile(); restoring = FALSE; return(0); @@ -841,7 +841,7 @@ register int fd; get_plname_from_file(fd, plname); getlev(fd, 0, (xchar)0, FALSE); - (void) close(fd); + (void) nhclose(fd); /* Now set the restore settings to match the * settings used by the save file output routines @@ -1558,7 +1558,7 @@ register unsigned int len; } else { pline("Read %d instead of %u bytes.", rlen, len); if(restoring) { - (void) close(fd); + (void) nhclose(fd); (void) delete_savefile(); error("Error restoring old game."); } diff --git a/src/save.c b/src/save.c index 094f54042..673a37c1f 100644 --- a/src/save.c +++ b/src/save.c @@ -162,7 +162,7 @@ dosave0() nh_uncompress(fq_save); fd = open_savefile(); if (fd > 0) { - (void) close(fd); + (void) nhclose(fd); clear_nhwindow(WIN_MESSAGE); There("seems to be an old save file."); if (yn("Overwrite the old file?") == 'n') { @@ -218,7 +218,7 @@ dosave0() pline("Require %ld bytes but only have %ld.", needed, fds); } flushout(); - (void) close(fd); + (void) nhclose(fd); (void) delete_savefile(); return 0; } @@ -265,7 +265,7 @@ dosave0() ofd = open_levelfile(ltmp, whynot); if (ofd < 0) { HUP pline1(whynot); - (void) close(fd); + (void) nhclose(fd); (void) delete_savefile(); HUP Strcpy(killer.name, whynot); HUP done(TRICKED); @@ -273,7 +273,7 @@ dosave0() } minit(); /* ZEROCOMP */ getlev(ofd, hackpid, ltmp, FALSE); - (void) close(ofd); + (void) nhclose(ofd); bwrite(fd, (genericptr_t) <mp, sizeof ltmp); /* level number*/ savelev(fd, ltmp, WRITE_SAVE | FREE_SAVE); /* actual level*/ delete_levelfile(ltmp); @@ -404,7 +404,7 @@ savestateinlock() Strcpy(killer.name, whynot); done(TRICKED); } - (void) close(fd); + (void) nhclose(fd); fd = create_levelfile(0, whynot); if (fd < 0) { @@ -742,7 +742,7 @@ def_bclose(fd) bw_FILE = 0; } else #endif - (void) close(fd); + (void) nhclose(fd); return; } @@ -879,7 +879,7 @@ zerocomp_bclose(fd) int fd; { zerocomp_bufoff(fd); - (void) close(fd); + (void) nhclose(fd); return; } #endif /* ZEROCOMP */ @@ -1443,8 +1443,8 @@ char *from, *to; if (nto != nfrom) panic("Copyfile failed!"); } while (nfrom == BUFSIZ); - (void) close(fdfrom); - (void) close(fdto); + (void) nhclose(fdfrom); + (void) nhclose(fdto); # endif /* TOS */ } diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 67ae57dba..e9b3aade0 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -405,7 +405,7 @@ char *argv[]; hackpid = 1; #endif write(fd, (genericptr_t) &hackpid, sizeof(hackpid)); - close(fd); + nhclose(fd); } #ifdef MFLOPPY level_info[0].where = ACTIVE; diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index 16d36bbb7..6aea59998 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -282,7 +282,7 @@ int start; if (sysflags.asksavedisk) { /* Don't prompt if you can find the save file */ if ((fd = open_savefile()) >= 0) { - (void) close(fd); + (void) nhclose(fd); return 1; } clear_nhwindow(WIN_MESSAGE); @@ -335,7 +335,7 @@ comspec_exists() if ((comspec = getcomspec())) if ((fd = open(comspec, O_RDONLY)) >= 0) { - (void) close(fd); + (void) nhclose(fd); return TRUE; } return FALSE; diff --git a/sys/share/pcunix.c b/sys/share/pcunix.c index 24316aac2..e5ce95e89 100644 --- a/sys/share/pcunix.c +++ b/sys/share/pcunix.c @@ -150,7 +150,7 @@ getlock() error("Cannot open %s", fq_lock); } - (void) close(fd); + (void) nhclose(fd); if(iflags.window_inited) { # ifdef SELF_RECOVER @@ -248,7 +248,7 @@ gotlock: # endif error("cannot write lock (%s)", fq_lock); } - if(close(fd) == -1) { + if(nhclose(fd) == -1) { # if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS) chdirx(orgdir, 0); # endif