diff --git a/doc/xnh-changelog-9.0.md b/doc/xnh-changelog-9.0.md index 4687e3c41..176c1f004 100644 --- a/doc/xnh-changelog-9.0.md +++ b/doc/xnh-changelog-9.0.md @@ -40,6 +40,9 @@ changes: monsters. - Monsters stepping on a squeaky board near you can wake you up. - Leprechauns have a one-sided grudge against gold golems and gold dragons. +- New artifact The Amulet of Storms: a chaotic amulet of flying that grants + shock resistance when worn and allows you to chat to hostile vortices, air + elementals, and storm giants to pacify them. ### Interface changes diff --git a/include/artilist.h b/include/artilist.h index e943586f3..5fd4b5647 100644 --- a/include/artilist.h +++ b/include/artilist.h @@ -189,6 +189,11 @@ static NEARDATA struct artifact artilist[] = { NO_CARY, CONFLICT, A_CHAOTIC, NON_PM, NON_PM, 4000L, NO_COLOR, GOLD, APPLE_OF_DISCORD), + A("The Amulet of Storms", AMULET_OF_FLYING, + (SPFX_RESTR | SPFX_DEFN), 0, 0, + NO_ATTK, DFNS(AD_ELEC), NO_CARY, 0, A_CHAOTIC, NON_PM, + NON_PM, 600L, NO_COLOR, DEFAULT_MAT, AMULET_OF_STORMS), + /* * The artifacts for the quest dungeon, all self-willed. */ diff --git a/src/objnam.c b/src/objnam.c index 2d32c6f93..3b2e2a73b 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -4472,7 +4472,9 @@ readobjnam_postparse1(struct _readobjnam_data *d) && strncmpi(d->bp, "light armor", 11) && strncmpi(d->bp, "tooled horn", 11) && strncmpi(d->bp, "food ration", 11) - && strncmpi(d->bp, "meat ring", 9)) + && strncmpi(d->bp, "meat ring", 9) + && strncmpi(d->bp, "amulet of storms", 16) + ) for (i = 0; i < (int) (sizeof wrpsym); i++) { register int j = Strlen(wrp[i]); diff --git a/src/sounds.c b/src/sounds.c index 3612437c2..53e2c23b4 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -12,6 +12,8 @@ static boolean temple_priest_sound(struct monst *); static boolean mon_is_gecko(struct monst *); static int domonnoise(struct monst *); static int dochat(void); +static boolean is_stormy_monster(struct monst *); +static void pacify_with_words(struct monst *); static struct monst *responsive_mon_at(int, int); static int mon_in_room(struct monst *, int); @@ -1353,6 +1355,11 @@ dochat(void) return ECMD_OK; } if (u.uswallow) { + if (uamul && uamul->oartifact == ART_AMULET_OF_STORMS + && is_stormy_monster(u.ustuck)) { + pacify_with_words(u.ustuck); + return ECMD_OK; + } pline("They won't hear you out there."); return ECMD_OK; } @@ -1490,6 +1497,12 @@ dochat(void) return ECMD_OK; } + if (uamul && uamul->oartifact == ART_AMULET_OF_STORMS + && is_stormy_monster(mtmp)) { + pacify_with_words(mtmp); + return ECMD_OK; + } + /* if this monster is waiting for something, prod it into action */ mtmp->mstrategy &= ~STRAT_WAITMASK; @@ -1513,6 +1526,32 @@ dochat(void) return domonnoise(mtmp); } +/* is mtmp a storm-like monster pacifiable by the Amulet of Storms? */ +static boolean +is_stormy_monster(struct monst *mtmp) +{ + /* already peaceful */ + if (mtmp->mpeaceful) + return FALSE; + + /* not a "true" stormy monster (but shapeshifters currently turned into one + * are okay) */ + if (mtmp->iswiz || is_vampshifter(mtmp)) + return FALSE; + + return (mtmp->data->mlet == S_VORTEX + || mtmp->data == &mons[PM_AIR_ELEMENTAL] + || mtmp->data == &mons[PM_STORM_GIANT]); +} + +static void +pacify_with_words(struct monst *mtmp) +{ + Your("words calm %s.", mon_nam(mtmp)); + mtmp->mpeaceful = 1; + newsym(mtmp->mx, mtmp->my); +} + /* is there a monster at that can see the hero and react? */ static struct monst * responsive_mon_at(int x, int y)