Skip to content

Commit

Permalink
Overhauled the fear/afraid system; new fearless property for weapons …
Browse files Browse the repository at this point in the history
…and armor.

I've been a bit unhappy with how the fear stuff has been handled, it was very clumsy and inconsistent. So I cleaned it up and gave it an official attribute called Fearless. This attribute is now de-coupled from the Psychic_resistance attribute. Before, illithids would start the game with both psychic and full fear resistance!

I gave the necromancer intrinsic fear resistance from level 1 - feels like the right role for it. I also removed the undead slayer from any fearless parts, they will have to find their own sources of bravery.

Pridwin grants full fearlessness when worn and Dragonbane will protect you from - and cure - the frightful roars of Dragons, but only dragons. I decided to leave the tinfoil hat as is, so it still grants psychic and fearless - but it blocks ESP and clairvoyance, a tradeoff the player will need to contend with.

I also added another party trick to the magic trap that can cause a very short period of fright.

The new bravery property should also come in handy. Weapons and armor with this property will prevent fear, and can be worn or wielded to cure the afraid status.
  • Loading branch information
elunna committed Sep 30, 2023
1 parent 4696421 commit 4ee3405
Show file tree
Hide file tree
Showing 18 changed files with 207 additions and 95 deletions.
1 change: 1 addition & 0 deletions include/extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ E void NDECL(mkot_trap_warn);
E boolean FDECL(is_magic_key, (struct monst *, struct obj *));
E struct obj *FDECL(has_magic_key, (struct monst *));
E boolean FDECL(wielding_artifact, (int));
E boolean FDECL(wearing_artifact, (int));
E boolean NDECL(awaiting_guaranteed_gift);
E int FDECL(arti_align, (int));
E boolean FDECL(non_wishable_artifact, (struct obj *));
Expand Down
7 changes: 4 additions & 3 deletions include/obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -613,11 +613,12 @@ struct obj {
#define ITEM_STABLE 0x01000000L /* extrinsic clobber resistance */
#define ITEM_WWALK 0x02000000L /* extrinsic water walking */
#define ITEM_SWIM 0x04000000L /* extrinsic swimming */
#define ITEM_BRAVE 0x08000000L /* extrinsic fear */

#define ITEM_MAGICAL 0x80000000L /* known to have magical properties */

#define ITEM_PROP_MASK 0x07FFFFFFL /* all current properties */
#define MAX_ITEM_PROPS 27
#define ITEM_PROP_MASK 0x0FFFFFFFL /* all current properties */
#define MAX_ITEM_PROPS 28

/* Properties that grant both a worn resistance and attack type */
#define ITEM_RES_PROPS (ITEM_FIRE | ITEM_FROST | ITEM_SHOCK | ITEM_VENOM \
Expand All @@ -628,7 +629,7 @@ struct obj {
#define ITEM_GOOD_PROPS (ITEM_OILSKIN | ITEM_ESP | ITEM_SEARCHING \
| ITEM_WARNING | ITEM_EXCEL | ITEM_SUSTAIN \
| ITEM_STEALTH | ITEM_SEEINV | ITEM_STABLE \
| ITEM_WWALK | ITEM_SWIM)
| ITEM_WWALK | ITEM_SWIM | ITEM_BRAVE)
/* Negative properties */
#define ITEM_BAD_PROPS (ITEM_FUMBLING | ITEM_HUNGER | ITEM_AGGRO \
| ITEM_TELE | ITEM_SLOW)
Expand Down
147 changes: 74 additions & 73 deletions include/prop.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,84 +23,85 @@ enum prop_types {
SONIC_RES = 9,
PSYCHIC_RES = 10,
/* note: for the first ten properties, MR_xxx == (1 << (xxx_RES - 1)) */
DRAIN_RES = 11,
SICK_RES = 12,
DEATH_RES = 13,
INVULNERABLE = 14,
ANTIMAGIC = 15,
FEARLESS = 11,
DRAIN_RES = 12,
SICK_RES = 13,
DEATH_RES = 14,
INVULNERABLE = 15,
ANTIMAGIC = 16,
/* Troubles */
STUNNED = 16,
STUN_RES = 17,
CONFUSION = 18,
AFRAID = 19,
BLINDED = 20,
DEAF = 21,
SICK = 22,
STONED = 23,
STRANGLED = 24,
VOMITING = 25,
GLIB = 26,
LARVACARRIER = 27,
SLIMED = 28,
HALLUC = 29,
HALLUC_RES = 30,
FUMBLING = 31,
WOUNDED_LEGS = 32,
SLEEPY = 33,
HUNGER = 34,
STUNNED = 17,
STUN_RES = 18,
CONFUSION = 19,
AFRAID = 20,
BLINDED = 21,
DEAF = 22,
SICK = 23,
STONED = 24,
STRANGLED = 25,
VOMITING = 26,
GLIB = 27,
LARVACARRIER = 28,
SLIMED = 29,
HALLUC = 30,
HALLUC_RES = 31,
FUMBLING = 32,
WOUNDED_LEGS = 33,
SLEEPY = 34,
HUNGER = 35,
/* Vision and senses */
SEE_INVIS = 35,
TELEPAT = 36,
WARNING = 37,
WARN_OF_MON = 38,
WARN_UNDEAD = 39,
SEARCHING = 40,
CLAIRVOYANT = 41,
INFRAVISION = 42,
DETECT_MONSTERS = 43,
FOOD_SENSE = 44,
XRAY_VISION = 45,
SEE_INVIS = 36,
TELEPAT = 37,
WARNING = 38,
WARN_OF_MON = 39,
WARN_UNDEAD = 40,
SEARCHING = 41,
CLAIRVOYANT = 42,
INFRAVISION = 43,
DETECT_MONSTERS = 44,
FOOD_SENSE = 45,
XRAY_VISION = 46,
/* Appearance and behavior */
ADORNED = 46,
INVIS = 47,
DISPLACED = 48,
STEALTH = 49,
AGGRAVATE_MONSTER = 50,
CONFLICT = 51,
ADORNED = 47,
INVIS = 48,
DISPLACED = 49,
STEALTH = 50,
AGGRAVATE_MONSTER = 51,
CONFLICT = 52,
/* Transportation */
JUMPING = 52,
TELEPORT = 53,
TELEPORT_CONTROL = 54,
LEVITATION = 55,
FLYING = 56,
WWALKING = 57,
SWIMMING = 58,
MAGICAL_BREATHING = 59,
PASSES_WALLS = 60,
JUMPING = 53,
TELEPORT = 54,
TELEPORT_CONTROL = 55,
LEVITATION = 56,
FLYING = 57,
WWALKING = 58,
SWIMMING = 59,
MAGICAL_BREATHING = 60,
PASSES_WALLS = 61,
/* Physical attributes */
SLOW_DIGESTION = 61,
HALF_SPDAM = 62,
HALF_PHDAM = 63,
REGENERATION = 64,
ENERGY_REGENERATION = 65,
PROTECTION = 66,
PROT_FROM_SHAPE_CHANGERS = 67,
POLYMORPH = 68,
POLYMORPH_CONTROL = 69,
UNCHANGING = 70,
SLOW = 71,
FAST = 72,
REFLECTING = 73,
FREE_ACTION = 74,
FIXED_ABIL = 75,
WITHERING = 76,
LIFESAVED = 77,
VULN_FIRE = 78,
VULN_COLD = 79,
VULN_ELEC = 80,
VULN_ACID = 81,
BREATHLESS = 82,
STABLE = 83
SLOW_DIGESTION = 62,
HALF_SPDAM = 63,
HALF_PHDAM = 64,
REGENERATION = 65,
ENERGY_REGENERATION = 66,
PROTECTION = 67,
PROT_FROM_SHAPE_CHANGERS = 68,
POLYMORPH = 69,
POLYMORPH_CONTROL = 70,
UNCHANGING = 71,
SLOW = 72,
FAST = 73,
REFLECTING = 74,
FREE_ACTION = 75,
FIXED_ABIL = 76,
WITHERING = 77,
LIFESAVED = 78,
VULN_FIRE = 79,
VULN_COLD = 80,
VULN_ELEC = 81,
VULN_ACID = 82,
BREATHLESS = 83,
STABLE = 84
};
#define LAST_PROP (STABLE)

Expand Down
5 changes: 5 additions & 0 deletions include/youprop.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
#define EPsychic_resistance u.uprops[PSYCHIC_RES].extrinsic
#define Psychic_resistance (HPsychic_resistance || EPsychic_resistance)

#define HFearless u.uprops[FEARLESS].intrinsic
/* This is not clean, but unfortunately we are out of SPFX fields */
#define EFearless u.uprops[FEARLESS].extrinsic
#define Fearless (HFearless || EFearless)

#define HStun_resistance u.uprops[STUN_RES].intrinsic
#define EStun_resistance u.uprops[STUN_RES].extrinsic
#define Stun_resistance (HStun_resistance || EStun_resistance \
Expand Down
2 changes: 1 addition & 1 deletion src/apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -4778,7 +4778,7 @@ struct obj *obj;
affects_objects = FALSE;
break;
case WAN_FEAR:
if (!Role_if(PM_NECROMANCER)) {
if (!Fearless) {
make_afraid((HAfraid & TIMEOUT) + (long) rn1(10, 5), TRUE);
}
wandfear(obj);
Expand Down
23 changes: 23 additions & 0 deletions src/artifact.c
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,8 @@ long wp_mask;
mask = &Free_action;
} else if (dtyp == AD_LOUD) {
mask = &ESonic_resistance;
} else if (dtyp == AD_PSYC) {
mask = &EPsychic_resistance;
} else if (dtyp == AD_STUN) {
mask = &EStun_resistance;
if (Stunned) {
Expand Down Expand Up @@ -4687,6 +4689,27 @@ int art;
|| (u.twoweap && uswapwep->oartifact == art));
}

boolean
wearing_artifact(art)
int art;
{
if (!art)
return FALSE;

return ((uarm && uarm->oartifact == art)
|| (uarmh && uarmh->oartifact == art)
|| (uarmg && uarmg->oartifact == art)
|| (uarmf && uarmf->oartifact == art)
|| (uarms && uarms->oartifact == art)
|| (uarmc && uarmc->oartifact == art)
|| (uarmu && uarmu->oartifact == art)
|| (uamul && uamul->oartifact == art)
|| (ublindf && ublindf->oartifact == art)
|| (uleft && uleft->oartifact == art)
|| (uright && uright->oartifact == art));
}


boolean
awaiting_guaranteed_gift()
{
Expand Down
1 change: 1 addition & 0 deletions src/attrib.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ static const struct innate {

nec_abil[] = { /* 1, Fear Resistance - hardcoded elsewhere */
{ 1, &(HDrain_resistance), "", "" },
{ 1, &(HFearless), "", "" },
{ 1, &(HSick_resistance), "hale", "" },
{ 3, &(HUndead_warning), "sensitive", "" },
{ 0, 0, 0, 0 } },
Expand Down
2 changes: 2 additions & 0 deletions src/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3377,6 +3377,8 @@ int final;
you_are("petrification resistant", from_what(STONE_RES));
if (Stun_resistance)
you_are("stun resistant", from_what(STUN_RES));
if (Fearless)
you_are("fearless", from_what(FEARLESS));
if (Death_resistance)
you_are("immune to the effects of death magic", from_what(DEATH_RES));
if (Halluc_resistance)
Expand Down
29 changes: 27 additions & 2 deletions src/do_wear.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,15 @@ long mask;
ESick_resistance |= mask;
if (props & ITEM_STUN)
EStun_resistance |= mask;
if (props & ITEM_BRAVE) {
EFearless |= mask;
if (Afraid) {
make_afraid(0L, TRUE);
context.botl = 1;
otmp->oprops_known |= ITEM_BRAVE;
}
}

if (props & ITEM_OILSKIN) {
pline("%s very tightly.", Tobjnam(otmp, "fit"));
otmp->oprops_known |= ITEM_OILSKIN;
Expand Down Expand Up @@ -336,6 +345,8 @@ long mask;
ESick_resistance &= ~mask;
if (props & ITEM_STUN)
EStun_resistance &= ~mask;
if (props & ITEM_BRAVE)
EFearless &= ~mask;
if (props & ITEM_OILSKIN)
otmp->oprops_known |= ITEM_OILSKIN;
if (props & ITEM_ESP) {
Expand Down Expand Up @@ -785,11 +796,12 @@ Helmet_on(VOID_ARGS)
Your("thoughts feel much more secure.");
uarmh->known = 1;
makeknown(TINFOIL_HAT);
EFearless |= W_ARMH;
BClairvoyant |= W_ARMH;
if (Afraid) {
make_afraid(0L, TRUE);
context.botl = TRUE;
}
BClairvoyant |= W_ARM;
break;
case HELM_OF_BRILLIANCE:
adj_abon(uarmh, uarmh->spe);
Expand Down Expand Up @@ -948,7 +960,8 @@ Helmet_off(VOID_ARGS)
uchangealign(u.ualignbase[A_CURRENT], 2);
break;
case TINFOIL_HAT:
BClairvoyant &= ~W_ARM;
BClairvoyant &= ~W_ARMH;
EFearless &= ~W_ARMH;
break;
default:
impossible(unknown_type, c_helmet, uarmh->otyp);
Expand Down Expand Up @@ -1122,6 +1135,14 @@ Shield_on(VOID_ARGS)
oprops_on(uarms, WORN_SHIELD);
}
toggle_armor_light(uarms, TRUE);

if (uarms->oartifact == ART_PRIDWEN) {
EFearless |= W_ARMS;
if (Afraid) {
make_afraid(0L, TRUE);
context.botl = TRUE;
}
}
return 0;
}

Expand Down Expand Up @@ -1157,6 +1178,10 @@ Shield_off(VOID_ARGS)
}
if (was_arti_light)
toggle_armor_light(otmp, FALSE);

if (uarms->oartifact == ART_PRIDWEN) {
EFearless &= ~W_ARMS;
}
return 0;
}

Expand Down
9 changes: 3 additions & 6 deletions src/mhitu.c
Original file line number Diff line number Diff line change
Expand Up @@ -3436,8 +3436,7 @@ struct attack *mattk;
}
if (Sonic_resistance)
break;
if (Psychic_resistance || Role_if(PM_NECROMANCER)
|| Role_if(PM_UNDEAD_SLAYER)) {
if (Fearless) {
You("are not afraid.");
break;
}
Expand Down Expand Up @@ -3939,9 +3938,7 @@ struct attack *mattk;
&& mtmp->mcansee && !rn2(3)
&& !mtmp->mspec_used
&& (ACURR(A_CHA) - mtmp->m_lev + u.ulevel < rn2(25))) {
if (Psychic_resistance
|| Role_if(PM_NECROMANCER)
|| Role_if(PM_UNDEAD_SLAYER)) {
if (Fearless) {
You("are not afraid of the %s!", mon_nam(mtmp));
break;
} else if (ublindf && ublindf->oartifact == ART_EYES_OF_THE_OVERWORLD && rn2(3)) {
Expand Down Expand Up @@ -4203,7 +4200,7 @@ struct attack *mattk;
pline("%s protect you from %s frightening gaze.",
An(bare_artifactname(ublindf)), s_suffix(mon_nam(mtmp)));
break;
} else if (Role_if(PM_NECROMANCER) || Role_if(PM_UNDEAD_SLAYER)) {
} else if (Fearless) {
You("are not afraid of the %s!", mon_nam(mtmp));
break;
}
Expand Down
8 changes: 3 additions & 5 deletions src/mon.c
Original file line number Diff line number Diff line change
Expand Up @@ -5091,18 +5091,16 @@ struct monst *mtmp;
}
wake_nearto(mtmp->mx, mtmp->my, 5 * 5);
if ((canseemon(mtmp) || (!Deaf && !Sonic_resistance))
&& !Underwater
&& !Confusion
&& !Underwater && !Confusion
&& !Role_if(PM_KNIGHT)
&& !wielding_artifact(ART_DRAGONBANE)
&& !(uarms && uarms->oartifact == ART_PRIDWEN)) {
&& !wielding_artifact(ART_DRAGONBANE)) {
i = 1 + max(0, (int) mtmp->m_lev - (int) mtmp->data->mlevel);

if (u.usleep) {
unmul("What a awful nightmare! You wake up!");
}

if (Psychic_resistance) {
if (Fearless) {
You("are not intimidated.");
} else if (ACURR(A_CHA) + (Deaf ? 5 : 0) < rn2(25 + i)) {
make_afraid((HAfraid & TIMEOUT) + (long) rn1(10, 5 * i), TRUE);
Expand Down
Loading

0 comments on commit 4ee3405

Please sign in to comment.