From bb86fa2bb7e0978f800005c2e067d1b277388c5a Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 9 Jan 2019 18:10:55 -0800 Subject: [PATCH 1/4] hero infravision Take a first step towards making the mons[] array be readonly. The only other place that updates it is when changing succubus and incubus AD_SSEX attacks to AD_SEDU ones and that can be handled via existing getmattk(), but so far has proven to be trickier than anticipated. --- include/mondata.h | 8 ++++---- src/polyself.c | 5 +++-- src/role.c | 11 ++++++++++- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/mondata.h b/include/mondata.h index 0b1df5ccc..8febb8fb2 100644 --- a/include/mondata.h +++ b/include/mondata.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mondata.h $NHDT-Date: 1513297342 2017/12/15 00:22:22 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 3.6 mondata.h $NHDT-Date: 1547086248 2019/01/10 02:10:48 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.35 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ @@ -127,9 +127,9 @@ #define is_longworm(ptr) \ (((ptr) == &mons[PM_BABY_LONG_WORM]) || ((ptr) == &mons[PM_LONG_WORM]) \ || ((ptr) == &mons[PM_LONG_WORM_TAIL])) -#define is_covetous(ptr) ((ptr->mflags3 & M3_COVETOUS)) -#define infravision(ptr) ((ptr->mflags3 & M3_INFRAVISION)) -#define infravisible(ptr) ((ptr->mflags3 & M3_INFRAVISIBLE)) +#define is_covetous(ptr) (((ptr)->mflags3 & M3_COVETOUS)) +#define infravision(ptr) (((ptr)->mflags3 & M3_INFRAVISION)) +#define infravisible(ptr) (((ptr)->mflags3 & M3_INFRAVISIBLE)) #define is_displacer(ptr) (((ptr)->mflags3 & M3_DISPLACES) != 0L) #define is_mplayer(ptr) \ (((ptr) >= &mons[PM_ARCHEOLOGIST]) && ((ptr) <= &mons[PM_WIZARD])) diff --git a/src/polyself.c b/src/polyself.c index e136d1898..fec59787c 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 polyself.c $NHDT-Date: 1520797126 2018/03/11 19:38:46 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.117 $ */ +/* NetHack 3.6 polyself.c $NHDT-Date: 1547086249 2019/01/10 02:10:49 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.125 $ */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -81,7 +81,8 @@ set_uasmon() PROPSET(HALLUC_RES, dmgtype(mdat, AD_HALU)); PROPSET(SEE_INVIS, perceives(mdat)); PROPSET(TELEPAT, telepathic(mdat)); - PROPSET(INFRAVISION, infravision(mdat)); + /* note that Infravision uses mons[race] rather than usual mons[role] */ + PROPSET(INFRAVISION, infravision(Upolyd ? mdat : &mons[urace.malenum])); PROPSET(INVIS, pm_invisible(mdat)); PROPSET(TELEPORT, can_teleport(mdat)); PROPSET(TELEPORT_CONTROL, control_teleport(mdat)); diff --git a/src/role.c b/src/role.c index 860f7644e..2a2acce53 100644 --- a/src/role.c +++ b/src/role.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 role.c $NHDT-Date: 1546137492 2018/12/30 02:38:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.55 $ */ +/* NetHack 3.6 role.c $NHDT-Date: 1547086250 2019/01/10 02:10:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.56 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2098,6 +2098,14 @@ role_init() /* 0 or 1; no gods are neuter, nor is gender randomized */ quest_status.godgend = !strcmpi(align_gtitle(alignmnt), "goddess"); +#if 0 +/* + * Disable this fixup so that mons[] can be const. The only + * place where it actually matters for the hero is in set_uasmon() + * and that can use mons[race] rather than mons[role] for this + * particular property. Despite the comment, it is checked--where + * needed--via instrinsic 'Infravision' which set_uasmon() manages. + */ /* Fix up infravision */ if (mons[urace.malenum].mflags3 & M3_INFRAVISION) { /* although an infravision intrinsic is possible, infravision @@ -2113,6 +2121,7 @@ role_init() if (urole.femalenum != NON_PM) mons[urole.femalenum].mflags3 |= M3_INFRAVISION; } +#endif /*0*/ /* Artifacts are fixed in hack_artifacts() */ From a637e91f376c6e37160ba24b987e545953759d2a Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 9 Jan 2019 18:15:43 -0800 Subject: [PATCH 2/4] miscellaneous formatting Some minor stuff that's been sitting around for a while. --- src/do.c | 15 +++++++-------- src/dokick.c | 19 ++++++++++--------- src/lock.c | 11 ++++++----- src/mkobj.c | 10 +++++----- src/potion.c | 17 +++++++++-------- 5 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/do.c b/src/do.c index b05339df4..53d0c60ae 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do.c $NHDT-Date: 1545597418 2018/12/23 20:36:58 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.182 $ */ +/* NetHack 3.6 do.c $NHDT-Date: 1547086513 2019/01/10 02:15:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.183 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -371,7 +371,7 @@ register struct obj *obj; goto giveback; case RIN_SLOW_DIGESTION: pline_The("ring is regurgitated!"); - giveback: + giveback: obj->in_use = FALSE; dropx(obj); trycall(obj); @@ -890,7 +890,7 @@ int retry; } } -drop_done: + drop_done: return n_dropped; } @@ -1698,17 +1698,16 @@ struct obj *corpse; where = corpse->where; is_uwep = (corpse == uwep); chewed = (corpse->oeaten != 0); - Strcpy(cname, - corpse_xname(corpse, chewed ? "bite-covered" : (const char *) 0, - CXN_SINGULAR)); + Strcpy(cname, corpse_xname(corpse, + chewed ? "bite-covered" : (const char *) 0, + CXN_SINGULAR)); mcarry = (where == OBJ_MINVENT) ? corpse->ocarry : 0; if (where == OBJ_CONTAINED) { struct monst *mtmp2; container = corpse->ocontainer; - mtmp2 = - get_container_location(container, &container_where, (int *) 0); + mtmp2 = get_container_location(container, &container_where, (int *) 0); /* container_where is the outermost container's location even if * nested */ if (container_where == OBJ_MINVENT && mtmp2) diff --git a/src/dokick.c b/src/dokick.c index 68eb49c24..04d33e3e2 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dokick.c $NHDT-Date: 1543185070 2018/11/25 22:31:10 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.128 $ */ +/* NetHack 3.6 dokick.c $NHDT-Date: 1547086527 2019/01/10 02:15:27 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.129 $ */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -247,7 +247,7 @@ xchar x, y; else if (uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25)) clumsy = TRUE; -doit: + doit: You("kick %s.", mon_nam(mon)); if (!rn2(clumsy ? 3 : 4) && (clumsy || !bigmonst(mon->data)) && mon->mcansee && !mon->mtrapped && !thick_skinned(mon->data) @@ -1203,7 +1203,7 @@ dokick() || IS_STWALL(maploc->typ)) { if (!IS_STWALL(maploc->typ) && maploc->ladder == LA_DOWN) goto dumb; - ouch: + ouch: pline("Ouch! That hurts!"); exercise(A_DEX, FALSE); exercise(A_STR, FALSE); @@ -1230,7 +1230,7 @@ dokick() if (maploc->doormask == D_ISOPEN || maploc->doormask == D_BROKEN || maploc->doormask == D_NODOOR) { - dumb: + dumb: exercise(A_DEX, FALSE); if (martial() || ACURR(A_DEX) >= 16 || rn2(3)) { You("kick at empty space."); @@ -1412,10 +1412,11 @@ xchar dlev; /* if !0 send to dlev near player */ obj_extract_self(obj); if (costly) { - price += stolen_value( - obj, x, y, (costly_spot(u.ux, u.uy) - && index(u.urooms, *in_rooms(x, y, SHOPBASE))), - TRUE); + price += stolen_value(obj, x, y, + (costly_spot(u.ux, u.uy) + && index(u.urooms, + *in_rooms(x, y, SHOPBASE))), + TRUE); /* set obj->no_charge to 0 */ if (Has_contents(obj)) picked_container(obj); /* does the right thing */ @@ -1681,7 +1682,7 @@ unsigned long deliverflags; struct obj *otmp, *otmp2; int where, maxobj = 1; boolean at_crime_scene = In_mines(&u.uz); - + if ((deliverflags & DF_RANDOM) && cnt > 1) maxobj = rnd(cnt); else if (deliverflags & DF_ALL) diff --git a/src/lock.c b/src/lock.c index 5c52532b9..0f4c4dbff 100644 --- a/src/lock.c +++ b/src/lock.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 lock.c $NHDT-Date: 1544442712 2018/12/10 11:51:52 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.82 $ */ +/* NetHack 3.6 lock.c $NHDT-Date: 1547086531 2019/01/10 02:15:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.83 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -195,12 +195,13 @@ boolean destroyit; if (!rn2(3) || otmp->oclass == POTION_CLASS) { chest_shatter_msg(otmp); if (costly) - loss += - stolen_value(otmp, u.ux, u.uy, peaceful_shk, TRUE); + loss += stolen_value(otmp, u.ux, u.uy, peaceful_shk, TRUE); if (otmp->quan == 1L) { obfree(otmp, (struct obj *) 0); continue; } + /* this works because we're sure to have at least 1 left; + otherwise it would fail since otmp is not in inventory */ useup(otmp); } if (box->otyp == ICE_BOX && otmp->otyp == CORPSE) { @@ -746,7 +747,7 @@ boolean quietly; return TRUE; } if (OBJ_AT(x, y)) { - objhere: + objhere: if (!quietly) pline("%s's in the way.", Something); return TRUE; @@ -812,7 +813,7 @@ doclose() else if (portcullis || door->typ == DRAWBRIDGE_DOWN) There("is no obvious way to close the drawbridge."); else { - nodoor: + nodoor: You("%s no door there.", Blind ? "feel" : "see"); } return res; diff --git a/src/mkobj.c b/src/mkobj.c index 29444b424..0c6b960ca 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1546837153 2019/01/07 04:59:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.140 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1547086532 2019/01/10 02:15:32 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.141 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -71,7 +71,7 @@ newoextra() { struct oextra *oextra; - oextra = (struct oextra *) alloc(sizeof(struct oextra)); + oextra = (struct oextra *) alloc(sizeof (struct oextra)); oextra->oname = 0; oextra->omonst = 0; oextra->omid = 0; @@ -391,7 +391,7 @@ struct obj *obj2, *obj1; if (!OMONST(obj2)) newomonst(obj2); (void) memcpy((genericptr_t) OMONST(obj2), - (genericptr_t) OMONST(obj1), sizeof(struct monst)); + (genericptr_t) OMONST(obj1), sizeof (struct monst)); OMONST(obj2)->mextra = (struct mextra *) 0; OMONST(obj2)->nmon = (struct monst *) 0; #if 0 @@ -406,13 +406,13 @@ struct obj *obj2, *obj1; if (!OMID(obj2)) newomid(obj2); (void) memcpy((genericptr_t) OMID(obj2), (genericptr_t) OMID(obj1), - sizeof(unsigned)); + sizeof (unsigned)); } if (has_olong(obj1)) { if (!OLONG(obj2)) newolong(obj2); (void) memcpy((genericptr_t) OLONG(obj2), (genericptr_t) OLONG(obj1), - sizeof(long)); + sizeof (long)); } if (has_omailcmd(obj1)) { new_omailcmd(obj2, OMAILCMD(obj1)); diff --git a/src/potion.c b/src/potion.c index 482321692..dc2613a34 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 potion.c $NHDT-Date: 1545597429 2018/12/23 20:37:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.157 $ */ +/* NetHack 3.6 potion.c $NHDT-Date: 1547086533 2019/01/10 02:15:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.158 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1402,7 +1402,7 @@ int how; /*FALLTHRU*/ case POT_RESTORE_ABILITY: case POT_GAIN_ABILITY: - do_healing: + do_healing: angermon = FALSE; if (mon->mhp < mon->mhpmax) { mon->mhp = mon->mhpmax; @@ -1424,7 +1424,7 @@ int how; pline("%s looks unharmed.", Monnam(mon)); break; } - do_illness: + do_illness: if ((mon->mhpmax > 3) && !resist(mon, POTION_CLASS, 0, NOTELL)) mon->mhpmax /= 2; if ((mon->mhp > 2) && !resist(mon, POTION_CLASS, 0, NOTELL)) @@ -2146,7 +2146,7 @@ dodip() useup(potion); return 1; } -more_dips: + more_dips: /* Allow filling of MAGIC_LAMPs to prevent identification by player */ if ((obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP) @@ -2234,9 +2234,10 @@ more_dips: } } obj_extract_self(singlepotion); - singlepotion = - hold_another_object(singlepotion, "You juggle and drop %s!", - doname(singlepotion), (const char *) 0); + singlepotion = hold_another_object(singlepotion, + "You juggle and drop %s!", + doname(singlepotion), + (const char *) 0); nhUse(singlepotion); update_inventory(); return 1; @@ -2245,7 +2246,7 @@ more_dips: pline("Interesting..."); return 1; -poof: + poof: if (!objects[potion->otyp].oc_name_known && !objects[potion->otyp].oc_uname) docall(potion); From 79d40658c7a00e27d9a8ce29bf9fee4ebd8f2c14 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 9 Jan 2019 18:18:11 -0800 Subject: [PATCH 3/4] characteristics loss A hero run by the fuzzer that has characteristics plummet to 3 and then sometimes hang around there instead of being recovered by restore ability is happening because loss that tries to reduce the base value below 3 lowers the max (peak) value instead, and once that also gets down to 3, restore ability is no longer able to do anything with it. This changes an attempt to reduce a characteristic by N points below 3 to reduce it by rn2(N + 1) instead. That's N/2 on average and a 50% chance to be 0 when N is 1, so the peak value reached doesn't plummet to 3 quite to quickly. It can still drop to that though. There is a pull request dealing with simplifying attribute handling and part of it affects the code being changed here, but the bit of simplification included in this patch doesn't use it. --- src/attrib.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/attrib.c b/src/attrib.c index a3812d54b..7b68e5401 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 attrib.c $NHDT-Date: 1494034337 2017/05/06 01:32:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.62 $ */ +/* NetHack 3.6 attrib.c $NHDT-Date: 1547086687 2019/01/10 02:18:07 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.64 $ */ /* Copyright 1988, 1989, 1990, 1992, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ @@ -115,7 +115,7 @@ adjattrib(ndx, incr, msgflg) int ndx, incr; int msgflg; /* positive => no message, zero => message, and */ { /* negative => conditional (msg if change made) */ - int old_acurr, old_abase; + int old_acurr, old_abase, old_amax, decr; boolean abonflg; const char *attrstr; @@ -130,23 +130,38 @@ int msgflg; /* positive => no message, zero => message, and */ old_acurr = ACURR(ndx); old_abase = ABASE(ndx); + old_amax = AMAX(ndx); + ABASE(ndx) += incr; /* when incr is negative, this reduces ABASE() */ if (incr > 0) { - ABASE(ndx) += incr; if (ABASE(ndx) > AMAX(ndx)) { - incr = ABASE(ndx) - AMAX(ndx); - AMAX(ndx) += incr; + AMAX(ndx) = ABASE(ndx); if (AMAX(ndx) > ATTRMAX(ndx)) - AMAX(ndx) = ATTRMAX(ndx); - ABASE(ndx) = AMAX(ndx); + ABASE(ndx) = AMAX(ndx) = ATTRMAX(ndx); } attrstr = plusattr[ndx]; abonflg = (ABON(ndx) < 0); - } else { - ABASE(ndx) += incr; + } else { /* incr is negative */ if (ABASE(ndx) < ATTRMIN(ndx)) { - incr = ABASE(ndx) - ATTRMIN(ndx); + /* + * If base value has dropped so low that it is trying to be + * taken below the minimum, reduce max value (peak reached) + * instead. That means that restore ability and repeated + * applications of unicorn horn will not be able to recover + * all the lost value. Starting will 3.6.2, we only take away + * some (average half, possibly zero) of the excess from max + * instead of all of it, but without intervening recovery, it + * can still eventually drop to the minimum allowed. After + * that, it can't be recovered, only improved with new gains. + * + * This used to assign a new negative value to incr and then + * add it, but that could affect messages below, possibly + * making a large decrease be described as a small one. + * + * decr = rn2(-(ABASE - ATTRMIN) + 1); + */ + decr = rn2(ATTRMIN(ndx) - ABASE(ndx) + 1); ABASE(ndx) = ATTRMIN(ndx); - AMAX(ndx) += incr; + AMAX(ndx) -= decr; if (AMAX(ndx) < ATTRMIN(ndx)) AMAX(ndx) = ATTRMIN(ndx); } @@ -155,12 +170,15 @@ int msgflg; /* positive => no message, zero => message, and */ } if (ACURR(ndx) == old_acurr) { if (msgflg == 0 && flags.verbose) { - if (ABASE(ndx) == old_abase) + if (ABASE(ndx) == old_abase && AMAX(ndx) == old_amax) { pline("You're %s as %s as you can get.", abonflg ? "currently" : "already", attrstr); - else /* current stayed the same but base value changed */ + } else { + /* current stayed the same but base value changed, or + base is at minimum and reduction caused max to drop */ Your("innate %s has %s.", attrname[ndx], (incr > 0) ? "improved" : "declined"); + } } return FALSE; } @@ -582,7 +600,7 @@ exerchk() (mod_val > 0) ? "must have been" : "haven't been", exertext[i][(mod_val > 0) ? 0 : 1]); } - nextattrib: + nextattrib: /* this used to be ``AEXE(i) /= 2'' but that would produce platform-dependent rounding/truncation for negative vals */ AEXE(i) = (abs(ax) / 2) * mod_val; From b1782b813f418f13823efc2ae61a4b75df8254cb Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 10 Jan 2019 03:10:35 -0800 Subject: [PATCH 4/4] SEDUCE=0 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. --- doc/fixes36.2 | 4 +++- src/mhitm.c | 10 +++++----- src/mhitu.c | 49 ++++++++++++++++++++++++++++++++++--------------- src/monst.c | 6 +++--- src/sys.c | 13 ++++++++++--- src/uhitm.c | 8 ++++---- 6 files changed, 59 insertions(+), 31 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 92c65117b..2fd1d5594 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -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 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 be known even though knowing and casting a spell should be (and is 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 diff --git a/src/mhitm.c b/src/mhitm.c index 774e9a56e..30a569283 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -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) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -915,7 +915,7 @@ register struct attack *mattk; case AD_WERE: case AD_HEAL: case AD_PHYS: - physical: + physical: if (mattk->aatyp == AT_KICK && thick_skinned(pd)) { tmp = 0; } else if (mattk->aatyp == AT_WEAP) { @@ -1075,7 +1075,7 @@ register struct attack *mattk; case AD_STON: if (magr->mcan) break; - do_stone: + do_stone: /* may die from the acid if it eats a stone-curing corpse */ if (munstone(mdef, FALSE)) goto post_stone; @@ -1088,7 +1088,7 @@ register struct attack *mattk; if (vis && canseemon(mdef)) pline("%s turns to stone!", Monnam(mdef)); monstone(mdef); - post_stone: + post_stone: if (!DEADMONSTER(mdef)) return 0; else if (mdef->mtame && !vis) @@ -1661,7 +1661,7 @@ int mdead; else tmp = 0; -assess_dmg: + assess_dmg: if ((magr->mhp -= tmp) <= 0) { monkilled(magr, "", (int) mddat->mattk[i].adtyp); return (mdead | mhit | MM_AGR_DIED); diff --git a/src/mhitu.c b/src/mhitu.c index 67966db5f..a981aba5f 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -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) Robert Patrick Rankin, 2012. */ /* 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 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 from hitting with both of them on the same turn; if the first has already hit, switch to a stun attack for the second */ @@ -1115,7 +1132,7 @@ register struct attack *mattk; goto dopois; case AD_DRCO: ptmp = A_CON; - dopois: + dopois: hitmsg(mtmp, mattk); if (uncancelled && !rn2(8)) { 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))); if (!rn2(10) || (flags.moonphase == NEW_MOON && !have_lizard())) { - do_stone: + do_stone: if (!Stoned && !Stone_resistance && !(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) { @@ -1326,7 +1343,10 @@ register struct attack *mattk; break; /* Continue below */ } 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), Deaf ? "says something but you can't hear it" : mtmp->minvent @@ -2019,7 +2039,7 @@ boolean ufound; static analysis complains that 'physical_damage' is always False when tested below; it's right, but having that in place means one less thing to update if AD_PHYS gets added */ - common: + common: if (!not_affected) { if (ACURR(A_DEX) > rnd(20)) { @@ -2328,6 +2348,7 @@ struct attack *mattk; struct permonst *pagr; boolean agrinvis, defperc; xchar genagr, gendef; + int adtyp = mattk ? mattk->adtyp : AD_PHYS; if (is_animal(magr->data)) return 0; @@ -2347,20 +2368,18 @@ struct attack *mattk; defperc = perceives(mdef->data); gendef = gender(mdef); } + if (adtyp == AD_SSEX && !SYSOPT_SEDUCE) + adtyp = AD_SEDU; - if (agrinvis && !defperc - && (!SYSOPT_SEDUCE || (mattk && mattk->adtyp != AD_SSEX))) + if (agrinvis && !defperc && adtyp == AD_SEDU) return 0; - if (pagr->mlet != S_NYMPH - && ((pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS]) - || (SYSOPT_SEDUCE && mattk && mattk->adtyp != AD_SSEX))) + if ((pagr->mlet != S_NYMPH + && pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS]) + || (adtyp != AD_SEDU && adtyp != AD_SSEX)) return 0; - if (genagr == 1 - gendef) - return 1; - else - return (pagr->mlet == S_NYMPH) ? 2 : 0; + return (genagr == 1 - gendef) ? 1 : (pagr->mlet == S_NYMPH) ? 2 : 0; } /* returns 1 if monster teleported (or hero leaves monster's vicinity) */ @@ -2888,7 +2907,7 @@ struct attack *mattk; else tmp = 0; -assess_dmg: + assess_dmg: if ((mtmp->mhp -= tmp) <= 0) { pline("%s dies!", Monnam(mtmp)); xkilled(mtmp, XKILL_NOMSG); diff --git a/src/monst.c b/src/monst.c index c513f73b4..6b8a5f76e 100644 --- a/src/monst.c +++ b/src/monst.c @@ -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) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3235,8 +3235,8 @@ monst_init() return; } -struct attack sa_yes[NATTK] = SEDUCTION_ATTACKS_YES; -struct attack sa_no[NATTK] = SEDUCTION_ATTACKS_NO; +const struct attack sa_yes[NATTK] = SEDUCTION_ATTACKS_YES; +const struct attack sa_no[NATTK] = SEDUCTION_ATTACKS_NO; #endif /*monst.c*/ diff --git a/src/sys.c b/src/sys.c index 6adc8f71f..1ff73d57a 100644 --- a/src/sys.c +++ b/src/sys.c @@ -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. */ /* NetHack may be freely redistributed. See license for details. */ @@ -120,13 +120,17 @@ sysopt_release() return; } -extern struct attack sa_yes[NATTK]; -extern struct attack sa_no[NATTK]; +extern const struct attack sa_yes[NATTK]; +extern const struct attack sa_no[NATTK]; void sysopt_seduce_set(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; int x; @@ -134,6 +138,9 @@ int val; mons[PM_INCUBUS].mattk[x] = setval[x]; mons[PM_SUCCUBUS].mattk[x] = setval[x]; } +#else + nhUse(val); +#endif /*0*/ return; } diff --git a/src/uhitm.c b/src/uhitm.c index fa50677dc..e0b8b5e99 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -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) Robert Patrick Rankin, 2012. */ /* 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_HEAL: /* likewise */ case AD_PHYS: - physical: + physical: if (mattk->aatyp == AT_WEAP) { if (uwep) tmp = 0; @@ -1990,7 +1990,7 @@ register struct attack *mattk; goto common; case AD_ELEC: resistance = resists_elec(mdef); - common: + common: if (!resistance) { pline("%s gets blasted!", Monnam(mdef)); mdef->mhp -= tmp; @@ -2289,7 +2289,7 @@ register struct monst *mon; weapon = 0; switch (mattk->aatyp) { case AT_WEAP: - use_weapon: + use_weapon: /* Certain monsters don't use weapons when encountered as enemies, * but players who polymorph into them have hands or claws and * thus should be able to use weapons. This shouldn't prohibit