Merge branch 'master' into win32-x64-working

Resolved Conflicts:
	src/mkobj.c
	src/mon.c
	src/options.c

 Changes to be committed:
	modified:   DEVEL/hooksdir/nhsub
	modified:   src/invent.c
	modified:   src/mkobj.c
	modified:   src/mon.c
	modified:   src/options.c
This commit is contained in:
nhmall
2015-05-01 08:22:36 -04:00
5 changed files with 212 additions and 82 deletions

View File

@@ -5,7 +5,7 @@
# Note: was originally called nhdate; the rename is not reflected in the code. # Note: was originally called nhdate; the rename is not reflected in the code.
use strict; use strict;
my %opt; #cmd v n f F (other single char, but we don't care) our %opt; #cmd v n f F m (other single char, but we don't care)
my $mode; # a c d f (add, commit, date, date -f) my $mode; # a c d f (add, commit, date, date -f)
if(length $ENV{GIT_PREFIX}){ if(length $ENV{GIT_PREFIX}){
@@ -249,7 +249,6 @@ my $count = s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+))?)\$/&handlevar($2
my $ofile = $file . ".nht"; my $ofile = $file . ".nht";
open(TOUT, ">", $ofile) or die "Can't open $ofile"; open(TOUT, ">", $ofile) or die "Can't open $ofile";
#XXX MUST add a loop here
# die "write failed: $!" unless defined syswrite(TOUT, $_); # die "write failed: $!" unless defined syswrite(TOUT, $_);
my $offset = 0; my $offset = 0;
my $sent; my $sent;
@@ -267,7 +266,7 @@ 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"; rename $ofile, $file or die "Can't rename $ofile to $file";
} }
# XXX docs for --fixup and --squash are wrong in synopsis. --file missing # XXX docs for --fixup and --squash are wrong in git's synopsis. --file missing
# --message --template -t # --message --template -t
sub cmdparse { sub cmdparse {
my(@in) = @_; my(@in) = @_;
@@ -305,11 +304,15 @@ sub cmdparse {
shift @in; shift @in;
next; next;
} }
# XXX this is messy - time for a rewrite?
if(m/^-(.*)/){ if(m/^-(.*)/){
foreach my $single ( split(//,$1) ){ foreach my $single ( split(//,$1) ){
# don't do -v here from add/commit # don't do -v here from add/commit
if($single ne 'v'){ if($single ne 'v'){
$opt{$single}++; # don't use -m from add/commit
if($opt{cmd} eq 'date' || $single ne 'm'){
$opt{$single}++;
}
} elsif($opt{cmd} eq 'date'){ } elsif($opt{cmd} eq 'date'){
$opt{$single}++; $opt{$single}++;
} }
@@ -408,8 +411,14 @@ use POSIX qw(strftime);
# On pull, keep the current value so we can see the last change date. # On pull, keep the current value so we can see the last change date.
sub Date { sub Date {
my($val) = @_; my($val) = @_;
# we add this to make merge easier for now XXX my $now;
my $now = time; # not %s below - may not be portable if($opt{m}){
my $hash = `git log -1 '--format=format:%H' $::current_file`;
#author keni <keni@his.com> 1429884677 -0400
chomp($now = `git cat-file -p $hash | awk '/author/{print \$4}'`);
} else {
$now = time;
}
# YYYY/MM/DD HH:MM:SS # YYYY/MM/DD HH:MM:SS
$val = "$now " . strftime("%Y/%m/%d %H:%M:%S", gmtime($now)); $val = "$now " . strftime("%Y/%m/%d %H:%M:%S", gmtime($now));
return $val; return $val;
@@ -448,7 +457,7 @@ C<nhsub> - NetHack git command for substitution variables
=head1 SYNOPSIS =head1 SYNOPSIS
C<git nhsub [-v[v[v]] [-n] [-f|-F] [--] [file...]> C<git nhsub [-v[v[v]] [-n] [-f|-F] [-m] [--] [file...]>
=head1 DESCRIPTION =head1 DESCRIPTION
@@ -498,4 +507,11 @@ even if the NHSUBST attribute is not set for the
file, and only if the file is not ignored by git. Not available file, and only if the file is not ignored by git. Not available
when invoked as part of C<nhadd> or C<nhcommit>. when invoked as part of C<nhadd> or C<nhcommit>.
=item C<-m>
Use metadata (C<git log> and C<git cat-file>) to find the last change date to
substitute. Often used with C<-f>. This is useful for cleaning up dates in files that were not
updated when last changed. (Do not use C<git nhadd>/C<git nhcommit> after C<nhsub -m>
or the changes will be overwritten with the current date.)
=back =back

View File

@@ -1906,6 +1906,7 @@ long* out_cnt;
} }
start_menu(win); start_menu(win);
any = zeroany;
if (wizard && iflags.override_ID) { if (wizard && iflags.override_ID) {
char prompt[BUFSZ]; char prompt[BUFSZ];
any.a_char = -1; any.a_char = -1;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.5 mkobj.c $NHDT-Date: 1428715841 2015/04/11 01:30:41 $ $NHDT-Branch: master $:$NHDT-Revision: 1.91 $ */ /* NetHack 3.5 mkobj.c $NHDT-Date: 1430472720 2015/05/01 09:32:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.95 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -15,6 +15,7 @@ STATIC_DCL const char *FDECL(where_name, (struct obj *));
STATIC_DCL void FDECL(insane_object, STATIC_DCL void FDECL(insane_object,
(struct obj *,const char *,const char *,struct monst *)); (struct obj *,const char *,const char *,struct monst *));
STATIC_DCL void FDECL(check_contained, (struct obj *,const char *)); STATIC_DCL void FDECL(check_contained, (struct obj *,const char *));
STATIC_DCL void FDECL(sanity_check_worn, (struct obj *));
struct icp { struct icp {
int iprob; /* probability of an item type */ int iprob; /* probability of an item type */
@@ -1967,18 +1968,18 @@ obj_sanity_check()
those objects should have already been sanity checked via those objects should have already been sanity checked via
the floor list so container contents are skipped here */ the floor list so container contents are skipped here */
for (x = 0; x < COLNO; x++) for (x = 0; x < COLNO; x++)
for (y = 0; y < ROWNO; y++) for (y = 0; y < ROWNO; y++)
for (obj = level.objects[x][y]; obj; obj = obj->nexthere) { for (obj = level.objects[x][y]; obj; obj = obj->nexthere) {
/* <ox,oy> should match <x,y>; <0,*> should always be empty */ /* <ox,oy> should match <x,y>; <0,*> should always be empty */
if (obj->where != OBJ_FLOOR || x == 0 || if (obj->where != OBJ_FLOOR || x == 0 ||
obj->ox != x || obj->oy != y) { obj->ox != x || obj->oy != y) {
char at_fmt[BUFSZ]; char at_fmt[BUFSZ];
Sprintf(at_fmt, "%%s obj@<%d,%d> %%s %%s: %%s@<%d,%d>", Sprintf(at_fmt, "%%s obj@<%d,%d> %%s %%s: %%s@<%d,%d>",
x, y, obj->ox, obj->oy); x, y, obj->ox, obj->oy);
insane_object(obj, at_fmt, "location sanity", insane_object(obj, at_fmt, "location sanity",
(struct monst *)0); (struct monst *)0);
} }
} }
objlist_sanity(invent, OBJ_INVENT, "invent sanity"); objlist_sanity(invent, OBJ_INVENT, "invent sanity");
@@ -1991,16 +1992,16 @@ obj_sanity_check()
/* monsters temporarily in transit; /* monsters temporarily in transit;
they should have arrived with hero by the time we get called */ they should have arrived with hero by the time we get called */
if (mydogs) { if (mydogs) {
pline("mydogs sanity [not empty]"); pline("mydogs sanity [not empty]");
mon_obj_sanity(mydogs, "mydogs minvent sanity"); mon_obj_sanity(mydogs, "mydogs minvent sanity");
} }
/* objects temporarily freed from invent/floor lists; /* objects temporarily freed from invent/floor lists;
they should have arrived somewhere by the time we get called */ they should have arrived somewhere by the time we get called */
if (thrownobj) if (thrownobj)
insane_object(thrownobj, ofmt3, "thrownobj sanity", (struct monst *)0); insane_object(thrownobj, ofmt3, "thrownobj sanity", (struct monst *)0);
if (kickedobj) if (kickedobj)
insane_object(kickedobj, ofmt3, "kickedobj sanity", (struct monst *)0); insane_object(kickedobj, ofmt3, "kickedobj sanity", (struct monst *)0);
/* [how about current_wand too?] */ /* [how about current_wand too?] */
} }
@@ -2014,15 +2015,40 @@ const char *mesg;
struct obj *obj; struct obj *obj;
for (obj = objlist; obj; obj = obj->nobj) { for (obj = objlist; obj; obj = obj->nobj) {
if (obj->where != wheretype) if (obj->where != wheretype)
insane_object(obj, ofmt0, mesg, (struct monst *)0); insane_object(obj, ofmt0, mesg, (struct monst *)0);
if (Has_contents(obj)) { if (Has_contents(obj)) {
if (wheretype == OBJ_ONBILL) if (wheretype == OBJ_ONBILL)
/* containers on shop bill should always be empty */ /* containers on shop bill should always be empty */
insane_object(obj, "%s obj contains something! %s %s: %s", insane_object(obj, "%s obj contains something! %s %s: %s",
mesg, (struct monst *)0); mesg, (struct monst *)0);
check_contained(obj, mesg); check_contained(obj, mesg);
} }
if (obj->owornmask) {
char maskbuf[40];
boolean bc_ok = FALSE;
switch (obj->where) {
case OBJ_INVENT:
case OBJ_MINVENT:
case OBJ_MIGRATING:
sanity_check_worn(obj);
break;
case OBJ_FLOOR:
/* note: ball and chain can also be OBJ_FREE, but not across
turns so this sanity check shouldn't encounter that */
bc_ok = TRUE;
/*FALLTHRU*/
default:
if ((obj != uchain && obj != uball) || !bc_ok) {
/* discovered an object not in inventory which
erroneously has worn mask set */
Sprintf(maskbuf, "worn mask 0x%08lx", obj->owornmask);
insane_object(obj, ofmt0, maskbuf, (struct monst *)0);
}
break;
}
}
} }
} }
@@ -2036,18 +2062,18 @@ const char *mesg;
struct obj *obj; struct obj *obj;
for (mon = monlist; mon; mon = mon->nmon) for (mon = monlist; mon; mon = mon->nmon)
for (obj = mon->minvent; obj; obj = obj->nobj) { for (obj = mon->minvent; obj; obj = obj->nobj) {
if (obj->where != OBJ_MINVENT) if (obj->where != OBJ_MINVENT)
insane_object(obj, mfmt1, mesg, mon); insane_object(obj, mfmt1, mesg, mon);
if (obj->ocarry != mon) if (obj->ocarry != mon)
insane_object(obj, mfmt2, mesg, mon); insane_object(obj, mfmt2, mesg, mon);
check_contained(obj, mesg); check_contained(obj, mesg);
} }
} }
/* This must stay consistent with the defines in obj.h. */ /* This must stay consistent with the defines in obj.h. */
static const char *obj_state_names[NOBJ_STATES] = { static const char *obj_state_names[NOBJ_STATES] = {
"free", "floor", "contained", "invent", "free", "floor", "contained", "invent",
"minvent", "migrating", "buried", "onbill" "minvent", "migrating", "buried", "onbill"
}; };
@@ -2061,8 +2087,8 @@ struct obj *obj;
if (!obj) return "nowhere"; if (!obj) return "nowhere";
where = obj->where; where = obj->where;
if (where < 0 || where >= NOBJ_STATES || !obj_state_names[where]) { if (where < 0 || where >= NOBJ_STATES || !obj_state_names[where]) {
Sprintf(unknown, "unknown[%d]", where); Sprintf(unknown, "unknown[%d]", where);
return unknown; return unknown;
} }
return obj_state_names[where]; return obj_state_names[where];
} }
@@ -2078,19 +2104,19 @@ struct monst *mon;
objnm = monnm = "null!"; objnm = monnm = "null!";
if (obj) { if (obj) {
iflags.override_ID++; iflags.override_ID++;
objnm = doname(obj); objnm = doname(obj);
iflags.override_ID--; iflags.override_ID--;
} }
if (mon || (strstri(mesg, "minvent") && !strstri(mesg, "contained"))) { if (mon || (strstri(mesg, "minvent") && !strstri(mesg, "contained"))) {
Strcat(strcpy(altfmt, fmt), " held by mon %s (%s)"); Strcat(strcpy(altfmt, fmt), " held by mon %s (%s)");
if (mon) if (mon)
monnm = x_monnam(mon, ARTICLE_A, (char *)0, EXACT_NAME, TRUE); monnm = x_monnam(mon, ARTICLE_A, (char *)0, EXACT_NAME, TRUE);
pline(altfmt, mesg, pline(altfmt, mesg,
fmt_ptr((genericptr_t)obj), where_name(obj), objnm, fmt_ptr((genericptr_t)obj), where_name(obj), objnm,
fmt_ptr((genericptr_t)mon), monnm); fmt_ptr((genericptr_t)mon), monnm);
} else { } else {
pline(fmt, mesg, fmt_ptr((genericptr_t)obj), where_name(obj), objnm); pline(fmt, mesg, fmt_ptr((genericptr_t)obj), where_name(obj), objnm);
} }
} }
@@ -2108,37 +2134,122 @@ check_contained(container, mesg)
/* change "invent sanity" to "contained invent sanity" /* change "invent sanity" to "contained invent sanity"
but leave "nested contained invent sanity" as is */ but leave "nested contained invent sanity" as is */
if (!strstri(mesg, "contained")) if (!strstri(mesg, "contained"))
mesg = strcat(strcpy(mesgbuf, "contained "), mesg); mesg = strcat(strcpy(mesgbuf, "contained "), mesg);
for (obj = container->cobj; obj; obj = obj->nobj) { for (obj = container->cobj; obj; obj = obj->nobj) {
/* catch direct cycle to avoid unbounded recursion */ /* catch direct cycle to avoid unbounded recursion */
if (obj == container) if (obj == container)
panic("failed sanity check: container holds itself"); panic("failed sanity check: container holds itself");
if (obj->where != OBJ_CONTAINED) if (obj->where != OBJ_CONTAINED)
insane_object(obj, "%s obj %s %s: %s", mesg, (struct monst *)0); insane_object(obj, "%s obj %s %s: %s", mesg, (struct monst *)0);
else if (obj->ocontainer != container) else if (obj->ocontainer != container)
pline("%s obj %s in container %s, not %s", mesg, pline("%s obj %s in container %s, not %s", mesg,
fmt_ptr((genericptr_t)obj), fmt_ptr((genericptr_t)obj),
fmt_ptr((genericptr_t)obj->ocontainer), fmt_ptr((genericptr_t)obj->ocontainer),
fmt_ptr((genericptr_t)container)); fmt_ptr((genericptr_t)container));
if (Has_contents(obj)) { if (Has_contents(obj)) {
/* catch most likely indirect cycle; we won't notice if /* catch most likely indirect cycle; we won't notice if
parent is present when something comes before it, or parent is present when something comes before it, or
notice more deeply embedded cycles (grandparent, &c) */ notice more deeply embedded cycles (grandparent, &c) */
if (obj->cobj == container) if (obj->cobj == container)
panic("failed sanity check: container holds its parent"); panic("failed sanity check: container holds its parent");
/* change "contained... sanity" to "nested contained... sanity" /* change "contained... sanity" to "nested contained... sanity"
and "nested contained..." to "nested nested contained..." */ and "nested contained..." to "nested nested contained..." */
Strcpy(nestedmesg, "nested "); Strcpy(nestedmesg, "nested ");
copynchars(eos(nestedmesg), mesg, copynchars(eos(nestedmesg), mesg,
(int)sizeof nestedmesg - (int)strlen(nestedmesg) - 1); (int)sizeof nestedmesg - (int)strlen(nestedmesg) - 1);
/* recursively check contents */ /* recursively check contents */
check_contained(obj, nestedmesg); check_contained(obj, nestedmesg);
} }
} }
} }
/* check an object in hero's or monster's inventory which has worn mask set */
STATIC_OVL void
sanity_check_worn(obj)
struct obj *obj;
{
#if defined(BETA) || defined(DEBUG)
static unsigned long wearbits[] = {
W_ARM, W_ARMC, W_ARMH, W_ARMS, W_ARMG, W_ARMF, W_ARMU,
W_WEP, W_QUIVER, W_SWAPWEP, W_AMUL, W_RINGL, W_RINGR,
W_TOOL, W_SADDLE, W_BALL, W_CHAIN,
0
/* [W_ART,W_ARTI are property bits for items which aren't worn] */
};
char maskbuf[60];
unsigned long allmask = 0L;
int i, n = 0;
for (i = 0; wearbits[i]; ++i) {
allmask |= wearbits[i];
if ((obj->owornmask & wearbits[i]) != 0L) ++n;
}
if (n > 1) {
/* multiple bits set */
Sprintf(maskbuf, "worn mask (multiple) 0x%08lx", obj->owornmask);
insane_object(obj, ofmt0, maskbuf, (struct monst *)0);
}
if ((obj->owornmask & ~allmask) != 0L
|| (carried(obj) && (obj->owornmask & W_SADDLE) != 0L)) {
/* non-wearable bit(s) set */
Sprintf(maskbuf, "worn mask (bogus)) 0x%08lx", obj->owornmask);
insane_object(obj, ofmt0, maskbuf, (struct monst *)0);
}
if (n == 1 && (carried(obj)
|| (obj->owornmask & (W_BALL|W_CHAIN)) != 0L)) {
const char *what = 0;
/* verify that obj in hero's invent (or ball/chain elsewhere)
with owornmask of W_foo is the object pointed to by ufoo */
switch (obj->owornmask) {
case W_ARM: if (obj != uarm) what = "armor"; /* suit */
break;
case W_ARMC: if (obj != uarmc) what = "cloak";
break;
case W_ARMH: if (obj != uarmh) what = "helm";
break;
case W_ARMS: if (obj != uarms) what = "shield";
break;
case W_ARMG: if (obj != uarmg) what = "gloves";
break;
case W_ARMF: if (obj != uarmf) what = "boots";
break;
case W_ARMU: if (obj != uarmu) what = "shirt";
break;
case W_WEP: if (obj != uwep) what = "primary weapon";
break;
case W_QUIVER: if (obj != uquiver) what = "quiver";
break;
case W_SWAPWEP: if (obj != uswapwep)
what = u.twoweap ? "secondary weapon" : "alternate weapon";
break;
case W_AMUL: if (obj != uamul) what = "amulet";
break;
case W_RINGL: if (obj != uleft) what = "left ring";
break;
case W_RINGR: if (obj != uright) what = "right ring";
break;
case W_TOOL: if (obj != ublindf) what = "blindfold";
break;
/* case W_SADDLE: */
case W_BALL: if (obj != uball) what = "ball";
break;
case W_CHAIN: if (obj != uchain) what = "chain";
break;
default: break;
}
if (what) {
Sprintf(maskbuf, "worn mask 0x%08lx != %s", obj->owornmask, what);
insane_object(obj, ofmt0, maskbuf, (struct monst *)0);
}
}
#else /* not (BETA || DEBUG) */
/* dummy use of obj to avoid "arg not used" complaint */
if (!obj) insane_object(obj, ofmt0, "<null>", (struct monst *)0);
#endif
}
/* /*
* wrapper to make "near this object" convenient * wrapper to make "near this object" convenient

View File

@@ -1,4 +1,4 @@
/* NetHack 3.5 mon.c $NHDT-Date: 1430433254 2015/04/30 22:34:14 $ $NHDT-Branch: win32-x64-working $:$NHDT-Revision: 1.171 $ */ /* NetHack 3.5 mon.c $NHDT-Date: 1430480373 2015/05/01 11:39:33 $ $NHDT-Branch: master $:$NHDT-Revision: 1.170 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1866,7 +1866,7 @@ register struct monst *mtmp;
u.uy = mtmp->my; u.uy = mtmp->my;
u.uswallow = 0; u.uswallow = 0;
u.uswldtim = 0; u.uswldtim = 0;
if (Punished && uball->where == OBJ_FREE) placebc(); if (Punished && uchain->where != OBJ_FLOOR) placebc();
vision_full_recalc = 1; vision_full_recalc = 1;
docrt(); docrt();
} }

View File

@@ -1,4 +1,4 @@
/* NetHack 3.5 options.c $NHDT-Date: 1430192504 2015/04/28 03:41:44 $ $NHDT-Branch: master $:$NHDT-Revision: 1.189 $ */ /* NetHack 3.5 options.c $NHDT-Date: 1430441885 2015/05/01 00:58:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.191 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -500,7 +500,7 @@ STATIC_OVL int FDECL(count_ape_maps, (int *, int *));
STATIC_DCL const char *FDECL(clr2colorname, (int)); STATIC_DCL const char *FDECL(clr2colorname, (int));
STATIC_DCL const char *FDECL(attr2attrname, (int)); STATIC_DCL const char *FDECL(attr2attrname, (int));
STATIC_DCL int NDECL(query_color); STATIC_DCL int NDECL(query_color);
STATIC_DCL int FDECL(query_attr, (char *)); STATIC_DCL int FDECL(query_attr, (const char *));
STATIC_DCL boolean FDECL(add_menu_coloring_parsed, (char *, int, int)); STATIC_DCL boolean FDECL(add_menu_coloring_parsed, (char *, int, int));
STATIC_DCL void FDECL(free_one_menu_coloring, (int)); STATIC_DCL void FDECL(free_one_menu_coloring, (int));
STATIC_DCL int NDECL(count_menucolors); STATIC_DCL int NDECL(count_menucolors);
@@ -1220,7 +1220,7 @@ query_color()
int int
query_attr(prompt) query_attr(prompt)
char *prompt; const char *prompt;
{ {
winid tmpwin; winid tmpwin;
anything any; anything any;
@@ -1232,7 +1232,8 @@ char *prompt;
any = zeroany; any = zeroany;
for (i = 0; i < SIZE(attrnames); i++) { for (i = 0; i < SIZE(attrnames); i++) {
any.a_int = i + 1; any.a_int = i + 1;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, attrnames[i].attr, attrnames[i].name, MENU_UNSELECTED); add_menu(tmpwin, NO_GLYPH, &any, 0, 0,
attrnames[i].attr, attrnames[i].name, MENU_UNSELECTED);
} }
end_menu(tmpwin, prompt ? prompt : "Pick an attribute"); end_menu(tmpwin, prompt ? prompt : "Pick an attribute");
pick_cnt = select_menu(tmpwin, PICK_ONE, &picks); pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
@@ -3569,6 +3570,7 @@ boolean setinitial,setfromfile;
menu_item *sortl_pick = (menu_item *)0; menu_item *sortl_pick = (menu_item *)0;
tmpwin = create_nhwindow(NHW_MENU); tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin); start_menu(tmpwin);
any = zeroany;
for (i = 0; i < SIZE(sortltype); i++) { for (i = 0; i < SIZE(sortltype); i++) {
sortl_name = sortltype[i]; sortl_name = sortltype[i];
any.a_char = *sortl_name; any.a_char = *sortl_name;