Skip to content

Commit

Permalink
Add the Amulet of Storms artifact
Browse files Browse the repository at this point in the history
Note by copperwater: Intent of this is to continue expanding a few pools
of artifacts:
    - non-weapon non-quest artifacts
    - chaotic artifacts
    - less powerful artifacts

while still being useful enough to appreciate when given as a sacrifice
gift.

From the original patch, I adjusted the price down (it's not powerful
enough to be worth 2000 base price) and refactored is_stormy_monster for
clarity. I also gave it an additional side effect of blocking lightning
paralysis (but not damage) on the Plane of Air; seems reasonable that
it'd have this protective effect as well.
  • Loading branch information
Nephi Allred authored and copperwater committed Jun 14, 2024
1 parent 3088aab commit 37b10da
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 2 deletions.
4 changes: 4 additions & 0 deletions doc/xnh-changelog-9.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ 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. It also prevents you from being
paralyzed by lightning on the Plane of Air.

### Interface changes

Expand Down
5 changes: 5 additions & 0 deletions include/artilist.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
4 changes: 3 additions & 1 deletion src/objnam.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);

Expand Down
41 changes: 41 additions & 0 deletions src/sounds.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -1490,6 +1497,12 @@ dochat(void)
return ECMD_OK;
}

if (uamul && uamul->oartifact == ART_AMULET_OF_STORMS
&& !mtmp->mpeaceful && 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;

Expand All @@ -1513,6 +1526,34 @@ 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)
{
pline("%s recognizes your amulet.", Monnam(mtmp));
You("manage to calm %s.",
genders[pronoun_gender(mtmp, PRONOUN_HALLU)].him);
mtmp->mpeaceful = 1;
newsym(mtmp->mx, mtmp->my);
}

/* is there a monster at <x,y> that can see the hero and react? */
static struct monst *
responsive_mon_at(int x, int y)
Expand Down
3 changes: 2 additions & 1 deletion src/timeout.c
Original file line number Diff line number Diff line change
Expand Up @@ -1829,7 +1829,8 @@ do_storms(void)
pline("Kaboom!!! Boom!! Boom!!");
incr_itimeout(&HDeaf, rn1(20, 30));
gc.context.botl = TRUE;
if (!u.uinvulnerable) {
if (!u.uinvulnerable
|| !(uamul && uamul->oartifact == ART_AMULET_OF_STORMS)) {
stop_occupation();
nomul(-3);
gm.multi_reason = "hiding from thunderstorm";
Expand Down

0 comments on commit 37b10da

Please sign in to comment.