From 8d32f375888c66ebec517330b633917dde4bd2f1 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 17 Oct 2016 17:31:00 +0100 Subject: [PATCH 1/6] Make the Elbereth restrictions more flavour-consistent Elbereth now has to be on a square by itself; it's hard to justify why text before it would prevent it working if text after it fails to prevent it working. --- src/engrave.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/engrave.c b/src/engrave.c index 0c2670af2..04921ca2a 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -257,8 +257,7 @@ xchar x, y; * Ignore headstones, in case the player names herself "Elbereth". * * If strict checking is requested, the word is only considered to be - * present if it is intact and is the first word in the engraving. - * ("Elbereth burrito" matches; "o Elbereth" does not.) + * present if it is intact and is the entire content of the engraving. */ int sengr_at(s, x, y, strict) @@ -269,7 +268,7 @@ boolean strict; register struct engr *ep = engr_at(x, y); if (ep && ep->engr_type != HEADSTONE && ep->engr_time <= moves) { - return strict ? (strncmpi(ep->engr_txt, s, strlen(s)) == 0) + return strict ? (fuzzymatch(ep->engr_txt, s, "", TRUE)) : (strstri(ep->engr_txt, s) != 0); } return FALSE; From 5c12362a98f458d75a372dc7bc658598b8dca76b Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 17 Oct 2016 17:34:08 +0100 Subject: [PATCH 2/6] Fix engrave.c; I used the wrong commit command --- src/engrave.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engrave.c b/src/engrave.c index 04921ca2a..faa813351 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -271,6 +271,7 @@ boolean strict; return strict ? (fuzzymatch(ep->engr_txt, s, "", TRUE)) : (strstri(ep->engr_txt, s) != 0); } + return FALSE; } From ee5b4885148d08d390b075a2a11cd4fe8cdcb131 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 17 Oct 2016 18:15:57 +0100 Subject: [PATCH 3/6] Differentiate between monster anger from attacks and from other causes setmangry() and wakeup() were being used for multiple purposes. Add an extra parameter to track which. This fixes several minor bugs (e.g. whether monsters with no eyes were angered by (useless) gaze attacks against them previously depended on the state of a UI option, and the Minetown guards would be annoyed if you used a cursed scroll of tame monster on a shopkeeper). It's also a prerequisite for the Elbereth changes I'm working on. --- include/extern.h | 4 ++-- src/apply.c | 4 ++-- src/dig.c | 2 +- src/dokick.c | 6 +++--- src/dothrow.c | 12 +++++++----- src/explode.c | 2 +- src/mon.c | 18 ++++++++++++++---- src/music.c | 2 +- src/polyself.c | 2 +- src/potion.c | 2 +- src/priest.c | 3 ++- src/read.c | 2 +- src/region.c | 2 +- src/trap.c | 4 ++-- src/uhitm.c | 24 ++++++++++++------------ src/vault.c | 2 +- src/zap.c | 9 +++------ 17 files changed, 55 insertions(+), 45 deletions(-) diff --git a/include/extern.h b/include/extern.h index 0129b888f..300af5e06 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1355,8 +1355,8 @@ E void FDECL(mnexto, (struct monst *)); E void FDECL(maybe_mnexto, (struct monst *)); E boolean FDECL(mnearto, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P)); E void FDECL(m_respond, (struct monst *)); -E void FDECL(setmangry, (struct monst *)); -E void FDECL(wakeup, (struct monst *)); +E void FDECL(setmangry, (struct monst *, boolean)); +E void FDECL(wakeup, (struct monst *, boolean)); E void NDECL(wake_nearby); E void FDECL(wake_nearto, (int, int, int)); E void FDECL(seemimic, (struct monst *)); diff --git a/src/apply.c b/src/apply.c index 8d64620a8..2e1fb0cf1 100644 --- a/src/apply.c +++ b/src/apply.c @@ -2695,7 +2695,7 @@ struct obj *obj; pline1(msg_slipsfree); } if (mtmp) - wakeup(mtmp); + wakeup(mtmp, TRUE); } else pline1(msg_snap); @@ -2789,7 +2789,7 @@ struct obj *obj; } else { pline1(msg_slipsfree); } - wakeup(mtmp); + wakeup(mtmp, TRUE); } else { if (mtmp->m_ap_type && !Protection_from_shape_changers && !sensemon(mtmp)) diff --git a/src/dig.c b/src/dig.c index 5f45e117e..4407c4c15 100644 --- a/src/dig.c +++ b/src/dig.c @@ -2008,7 +2008,7 @@ struct monst *mtmp; } mtmp->mburied = TRUE; - wakeup(mtmp); /* at least give it a chance :-) */ + wakeup(mtmp, FALSE); /* at least give it a chance :-) */ newsym(mtmp->mx, mtmp->my); } diff --git a/src/dokick.c b/src/dokick.c index f1e0dcddf..2cb485472 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -156,7 +156,7 @@ xchar x, y; int i, j; /* anger target even if wild miss will occur */ - setmangry(mon); + setmangry(mon, TRUE); if (Levitation && !rn2(3) && verysmall(mon->data) && !is_flyer(mon->data)) { @@ -298,7 +298,7 @@ register struct obj *gold; if (!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest && !mtmp->isgd && !is_mercenary(mtmp->data)) { - wakeup(mtmp); + wakeup(mtmp, TRUE); } else if (!mtmp->mcanmove) { /* too light to do real damage */ if (canseemon(mtmp)) { @@ -312,7 +312,7 @@ register struct obj *gold; mtmp->msleeping = 0; finish_meating(mtmp); if (!mtmp->isgd && !rn2(4)) /* not always pleasing */ - setmangry(mtmp); + setmangry(mtmp, TRUE); /* greedy monsters catch gold */ if (cansee(mtmp->mx, mtmp->my)) pline("%s catches the gold.", Monnam(mtmp)); diff --git a/src/dothrow.c b/src/dothrow.c index 70496ef7a..98d41de9e 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -608,7 +608,8 @@ int x, y; if ((mon = m_at(x, y)) != 0) { You("bump into %s.", a_monnam(mon)); - wakeup(mon); + wakeup(mon, FALSE); + setmangry(mon, FALSE); wake_nearto(x,y, 10); return FALSE; } @@ -1346,7 +1347,7 @@ boolean maybe_wakeup; else miss(missile, mon); if (maybe_wakeup && !rn2(3)) - wakeup(mon); + wakeup(mon, TRUE); return; } @@ -1448,7 +1449,8 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */ at leader... (kicked artifact is ok too; HMON_APPLIED could occur if quest artifact polearm or grapnel ever gets added) */ if (hmode != HMON_APPLIED && quest_arti_hits_leader(obj, mon)) { - /* not wakeup(), which angers non-tame monsters */ + /* AIS: changes to wakeup() means that it's now less inappropriate here + than it used to be, but the manual version works just as well */ mon->msleeping = 0; mon->mstrategy &= ~STRAT_WAITMASK; @@ -1562,7 +1564,7 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */ } else { tmiss(obj, mon, TRUE); if (hmode == HMON_APPLIED) - wakeup(mon); + wakeup(mon, TRUE); } } else if (otyp == HEAVY_IRON_BALL) { @@ -1610,7 +1612,7 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */ } } else if (guaranteed_hit) { /* this assumes that guaranteed_hit is due to swallowing */ - wakeup(mon); + wakeup(mon, TRUE); if (obj->otyp == CORPSE && touch_petrifies(&mons[obj->corpsenm])) { if (is_animal(u.ustuck->data)) { minstapetrify(u.ustuck, TRUE); diff --git a/src/explode.c b/src/explode.c index e6f85866b..e26e58d8a 100644 --- a/src/explode.c +++ b/src/explode.c @@ -433,7 +433,7 @@ int expltype; monkilled(mtmp, "", (int) adtyp); } else if (!context.mon_moving) { /* all affected monsters, even if mdef is set */ - setmangry(mtmp); + setmangry(mtmp, TRUE); } } diff --git a/src/mon.c b/src/mon.c index e31ecb27b..d0586b200 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2583,10 +2583,18 @@ struct monst *mtmp; } } +/* Called whenever the player attacks mtmp; also called in other situations + where mtmp gets annoyed at the player. Handles mtmp getting annoyed at the + attack and any ramifications that might have. Useful also in situations where + mtmp was already hostile; it checks for situations where the player shouldn't + be attacking and any ramifications /that/ might have. */ void -setmangry(mtmp) +setmangry(mtmp, via_attack) struct monst *mtmp; +boolean via_attack; { + (void) via_attack; /* AIS: not used yet */ + /* AIS: Should this be in both places, or just in wakeup()? */ mtmp->mstrategy &= ~STRAT_WAITMASK; if (!mtmp->mpeaceful) return; @@ -2681,14 +2689,16 @@ struct monst *mtmp; } -/* wake up a monster, usually making it angry in the process */ +/* wake up a monster, possibly making it angry in the process */ void -wakeup(mtmp) +wakeup(mtmp, via_attack) register struct monst *mtmp; +boolean via_attack; { mtmp->msleeping = 0; finish_meating(mtmp); - setmangry(mtmp); + if (via_attack) + setmangry(mtmp, TRUE); if (mtmp->m_ap_type) { seemimic(mtmp); } else if (context.forcefight && !context.mon_moving diff --git a/src/music.c b/src/music.c index 58cc4b0f0..75ab39d4d 100644 --- a/src/music.c +++ b/src/music.c @@ -263,7 +263,7 @@ int force; for (x = start_x; x <= end_x; x++) for (y = start_y; y <= end_y; y++) { if ((mtmp = m_at(x, y)) != 0) { - wakeup(mtmp); /* peaceful monster will become hostile */ + wakeup(mtmp, TRUE); /* peaceful monster will become hostile */ if (mtmp->mundetected && is_hider(mtmp->data)) { mtmp->mundetected = 0; if (cansee(x, y)) diff --git a/src/polyself.c b/src/polyself.c index 71f9ce8ba..869a37a07 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1310,8 +1310,8 @@ dogaze() mon_nam(mtmp)); if (yn(qbuf) != 'y') continue; - setmangry(mtmp); } + setmangry(mtmp, TRUE); if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleeping || !mtmp->mcansee || !haseyes(mtmp->data)) { looked--; diff --git a/src/potion.c b/src/potion.c index b5971dd79..38f5c6553 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1488,7 +1488,7 @@ boolean your_fault; /* target might have been killed */ if (mon->mhp > 0) { if (angermon) - wakeup(mon); + wakeup(mon, TRUE); else mon->msleeping = 0; } diff --git a/src/priest.c b/src/priest.c index ec76c91bb..0cce5cf36 100644 --- a/src/priest.c +++ b/src/priest.c @@ -795,7 +795,8 @@ angry_priest() if ((priest = findpriest(temple_occupied(u.urooms))) != 0) { struct epri *eprip = EPRI(priest); - wakeup(priest); + wakeup(priest, FALSE); + setmangry(priest, FALSE); /* * If the altar has been destroyed or converted, let the * priest run loose. diff --git a/src/read.c b/src/read.c index 12e3cc002..efc36e3cb 100644 --- a/src/read.c +++ b/src/read.c @@ -901,7 +901,7 @@ struct obj *sobj; unsigned was_peaceful = mtmp->mpeaceful; if (sobj->cursed) { - setmangry(mtmp); + setmangry(mtmp, FALSE); if (was_peaceful && !mtmp->mpeaceful) return -1; } else { diff --git a/src/region.c b/src/region.c index 240f7270c..3ab0317b2 100644 --- a/src/region.c +++ b/src/region.c @@ -974,7 +974,7 @@ genericptr_t p2; if (cansee(mtmp->mx, mtmp->my)) pline("%s coughs!", Monnam(mtmp)); if (heros_fault(reg)) - setmangry(mtmp); + setmangry(mtmp, TRUE); if (haseyes(mtmp->data) && mtmp->mcansee) { mtmp->mblinded = 1; mtmp->mcansee = 0; diff --git a/src/trap.c b/src/trap.c index 9e5b2f500..23e26dec3 100644 --- a/src/trap.c +++ b/src/trap.c @@ -2119,7 +2119,7 @@ register struct monst *mtmp; Recognizing who made the trap isn't completely unreasonable; everybody has their own style. */ if (trap->madeby_u && rnl(5)) - setmangry(mtmp); + setmangry(mtmp, TRUE); in_sight = canseemon(mtmp); see_it = cansee(mtmp->mx, mtmp->my); @@ -4541,7 +4541,7 @@ boolean *noticed; /* set to true iff hero notices the effect; */ or if you sense the monster who becomes trapped */ *noticed = cansee(t->tx, t->ty) || canspotmon(mon); /* monster will be angered; mintrap doesn't handle that */ - wakeup(mon); + wakeup(mon, TRUE); ++force_mintrap; result = (mintrap(mon) != 0); --force_mintrap; diff --git a/src/uhitm.c b/src/uhitm.c index 832390694..a4a31cde0 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -145,7 +145,7 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */ if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK)) u.ustuck = mtmp; } - wakeup(mtmp); /* always necessary; also un-mimics mimics */ + wakeup(mtmp, TRUE); /* always necessary; also un-mimics mimics */ return TRUE; } @@ -190,7 +190,7 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */ */ if ((mtmp->mundetected || mtmp->m_ap_type) && sensemon(mtmp)) { mtmp->mundetected = 0; - wakeup(mtmp); + wakeup(mtmp, TRUE); } if (flags.confirm && mtmp->mpeaceful && !Confusion && !Hallucination @@ -573,7 +573,7 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */ unconventional[0] = '\0'; saved_oname[0] = '\0'; - wakeup(mon); + wakeup(mon, TRUE); if (!obj) { /* attack with bare hands */ if (mdat == &mons[PM_SHADE]) tmp = 0; @@ -894,7 +894,7 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */ pline("%s %s over %s!", what, vtense(what, "splash"), whom); } - setmangry(mon); + setmangry(mon, TRUE); mon->mcansee = 0; tmp = rn1(25, 21); if (((int) mon->mblinded + tmp) > 127) @@ -903,7 +903,7 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */ mon->mblinded += tmp; } else { pline(obj->otyp == CREAM_PIE ? "Splat!" : "Splash!"); - setmangry(mon); + setmangry(mon, TRUE); } if (thrown) obfree(obj, (struct obj *) 0); @@ -2097,7 +2097,7 @@ boolean wouldhavehit; else You("miss it."); if (!mdef->msleeping && mdef->mcanmove) - wakeup(mdef); + wakeup(mdef, TRUE); } /* attack monster as a monster. */ @@ -2178,7 +2178,7 @@ register struct monst *mon; sum[i] = damageum(mon, mattk); break; } - wakeup(mon); + wakeup(mon, TRUE); /* maybe this check should be in damageum()? */ if (mon->data == &mons[PM_SHADE] && !(mattk->aatyp == AT_KICK && uarmf @@ -2212,7 +2212,7 @@ register struct monst *mon; * already grabbed in a previous attack */ dhit = 1; - wakeup(mon); + wakeup(mon, TRUE); if (mon->data == &mons[PM_SHADE]) Your("hug passes harmlessly through %s.", mon_nam(mon)); else if (!sticks(mon->data) && !u.uswallow) { @@ -2230,7 +2230,7 @@ register struct monst *mon; case AT_EXPL: /* automatic hit if next to */ dhit = -1; - wakeup(mon); + wakeup(mon, TRUE); sum[i] = explum(mon, mattk); break; @@ -2238,7 +2238,7 @@ register struct monst *mon; tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0, &attknum, &armorpenalty); if ((dhit = (tmp > rnd(20 + i)))) { - wakeup(mon); + wakeup(mon, TRUE); if (mon->data == &mons[PM_SHADE]) Your("attempt to surround %s is harmless.", mon_nam(mon)); else { @@ -2637,7 +2637,7 @@ struct monst *mtmp; if (what) pline(fmt, what); - wakeup(mtmp); /* clears mimicking */ + wakeup(mtmp, FALSE); /* clears mimicking */ /* if hero is blind, wakeup() won't display the monster even though it's no longer concealed */ if (!canspotmon(mtmp) @@ -2695,7 +2695,7 @@ struct obj *otmp; /* source of flash */ } if (mtmp->mhp > 0) { if (!context.mon_moving) - setmangry(mtmp); + setmangry(mtmp, TRUE); if (tmp < 9 && !mtmp->isshk && rn2(4)) monflee(mtmp, rn2(4) ? rnd(100) : 0, FALSE, TRUE); mtmp->mcansee = 0; diff --git a/src/vault.c b/src/vault.c index 909cc3872..f076986f5 100644 --- a/src/vault.c +++ b/src/vault.c @@ -400,7 +400,7 @@ invault() } mongone(guard); } else { - setmangry(guard); + setmangry(guard, FALSE); if (Deaf) { if (!Blind) pline("%s mouths something and looks very angry!", diff --git a/src/zap.c b/src/zap.c index b2df5212f..9cf38e030 100644 --- a/src/zap.c +++ b/src/zap.c @@ -426,7 +426,7 @@ struct obj *otmp; } if (wake) { if (mtmp->mhp > 0) { - wakeup(mtmp); + wakeup(mtmp, TRUE); m_respond(mtmp); if (mtmp->isshk && !*u.ushops) hot_pursuit(mtmp); @@ -4535,12 +4535,9 @@ short exploding_wand_typ; You("%s of smoke.", !Blind ? "see a puff" : "smell a whiff"); } if ((mon = m_at(x, y)) != 0) { - /* Cannot use wakeup() which also angers the monster */ - mon->msleeping = 0; - if (mon->m_ap_type) - seemimic(mon); + wakeup(mon, FALSE); if (type >= 0) { - setmangry(mon); + setmangry(mon, TRUE); if (mon->ispriest && *in_rooms(mon->mx, mon->my, TEMPLE)) ghod_hitsu(mon); if (mon->isshk && !*u.ushops) From 348e54aa32683728304fbd8b2b9e4e78b502c1fc Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 17 Oct 2016 18:26:44 +0100 Subject: [PATCH 4/6] Change the rules for Elbereth erosion If you attack a monster under Elbereth protection, and it wasn't scuffed by the attack itself, then it'll be automatically removed with an alignment penalty. It no longer fades from scaring monsters; only from being abused to attack monsters while protected. --- src/mon.c | 16 +++++++++++++++- src/monmove.c | 6 ------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/mon.c b/src/mon.c index d0586b200..3a70ba3f8 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2593,7 +2593,21 @@ setmangry(mtmp, via_attack) struct monst *mtmp; boolean via_attack; { - (void) via_attack; /* AIS: not used yet */ + if (via_attack && sengr_at("Elbereth", u.ux, u.uy, TRUE)) { + You_feel("like a hypocrite."); + /* AIS: Yes, I know alignment penalties and bonuses aren't balanced at + the moment. This is about correct relative to other "small" + penalties; it should be fairly large, as attacking while standing on + an Elbereth means that you're requesting peace and then violating + your own request. I know 5 isn't actually large, but it's + intentionally larger than the 1s and 2s that are normally given for + this sort of thing. */ + adjalign(-5); + if (!Blind) + pline("The engraving beneath you fades."); + del_engr_at(u.ux, u.uy); + } + /* AIS: Should this be in both places, or just in wakeup()? */ mtmp->mstrategy &= ~STRAT_WAITMASK; if (!mtmp->mpeaceful) diff --git a/src/monmove.c b/src/monmove.c index c032db504..0b60d0c15 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -320,12 +320,6 @@ int *inrange, *nearby, *scared; || (!mtmp->mpeaceful && in_your_sanctuary(mtmp, 0, 0)))) { *scared = 1; monflee(mtmp, rnd(rn2(7) ? 10 : 100), TRUE, TRUE); - - /* magical protection won't last forever, so there'll be a - * chance of the magic being used up regardless of type */ - if (sawscary) { - wipe_engr_at(seescaryx, seescaryy, 1, TRUE); - } } else *scared = 0; } From d01c0364f1b80b2c7641b8e620e836e64497e710 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 17 Oct 2016 18:29:09 +0100 Subject: [PATCH 5/6] Ugh, why does NH3's commit process have to differ from NH4's? --- src/mon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mon.c b/src/mon.c index 3a70ba3f8..35966e381 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2603,6 +2603,7 @@ boolean via_attack; intentionally larger than the 1s and 2s that are normally given for this sort of thing. */ adjalign(-5); + if (!Blind) pline("The engraving beneath you fades."); del_engr_at(u.ux, u.uy); From 9c5cfc4153897fb06053daaa8a58ef186ac8b145 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Tue, 18 Oct 2016 16:52:21 +0100 Subject: [PATCH 6/6] Changelog for the Elbereth changes --- doc/fixes36.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index b997f6994..d57a14962 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -352,6 +352,8 @@ sometimes generate the random mazes with wide corridors, thick walls, or with dead ends changed to loops put throne room gold in the chest wielding Trollsbane prevents trolls from reviving +Elbereth must now be on a square by itself to function +Elbereth now erodes based on attacks by the player, not monsters scared Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository