Merge branch 'NetHack-3.7' into paxed-lua-v2-merged

This commit is contained in:
nhmall
2019-11-14 19:50:20 -05:00
18 changed files with 2260 additions and 127 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dothrow.c $NHDT-Date: 1569276989 2019/09/23 22:16:29 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.161 $ */
/* NetHack 3.6 dothrow.c $NHDT-Date: 1573688688 2019/11/13 23:44:48 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.164 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1149,6 +1149,10 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
will be left with a stale pointer. */
if (u.uswallow) {
if (obj == uball) {
uball->ox = uchain->ox = u.ux;
uball->oy = uchain->oy = u.uy;
}
mon = u.ustuck;
g.bhitpos.x = mon->mx;
g.bhitpos.y = mon->my;
@@ -1283,7 +1287,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
(void) snuff_candle(obj);
g.notonhead = (g.bhitpos.x != mon->mx || g.bhitpos.y != mon->my);
obj_gone = thitmonst(mon, obj);
/* Monster may have been tamed; this frees old mon */
/* Monster may have been tamed; this frees old mon [obsolete] */
mon = m_at(g.bhitpos.x, g.bhitpos.y);
/* [perhaps this should be moved into thitmonst or hmon] */
@@ -1308,8 +1312,8 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
clear_thrownobj = TRUE;
goto throwit_return;
} else {
/* Mjollnir must we wielded to be thrown--caller verifies this;
aklys must we wielded as primary to return when thrown */
/* Mjollnir must be wielded to be thrown--caller verifies this;
aklys must be wielded as primary to return when thrown */
if (iflags.returning_missile) { /* Mjollnir or aklys */
if (rn2(100)) {
if (tethered_weapon)

View File

@@ -56,7 +56,7 @@ const
#endif
#if defined(MSDOS) || defined(OS2) || defined(TOS) || defined(WIN32)
#ifndef GNUDOS
#ifndef __DJGPP__
#include <sys\stat.h>
#else
#include <sys/stat.h>

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitm.c $NHDT-Date: 1560161806 2019/06/10 10:16:46 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.116 $ */
/* NetHack 3.6 mhitm.c $NHDT-Date: 1573773926 2019/11/14 23:25:26 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.118 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -52,16 +52,35 @@ struct attack *mattk;
{
const char *fmt;
char buf[BUFSZ];
boolean showit = FALSE;
/* unhiding or unmimicking happens even if hero can't see it
because the formerly concealed monster is now in action */
if (M_AP_TYPE(mdef)) {
seemimic(mdef);
showit |= g.vis;
} else if (mdef->mundetected) {
mdef->mundetected = 0;
showit |= g.vis;
}
if (M_AP_TYPE(magr)) {
seemimic(magr);
showit |= g.vis;
} else if (magr->mundetected) {
magr->mundetected = 0;
showit |= g.vis;
}
if (g.vis) {
if (!canspotmon(magr))
map_invisible(magr->mx, magr->my);
else if (showit)
newsym(magr->mx, magr->my);
if (!canspotmon(mdef))
map_invisible(mdef->mx, mdef->my);
if (M_AP_TYPE(mdef))
seemimic(mdef);
if (M_AP_TYPE(magr))
seemimic(magr);
else if (showit)
newsym(mdef->mx, mdef->my);
fmt = (could_seduce(magr, mdef, mattk) && !magr->mcan)
? "%s pretends to be friendly to"
: "%s misses";
@@ -381,9 +400,9 @@ register struct monst *magr, *mdef;
|| mdef->data == &mons[PM_BROWN_PUDDING])
&& (g.otmp && (objects[g.otmp->otyp].oc_material == IRON
|| objects[g.otmp->otyp].oc_material == METAL))
&& mdef->mhp > 1
&& !mdef->mcan) {
&& mdef->mhp > 1 && !mdef->mcan) {
struct monst *mclone;
if ((mclone = clone_mon(mdef, 0, 0)) != 0) {
if (g.vis && canspotmon(mdef)) {
char buf[BUFSZ];
@@ -425,6 +444,13 @@ register struct monst *magr, *mdef;
break;
case AT_ENGL:
if (mdef->data == &mons[PM_SHADE]) { /* no silver teeth... */
if (g.vis)
pline("%s attempt to engulf %s is futile.",
s_suffix(Monnam(magr)), mon_nam(mdef));
strike = 0;
break;
}
if (u.usteed && mdef == u.usteed) {
strike = 0;
break;
@@ -501,23 +527,49 @@ hitmm(magr, mdef, mattk)
register struct monst *magr, *mdef;
struct attack *mattk;
{
boolean weaponhit = ((mattk->aatyp == AT_WEAP
|| (mattk->aatyp == AT_CLAW && g.otmp))),
silverhit = (weaponhit && g.otmp
&& objects[g.otmp->otyp].oc_material == SILVER),
showit = FALSE;
/* unhiding or unmimicking happens even if hero can't see it
because the formerly concealed monster is now in action */
if (M_AP_TYPE(mdef)) {
seemimic(mdef);
showit |= g.vis;
} else if (mdef->mundetected) {
mdef->mundetected = 0;
showit |= g.vis;
}
if (M_AP_TYPE(magr)) {
seemimic(magr);
showit |= g.vis;
} else if (magr->mundetected) {
magr->mundetected = 0;
showit |= g.vis;
}
if (g.vis) {
int compat;
char buf[BUFSZ];
if (!canspotmon(magr))
map_invisible(magr->mx, magr->my);
else if (showit)
newsym(magr->mx, magr->my);
if (!canspotmon(mdef))
map_invisible(mdef->mx, mdef->my);
if (M_AP_TYPE(mdef))
seemimic(mdef);
if (M_AP_TYPE(magr))
seemimic(magr);
else if (showit)
newsym(mdef->mx, mdef->my);
if ((compat = could_seduce(magr, mdef, mattk)) && !magr->mcan) {
Sprintf(buf, "%s %s", Monnam(magr),
mdef->mcansee ? "smiles at" : "talks to");
pline("%s %s %s.", buf, mon_nam(mdef),
compat == 2 ? "engagingly" : "seductively");
} else if (shade_miss(magr, mdef, g.otmp, FALSE, TRUE)) {
return MM_MISS; /* bypass mdamagem() */
} else {
char magr_name[BUFSZ];
@@ -548,6 +600,28 @@ struct attack *mattk;
Sprintf(buf, "%s hits", magr_name);
}
pline("%s %s.", buf, mon_nam_too(mdef, magr));
if (mon_hates_silver(mdef) && silverhit) {
char *mdef_name = mon_nam_too(mdef, magr);
/* note: mon_nam_too returns a modifiable buffer; so
does s_suffix, but it returns a single static buffer
and we might be calling it twice for this message */
Strcpy(magr_name, s_suffix(magr_name));
if (!noncorporeal(mdef->data) && !amorphous(mdef->data)) {
if (mdef != magr) {
mdef_name = s_suffix(mdef_name);
} else {
(void) strsubst(mdef_name, "himself", "his own");
(void) strsubst(mdef_name, "herself", "her own");
(void) strsubst(mdef_name, "itself", "its own");
}
Strcat(mdef_name, " flesh");
}
pline("%s %s sears %s!", magr_name, /*s_suffix(magr_name), */
simpleonames(g.otmp), mdef_name);
}
}
} else
noises(magr, mattk);
@@ -775,11 +849,12 @@ mdamagem(magr, mdef, mattk)
register struct monst *magr, *mdef;
register struct attack *mattk;
{
struct obj *obj;
struct obj *obj, dmgwep;
char buf[BUFSZ];
struct permonst *pa = magr->data, *pd = mdef->data;
int armpro, num, tmp = d((int) mattk->damn, (int) mattk->damd),
res = MM_MISS;
int armpro, num,
tmp = d((int) mattk->damn, (int) mattk->damd),
res = MM_MISS;
boolean cancelled;
if ((touch_petrifies(pd) /* or flesh_petrifies() */
@@ -882,15 +957,26 @@ register struct attack *mattk;
case AD_HEAL:
case AD_PHYS:
physical:
if (mattk->aatyp == AT_KICK && thick_skinned(pd)) {
/* this shade check is necessary in case any attacks which
dish out physical damage bypass hitmm() to get here */
if ((mattk->aatyp == AT_WEAP || mattk->aatyp == AT_CLAW) && g.otmp)
dmgwep = *g.otmp;
else
dmgwep = cg.zeroobj;
if (shade_miss(magr, mdef, &dmgwep, FALSE, TRUE)) {
tmp = 0;
} else if (mattk->aatyp == AT_WEAP) {
} else if (mattk->aatyp == AT_KICK && thick_skinned(pd)) {
tmp = 0;
} else if (mattk->aatyp == AT_WEAP
|| (mattk->aatyp == AT_CLAW && g.otmp)) {
if (g.otmp) {
struct obj *marmg;
if (g.otmp->otyp == CORPSE
&& touch_petrifies(&mons[g.otmp->corpsenm]))
goto do_stone;
tmp += dmgval(g.otmp, mdef);
if ((marmg = which_armor(magr, W_ARMG)) != 0
&& marmg->otyp == GAUNTLETS_OF_POWER)

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitu.c $NHDT-Date: 1562800504 2019/07/10 23:15:04 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.166 $ */
/* NetHack 3.6 mhitu.c $NHDT-Date: 1573688693 2019/11/13 23:44:53 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.167 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1789,8 +1789,7 @@ struct attack *mattk;
if (!engulf_target(mtmp, &g.youmonst))
return 0;
if ((t && is_pit(t->ttyp))
&& sobj_at(BOULDER, u.ux, u.uy))
if ((t && is_pit(t->ttyp)) && sobj_at(BOULDER, u.ux, u.uy))
return 0;
if (Punished)
@@ -1873,6 +1872,14 @@ struct attack *mattk;
if (mtmp != u.ustuck)
return 0;
if (Punished) {
/* ball&chain are in limbo while swallowed; update their internal
location to be at swallower's spot */
if (uchain->where == OBJ_FREE)
uchain->ox = mtmp->mx, uchain->oy = mtmp->my;
if (uball->where == OBJ_FREE)
uball->ox = mtmp->mx, uball->oy = mtmp->my;
}
if (u.uswldtim > 0)
u.uswldtim -= 1;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mthrowu.c $NHDT-Date: 1564767726 2019/08/02 17:42:06 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.85 $ */
/* NetHack 3.6 mthrowu.c $NHDT-Date: 1573688695 2019/11/13 23:44:55 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.86 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Pasi Kallinen, 2016. */
/* NetHack may be freely redistributed. See license for details. */
@@ -346,6 +346,10 @@ boolean verbose; /* give message(s) even when you can't see what happened */
damage = dmgval(otmp, mtmp);
if (otmp->otyp == ACID_VENOM && resists_acid(mtmp))
damage = 0;
#if 0 /* can't use this because we don't have the attacker */
if (is_orc(mtmp->data) && is_elf(?magr?))
damage++;
#endif
if (ismimic)
seemimic(mtmp);
mtmp->msleeping = 0;
@@ -376,10 +380,19 @@ boolean verbose; /* give message(s) even when you can't see what happened */
}
if (objects[otmp->otyp].oc_material == SILVER
&& mon_hates_silver(mtmp)) {
if (vis)
pline_The("silver sears %s flesh!", s_suffix(mon_nam(mtmp)));
else if (verbose && !g.mtarget)
pline("Its flesh is seared!");
boolean flesh = (!noncorporeal(mtmp->data)
&& !amorphous(mtmp->data));
/* note: extra silver damage is handled by dmgval() */
if (vis) {
char *m_name = mon_nam(mtmp);
if (flesh) /* s_suffix returns a modifiable buffer */
m_name = strcat(s_suffix(m_name), " flesh");
pline_The("silver sears %s!", m_name);
} else if (verbose && !g.mtarget) {
pline("%s is seared!", flesh ? "Its flesh" : "It");
}
}
if (otmp->otyp == ACID_VENOM && cansee(mtmp->mx, mtmp->my)) {
if (resists_acid(mtmp)) {
@@ -531,7 +544,12 @@ struct obj *obj; /* missile (or stack providing it) */
while (range-- > 0) { /* Actually the loop is always exited by break */
g.bhitpos.x += dx;
g.bhitpos.y += dy;
if ((mtmp = m_at(g.bhitpos.x, g.bhitpos.y)) != 0) {
mtmp = m_at(g.bhitpos.x, g.bhitpos.y);
if (mtmp && shade_miss(mon, mtmp, singleobj, TRUE, TRUE)) {
/* if mtmp is a shade and missile passes harmlessly through it,
give message and skip it in order to keep going */
mtmp = (struct monst *) 0;
} else if (mtmp) {
if (ohitmon(mtmp, singleobj, range, TRUE))
break;
} else if (g.bhitpos.x == u.ux && g.bhitpos.y == u.uy) {
@@ -746,7 +764,7 @@ struct attack *mattk;
break;
default:
impossible("bad attack type in spitmu");
/* fall through */
/*FALLTHRU*/
case AD_ACID:
otmp = mksobj(ACID_VENOM, TRUE, FALSE);
break;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 options.c $NHDT-Date: 1572303730 2019/10/28 23:02:10 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.383 $ */
/* NetHack 3.6 options.c $NHDT-Date: 1573505739 2019/11/11 20:55:39 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.386 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2008. */
/* NetHack may be freely redistributed. See license for details. */
@@ -5367,44 +5367,6 @@ boolean setinitial, setfromfile;
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
any = cg.zeroany;
#ifdef CURSES_GRAPHICS /* this ought to be handled within curses... */
/*
* Symbol sets are formatted in two columns, "name description",
* on selectable lines. curses bases menu width on the length
* of non-selectable lines (main header, separators if present,
* with trailing spaces ignored) and defaults to half the map.
* Without something like this separator (shown after the menu
* title and a blank line which follows that) to force a wider
* menu, entries with long descriptions wrap. That would be
* ok if wrapping operated on the same two columns, but the
* menu doesn't know anything about those and the description
* is wrapping into the next line's name column, making long
* descriptions--and menus containing them--hard to read.
*/
if (WINDOWPORT("curses")) {
char tmp1[BUFSZ], tmp2[BUFSZ], bigbuf[BUFSZ + 1 + BUFSZ];
/* 4: room for space+letter+paren+space, fake selector;
2: added to 'biggest' when constructing 'fmtstr';
1: space between symset name+2 and symset description */
if (4 + biggest + 2 + 1 > (int) sizeof tmp1 - 1)
biggest = (int) sizeof tmp1 - 1 - (4 + 2 + 1);
(void) memset((genericptr_t) tmp1, '-', biggest);
tmp1[biggest] = '\0';
if (big_desc > (int) sizeof tmp2 - 1)
big_desc = (int) sizeof tmp2 - 1;
(void) memset((genericptr_t) tmp2, '-', big_desc);
tmp2[big_desc] = '\0';
Sprintf(bigbuf, "%4s", "");
Sprintf(eos(bigbuf), fmtstr, tmp1, tmp2);
bigbuf[BUFSZ - 1] = '\0';
any.a_int = 0;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
bigbuf, MENU_UNSELECTED);
}
#else
nhUse(big_desc);
#endif
any.a_int = 1; /* -1 + 2 [see 'if (sl->name) {' below]*/
if (!symset_name)
defindx = any.a_int;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 uhitm.c $NHDT-Date: 1567805813 2019/09/06 21:36:53 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.212 $ */
/* NetHack 3.6 uhitm.c $NHDT-Date: 1573764936 2019/11/14 20:55:36 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.215 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -691,10 +691,8 @@ int dieroll;
long silverhit = 0L;
int wtype;
struct obj *monwep;
char unconventional[BUFSZ]; /* substituted for word "attack" in msg */
char saved_oname[BUFSZ];
unconventional[0] = '\0';
saved_oname[0] = '\0';
wakeup(mon, TRUE);
@@ -867,7 +865,6 @@ int dieroll;
} else {
if (mdat == &mons[PM_SHADE] && !shade_aware(obj)) {
tmp = 0;
Strcpy(unconventional, cxname(obj));
} else {
switch (obj->otyp) {
case BOULDER: /* 1d20 */
@@ -1138,21 +1135,14 @@ int dieroll;
poiskilled = TRUE;
}
if (tmp < 1) {
boolean mon_is_shade = (mon->data == &mons[PM_SHADE]);
/* make sure that negative damage adjustment can't result
in inadvertently boosting the victim's hit points */
tmp = 0;
if (mdat == &mons[PM_SHADE]) {
if (!hittxt) {
const char *what = *unconventional ? unconventional : "attack";
Your("%s %s harmlessly through %s.", what,
vtense(what, "pass"), mon_nam(mon));
hittxt = TRUE;
}
} else {
if (get_dmg_bonus)
tmp = 1;
}
tmp = (get_dmg_bonus && !mon_is_shade) ? 1 : 0;
if (mon_is_shade && !hittxt
&& thrown != HMON_THROWN && thrown != HMON_KICKED)
hittxt = shade_miss(&g.youmonst, mon, obj, FALSE, TRUE);
}
if (jousting) {
@@ -1362,6 +1352,44 @@ struct obj *obj;
return FALSE;
}
/* used for hero vs monster and monster vs monster; also handles
monster vs hero but that won't happen because hero can't be a shade */
boolean
shade_miss(magr, mdef, obj, thrown, verbose)
struct monst *magr, *mdef;
struct obj *obj;
boolean thrown, verbose;
{
const char *what, *whose, *target;
boolean youagr = (magr == &g.youmonst), youdef = (mdef == &g.youmonst);
/* we're using dmgval() for zero/not-zero, not for actual damage amount */
if (mdef->data != &mons[PM_SHADE] || (obj && dmgval(obj, mdef)))
return FALSE;
if (verbose
&& ((youdef || cansee(mdef->mx, mdef->my) || sensemon(mdef))
|| (magr == &g.youmonst && distu(mdef->mx, mdef->my) <= 2))) {
static const char harmlessly_thru[] = " harmlessly through ";
what = (!obj || shade_aware(obj)) ? "attack" : cxname(obj);
target = youdef ? "you" : mon_nam(mdef);
if (!thrown) {
whose = youagr ? "Your" : s_suffix(Monnam(magr));
pline("%s %s %s%s%s.", whose, what,
vtense(what, "pass"), harmlessly_thru, target);
} else {
pline("%s %s%s%s.", The(what), /* note: not pline_The() */
vtense(what, "pass"), harmlessly_thru, target);
}
if (!youdef && !canspotmon(mdef))
map_invisible(mdef->mx, mdef->my);
}
if (!youdef)
mdef->msleeping = 0;
return TRUE;
}
/* check whether slippery clothing protects from hug or wrap attack */
/* [currently assumes that you are the attacker] */
static boolean

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 zap.c $NHDT-Date: 1561927499 2019/06/30 20:44:59 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.312 $ */
/* NetHack 3.6 zap.c $NHDT-Date: 1573688696 2019/11/13 23:44:56 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.316 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -3341,13 +3341,20 @@ struct obj **pobj; /* object tossed/used, set to NULL
if (range > 3) /* another bounce? */
skiprange(range, &skiprange_start, &skiprange_end);
} else if (mtmp && M_IN_WATER(mtmp->data)) {
if ((!Blind && canseemon(mtmp)) || sensemon(mtmp))
if (!Blind && canspotmon(mtmp))
pline("%s %s over %s.", Yname2(obj), otense(obj, "pass"),
mon_nam(mtmp));
mtmp = (struct monst *) 0;
}
}
if (mtmp && !(in_skip && M_IN_WATER(mtmp->data))) {
/* if mtmp is a shade and missile passes harmlessly through it,
give message and skip it in order to keep going */
if (mtmp && (weapon == THROWN_WEAPON || weapon == KICKED_WEAPON)
&& shade_miss(&g.youmonst, mtmp, obj, TRUE, TRUE))
mtmp = (struct monst *) 0;
if (mtmp) {
g.notonhead = (g.bhitpos.x != mtmp->mx || g.bhitpos.y != mtmp->my);
if (weapon == FLASHED_LIGHT) {
/* FLASHED_LIGHT hitting invisible monster should