Adjust seenres when observed attack succeeds

If a monster sees an elemental attack succeed from some other creature
or environmental danger, it will be willing to try those attacks again.
This commit is contained in:
Michael Meyer
2023-08-28 11:28:25 -04:00
committed by Pasi Kallinen
parent 82d83dc83d
commit 8fa53d6ac5
13 changed files with 100 additions and 12 deletions

View File

@@ -90,6 +90,7 @@ enum m_seen_resistance {
#define m_setseenres(mon, mask) ((mon)->seen_resistance |= (mask))
#define m_clearseenres(mon, mask) ((mon)->seen_resistance &= ~(mask))
#define monstseesu_ad(adtyp) monstseesu(cvt_adtyp_to_mseenres(adtyp))
#define monstunseesu_ad(adtyp) monstunseesu(cvt_adtyp_to_mseenres(adtyp))
#define monstunseesu_prop(prop) monstunseesu(cvt_prop_to_mseenres(prop))
struct monst {

View File

@@ -636,6 +636,8 @@ explode(
/* You resisted the damage, lets not keep that to ourselves */
if (uhurt == 1)
monstseesu_ad(adtyp);
else
monstunseesu_ad(adtyp);
if (u.uhp <= 0 || (Upolyd && u.mh <= 0)) {
if (Upolyd) {

View File

@@ -574,8 +574,10 @@ drinksink(void)
if (Fire_resistance) {
pline("It seems quite tasty.");
monstseesu(M_SEEN_FIRE);
} else
} else {
losehp(rnd(6), "sipping boiling water", KILLED_BY);
monstunseesu(M_SEEN_FIRE);
}
/* boiling water burns considered fire damage */
break;
case 3:

View File

@@ -294,6 +294,8 @@ castmu(
pline("But you resist the effects.");
monstseesu(M_SEEN_FIRE);
dmg = 0;
} else {
monstunseesu(M_SEEN_FIRE);
}
burn_away_slime();
break;
@@ -304,6 +306,8 @@ castmu(
pline("But you resist the effects.");
monstseesu(M_SEEN_COLD);
dmg = 0;
} else {
monstunseesu(M_SEEN_COLD);
}
break;
case AD_MAGM:
@@ -313,8 +317,10 @@ castmu(
pline_The("missiles bounce off!");
monstseesu(M_SEEN_MAGR);
dmg = 0;
} else
} else {
dmg = d((int) mtmp->m_lev / 2 + 1, 6);
monstunseesu(M_SEEN_MAGR);
}
break;
case AD_SPEL: /* wizard spell */
case AD_CLRC: /* clerical spell */
@@ -434,6 +440,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
} else {
touch_of_death(mtmp);
}
monstunseesu(M_SEEN_MAGR);
} else {
if (Antimagic) {
shieldeff(u.ux, u.uy);
@@ -496,6 +503,10 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
pline("A field of force surrounds you!");
} else if (!destroy_arm(some_armor(&gy.youmonst))) {
Your("skin itches.");
} else {
/* monsters only realize you aren't magic-protected if armor is
actually destroyed */
monstunseesu(M_SEEN_MAGR);
}
dmg = 0;
break;
@@ -517,6 +528,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
death_inflicted_by(kbuf, "strength loss", mtmp),
KILLED_BY);
gk.killer.name[0] = '\0'; /* not killed if we get here... */
monstunseesu(M_SEEN_MAGR);
}
dmg = 0;
break;
@@ -545,6 +557,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
if (Half_spell_damage)
dmg = (dmg + 1) / 2;
make_stunned((HStun & TIMEOUT) + (long) dmg, FALSE);
monstunseesu(M_SEEN_MAGR);
}
dmg = 0;
break;
@@ -562,6 +575,8 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR);
dmg = (dmg + 1) / 2;
} else {
monstunseesu(M_SEEN_MAGR);
}
if (dmg <= 5)
You("get a slight %sache.", body_part(HEAD));
@@ -608,8 +623,10 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_FIRE);
dmg = 0;
} else
} else {
dmg = d(8, 6);
monstunseesu(M_SEEN_FIRE);
}
if (Half_spell_damage)
dmg = (dmg + 1) / 2;
burn_away_slime();
@@ -633,9 +650,12 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
monstseesu(M_SEEN_REFL);
break;
}
monstunseesu(M_SEEN_REFL);
monstseesu(M_SEEN_ELEC);
} else
} else {
dmg = d(8, 6);
monstunseesu(M_SEEN_ELEC | M_SEEN_REFL);
}
if (Half_spell_damage)
dmg = (dmg + 1) / 2;
destroy_item(WAND_CLASS, AD_ELEC);
@@ -757,6 +777,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
dmg = 4 + (int) mtmp->m_lev;
if (Half_spell_damage)
dmg = (dmg + 1) / 2;
monstunseesu(M_SEEN_MAGR);
}
nomul(-dmg);
gm.multi_reason = "paralyzed by a monster";
@@ -779,6 +800,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
You_feel("%s!", oldprop ? "trippier" : "trippy");
else
You_feel("%sconfused!", oldprop ? "more " : "");
monstunseesu(M_SEEN_MAGR);
}
dmg = 0;
break;
@@ -790,6 +812,8 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR);
dmg = (dmg + 1) / 2;
} else {
monstunseesu(M_SEEN_MAGR);
}
if (dmg <= 5)
Your("skin itches badly for a moment.");

View File

@@ -1355,6 +1355,8 @@ gulpmu(struct monst *mtmp, struct attack *mattk)
case AD_ACID:
if (Acid_resistance) {
You("are covered with a seemingly harmless goo.");
/* NB: the monst[un]seesu calls in gulpmu are no-ops since the
hero must be currently swallowed for the attack to hit... */
monstseesu(M_SEEN_ACID);
tmp = 0;
} else {
@@ -1363,6 +1365,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk)
else
You("are covered in slime! It burns!");
exercise(A_STR, FALSE);
monstunseesu(M_SEEN_ACID);
}
break;
case AD_BLND:
@@ -1390,6 +1393,8 @@ gulpmu(struct monst *mtmp, struct attack *mattk)
monstseesu(M_SEEN_ELEC);
ugolemeffects(AD_ELEC, tmp);
tmp = 0;
} else {
monstunseesu(M_SEEN_ELEC);
}
} else
tmp = 0;
@@ -1402,8 +1407,10 @@ gulpmu(struct monst *mtmp, struct attack *mattk)
monstseesu(M_SEEN_COLD);
ugolemeffects(AD_COLD, tmp);
tmp = 0;
} else
} else {
You("are freezing to death!");
monstunseesu(M_SEEN_COLD);
}
} else
tmp = 0;
break;
@@ -1415,8 +1422,10 @@ gulpmu(struct monst *mtmp, struct attack *mattk)
monstseesu(M_SEEN_FIRE);
ugolemeffects(AD_FIRE, tmp);
tmp = 0;
} else
} else {
You("are burning to a crisp!");
monstunseesu(M_SEEN_FIRE);
}
burn_away_slime();
} else
tmp = 0;
@@ -1714,6 +1723,8 @@ gazemu(struct monst *mtmp, struct attack *mattk)
monstseesu(M_SEEN_FIRE);
ugolemeffects(AD_FIRE, d(12, 6));
dmg = 0;
} else {
monstunseesu(M_SEEN_FIRE);
}
burn_away_slime();
if (lev > rn2(20))
@@ -1741,6 +1752,7 @@ gazemu(struct monst *mtmp, struct attack *mattk)
fall_asleep(-rnd(10), TRUE);
pline("%s gaze makes you very sleepy...",
s_suffix(Monnam(mtmp)));
monstunseesu(M_SEEN_SLEEP);
}
}
break;

View File

@@ -139,8 +139,10 @@ thitu(
pline_The("silver sears your flesh!");
exercise(A_CON, FALSE);
}
if (is_acid)
if (is_acid) {
pline("It burns!");
monstunseesu(M_SEEN_ACID);
}
losehp(dam, knm, kprefix); /* acid damage */
exercise(A_STR, FALSE);
}

View File

@@ -884,6 +884,7 @@ peffect_sleeping(struct obj *otmp)
You("yawn.");
} else {
You("suddenly fall asleep!");
monstunseesu(M_SEEN_SLEEP);
fall_asleep(-rn1(10, 25 - 12 * bcsign(otmp)), TRUE);
}
}

View File

@@ -625,8 +625,11 @@ god_zaps_you(aligntyp resp_god)
shieldeff(u.ux, u.uy);
pline("It seems not to affect you.");
monstseesu(M_SEEN_ELEC);
} else
monstunseesu(M_SEEN_REFL);
} else {
fry_by_god(resp_god, FALSE);
monstunseesu(M_SEEN_REFL | M_SEEN_ELEC);
}
}
pline("%s is not deterred...", align_gname(resp_god));
@@ -657,6 +660,7 @@ god_zaps_you(aligntyp resp_god)
(void) destroy_arm(uarmu);
if (!Disint_resistance) {
fry_by_god(resp_god, TRUE);
monstunseesu(M_SEEN_DISINT);
} else {
You("bask in its %s glow for a minute...", NH_BLACK);
godvoice(resp_god, "I believe it not!");

View File

@@ -1760,6 +1760,7 @@ seffect_fire(struct obj **sobjp)
You_feel("a pleasant warmth in your %s.",
makeplural(body_part(HAND)));
} else {
monstunseesu(M_SEEN_FIRE);
pline_The("scroll catches fire and you burn your %s.",
makeplural(body_part(HAND)));
losehp(1, "scroll of fire", KILLED_BY_AN);

View File

@@ -1028,6 +1028,7 @@ inside_gas_cloud(genericptr_t p1, genericptr_t p2)
if (Half_gas_damage) /* worn towel */
dam = (dam + 1) / 2;
losehp(dam, "gas cloud", KILLED_BY_AN);
monstunseesu(M_SEEN_POISON);
return FALSE;
} else {
You("cough!");

View File

@@ -1422,6 +1422,7 @@ trapeffect_slp_gas_trap(
} else {
pline("A cloud of gas puts you to sleep!");
fall_asleep(-rnd(25), TRUE);
monstunseesu(M_SEEN_SLEEP);
}
(void) steedintrap(trap, (struct obj *) 0);
} else {
@@ -3835,6 +3836,7 @@ dofiretrap(
u.mhmax -= rn2(min(u.mhmax, num + 1)), gc.context.botl = TRUE;
if (u.mh > u.mhmax)
u.mh = u.mhmax, gc.context.botl = TRUE;
monstunseesu(M_SEEN_FIRE);
} else {
int uhpmin = minuhpmax(1), olduhpmax = u.uhpmax;
@@ -3849,6 +3851,7 @@ dofiretrap(
}
if (u.uhp > u.uhpmax)
u.uhp = u.uhpmax, gc.context.botl = TRUE;
monstunseesu(M_SEEN_FIRE);
}
if (!num)
You("are uninjured.");
@@ -5843,8 +5846,10 @@ chest_trap(
You("don't seem to be affected.");
monstseesu(M_SEEN_ELEC);
dmg = 0;
} else
} else {
dmg = d(4, 4);
monstunseesu(M_SEEN_ELEC);
}
destroy_item(RING_CLASS, AD_ELEC);
destroy_item(WAND_CLASS, AD_ELEC);
if (dmg)
@@ -6336,6 +6341,8 @@ lava_effects(void)
: " and are about to be immolated");
if (Fire_resistance)
monstseesu(M_SEEN_FIRE);
else
monstunseesu(M_SEEN_FIRE);
if (u.uhp > 1)
losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
KILLED_BY); /* lava damage */

View File

@@ -2439,6 +2439,7 @@ mhitm_ad_fire(
pline("You're %s!", on_fire(pd, mattk));
if (completelyburns(pd)) { /* paper or straw golem */
You("go up in flames!");
monstunseesu(M_SEEN_FIRE);
/* KMH -- this is okay with unchanging */
rehumanize();
return;
@@ -2446,6 +2447,8 @@ mhitm_ad_fire(
pline_The("fire doesn't feel hot!");
monstseesu(M_SEEN_FIRE);
mhm->damage = 0;
} else {
monstunseesu(M_SEEN_FIRE);
}
if ((int) magr->m_lev > rn2(20))
destroy_item(SCROLL_CLASS, AD_FIRE);
@@ -2530,6 +2533,8 @@ mhitm_ad_cold(
pline_The("frost doesn't seem cold!");
monstseesu(M_SEEN_COLD);
mhm->damage = 0;
} else {
monstunseesu(M_SEEN_COLD);
}
if ((int) magr->m_lev > rn2(20))
destroy_item(POTION_CLASS, AD_COLD);
@@ -2586,6 +2591,8 @@ mhitm_ad_elec(
pline_The("zap doesn't shock you!");
monstseesu(M_SEEN_ELEC);
mhm->damage = 0;
} else {
monstunseesu(M_SEEN_ELEC);
}
if ((int) magr->m_lev > rn2(20))
destroy_item(WAND_CLASS, AD_ELEC);
@@ -2635,6 +2642,7 @@ mhitm_ad_acid(
} else {
pline("You're covered in %s! It burns!", hliquid("acid"));
exercise(A_STR, FALSE);
monstunseesu(M_SEEN_ACID);
}
else
mhm->damage = 0;
@@ -3349,6 +3357,7 @@ mhitm_ad_slee(
monstseesu(M_SEEN_SLEEP);
return;
}
monstunseesu(M_SEEN_SLEEP);
fall_asleep(-rnd(10), TRUE);
if (Blind)
You("are put to sleep!");
@@ -5676,10 +5685,12 @@ passive(
You("are splashed by %s %s!", s_suffix(mon_nam(mon)),
hliquid("acid"));
if (!Acid_resistance)
if (!Acid_resistance) {
mdamageu(mon, tmp);
else
monstunseesu(M_SEEN_ACID);
} else {
monstseesu(M_SEEN_ACID);
}
if (!rn2(30))
erode_armor(&gy.youmonst, ERODE_CORRODE);
}
@@ -5749,6 +5760,7 @@ passive(
} else {
You("are hit by magic missiles appearing from thin air!");
mdamageu(mon, tmp);
monstunseesu(M_SEEN_MAGR);
}
break;
case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
@@ -5834,6 +5846,7 @@ passive(
ugolemeffects(AD_COLD, tmp);
break;
}
monstunseesu(M_SEEN_COLD);
You("are suddenly very cold!");
mdamageu(mon, tmp);
/* monster gets stronger with your heat! */
@@ -5858,6 +5871,7 @@ passive(
ugolemeffects(AD_FIRE, tmp);
break;
}
monstunseesu(M_SEEN_FIRE);
You("are suddenly very hot!");
mdamageu(mon, tmp); /* fire damage */
}
@@ -5870,6 +5884,7 @@ passive(
ugolemeffects(AD_ELEC, tmp);
break;
}
monstunseesu(M_SEEN_ELEC);
You("are jolted with electricity!");
mdamageu(mon, tmp);
break;

View File

@@ -2591,6 +2591,7 @@ zapyourself(struct obj *obj, boolean ordinary)
} else
damage = d(1 + obj->spe, 6);
exercise(A_STR, FALSE);
monstunseesu(M_SEEN_MAGR);
}
break;
@@ -2600,6 +2601,7 @@ zapyourself(struct obj *obj, boolean ordinary)
You("shock yourself!");
damage = d(12, 6);
exercise(A_CON, FALSE);
monstunseesu(M_SEEN_ELEC);
} else {
shieldeff(u.ux, u.uy);
You("zap yourself, but seem unharmed.");
@@ -2626,6 +2628,7 @@ zapyourself(struct obj *obj, boolean ordinary)
} else {
pline("You've set yourself afire!");
damage = d(12, 6);
monstunseesu(M_SEEN_FIRE);
}
burn_away_slime();
(void) burnarmor(&gy.youmonst);
@@ -2648,6 +2651,7 @@ zapyourself(struct obj *obj, boolean ordinary)
} else {
You("imitate a popsicle!");
damage = d(12, 6);
monstunseesu(M_SEEN_COLD);
}
destroy_item(POTION_CLASS, AD_COLD);
break;
@@ -2662,6 +2666,7 @@ zapyourself(struct obj *obj, boolean ordinary)
} else {
damage = d(4, 6);
pline("Idiot! You've shot yourself!");
monstunseesu(M_SEEN_MAGR);
}
break;
@@ -2728,6 +2733,7 @@ zapyourself(struct obj *obj, boolean ordinary)
pline_The("sleep ray hits you!");
else
You("fall alseep!");
monstunseesu(M_SEEN_SLEEP);
fall_asleep(-rnd(50), TRUE);
}
break;
@@ -4105,6 +4111,7 @@ zhitu(
} else {
dam = d(nd, 6);
exercise(A_STR, FALSE);
monstunseesu(M_SEEN_MAGR);
}
break;
case ZT_FIRE:
@@ -4115,6 +4122,7 @@ zhitu(
ugolemeffects(AD_FIRE, d(nd, 6));
} else {
dam = d(nd, 6);
monstunseesu(M_SEEN_FIRE);
}
burn_away_slime();
if (burnarmor(&gy.youmonst)) { /* "body hit" */
@@ -4137,6 +4145,7 @@ zhitu(
ugolemeffects(AD_COLD, d(nd, 6));
} else {
dam = d(nd, 6);
monstunseesu(M_SEEN_COLD);
}
if (!rn2(3))
destroy_item(POTION_CLASS, AD_COLD);
@@ -4147,6 +4156,7 @@ zhitu(
You("don't feel sleepy.");
monstseesu(M_SEEN_SLEEP);
} else {
monstunseesu(M_SEEN_SLEEP);
fall_asleep(-d(nd, 25), TRUE); /* sleep ray */
}
break;
@@ -4160,7 +4170,9 @@ zhitu(
break;
} else if (disn_prot) {
break;
} else if (uarms) {
}
monstunseesu(M_SEEN_DISINT);
if (uarms) {
/* destroy shield; other possessions are safe */
(void) destroy_arm(uarms);
break;
@@ -4187,6 +4199,7 @@ zhitu(
You("aren't affected.");
break;
}
monstunseesu(M_SEEN_MAGR);
gk.killer.format = KILLED_BY_AN;
Strcpy(gk.killer.name, fltxt ? fltxt : "");
/* when killed by disintegration breath, don't leave corpse */
@@ -4202,6 +4215,7 @@ zhitu(
} else {
dam = d(nd, 6);
exercise(A_CON, FALSE);
monstunseesu(M_SEEN_ELEC);
}
if (!rn2(3))
destroy_item(WAND_CLASS, AD_ELEC);
@@ -4220,6 +4234,7 @@ zhitu(
pline_The("%s burns!", hliquid("acid"));
dam = d(nd, 6);
exercise(A_STR, FALSE);
monstunseesu(M_SEEN_ACID);
}
/* using two weapons at once makes both of them more vulnerable */
if (!rn2(u.twoweap ? 3 : 6))
@@ -4605,6 +4620,7 @@ dobuzz(
/* flash_str here only used for killer; suppress
* hallucination */
zhitu(type, nd, flash_str(fltyp, TRUE), sx, sy);
monstunseesu(M_SEEN_REFL);
}
} else if (!Blind) {
pline("%s whizzes by you!", The(flash_str(fltyp, FALSE)));