diff --git a/.gitignore b/.gitignore index a0575b2b4..a4bfbe1de 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ TAGS .make.state .nse_depinfo *~ -#* +\#* .#* ,* _$* diff --git a/DEVEL/hooksdir/nhsub b/DEVEL/hooksdir/nhsub index 2dbc97800..c169609be 100644 --- a/DEVEL/hooksdir/nhsub +++ b/DEVEL/hooksdir/nhsub @@ -267,6 +267,8 @@ my $count = s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+))?)\$/&handlevar($2 rename $ofile, $file or die "Can't rename $ofile to $file"; } +# XXX docs for --fixup and --squash are wrong in synopsis. --file missing +# --message --template -t sub cmdparse { my(@in) = @_; @@ -315,6 +317,21 @@ sub cmdparse { if($opt{cmd} eq 'add' && $single eq 'n'){ exit 0; } +#need to deal with options that eat a following element (-m, -F etc etc) +#add: nothing? +#commit: -c -C -F -m +# -u mode is optional +# -S keyid is optional + if($opt{cmd} eq 'commit'){ + if($single =~ m/[uS]/){ + last; + } + if($single =~ m/[cCFm]/){ +#XXX this will be a mess if the argument is wrong, but can we tell? No. + shift @in; + last; + } + } } } shift @in; diff --git a/dat/.gitignore b/dat/.gitignore index caece5a59..c2fecbb7c 100644 --- a/dat/.gitignore +++ b/dat/.gitignore @@ -9,6 +9,7 @@ bogusmon engrave epitaph x11tiles +nhtiles.bmp *.lev spec_levs quest_levs diff --git a/dat/opthelp b/dat/opthelp index ce1d743cc..1cffdeb73 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -3,6 +3,7 @@ Boolean options not under specific compile flags (with default values in []): option setting, which is reached via the 'O' cmd.) autodig dig if moving and wielding digging tool [FALSE] +autoopen walking into a door attempts to open it [TRUE] autopickup automatically pick up objects you move over [TRUE] autoquiver when firing with an empty quiver, select some suitable inventory weapon to fill the quiver [FALSE] diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index a62cfd02a..8b32a50aa 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1905,6 +1905,8 @@ Cannot be set with the `O' command. .lp autodig Automatically dig if you are wielding a digging tool and moving into a place that can be dug (default false). +.lp autoopen +Walking into a door attempts to open it (default true). .lp "autopickup " Automatically pick up things onto which you move (default on). See diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index d31fa52aa..057fbc8e9 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -2306,6 +2306,9 @@ Cannot be set with the `{\tt O}' command. Automatically dig if you are wielding a digging tool and moving into a place that can be dug (default false). %.lp +\item[\ib{autoopen}] +Walking into a door attempts to open it (default true). +%.lp \item[\ib{autopickup}] Automatically pick up things onto which you move (default on). See ``{\it pickup\_types\/}'' to refine the behavior. diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 27c9aca0d..36894c697 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -897,6 +897,11 @@ allow showing legal positions for stinking cloud, jumping and polearms cloned creatures (of any type) don't deathdrop items pudding corpses behave somewhat differently than before mithril armor should have silver color +lichen corpse is an acid indicator +camera may contain a picture-painting demon +some monsters can eat through iron bars +inaccessible niches occasionally have iron bars in front +sinks may teleport or polymorph Platform- and/or Interface-Specific Fixes @@ -1161,6 +1166,7 @@ Aardvark Joe's Extended Logfile Michael Deutschmann's use_darkgray Clive Crous' dark_room sortloot by Jeroen Demeyer and Jukka Lahtinen +Auto open doors by Stefano Busti Code Cleanup and Reorganization diff --git a/include/context.h b/include/context.h index a544f6ae0..dfacbb5ad 100644 --- a/include/context.h +++ b/include/context.h @@ -110,6 +110,7 @@ struct context_info { boolean bypasses; /* bypass flag is set on at least one fobj */ boolean botl; /* partially redo status line */ boolean botlx; /* print an entirely new bottom line */ + boolean door_opened; /* set to true if door was opened during test_move */ struct dig_info digging; struct victual_info victual; struct tin_info tin; diff --git a/include/decl.h b/include/decl.h index abdc5261a..fbdfebc19 100644 --- a/include/decl.h +++ b/include/decl.h @@ -265,7 +265,7 @@ E NEARDATA struct c_color_names { const char *const c_black, *const c_amber, *const c_golden, *const c_light_blue,*const c_red, *const c_green, *const c_silver, *const c_blue, *const c_purple, - *const c_white; + *const c_white, *const c_orange; } c_color_names; #define NH_BLACK c_color_names.c_black #define NH_AMBER c_color_names.c_amber @@ -277,6 +277,7 @@ E NEARDATA struct c_color_names { #define NH_BLUE c_color_names.c_blue #define NH_PURPLE c_color_names.c_purple #define NH_WHITE c_color_names.c_white +#define NH_ORANGE c_color_names.c_orange /* The names of the colors used for gems, etc. */ E const char *c_obj_colors[]; diff --git a/include/extern.h b/include/extern.h index 997885882..3a0535cf0 100644 --- a/include/extern.h +++ b/include/extern.h @@ -39,6 +39,7 @@ E void FDECL(m_unleash, (struct monst *,BOOLEAN_P)); E void NDECL(unleash_all); E boolean NDECL(next_to_u); E struct obj *FDECL(get_mleash, (struct monst *)); +E const char *NDECL(beautiful); E void FDECL(check_leash, (XCHAR_P,XCHAR_P)); E boolean FDECL(um_dist, (XCHAR_P,XCHAR_P,XCHAR_P)); E boolean FDECL(snuff_candle, (struct obj *)); @@ -497,6 +498,7 @@ E int FDECL(omon_adj, (struct monst *,struct obj *,BOOLEAN_P)); E int FDECL(thitmonst, (struct monst *,struct obj *)); E int FDECL(hero_breaks, (struct obj *,XCHAR_P,XCHAR_P,BOOLEAN_P)); E int FDECL(breaks, (struct obj *,XCHAR_P,XCHAR_P)); +E void FDECL(release_camera_demon, (struct obj *, XCHAR_P,XCHAR_P)); E void FDECL(breakobj, (struct obj *,XCHAR_P,XCHAR_P,BOOLEAN_P,BOOLEAN_P)); E boolean FDECL(breaktest, (struct obj *)); E boolean FDECL(walk_path, (coord *, coord *, boolean (*)(genericptr_t,int,int), genericptr_t)); @@ -979,6 +981,7 @@ E int NDECL(doforce); E boolean FDECL(boxlock, (struct obj *,struct obj *)); E boolean FDECL(doorlock, (struct obj *,int,int)); E int NDECL(doopen); +E int FDECL(doopen_indir, (int,int)); E int NDECL(doclose); #ifdef MAC @@ -1366,6 +1369,7 @@ E boolean FDECL(onscary, (int,int,struct monst *)); E void FDECL(monflee, (struct monst *, int, BOOLEAN_P, BOOLEAN_P)); E int FDECL(dochug, (struct monst *)); E int FDECL(m_move, (struct monst *,int)); +E void FDECL(dissolve_bars, (int,int)); E boolean FDECL(closed_door, (int,int)); E boolean FDECL(accessible, (int,int)); E void FDECL(set_apparxy, (struct monst *)); diff --git a/include/flag.h b/include/flag.h index 9f44bd06f..1bbf5ff2a 100644 --- a/include/flag.h +++ b/include/flag.h @@ -18,6 +18,7 @@ struct flag { boolean acoustics; /* allow dungeon sound messages */ boolean autodig; /* MRKR: Automatically dig */ boolean autoquiver; /* Automatically fill quiver */ + boolean autoopen; /* open doors by walking into them */ boolean beginner; boolean biff; /* enable checking for mail */ boolean bones; /* allow saving/loading bones */ diff --git a/include/hack.h b/include/hack.h index 0b5feb501..285c5753e 100644 --- a/include/hack.h +++ b/include/hack.h @@ -43,6 +43,15 @@ #define EXT_ENCUMBER 4 /* Overtaxed */ #define OVERLOADED 5 /* Overloaded */ +/* hunger states - see hu_stat in eat.c */ +#define SATIATED 0 +#define NOT_HUNGRY 1 +#define HUNGRY 2 +#define WEAK 3 +#define FAINTING 4 +#define FAINTED 5 +#define STARVED 6 + /* Macros for how a rumor was delivered in outrumor() */ #define BY_ORACLE 0 #define BY_COOKIE 1 diff --git a/include/patchlevel.h b/include/patchlevel.h index 76d514afa..0665df6fe 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -14,7 +14,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 60 +#define EDITLEVEL 61 #define COPYRIGHT_BANNER_A \ "NetHack, Copyright 1985-2015" diff --git a/src/apply.c b/src/apply.c index 40249be1f..e8b0bfea4 100644 --- a/src/apply.c +++ b/src/apply.c @@ -703,6 +703,14 @@ register xchar x, y; } } +const char * +beautiful() +{ + return (ACURR(A_CHA) > 14) ? + (poly_gender() == 1 ? "beautiful" : "handsome") : "ugly"; +} + + #define WEAK 3 /* from eat.c */ static const char look_str[] = "look %s."; @@ -720,8 +728,7 @@ struct obj *obj; if(!getdir((char *)0)) return 0; invis_mirror = Invis; useeit = !Blind && (!invis_mirror || See_invisible); - uvisage = (ACURR(A_CHA) > 14) ? - (poly_gender() == 1 ? "beautiful" : "handsome") : "ugly"; + uvisage = beautiful(); mirror = simpleonames(obj); /* "mirror" or "looking glass" */ if(obj->cursed && !rn2(2)) { if (!Blind) diff --git a/src/attrib.c b/src/attrib.c index 940467c98..25712cf94 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -371,15 +371,6 @@ boolean inc_or_dec; if (moves > 0 && (i == A_STR || i == A_CON)) (void)encumber_msg(); } -/* hunger values - from eat.c */ -#define SATIATED 0 -#define NOT_HUNGRY 1 -#define HUNGRY 2 -#define WEAK 3 -#define FAINTING 4 -#define FAINTED 5 -#define STARVED 6 - STATIC_OVL void exerper() { diff --git a/src/decl.c b/src/decl.c index d9429dbcf..3508b2621 100644 --- a/src/decl.c +++ b/src/decl.c @@ -216,7 +216,7 @@ NEARDATA struct c_color_names c_color_names = { "black", "amber", "golden", "light blue", "red", "green", "silver", "blue", "purple", - "white" + "white", "orange" }; struct menucoloring *menu_colorings = NULL; diff --git a/src/do.c b/src/do.c index 9a797ef06..27255d030 100644 --- a/src/do.c +++ b/src/do.c @@ -8,6 +8,8 @@ #include "lev.h" STATIC_DCL void FDECL(trycall, (struct obj *)); +STATIC_DCL void NDECL(polymorph_sink); +STATIC_DCL boolean NDECL(teleport_sink); STATIC_DCL void FDECL(dosinkring, (struct obj *)); STATIC_PTR int FDECL(drop, (struct obj *)); @@ -259,6 +261,72 @@ register struct obj *obj; docall(obj); } +/** Transforms the sink at the player's position into + * a fountain, throne, altar or grave. */ +STATIC_DCL +void +polymorph_sink() +{ + if (levl[u.ux][u.uy].typ != SINK) return; + + level.flags.nsinks--; + levl[u.ux][u.uy].doormask = 0; + switch(rn2(4)) { + default: + case 0: + levl[u.ux][u.uy].typ = FOUNTAIN; + level.flags.nfountains++; + break; + case 1: + levl[u.ux][u.uy].typ = THRONE; + break; + case 2: + levl[u.ux][u.uy].typ = ALTAR; + levl[u.ux][u.uy].altarmask = Align2amask(rn2((int)A_LAWFUL+2) - 1); + break; + case 3: + levl[u.ux][u.uy].typ = ROOM; + make_grave(u.ux, u.uy, (char *) 0); + break; + } + pline_The("sink transforms into %s!", + (levl[u.ux][u.uy].typ == THRONE) ? + "a throne" : an(surface(u.ux, u.uy))); + newsym(u.ux,u.uy); +} + +/** Teleports the sink at the player's position. + * @return TRUE if sink teleported */ +STATIC_DCL +boolean +teleport_sink() +{ + int cx, cy; + int cnt = 0; + struct trap *trp; + struct engr *eng; + do { + cx = rnd(COLNO-1); + cy = rn2(ROWNO); + trp = t_at(cx,cy); + eng = engr_at(cx,cy); + } while (((levl[cx][cy].typ != ROOM) || (trp) || (eng) || + cansee(cx,cy)) && (cnt++ < 200)); + if ((levl[cx][cy].typ == ROOM) && !trp && !eng) { + /* create sink at new position */ + levl[cx][cy].typ = SINK; + levl[cx][cy].looted = levl[u.ux][u.uy].looted; + newsym(cx,cy); + /* remove old sink */ + levl[u.ux][u.uy].typ = ROOM; + levl[u.ux][u.uy].looted = 0; + newsym(u.ux,u.uy); + return TRUE; + } + return FALSE; +} + + STATIC_OVL void dosinkring(obj) /* obj is a ring being dropped over a kitchen sink */ @@ -266,6 +334,7 @@ register struct obj *obj; { register struct obj *otmp,*otmp2; register boolean ideed = TRUE; + boolean nosink = FALSE; You("drop %s down the drain.", doname(obj)); obj->in_use = TRUE; /* block free identification via interrupt */ @@ -288,8 +357,9 @@ giveback: You("smell rotten %s.", makeplural(fruitname(FALSE))); break; case RIN_AGGRAVATE_MONSTER: - pline("Several flies buzz angrily around the sink."); - break; + pline("Several %s buzz angrily around the sink.", + Hallucination ? makeplural(rndmonnam(NULL)) : "flies"); + break; case RIN_SHOCK_RESISTANCE: pline("Static electricity surrounds the sink."); break; @@ -354,7 +424,8 @@ giveback: You_see("the ring slide right down the drain!"); break; case RIN_SEE_INVISIBLE: - You_see("some air in the sink."); + You_see("some %s in the sink.", + Hallucination ? "oxygen molecules" : "air"); break; case RIN_STEALTH: pline_The("sink seems to blend into the floor for a moment."); @@ -376,13 +447,15 @@ giveback: pline_The("sink glows %s for a moment.", hcolor(NH_WHITE)); break; case RIN_TELEPORTATION: - pline_The("sink momentarily vanishes."); + nosink = teleport_sink(); + pline_The("sink %svanishes.", nosink ? "" : "momentarily "); break; case RIN_TELEPORT_CONTROL: pline_The("sink looks like it is being beamed aboard somewhere."); break; case RIN_POLYMORPH: - pline_The("sink momentarily looks like a fountain."); + polymorph_sink(); + nosink = TRUE; break; case RIN_POLYMORPH_CONTROL: pline_The("sink momentarily looks like a regularly erupting geyser."); @@ -391,9 +464,9 @@ giveback: } if(ideed) trycall(obj); - else + else if (!nosink) You_hear("the ring bouncing down the drainpipe."); - if (!rn2(20)) { + if (!rn2(20) && !nosink) { pline_The("sink backs up, leaving %s.", doname(obj)); obj->in_use = FALSE; dropx(obj); diff --git a/src/do_name.c b/src/do_name.c index 11ad9a805..df4eabcf2 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -420,10 +420,7 @@ do_mname() mtmp = u.usteed; else { pline("This %s creature is called %s and cannot be renamed.", - ACURR(A_CHA) > 14 ? - (flags.female ? "beautiful" : "handsome") : - "ugly", - plname); + beautiful(), plname); return; } } else diff --git a/src/dothrow.c b/src/dothrow.c index ab4b96497..679d49a6e 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1665,6 +1665,21 @@ xchar x, y; /* object location (ox, oy may not be right) */ return 1; } +void +release_camera_demon(obj, x,y) +struct obj *obj; +xchar x,y; +{ + struct monst *mtmp; + if (!rn2(3) && (mtmp = makemon(&mons[rn2(3) ? PM_HOMUNCULUS : PM_IMP],x,y, NO_MM_FLAGS)) != 0) { + if (canspotmon(mtmp)) + pline("%s is released!", Hallucination ? + An(rndmonnam(NULL)) : "The picture-painting demon"); + mtmp->mpeaceful = !obj->cursed; + set_malign(mtmp); + } +} + /* * Unconditionally break an object. Assumes all resistance checks * and break messages have been delivered prior to getting here. @@ -1707,6 +1722,9 @@ boolean from_invent; } /* monster breathing isn't handled... [yet?] */ break; + case EXPENSIVE_CAMERA: + release_camera_demon(obj, x,y); + break; case EGG: /* breaking your own eggs is bad luck */ if (hero_caused && obj->spe && obj->corpsenm >= LOW_PM) diff --git a/src/eat.c b/src/eat.c index bd0c55c33..27eb04d72 100644 --- a/src/eat.c +++ b/src/eat.c @@ -39,15 +39,6 @@ STATIC_DCL boolean FDECL(maybe_cannibal, (int,BOOLEAN_P)); char msgbuf[BUFSZ]; -/* hunger texts used on bottom line (each 8 chars long) */ -#define SATIATED 0 -#define NOT_HUNGRY 1 -#define HUNGRY 2 -#define WEAK 3 -#define FAINTING 4 -#define FAINTED 5 -#define STARVED 6 - /* also used to see if you're allowed to eat cats and dogs */ #define CANNIBAL_ALLOWED() (Role_if(PM_CAVEMAN) || Race_if(PM_ORC)) @@ -75,6 +66,7 @@ STATIC_OVL NEARDATA const char allobj[] = { STATIC_OVL boolean force_save_hs = FALSE; +/* see hunger states in hack.h - texts used on bottom line */ const char *hu_stat[] = { "Satiated", " ", diff --git a/src/files.c b/src/files.c index 952737275..77d266c32 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 files.c $NHDT-Date: 1427337311 2015/03/26 02:35:11 $ $NHDT-Branch: derek-farming $:$NHDT-Revision: 1.141 $ */ +/* NetHack 3.5 files.c $NHDT-Date: 1428972596 2015/04/14 00:49:56 $ $NHDT-Branch: master $:$NHDT-Revision: 1.164 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3346,10 +3346,8 @@ int tribpassage; char *endp; char line[BUFSZ]; - int scopes[4] = {0, SECTIONSCOPE, TITLESCOPE, PASSAGESCOPE}; - int scope = 0, section = 0, passage = 0, book = 0; - int linect = 0, passagecnt = 0, targetpassage = 0, textcnt = 0; - char *sectionnm = "", *booknm = ""; + int scope = 0; + int linect = 0, passagecnt = 0, targetpassage = 0; const char *badtranslation = "an incomprehensible foreign translation"; boolean matchedsection = FALSE, matchedtitle = FALSE; winid tribwin = WIN_ERR; diff --git a/src/hack.c b/src/hack.c index 976735600..f87f672bb 100644 --- a/src/hack.c +++ b/src/hack.c @@ -347,7 +347,7 @@ still_chewing(x,y) if (!boulder && IS_ROCK(lev->typ) && !may_dig(x,y)) { You("hurt your teeth on the %s.", - IS_TREE(lev->typ) ? "tree" : "hard stone"); + lev->typ == IRONBARS ? "bars" : (IS_TREE(lev->typ) ? "tree" : "hard stone")); nomul(0); return 1; } else if (context.digging.pos.x != x || context.digging.pos.y != y || @@ -362,9 +362,10 @@ still_chewing(x,y) context.digging.effort = (IS_ROCK(lev->typ) && !IS_TREE(lev->typ) ? 30 : 60) + u.udaminc; You("start chewing %s %s.", - (boulder || IS_TREE(lev->typ)) ? "on a" : "a hole in the", + (boulder || IS_TREE(lev->typ) || lev->typ == IRONBARS) ? "on a" : "a hole in the", boulder ? "boulder" : - IS_TREE(lev->typ) ? "tree" : IS_ROCK(lev->typ) ? "rock" : "door"); + IS_TREE(lev->typ) ? "tree" : IS_ROCK(lev->typ) ? "rock" : + lev->typ == IRONBARS ? "bar" : "door"); watch_dig((struct monst *)0, x, y, FALSE); return 1; } else if ((context.digging.effort += (30 + u.udaminc)) <= 100) { @@ -373,7 +374,8 @@ still_chewing(x,y) context.digging.chew ? "continue" : "begin", boulder ? "boulder" : IS_TREE(lev->typ) ? "tree" : - IS_ROCK(lev->typ) ? "rock" : "door"); + IS_ROCK(lev->typ) ? "rock" : + lev->typ == IRONBARS ? "bars" : "door"); context.digging.chew = TRUE; watch_dig((struct monst *)0, x, y, FALSE); return 1; @@ -418,6 +420,9 @@ still_chewing(x,y) } else if (IS_TREE(lev->typ)) { digtxt = "chew through the tree."; lev->typ = ROOM; + } else if (lev->typ == IRONBARS) { + digtxt = "eat through the bars."; + dissolve_bars(x,y); } else if (lev->typ == SDOOR) { if (lev->doormask & D_TRAPPED) { lev->doormask = D_NODOOR; @@ -622,6 +627,7 @@ int mode; register struct rm *tmpr = &levl[x][y]; register struct rm *ust; + context.door_opened = FALSE; /* * Check for physical obstacles. First, the place we are going. */ @@ -630,10 +636,15 @@ int mode; if (Passes_walls && may_passwall(x,y)) { ; /* do nothing */ } else if (tmpr->typ == IRONBARS) { + if ((dmgtype(youmonst.data, AD_RUST) || + dmgtype(youmonst.data, AD_CORR)) && + mode == DO_MOVE && still_chewing(x,y)) { + return FALSE; + } if (!(Passes_walls || passes_bars(youmonst.data))) { if (iflags.mention_walls) You("cannot pass through the bars."); - return FALSE; + return FALSE; } } else if (tunnels(youmonst.data) && !needspick(youmonst.data)) { /* Eat the rock. */ @@ -670,8 +681,10 @@ int mode; if (mode == DO_MOVE) { if (amorphous(youmonst.data)) You("try to ooze under the door, but can't squeeze your possessions through."); - else if (x == ux || y == uy) { - if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling) { + if (flags.autoopen && !context.run && !Confusion && !Stunned && !Fumbling) { + context.door_opened = context.move = doopen_indir(x, y); + } else if (x == ux || y == uy) { + if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling) { if (u.usteed) { You_cant("lead %s through that closed door.", y_monnam(u.usteed)); @@ -1395,9 +1408,11 @@ domove() } if (!test_move(u.ux, u.uy, x-u.ux, y-u.uy, DO_MOVE)) { - context.move = 0; - nomul(0); - return; + if (!context.door_opened) { + context.move = 0; + nomul(0); + } + return; } /* Move ball and chain. */ diff --git a/src/invent.c b/src/invent.c index 9e4041603..c66129cf0 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2540,6 +2540,7 @@ mergable(otmp, obj) /* returns TRUE if obj & otmp can be merged */ register struct obj *otmp, *obj; { int objnamelth = 0, otmpnamelth = 0; + if (obj == otmp) return FALSE; /* already the same object */ if (obj->otyp != otmp->otyp) return FALSE; /* coins of the same kind will always merge */ if (obj->oclass == COIN_CLASS) return TRUE; diff --git a/src/lock.c b/src/lock.c index 3de76fe66..c29be8549 100644 --- a/src/lock.c +++ b/src/lock.c @@ -523,6 +523,14 @@ doforce() /* try to force a chest with your weapon */ int doopen() /* try to open a door */ { + return doopen_indir(0, 0); +} + +int +doopen_indir(x, y) /* try to open a door in direction u.dx/u.dy */ +int x, y; +{ + coord cc; register struct rm *door; struct monst *mtmp; @@ -539,7 +547,10 @@ doopen() /* try to open a door */ return 0; } - if(!get_adjacent_loc((char *)0, (char *)0, u.ux, u.uy, &cc)) return(0); + if (x > 0 && y > 0) { + cc.x = x; + cc.y = y; + } else if(!get_adjacent_loc((char *)0, (char *)0, u.ux, u.uy, &cc)) return(0); if((cc.x == u.ux) && (cc.y == u.uy)) return(0); diff --git a/src/mklev.c b/src/mklev.c index a2cc4e12a..b7cfc8e90 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -492,6 +492,15 @@ int trap_type; if(rn2(7)) dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); else { + /* inaccessible niches occasionally have iron bars */ + if (!rn2(5) && IS_WALL(levl[xx][yy].typ)) { + levl[xx][yy].typ = IRONBARS; + if (rn2(3)) + (void) mkcorpstat(CORPSE, + (struct monst *)0, + mkclass(S_HUMAN, 0), + xx, yy+dy, TRUE); + } if (!level.flags.noteleport) (void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy, TRUE, FALSE); diff --git a/src/mondata.c b/src/mondata.c index 98c3244f5..0c26a6005 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -285,6 +285,7 @@ struct permonst *mptr; { return (boolean) (passes_walls(mptr) || amorphous(mptr) || unsolid(mptr) || is_whirly(mptr) || verysmall(mptr) || + dmgtype(mptr, AD_CORR) || dmgtype(mptr, AD_RUST) || (slithy(mptr) && !bigmonst(mptr))); } diff --git a/src/monmove.c b/src/monmove.c index 81eb563d3..a7a3ca46f 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1180,7 +1180,14 @@ postmov: add_damage(mtmp->mx, mtmp->my, 0L); } } else if (levl[mtmp->mx][mtmp->my].typ == IRONBARS) { - if (flags.verbose && canseemon(mtmp)) + if (may_dig(mtmp->mx,mtmp->my) && + (dmgtype(ptr, AD_RUST) || dmgtype(ptr, AD_CORR))) { + if (canseemon(mtmp)) + pline("%s eats through the iron bars.", + Monnam(mtmp)); + dissolve_bars(mtmp->mx, mtmp->my); + return(3); + } else if (flags.verbose && canseemon(mtmp)) Norep("%s %s %s the iron bars.", Monnam(mtmp), /* pluralization fakes verb conjugation */ makeplural(locomotion(ptr, "pass")), @@ -1266,6 +1273,14 @@ postmov: return(mmoved); } +void +dissolve_bars(x, y) +register int x, y; +{ + levl[x][y].typ = (Is_special(&u.uz) || *in_rooms(x,y,0)) ? ROOM : CORR; + newsym(x, y); +} + boolean closed_door(x, y) register int x, y; diff --git a/src/music.c b/src/music.c index 24a7b75bd..3fabfec06 100644 --- a/src/music.c +++ b/src/music.c @@ -453,7 +453,7 @@ struct obj *instr; if (do_spec && instr->spe > 0) { consume_obj_charge(instr, TRUE); - You("produce soft music."); + You("produce %s music.", Hallucination ? "piped" : "soft"); put_monsters_to_sleep(u.ulevel * 5); exercise(A_DEX, TRUE); break; diff --git a/src/options.c b/src/options.c index 755c9e754..2354f1b03 100644 --- a/src/options.c +++ b/src/options.c @@ -77,6 +77,7 @@ static struct Bool_Opt {"asksavedisk", (boolean *)0, FALSE, SET_IN_FILE}, #endif {"autodig", &flags.autodig, FALSE, SET_IN_GAME}, + {"autoopen", &flags.autoopen, TRUE, SET_IN_GAME}, {"autopickup", &flags.pickup, TRUE, SET_IN_GAME}, {"autoquiver", &flags.autoquiver, FALSE, SET_IN_GAME}, #if defined(MICRO) && !defined(AMIGA) diff --git a/src/potion.c b/src/potion.c index d95395083..05bf99a3c 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 potion.c $NHDT-Date: 1426953330 2015/03/21 15:55:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.99 $ */ +/* NetHack 3.5 potion.c $NHDT-Date: 1428972597 2015/04/14 00:49:57 $ $NHDT-Branch: master $:$NHDT-Revision: 1.111 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1818,6 +1818,15 @@ dodip() return 1; } + if(potion->otyp == POT_ACID && obj->otyp == CORPSE && + obj->corpsenm == PM_LICHEN && !Blind) { + pline("%s %s %s around the edges.", The(cxname(obj)), + otense(obj, "turn"), potion->odiluted ? + hcolor(NH_ORANGE) : hcolor(NH_RED)); + potion->in_use = FALSE; /* didn't go poof */ + return(1); + } + if(is_poisonable(obj)) { if(potion->otyp == POT_SICKNESS && !obj->opoisoned) { char buf[BUFSZ]; diff --git a/src/pray.c b/src/pray.c index e78d37a89..99cbf2841 100644 --- a/src/pray.c +++ b/src/pray.c @@ -148,16 +148,6 @@ in_trouble() struct obj *otmp; int i, j, count=0; -/* Borrowed from eat.c */ - -#define SATIATED 0 -#define NOT_HUNGRY 1 -#define HUNGRY 2 -#define WEAK 3 -#define FAINTING 4 -#define FAINTED 5 -#define STARVED 6 - /* * major troubles */ @@ -1369,7 +1359,7 @@ dosacrifice() a_gname(), u_gname()); pline("%s is enraged...", u_gname()); pline("Fortunately, %s permits you to live...", a_gname()); - pline(cloud_of_smoke, hcolor("orange")); + pline(cloud_of_smoke, hcolor(NH_ORANGE)); done(ESCAPED); } else { /* super big win */ adjalign(10); diff --git a/src/sit.c b/src/sit.c index 19cd63471..fd4207af5 100644 --- a/src/sit.c +++ b/src/sit.c @@ -67,9 +67,14 @@ dosit() register struct obj *obj; obj = level.objects[u.ux][u.uy]; - You("sit on %s.", the(xname(obj))); - if (!(Is_box(obj) || objects[obj->otyp].oc_material == CLOTH)) - pline("It's not very comfortable..."); + if (youmonst.data->mlet == S_DRAGON && obj->oclass == COIN_CLASS) { + You("coil up around your %shoard.", + (obj->quan + money_cnt(invent) < u.ulevel*1000) ? "meager " : ""); + } else { + You("sit on %s.", the(xname(obj))); + if (!(Is_box(obj) || objects[obj->otyp].oc_material == CLOTH)) + pline("It's not very comfortable..."); + } } else if (trap != 0 || (u.utrap && (u.utraptype >= TT_LAVA))) { if (u.utrap) { exercise(A_WIS, FALSE); /* you're getting stuck longer */ diff --git a/src/sp_lev.c b/src/sp_lev.c index f268e9348..bb3c416f1 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -407,7 +407,7 @@ opvar_clone(ov) case SPOVAR_VARIABLE: case SPOVAR_STRING: case SPOVAR_SEL: - tmpov->vardata.str = strdup(ov->vardata.str); + tmpov->vardata.str = dupstr(ov->vardata.str); break; default: impossible("Unknown push value type (%i)!", ov->spovartyp); } @@ -2677,7 +2677,7 @@ spo_monster(coder) case SP_M_V_NAME: if ((OV_typ(parm) == SPOVAR_STRING) && !tmpmons.name.str) - tmpmons.name.str = strdup(OV_s(parm)); + tmpmons.name.str = dupstr(OV_s(parm)); break; case SP_M_V_APPEAR: if ((OV_typ(parm) == SPOVAR_INT) && @@ -2685,7 +2685,7 @@ spo_monster(coder) tmpmons.appear = OV_i(parm); opvar_free(parm); OV_pop(parm); - tmpmons.appear_as.str = strdup(OV_s(parm)); + tmpmons.appear_as.str = dupstr(OV_s(parm)); } break; case SP_M_V_ASLEEP: @@ -2820,7 +2820,7 @@ spo_object(coder) case SP_O_V_NAME: if ((OV_typ(parm) == SPOVAR_STRING) && !tmpobj.name.str) - tmpobj.name.str = strdup(OV_s(parm)); + tmpobj.name.str = dupstr(OV_s(parm)); break; case SP_O_V_CORPSENM: if (OV_typ(parm) == SPOVAR_MONST) { @@ -3925,7 +3925,7 @@ spo_levregion(coder) tmplregion->del_islev = OV_i(del_islev); tmplregion->rtype = OV_i(rtype); tmplregion->padding = OV_i(padding); - tmplregion->rname.str = strdup(OV_s(rname)); + tmplregion->rname.str = dupstr(OV_s(rname)); if(!tmplregion->in_islev) { get_location(&tmplregion->inarea.x1, &tmplregion->inarea.y1, @@ -4494,7 +4494,7 @@ spo_var_init(coder) tmpvar = (struct splev_var *)malloc(sizeof(struct splev_var)); if (!tmpvar) panic("newvar tmpvar alloc"); tmpvar->next = coder->frame->variables; - tmpvar->name = strdup(OV_s(vname)); + tmpvar->name = dupstr(OV_s(vname)); coder->frame->variables = tmpvar; if (OV_i(arraylen) < 0) { diff --git a/src/uhitm.c b/src/uhitm.c index 2bf963c94..50c0523f6 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -741,6 +741,7 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */ case EXPENSIVE_CAMERA: You("succeed in destroying %s. Congratulations!", ysimple_name(obj)); + release_camera_demon(obj, u.ux, u.uy); useup(obj); return(TRUE); /*NOTREACHED*/ diff --git a/sys/share/posixregex.c b/sys/share/posixregex.c index 17cb2841e..3540d3b4c 100644 --- a/sys/share/posixregex.c +++ b/sys/share/posixregex.c @@ -1,8 +1,8 @@ -/* NetHack 3.5 posixregex.c $NHDT-Date: 1428590280 2015/04/09 14:38:00 $ $NHDT-Branch: scshunt-regex $:$NHDT-Revision: 1.0 $ */ +/* NetHack 3.5 posixregex.c $NHDT-Date: 1428970913 2015/04/14 00:21:53 $ $NHDT-Branch: master $:$NHDT-Revision: 1.0 $ */ /* Copyright (c) Sean Hunt 2015. */ /* NetHack may be freely redistributed. See license for details. */ -#include +#include "hack.h" #include @@ -50,7 +50,7 @@ struct nhregex { }; struct nhregex *regex_init() { - return malloc (sizeof (struct nhregex)); + return (struct nhregex *)alloc(sizeof (struct nhregex)); } boolean regex_compile(const char *s, struct nhregex *re) { @@ -65,7 +65,7 @@ const char *regex_error_desc(struct nhregex *re) { static char buf[BUFSZ]; if (!re || !re->err) - return NULL; + return (const char *)0; /* FIXME: Using a static buffer here is not ideal, but avoids memory * leaks. Consider the allocation more carefully. */ @@ -75,11 +75,12 @@ const char *regex_error_desc(struct nhregex *re) { } boolean regex_match(const char *s, struct nhregex *re) { + int result; + if (!re) return FALSE; - int result; - if ((result = regexec(&re->re, s, 0, NULL, 0))) { + if ((result = regexec(&re->re, s, 0, (genericptr_t)0, 0))) { if (result != REG_NOMATCH) re->err = result; return FALSE; diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index e71770a3b..49e0872f3 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -142,63 +142,6 @@ rc=Rc TARGET_CPU=x86 !ENDIF -# Common compiler flags: -# -c - compile without linking -# -W3 - Set warning level to level 3 (-W4 for 64-bit compilations) -# -Zi - generate debugging information -# -Od - disable all optimizations -# -Ox - use maximum optimizations -# -Zd - generate only public symbols and line numbers for debugging -# -GS - enable security checks -# -ccommon=-c -Zi -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -c -lflags=/INCREMENTAL:NO /NOLOGO - -!IF "$(TARGET_CPU)" == "x86" -cflags = $(ccommon) -D_X86_=1 -DWIN32 -D_WIN32 -W3 -scall = -Gz - -!ELSEIF "$(TARGET_CPU)" == "x64" -cflags = $(ccommon) -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -cflags = $(cflags) -W4 -scall = -!ENDIF - -# declarations for use on Intel x86 systems -!IF "$(TARGET_CPU)" == "x86" -DLLENTRY = @12 -!ENDIF - -# declarations for use on AMD64 systems -!IF "$(TARGET_CPU)" == "x64" -DLLENTRY = -!ENDIF - -# for Windows applications -conlflags = $(lflags) -subsystem:console,$(EXEVER) -guilflags = $(lflags) -subsystem:windows,$(EXEVER) -dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll - -# basic subsystem specific libraries, less the C Run-Time -baselibs = kernel32.lib $(optlibs) $(winsocklibs) advapi32.lib -winlibs = $(baselibs) user32.lib gdi32.lib comdlg32.lib winspool.lib - -# for Windows applications that use the C Run-Time libraries -conlibs = $(baselibs) -guilibs = $(winlibs) -# -# End of VS2013 and greater stuff -#============================================= - -# -#============================================= -# Visual Studio versions >= 2013 specific stuff -#============================================= - -!IF "$(TARGET_CPU)" == "" -TARGET_CPU=x86 -!ENDIF - # Common compiler flags: # -c - compile without linking # -W3 - Set warning level to level 3 (-W4 for 64-bit compilations) @@ -413,7 +356,7 @@ lflagsUtil = $(lflags) $(conlibs) # - Game build #========================================== -GAMEPDBFILE= /DEBUG /PDB:"$(O)$(GAME).PDB" +GAMEPDBFILE= /PDB:"$(O)$(GAME).PDB" GAMEMAPFILE= /MAP:"$(O)$(GAME).MAP" LIBS= user32.lib winmm.lib $(ZLIB) @@ -588,7 +531,6 @@ VOBJ24 = $(O)track.o $(O)trap.o $(O)u_init.o $(O)uhitm.o VOBJ25 = $(O)vault.o $(O)vis_tab.o $(O)vision.o $(O)weapon.o VOBJ26 = $(O)were.o $(O)wield.o $(O)windows.o $(O)wizard.o VOBJ27 = $(O)worm.o $(O)worn.o $(O)write.o $(O)zap.o - DLBOBJ = $(O)dlb.o REGEX = $(O)cppregex.o diff --git a/util/.gitignore b/util/.gitignore index 98b003527..22139b7ab 100644 --- a/util/.gitignore +++ b/util/.gitignore @@ -8,5 +8,6 @@ lev_yacc.c tile2x11 lev_comp tileedit +tile2bmp dlb recover diff --git a/win/win32/vs2010/NetHackW.vcxproj b/win/win32/vs2010/NetHackW.vcxproj index c90ff1112..3919d8cc7 100644 --- a/win/win32/vs2010/NetHackW.vcxproj +++ b/win/win32/vs2010/NetHackW.vcxproj @@ -637,6 +637,15 @@ copy ..\sys\winnt\defaults.nh ..\binary\defaults.nh %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) %(AdditionalIncludeDirectories)