fix #4206 - feedback for pet's weapon

The report that a tame Archon got two "<pet>'s long sword is not
affected" messages thought there was some duplication error when a
flaming sphere exploded, which was incorrect.  Since an Archon has
two weapon attacks, getting that message twice just meant that both
attacks hit.  However, the player has only 1/6 chance to suffering
passive fire damage to weapon, where monster-on-monster or monster-
on-polyd-hero was inflicting that for every successful hit, so
there was a bug here after all.  Give monsters the same 1/6 chance.
Also, add even more verbosity to that message--now that it won't be
delivered so often--to mention what didn't affect the item.

While investigating this, I noticed that hitting a steam vortex
with a flammable weapon was doing fire damage to that weapon.  Fire
damage in the steam vortex definition makes some sense in that it
allows fire resistance to give protection, but dishing out actual
fire damage makes no sense and is now prevented for passive counter-
effects.
This commit is contained in:
PatR
2016-01-27 17:51:02 -08:00
parent 90c4898c9a
commit 09ebe44ae9
4 changed files with 62 additions and 62 deletions

View File

@@ -129,6 +129,9 @@ adjust pending movement points when polymorphing into a slower creature
damage inflicted by burning glob of green slime gave wrong messages
monsters fleeing up the upstairs on level 1 were supposed to escape the
dungeon but ended up arriving on Plane of Earth
monster hitting fire-dealing monster with weapon triggered passive damage to
weapon every time, when hero doing so only had 1/6 chance per hit
hitting steam vortex with flammable weapon would damage the weapon with fire
Platform- and/or Interface-Specific Fixes

View File

@@ -1382,20 +1382,24 @@ rustm(mdef, obj)
struct monst *mdef;
struct obj *obj;
{
int dmgtyp;
int dmgtyp = -1, chance = 1;
if (!mdef || !obj)
return; /* just in case */
/* AD_ACID is handled in passivemm */
if (dmgtype(mdef->data, AD_CORR))
/* AD_ACID and AD_ENCH are handled in passivemm() and passiveum() */
if (dmgtype(mdef->data, AD_CORR)) {
dmgtyp = ERODE_CORRODE;
else if (dmgtype(mdef->data, AD_RUST))
} else if (dmgtype(mdef->data, AD_RUST)) {
dmgtyp = ERODE_RUST;
else if (dmgtype(mdef->data, AD_FIRE))
} else if (dmgtype(mdef->data, AD_FIRE)
/* steam vortex: fire resist applies, fire damage doesn't */
&& mdef->data != &mons[PM_STEAM_VORTEX]) {
dmgtyp = ERODE_BURN;
else
return;
(void) erode_obj(obj, NULL, dmgtyp, EF_GREASE | EF_VERBOSE);
chance = 6;
}
if (dmgtyp >= 0 && !rn2(chance))
(void) erode_obj(obj, (char *) 0, dmgtyp, EF_GREASE | EF_VERBOSE);
}
STATIC_OVL void

View File

@@ -141,24 +141,22 @@ const char *ostr;
int type;
int ef_flags;
{
static NEARDATA const char *const action[] = { "smoulder", "rust", "rot",
"corrode" };
static NEARDATA const char *const msg[] = { "burnt", "rusted", "rotten",
"corroded" };
boolean vulnerable = FALSE;
boolean is_primary = TRUE;
boolean check_grease = ef_flags & EF_GREASE;
boolean print = ef_flags & EF_VERBOSE;
int erosion;
static NEARDATA const char
*const action[] = { "smoulder", "rust", "rot", "corrode" },
*const msg[] = { "burnt", "rusted", "rotten", "corroded" },
*const bythe[] = { "heat", "oxidation", "decay", "corrosion" };
boolean vulnerable = FALSE, is_primary = TRUE,
check_grease = (ef_flags & EF_GREASE) ? TRUE : FALSE,
print = (ef_flags & EF_VERBOSE) ? TRUE : FALSE,
uvictim, vismon, visobj;
int erosion, cost_type;
struct monst *victim;
boolean vismon;
boolean visobj;
int cost_type;
if (!otmp)
return ER_NOTHING;
victim = carried(otmp) ? &youmonst : mcarried(otmp) ? otmp->ocarry : NULL;
uvictim = (victim == &youmonst);
vismon = victim && (victim != &youmonst) && canseemon(victim);
/* Is bhitpos correct here? Ugh. */
visobj = !victim && cansee(bhitpos.x, bhitpos.y);
@@ -192,35 +190,32 @@ int ef_flags;
if (!ostr)
ostr = cxname(otmp);
/* 'visobj' messages insert "the"; probably ought to switch to the() */
if (visobj && !(uvictim || vismon) && !strncmpi(ostr, "the ", 4))
ostr += 4;
if (check_grease && otmp->greased) {
grease_protect(otmp, ostr, victim);
return ER_GREASED;
} else if (!vulnerable || (otmp->oerodeproof && otmp->rknown)) {
if (print && flags.verbose) {
if (victim == &youmonst)
Your("%s %s not affected.", ostr, vtense(ostr, "are"));
else if (vismon)
pline("%s %s %s not affected.", s_suffix(Monnam(victim)),
ostr, vtense(ostr, "are"));
}
if (flags.verbose && print && (uvictim || vismon))
pline("%s %s %s not affected by %s.",
uvictim ? "Your" : s_suffix(Monnam(victim)),
ostr, vtense(ostr, "are"), bythe[type]);
return ER_NOTHING;
} else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
if (flags.verbose && (print || otmp->oerodeproof)) {
if (victim == &youmonst)
pline("Somehow, your %s %s not affected.", ostr,
vtense(ostr, "are"));
else if (vismon)
pline("Somehow, %s %s %s not affected.",
s_suffix(mon_nam(victim)), ostr, vtense(ostr, "are"));
else if (visobj)
pline("Somehow, the %s %s not affected.", ostr,
vtense(ostr, "are"));
}
if (flags.verbose && (print || otmp->oerodeproof)
&& (uvictim || vismon || visobj))
pline("Somehow, %s %s %s not affected by the %s.",
uvictim ? "your"
: !vismon ? "the" /* visobj */
: s_suffix(mon_nam(victim)),
ostr, vtense(ostr, "are"), bythe[type]);
/* We assume here that if the object is protected because it
* is blessed, it still shows some minor signs of wear, and
* the hero can distinguish this from an object that is
* actually proof against damage. */
* actually proof against damage.
*/
if (otmp->oerodeproof) {
otmp->rknown = TRUE;
if (victim == &youmonst)
@@ -233,13 +228,12 @@ int ef_flags;
? " completely"
: erosion ? " further" : "";
if (victim == &youmonst)
Your("%s %s%s!", ostr, vtense(ostr, action[type]), adverb);
else if (vismon)
pline("%s %s %s%s!", s_suffix(Monnam(victim)), ostr,
vtense(ostr, action[type]), adverb);
else if (visobj)
pline("The %s %s%s!", ostr, vtense(ostr, action[type]), adverb);
if (uvictim || vismon || visobj)
pline("%s %s %s%s!",
uvictim ? "Your"
: !vismon ? "The" /* visobj */
: s_suffix(Monnam(victim)),
ostr, vtense(ostr, action[type]), adverb);
if (ef_flags & EF_PAY)
costly_alteration(otmp, cost_type);
@@ -254,13 +248,12 @@ int ef_flags;
return ER_DAMAGED;
} else if (ef_flags & EF_DESTROY) {
if (victim == &youmonst)
Your("%s %s away!", ostr, vtense(ostr, action[type]));
else if (vismon)
pline("%s %s %s away!", s_suffix(Monnam(victim)), ostr,
vtense(ostr, action[type]));
else if (visobj)
pline("The %s %s away!", ostr, vtense(ostr, action[type]));
if (uvictim || vismon || visobj)
pline("%s %s %s away!",
uvictim ? "Your"
: !vismon ? "The" /* visobj */
: s_suffix(Monnam(victim)),
ostr, vtense(ostr, action[type]));
if (ef_flags & EF_PAY)
costly_alteration(otmp, cost_type);
@@ -270,15 +263,13 @@ int ef_flags;
return ER_DESTROYED;
} else {
if (flags.verbose && print) {
if (victim == &youmonst)
Your("%s %s completely %s.", ostr,
vtense(ostr, Blind ? "feel" : "look"), msg[type]);
else if (vismon)
pline("%s %s %s completely %s.", s_suffix(Monnam(victim)),
if (uvictim)
Your("%s %s completely %s.",
ostr, vtense(ostr, Blind ? "feel" : "look"), msg[type]);
else if (vismon || visobj)
pline("%s %s %s completely %s.",
!vismon ? "The" : s_suffix(Monnam(victim)),
ostr, vtense(ostr, "look"), msg[type]);
else if (visobj)
pline("The %s %s completely %s.", ostr, vtense(ostr, "look"),
msg[type]);
}
return ER_NOTHING;
}

View File

@@ -2533,7 +2533,9 @@ struct attack *mattk; /* null means we find one internally */
switch (mattk->adtyp) {
case AD_FIRE:
if (!rn2(6) && !mon->mcan) {
if (!rn2(6) && !mon->mcan
/* steam vortex: fire resist applies, fire damage doesn't */
&& mon->data != &mons[PM_STEAM_VORTEX]) {
(void) erode_obj(obj, NULL, ERODE_BURN, EF_NONE);
}
break;