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)\\ diff --git a/doc/fixes35.0 b/doc/fixes35.0 index c13d5e022..ca03b1276 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/include/extern.h b/include/extern.h index 50ca0d13b..e908973a9 100644 --- a/include/extern.h +++ b/include/extern.h @@ -745,6 +745,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 @@ -1161,6 +1162,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 5eb1c1de3..7a2ebe675 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/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/display.c b/src/display.c index 0e8b042a6..da5c194e7 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; } @@ -824,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 */ @@ -895,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/do.c b/src/do.c index eae360425..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 */ @@ -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/files.c b/src/files.c index 3271f9b4f..74fe41466 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/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 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/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), /* 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/read.c b/src/read.c index 0aa007928..b9ceed1fc 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 @@ -870,6 +871,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 @@ -1615,14 +1649,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; 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/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/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/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 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; 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