summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/artefact.cc6
-rw-r--r--crawl-ref/source/describe.cc11
-rw-r--r--crawl-ref/source/item_use.cc55
-rw-r--r--crawl-ref/source/makeitem.cc7
-rw-r--r--crawl-ref/source/monster.cc2
5 files changed, 75 insertions, 6 deletions
diff --git a/crawl-ref/source/artefact.cc b/crawl-ref/source/artefact.cc
index fb2687526a..0ac8f3ac0c 100644
--- a/crawl-ref/source/artefact.cc
+++ b/crawl-ref/source/artefact.cc
@@ -769,6 +769,12 @@ void static _get_randart_properties(const item_def &item,
{
proprt[ARTP_BRAND] = SPWPN_NORMAL;
}
+
+ if (atype == WPN_CROSSBOW && one_chance_in(5)
+ || atype == WPN_HAND_CROSSBOW && one_chance_in(10))
+ {
+ proprt[ARTP_BRAND] = SPWPN_ELECTROCUTION;
+ }
}
}
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 33f285c55d..e1b40e14b7 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -748,9 +748,14 @@ static std::string _describe_weapon(const item_def &item, bool verbose)
"cause great damage to the undead and demons.";
break;
case SPWPN_ELECTROCUTION:
- description += "Occasionally, upon striking a foe, it will "
- "discharge some electrical energy and cause terrible "
- "harm.";
+ if (is_range_weapon(item))
+ description += "It charges the ammunition it shoots with "
+ "electricity; occasionally upon a hit, such missiles "
+ "may discharge and cause terrible harm.";
+ else
+ description += "Occasionally, upon striking a foe, it will "
+ "discharge some electrical energy and cause terrible "
+ "harm.";
break;
case SPWPN_ORC_SLAYING:
description += "It is especially effective against all of "
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 60e172f553..6d132baa5c 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -1898,6 +1898,39 @@ static bool _dispersal_hit_victim(bolt& beam, actor* victim, int dmg,
return (true);
}
+static bool _charged_hit_victim(bolt &beam, actor* victim, int &dmg,
+ std::string &dmg_msg)
+{
+ if (victim->airborne() || victim->res_elec() > 0 || !one_chance_in(3))
+ return (false);
+
+ dmg += 10 + random2(15);
+
+ if (!beam.is_tracer && you.can_see(victim))
+ if (victim->atype() == ACT_PLAYER)
+ dmg_msg = "You are electrocuted!";
+ else
+ dmg_msg = "There is a sudden explosion of sparks!";
+ // TODO: lightning discharge into water
+
+ return (false);
+}
+
+static bool _blessed_hit_victim(bolt &beam, actor* victim, int &dmg,
+ std::string &dmg_msg)
+{
+ if (victim->undead_or_demonic())
+ {
+ dmg += 1 + (random2(dmg * 15) / 10);
+
+ if (!beam.is_tracer && you.can_see(victim))
+ dmg_msg = victim->name(DESC_CAP_THE) + " "
+ + victim->conj_verb("convulse") + "!";
+ }
+
+ return (false);
+}
+
bool setup_missile_beam(const actor *agent, bolt &beam, item_def &item,
std::string &ammo_name, bool &returning)
{
@@ -1996,7 +2029,11 @@ bool setup_missile_beam(const actor *agent, bolt &beam, item_def &item,
const bool silver = (ammo_brand == SPMSL_SILVER);
const bool disperses = (ammo_brand == SPMSL_DISPERSAL);
const bool reaping = (bow_brand == SPWPN_REAPING
- || ammo_brand == SPMSL_REAPING);
+ || ammo_brand == SPMSL_REAPING)
+ && bow_brand != SPWPN_HOLY_WRATH;
+ const bool charged = bow_brand == SPWPN_ELECTROCUTION;
+ const bool blessed = bow_brand == SPWPN_HOLY_WRATH
+ && ammo_brand != SPMSL_REAPING;
ASSERT(!exploding || !is_artefact(item));
@@ -2065,6 +2102,10 @@ bool setup_missile_beam(const actor *agent, bolt &beam, item_def &item,
beam.hit_funcs.push_back(_reaping_hit_victim);
if (disperses)
beam.hit_funcs.push_back(_dispersal_hit_victim);
+ if (charged)
+ beam.damage_funcs.push_back(_charged_hit_victim);
+ if (blessed)
+ beam.damage_funcs.push_back(_blessed_hit_victim);
if (reaping && ammo.special != SPMSL_REAPING)
{
@@ -2096,6 +2137,18 @@ bool setup_missile_beam(const actor *agent, bolt &beam, item_def &item,
ammo_name = "silvery " + ammo_name;
}
+ if (charged)
+ {
+ beam.name = "charged " + beam.name;
+ ammo_name = "charged " + ammo_name;
+ }
+
+ if (blessed)
+ {
+ beam.name = "blessed " + beam.name;
+ ammo_name = "blessed " + ammo_name;
+ }
+
// Do this here so that we get all the name mods except for a
// redundant "exploding".
if (exploding)
diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc
index 332187dd4e..0cb36ef77b 100644
--- a/crawl-ref/source/makeitem.cc
+++ b/crawl-ref/source/makeitem.cc
@@ -1437,6 +1437,9 @@ static brand_type _determine_weapon_brand(const item_def& item, int item_level)
rc = SPWPN_VORPAL;
else
rc = SPWPN_SPEED;
+ if (item.sub_type == WPN_HAND_CROSSBOW || item.sub_type == WPN_CROSSBOW)
+ if (one_chance_in(5))
+ rc = SPWPN_ELECTROCUTION;
break;
}
@@ -1552,12 +1555,12 @@ bool is_weapon_brand_ok(int type, int brand)
case SPWPN_VORPAL:
case SPWPN_CHAOS:
case SPWPN_REAPING:
+ case SPWPN_HOLY_WRATH:
+ case SPWPN_ELECTROCUTION:
break;
// Melee-only brands.
case SPWPN_FLAMING:
case SPWPN_FREEZING:
- case SPWPN_HOLY_WRATH:
- case SPWPN_ELECTROCUTION:
case SPWPN_ORC_SLAYING:
case SPWPN_DRAGON_SLAYING:
case SPWPN_DRAINING:
diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc
index 1a9e9e1737..60acd8e01e 100644
--- a/crawl-ref/source/monster.cc
+++ b/crawl-ref/source/monster.cc
@@ -1199,6 +1199,8 @@ static bool _compatible_launcher_ammo_brands(item_def *launcher,
return (bow_brand != SPWPN_FLAME && bow_brand != SPWPN_FROST);
case SPMSL_CHAOS:
return (bow_brand != SPWPN_CHAOS);
+ case SPMSL_REAPING:
+ return (bow_brand != SPWPN_HOLY_WRATH);
default:
return (true);
}