When SEDUCE is disabled, instead of swapping attacks in mons[] once,
do it on the fly in getmattk() whenever needed.  That allows mons[]
to become readonly, although this doesn't declare it 'const' because
doing so will require a zillion 'struct permonst *' updates to match.

This seemed trickier than it should be, but that turned out to be
because the old behavior was broken.  Setting SEDUCE=0 in sysconf or
user's own configuration file resulted in all succubus and incubus
attacks being described as monster smiles engagingly or seductively
rather than hitting (while dishing out physical damage).  I didn't
try rebuilding 3.4.3 to see whether this was already broken before
being migrated to SYSCF.
This commit is contained in:
PatR
2019-01-10 03:10:35 -08:00
parent 79d40658c7
commit b1782b813f
6 changed files with 59 additions and 31 deletions
+3 -1
View File
@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.225 $ $NHDT-Date: 1546770987 2019/01/06 10:36:27 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.226 $ $NHDT-Date: 1547118629 2019/01/10 11:10:29 $
This fixes36.2 file is here to capture information about updates in the 3.6.x This fixes36.2 file is here to capture information about updates in the 3.6.x
lineage following the release of 3.6.1 in April 2018. Please note, however, lineage following the release of 3.6.1 in April 2018. Please note, however,
@@ -327,6 +327,8 @@ when ^T resorted to the teleport-away spell if hero didn't have intrinsic
than casting with 'Z'; ^T also required that the corresponding book than casting with 'Z'; ^T also required that the corresponding book
be known even though knowing and casting a spell should be (and is be known even though knowing and casting a spell should be (and is
with 'Z') possible after forgetting the spellbook due to amnesia with 'Z') possible after forgetting the spellbook due to amnesia
setting SEDUCE=0 made all succubus and incubus attacks be described as
smiling engagingly or seductively rather than hitting or missing
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
+5 -5
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitm.c $NHDT-Date: 1513297346 2017/12/15 00:22:26 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.99 $ */ /* NetHack 3.6 mhitm.c $NHDT-Date: 1547118629 2019/01/10 11:10:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.112 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -915,7 +915,7 @@ register struct attack *mattk;
case AD_WERE: case AD_WERE:
case AD_HEAL: case AD_HEAL:
case AD_PHYS: case AD_PHYS:
physical: physical:
if (mattk->aatyp == AT_KICK && thick_skinned(pd)) { if (mattk->aatyp == AT_KICK && thick_skinned(pd)) {
tmp = 0; tmp = 0;
} else if (mattk->aatyp == AT_WEAP) { } else if (mattk->aatyp == AT_WEAP) {
@@ -1075,7 +1075,7 @@ register struct attack *mattk;
case AD_STON: case AD_STON:
if (magr->mcan) if (magr->mcan)
break; break;
do_stone: do_stone:
/* may die from the acid if it eats a stone-curing corpse */ /* may die from the acid if it eats a stone-curing corpse */
if (munstone(mdef, FALSE)) if (munstone(mdef, FALSE))
goto post_stone; goto post_stone;
@@ -1088,7 +1088,7 @@ register struct attack *mattk;
if (vis && canseemon(mdef)) if (vis && canseemon(mdef))
pline("%s turns to stone!", Monnam(mdef)); pline("%s turns to stone!", Monnam(mdef));
monstone(mdef); monstone(mdef);
post_stone: post_stone:
if (!DEADMONSTER(mdef)) if (!DEADMONSTER(mdef))
return 0; return 0;
else if (mdef->mtame && !vis) else if (mdef->mtame && !vis)
@@ -1661,7 +1661,7 @@ int mdead;
else else
tmp = 0; tmp = 0;
assess_dmg: assess_dmg:
if ((magr->mhp -= tmp) <= 0) { if ((magr->mhp -= tmp) <= 0) {
monkilled(magr, "", (int) mddat->mattk[i].adtyp); monkilled(magr, "", (int) mddat->mattk[i].adtyp);
return (mdead | mhit | MM_AGR_DIED); return (mdead | mhit | MM_AGR_DIED);
+34 -15
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitu.c $NHDT-Date: 1545130893 2018/12/18 11:01:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.160 $ */ /* NetHack 3.6 mhitu.c $NHDT-Date: 1547118629 2019/01/10 11:10:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.161 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -268,6 +268,23 @@ struct attack *alt_attk_buf;
struct attack *attk = &mptr->mattk[indx]; struct attack *attk = &mptr->mattk[indx];
struct obj *weap = (magr == &youmonst) ? uwep : MON_WEP(magr); struct obj *weap = (magr == &youmonst) ? uwep : MON_WEP(magr);
/* honor SEDUCE=0 */
if (!SYSOPT_SEDUCE) {
extern const struct attack sa_no[NATTK];
/* if the first attack is for SSEX damage, all six attacks will be
substituted (expected succubus/incubus handling); if it isn't
but another one is, only that other one will be substituted */
if (mptr->mattk[0].adtyp == AD_SSEX) {
*alt_attk_buf = sa_no[indx];
attk = alt_attk_buf;
} else if (attk->adtyp == AD_SSEX) {
*alt_attk_buf = *attk;
attk = alt_attk_buf;
attk->adtyp = AD_DRLI;
}
}
/* prevent a monster with two consecutive disease or hunger attacks /* prevent a monster with two consecutive disease or hunger attacks
from hitting with both of them on the same turn; if the first has from hitting with both of them on the same turn; if the first has
already hit, switch to a stun attack for the second */ already hit, switch to a stun attack for the second */
@@ -1115,7 +1132,7 @@ register struct attack *mattk;
goto dopois; goto dopois;
case AD_DRCO: case AD_DRCO:
ptmp = A_CON; ptmp = A_CON;
dopois: dopois:
hitmsg(mtmp, mattk); hitmsg(mtmp, mattk);
if (uncancelled && !rn2(8)) { if (uncancelled && !rn2(8)) {
Sprintf(buf, "%s %s", s_suffix(Monnam(mtmp)), Sprintf(buf, "%s %s", s_suffix(Monnam(mtmp)),
@@ -1234,7 +1251,7 @@ register struct attack *mattk;
You_hear("%s hissing!", s_suffix(mon_nam(mtmp))); You_hear("%s hissing!", s_suffix(mon_nam(mtmp)));
if (!rn2(10) if (!rn2(10)
|| (flags.moonphase == NEW_MOON && !have_lizard())) { || (flags.moonphase == NEW_MOON && !have_lizard())) {
do_stone: do_stone:
if (!Stoned && !Stone_resistance if (!Stoned && !Stone_resistance
&& !(poly_when_stoned(youmonst.data) && !(poly_when_stoned(youmonst.data)
&& polymon(PM_STONE_GOLEM))) { && polymon(PM_STONE_GOLEM))) {
@@ -1326,7 +1343,10 @@ register struct attack *mattk;
break; break;
/* Continue below */ /* Continue below */
} else if (dmgtype(youmonst.data, AD_SEDU) } else if (dmgtype(youmonst.data, AD_SEDU)
|| (SYSOPT_SEDUCE && dmgtype(youmonst.data, AD_SSEX))) { /* !SYSOPT_SEDUCE: when hero is attacking and AD_SSEX
is disabled, it would be changed to another damage
type, but when defending, it remains as-is */
|| dmgtype(youmonst.data, AD_SSEX)) {
pline("%s %s.", Monnam(mtmp), pline("%s %s.", Monnam(mtmp),
Deaf ? "says something but you can't hear it" Deaf ? "says something but you can't hear it"
: mtmp->minvent : mtmp->minvent
@@ -2019,7 +2039,7 @@ boolean ufound;
static analysis complains that 'physical_damage' is always static analysis complains that 'physical_damage' is always
False when tested below; it's right, but having that in False when tested below; it's right, but having that in
place means one less thing to update if AD_PHYS gets added */ place means one less thing to update if AD_PHYS gets added */
common: common:
if (!not_affected) { if (!not_affected) {
if (ACURR(A_DEX) > rnd(20)) { if (ACURR(A_DEX) > rnd(20)) {
@@ -2328,6 +2348,7 @@ struct attack *mattk;
struct permonst *pagr; struct permonst *pagr;
boolean agrinvis, defperc; boolean agrinvis, defperc;
xchar genagr, gendef; xchar genagr, gendef;
int adtyp = mattk ? mattk->adtyp : AD_PHYS;
if (is_animal(magr->data)) if (is_animal(magr->data))
return 0; return 0;
@@ -2347,20 +2368,18 @@ struct attack *mattk;
defperc = perceives(mdef->data); defperc = perceives(mdef->data);
gendef = gender(mdef); gendef = gender(mdef);
} }
if (adtyp == AD_SSEX && !SYSOPT_SEDUCE)
adtyp = AD_SEDU;
if (agrinvis && !defperc if (agrinvis && !defperc && adtyp == AD_SEDU)
&& (!SYSOPT_SEDUCE || (mattk && mattk->adtyp != AD_SSEX)))
return 0; return 0;
if (pagr->mlet != S_NYMPH if ((pagr->mlet != S_NYMPH
&& ((pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS]) && pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS])
|| (SYSOPT_SEDUCE && mattk && mattk->adtyp != AD_SSEX))) || (adtyp != AD_SEDU && adtyp != AD_SSEX))
return 0; return 0;
if (genagr == 1 - gendef) return (genagr == 1 - gendef) ? 1 : (pagr->mlet == S_NYMPH) ? 2 : 0;
return 1;
else
return (pagr->mlet == S_NYMPH) ? 2 : 0;
} }
/* returns 1 if monster teleported (or hero leaves monster's vicinity) */ /* returns 1 if monster teleported (or hero leaves monster's vicinity) */
@@ -2888,7 +2907,7 @@ struct attack *mattk;
else else
tmp = 0; tmp = 0;
assess_dmg: assess_dmg:
if ((mtmp->mhp -= tmp) <= 0) { if ((mtmp->mhp -= tmp) <= 0) {
pline("%s dies!", Monnam(mtmp)); pline("%s dies!", Monnam(mtmp));
xkilled(mtmp, XKILL_NOMSG); xkilled(mtmp, XKILL_NOMSG);
+3 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 monst.c $NHDT-Date: 1539804880 2018/10/17 19:34:40 $ $NHDT-Branch: keni-makedefsm $:$NHDT-Revision: 1.61 $ */ /* NetHack 3.6 monst.c $NHDT-Date: 1547118631 2019/01/10 11:10:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.62 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */ /*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -3235,8 +3235,8 @@ monst_init()
return; return;
} }
struct attack sa_yes[NATTK] = SEDUCTION_ATTACKS_YES; const struct attack sa_yes[NATTK] = SEDUCTION_ATTACKS_YES;
struct attack sa_no[NATTK] = SEDUCTION_ATTACKS_NO; const struct attack sa_no[NATTK] = SEDUCTION_ATTACKS_NO;
#endif #endif
/*monst.c*/ /*monst.c*/
+10 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 sys.c $NHDT-Date: 1448241785 2015/11/23 01:23:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.35 $ */ /* NetHack 3.6 sys.c $NHDT-Date: 1547118632 2019/01/10 11:10:32 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.43 $ */
/* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008. */ /* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -120,13 +120,17 @@ sysopt_release()
return; return;
} }
extern struct attack sa_yes[NATTK]; extern const struct attack sa_yes[NATTK];
extern struct attack sa_no[NATTK]; extern const struct attack sa_no[NATTK];
void void
sysopt_seduce_set(val) sysopt_seduce_set(val)
int val; int val;
{ {
#if 0
/*
* Attack substitution is now done on the fly in getmattk(mhitu.c).
*/
struct attack *setval = val ? sa_yes : sa_no; struct attack *setval = val ? sa_yes : sa_no;
int x; int x;
@@ -134,6 +138,9 @@ int val;
mons[PM_INCUBUS].mattk[x] = setval[x]; mons[PM_INCUBUS].mattk[x] = setval[x];
mons[PM_SUCCUBUS].mattk[x] = setval[x]; mons[PM_SUCCUBUS].mattk[x] = setval[x];
} }
#else
nhUse(val);
#endif /*0*/
return; return;
} }
+4 -4
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 uhitm.c $NHDT-Date: 1545597432 2018/12/23 20:37:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.197 $ */ /* NetHack 3.6 uhitm.c $NHDT-Date: 1547118630 2019/01/10 11:10:30 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.198 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1603,7 +1603,7 @@ register struct attack *mattk;
case AD_WERE: /* no special effect on monsters */ case AD_WERE: /* no special effect on monsters */
case AD_HEAL: /* likewise */ case AD_HEAL: /* likewise */
case AD_PHYS: case AD_PHYS:
physical: physical:
if (mattk->aatyp == AT_WEAP) { if (mattk->aatyp == AT_WEAP) {
if (uwep) if (uwep)
tmp = 0; tmp = 0;
@@ -1990,7 +1990,7 @@ register struct attack *mattk;
goto common; goto common;
case AD_ELEC: case AD_ELEC:
resistance = resists_elec(mdef); resistance = resists_elec(mdef);
common: common:
if (!resistance) { if (!resistance) {
pline("%s gets blasted!", Monnam(mdef)); pline("%s gets blasted!", Monnam(mdef));
mdef->mhp -= tmp; mdef->mhp -= tmp;
@@ -2289,7 +2289,7 @@ register struct monst *mon;
weapon = 0; weapon = 0;
switch (mattk->aatyp) { switch (mattk->aatyp) {
case AT_WEAP: case AT_WEAP:
use_weapon: use_weapon:
/* Certain monsters don't use weapons when encountered as enemies, /* Certain monsters don't use weapons when encountered as enemies,
* but players who polymorph into them have hands or claws and * but players who polymorph into them have hands or claws and
* thus should be able to use weapons. This shouldn't prohibit * thus should be able to use weapons. This shouldn't prohibit