Skip to content

Commit

Permalink
Shield properties can deal damage during power shield or shield bashing.
Browse files Browse the repository at this point in the history
This is something that sounded really neat for the power shield tech, but after getting the groundwork done, I decided to throw it in for the regular shield bashing attacks too. It occurs on 25% of shield bashes, so not too spammy but still adding some significant damage.

The sleep and disease properties felt too weird for shields to inflict damage so I left those out.
  • Loading branch information
elunna committed Oct 31, 2023
1 parent 80520fc commit da8bc89
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 45 deletions.
1 change: 1 addition & 0 deletions include/extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -2960,6 +2960,7 @@ E int FDECL(flash_hits_mon, (struct monst *, struct obj *));
E void FDECL(light_hits_gremlin, (struct monst *, int));
E boolean NDECL(dbl_dmg);
E void FDECL(steal_it, (struct monst *, struct attack *));
E int FDECL(shield_dmg, ( struct obj *, struct monst *));

/* ### unixmain.c ### */

Expand Down
41 changes: 22 additions & 19 deletions src/artifact.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,8 @@ struct obj *otmp;
return TRUE;

if (!weap && otmp->oprops
&& (otmp->oclass == WEAPON_CLASS || is_weptool(otmp))) {
&& (otmp->oclass == WEAPON_CLASS || is_weptool(otmp)
|| (uarms && otmp == uarms))) {
if (adtyp == AD_FIRE && (otmp->oprops & ITEM_FIRE))
return TRUE;
if (adtyp == AD_COLD && (otmp->oprops & ITEM_FROST))
Expand Down Expand Up @@ -1403,7 +1404,8 @@ int tmp;
spec_dbon_applies = FALSE;

if (!weap && otmp->oprops
&& (otmp->oclass == WEAPON_CLASS || is_weptool(otmp))) {
&& (otmp->oclass == WEAPON_CLASS || is_weptool(otmp)
|| (uarms && otmp == uarms))) {
/* until we know otherwise... */
if ((attacks(adtype = AD_FIRE, otmp)
&& ((yours) ? !(Fire_resistance || Underwater)
Expand Down Expand Up @@ -1864,8 +1866,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
: can_vaporize(mdef->data) ? "vaporizes part of"
: "burns",
hittee, !spec_dbon_applies ? '.' : '!');
} else if (otmp->oclass == WEAPON_CLASS
&& (otmp->oprops & ITEM_FIRE)) {
} else if ((otmp->oclass == WEAPON_CLASS || otmp == uarms)
&& otmp->oprops & ITEM_FIRE) {
pline_The("%s %s %s%c", distant_name(otmp, xname),
!spec_dbon_applies ? "hits"
: can_vaporize(mdef->data) ? "vaporizes part of"
Expand Down Expand Up @@ -1941,8 +1943,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
? "freezes part of"
: "freezes",
hittee, !spec_dbon_applies ? '.' : '!');
} else if (otmp->oclass == WEAPON_CLASS
&& (otmp->oprops & ITEM_FROST)) {
} else if ((otmp->oclass == WEAPON_CLASS || otmp == uarms)
&& otmp->oprops & ITEM_FROST) {
pline_The("%s %s %s%c",
distant_name(otmp, xname),
!spec_dbon_applies
Expand Down Expand Up @@ -1977,8 +1979,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
? ""
: "! Lightning strikes",
hittee, !spec_dbon_applies ? '.' : '!');
} else if (otmp->oclass == WEAPON_CLASS
&& (otmp->oprops & ITEM_SHOCK)) {
} else if ((otmp->oclass == WEAPON_CLASS || otmp == uarms)
&& otmp->oprops & ITEM_SHOCK) {
pline_The("%s %s %s%c",
distant_name(otmp, xname),
!spec_dbon_applies
Expand Down Expand Up @@ -2022,8 +2024,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
magr->my, mdx, mdy, TRUE);
}
}
} else if (otmp->oclass == WEAPON_CLASS
&& (otmp->oprops & ITEM_SCREAM)) {
} else if ((otmp->oclass == WEAPON_CLASS || otmp == uarms)
&& otmp->oprops & ITEM_SCREAM) {
if (!youattack && magr && cansee(magr->mx, magr->my)) {
if (!spec_dbon_applies) {
if (!youdefend)
Expand Down Expand Up @@ -2222,8 +2224,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
: mon_underwater(mdef) ? "hits"
: "burns",
hittee, !spec_dbon_applies ? '.' : '!');
} else if (otmp->oclass == WEAPON_CLASS
&& (otmp->oprops & ITEM_SIZZLE)) {
} else if ((otmp->oclass == WEAPON_CLASS || otmp == uarms)
&& otmp->oprops & ITEM_SIZZLE) {
pline_The("acidic %s %s %s%c",
distant_name(otmp, xname),
!spec_dbon_applies ? "hits"
Expand All @@ -2246,7 +2248,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
/* Sixth basic attack - poison */
if (attacks(AD_DRST, otmp)) {
if (realizes_damage) {
if (otmp->oclass == WEAPON_CLASS && (otmp->oprops & ITEM_VENOM)) {
if ((otmp->oclass == WEAPON_CLASS || otmp == uarms)
&& otmp->oprops & ITEM_VENOM) {
pline_The("%s %s %s%c", distant_name(otmp, xname),
(resists_poison(mdef) || defended(mdef, AD_DRST))
? "hits"
Expand Down Expand Up @@ -2449,8 +2452,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
pline_The("staff sprays a %s %s at %s!", rndcolor(),
(rn2(2) ? "gas" : "mist"), hittee);
}
} else if (otmp->oclass == WEAPON_CLASS
&& (otmp->oprops & ITEM_SLEEP)) {
} else if ((otmp->oclass == WEAPON_CLASS || otmp == uarms)
&& otmp->oprops & ITEM_SLEEP) {
pline_The("%s %s %s%c", distant_name(otmp, xname),
(resists_sleep(mdef) || defended(mdef, AD_SLEE))
? "hits"
Expand Down Expand Up @@ -3055,8 +3058,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
else if (otmp->oartifact == ART_LIFESTEALER)
pline_The("massive sword draws the %s from %s!",
life, mon_nam(mdef));
else if (otmp->oclass == WEAPON_CLASS
&& (otmp->oprops & ITEM_DECAY))
else if ((otmp->oclass == WEAPON_CLASS || otmp == uarms)
&& otmp->oprops & ITEM_DECAY)
pline_The("deadly %s draws the %s from %s!",
distant_name(otmp, xname), life,
mon_nam(mdef));
Expand Down Expand Up @@ -3100,8 +3103,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
pline_The("%s blade drains your %s!", hcolor(NH_BLACK), life);
else if (otmp->oartifact == ART_LIFESTEALER)
pline_The("massive sword drains your %s!", life);
else if (otmp->oclass == WEAPON_CLASS
&& (otmp->oprops & ITEM_DECAY))
else if ((otmp->oclass == WEAPON_CLASS || otmp == uarms)
&& otmp->oprops & ITEM_DECAY)
pline_The("deadly %s drains your %s!",
distant_name(otmp, xname), life);
/* The Staff of Aesculapius */
Expand Down
19 changes: 14 additions & 5 deletions src/tech.c
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,7 @@ struct monst *mtmp;
int dam;
{
int res = 0, cost = dam;
int counter_dmg;
int tech_no = get_tech_no(T_POWER_SHIELD);
int skillpoints = P_SKILL(P_SHIELD) + techlev(tech_no);

Expand All @@ -1286,16 +1287,24 @@ int dam;
use_skill(P_SHIELD, 1);
/* The projectile blocking has a message in thitu */
} else if (mtmp) {
counter_dmg = shield_dmg(uarms, mtmp);
if (rn2(2))
You("force your shield into the %s attack!",
s_suffix(mon_nam(mtmp)));
else
You("smash the %s with your shield!", mon_nam(mtmp));

res = damage_mon(mtmp, dam, AD_PHYS);
if (res)
You("smash the %s with your %s!", mon_nam(mtmp), xname(uarms));

/* Property effects */
if (uarms->oprops & (ITEM_FIRE | ITEM_FROST | ITEM_SHOCK
| ITEM_VENOM | ITEM_SIZZLE | ITEM_SCREAM | ITEM_DECAY)) {
artifact_hit(&youmonst, mtmp, uarms, &counter_dmg, rnd(20));
}

damage_mon(mtmp, counter_dmg, AD_PHYS);

if (DEADMONSTER(mtmp))
xkilled(mtmp, XKILL_GIVEMSG);
else if (!mtmp->mconf) {
else if (!mtmp->mconf && !rn2(7)) {
if (canseemon(mtmp))
pline("%s looks dazed.", Monnam(mtmp));
mtmp->mconf = 1;
Expand Down
61 changes: 40 additions & 21 deletions src/uhitm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1679,25 +1679,19 @@ int dieroll;
case SHIELD_OF_LIGHT:
case SHIELD_OF_MOBILITY:
case RESONANT_SHIELD:
if (uarms && P_SKILL(P_SHIELD) >= P_BASIC) {
/* dmgval for shields is just one point,
plus whatever material damage applies */
tmp = dmgval(obj, mon);

/* add extra damage based on the type
of shield */
if (obj->otyp == SMALL_SHIELD)
tmp += rn2(3) + 1;
else if (obj->otyp == TOWER_SHIELD)
tmp += rn2(12) + 1;
else
tmp += rn2(6) + 2;

/* sprinkle on a bit more damage if
shield skill is high enough */
if (P_SKILL(P_SHIELD) >= P_EXPERT)
tmp += rnd(4);
if (obj && (obj == uarms) && is_shield(obj)) {
You("bash %s with %s%s",
mon_nam(mon), ysimple_name(obj),
canseemon(mon) ? exclam(tmp) : ".");
tmp = shield_dmg(obj, mon);
/* Property effects */
if (obj->oprops & (ITEM_FIRE | ITEM_FROST | ITEM_SHOCK
| ITEM_VENOM | ITEM_SIZZLE | ITEM_SCREAM
| ITEM_DECAY) && !rn2(4)) {
artifact_hit(&youmonst, mon, uarms, &tmp, dieroll);
}
}

if (mon_hates_material(mon, obj->material)) {
/* dmgval() already added damage, but track hated_obj */
hated_obj = obj;
Expand Down Expand Up @@ -2212,9 +2206,6 @@ int dieroll;
canseemon(mon) ? exclam(tmp) : ".");
} else {
if (obj && (obj == uarms) && is_shield(obj)) {
You("bash %s with %s%s",
mon_nam(mon), ysimple_name(obj),
canseemon(mon) ? exclam(tmp) : ".");
/* placing this here, because order of events */
if (!rn2(10) && P_SKILL(P_SHIELD) >= P_EXPERT
&& (!(resists_stun(mon->data) || defended(mon, AD_STUN)))) {
Expand Down Expand Up @@ -5954,4 +5945,32 @@ u_bloodthirsty()

}

int
shield_dmg(obj, mon)
struct monst *mon;
struct obj *obj;
{
int tmp;
if (uarms && P_SKILL(P_SHIELD) >= P_BASIC) {
/* dmgval for shields is just one point,
plus whatever material damage applies */
tmp = dmgval(obj, mon);

/* add extra damage based on the type
of shield */
if (obj->otyp == SMALL_SHIELD)
tmp += rn2(3) + 1;
else if (obj->otyp == TOWER_SHIELD)
tmp += rn2(12) + 1;
else
tmp += rn2(6) + 2;

/* sprinkle on a bit more damage if
shield skill is high enough */
if (P_SKILL(P_SHIELD) >= P_EXPERT)
tmp += rnd(4);
}
return tmp;
}

/*uhitm.c*/

0 comments on commit da8bc89

Please sign in to comment.