summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/describe.cc20
-rw-r--r--crawl-ref/source/item_use.cc107
-rw-r--r--crawl-ref/source/itemname.cc21
-rw-r--r--crawl-ref/source/itemprop-enum.h10
-rw-r--r--crawl-ref/source/makeitem.cc26
-rw-r--r--crawl-ref/source/mapdef.cc7
6 files changed, 184 insertions, 7 deletions
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 8f06b1f582..426f4527ef 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -1069,7 +1069,25 @@ static std::string _describe_ammo(const item_def &item)
case SPMSL_CURARE:
description += "It is tipped with asphyxiating poison.";
break;
- case SPMSL_RETURNING:
+ case SPMSL_PARALYSIS:
+ description += "It is tipped with a paralyzing poison.";
+ break;
+ case SPMSL_SLOW:
+ description += "It is coated with a poison that causes slowness of the body.";
+ break;
+ case SPMSL_SLEEP:
+ description += "It is coated with a fast-acting tranquilizer.";
+ break;
+ case SPMSL_CONFUSION:
+ description += "It is tipped with a substance that causes confusion.";
+ break;
+ case SPMSL_SICKNESS:
+ description += "It has been contaminated by something likely to cause disease.";
+ break;
+ case SPMSL_RAGE:
+ description += "It is tipped with a substance that causes a mindless, berserk rage.";
+ break;
+ case SPMSL_RETURNING:
description += "A skilled user can throw it in such a way "
"that it will return to its owner.";
break;
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 816d8a00ba..618720050c 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -1926,6 +1926,92 @@ static bool _blessed_hit_victim(bolt &beam, actor* victim, int &dmg,
return (false);
}
+int _blowgun_power_roll (bolt &beam)
+{
+ actor* agent = beam.agent();
+ int base_power = 1;
+ int blowgun_base = 0;
+
+ if (agent->atype() == ACT_MONSTER)
+ {
+ monsters* mons = static_cast<monsters*>(agent);
+ base_power += mons->hit_dice;
+ blowgun_base += (*mons).launcher()->plus;
+ }
+ else
+ {
+ base_power += you.skills[SK_THROWING];
+ blowgun_base += (you.weapon())->plus;
+ }
+
+ return (base_power + blowgun_base);
+}
+
+static bool _paralysis_hit_victim (bolt& beam, actor* victim, int dmg,
+ int corpse)
+{
+ if (beam.is_tracer)
+ return (false);
+
+ int blowgun_power = _blowgun_power_roll(beam);
+ victim->paralyse(beam.agent(), 5 + random2(blowgun_power));
+ return (true);
+}
+
+static bool _sleep_hit_victim (bolt& beam, actor* victim, int dmg,
+ int corpse)
+{
+ if (beam.is_tracer)
+ return (false);
+
+ int blowgun_power = _blowgun_power_roll(beam);
+ victim->put_to_sleep(beam.agent(), 5 + random2(blowgun_power));
+ return (true);
+}
+
+static bool _confusion_hit_victim (bolt &beam, actor* victim, int dmg,
+ int corpse)
+{
+ if (beam.is_tracer)
+ return (false);
+
+ int blowgun_power = _blowgun_power_roll(beam);
+ victim->confuse(beam.agent(), 5 + random2(blowgun_power));
+ return (true);
+}
+
+static bool _slow_hit_victim (bolt &beam, actor* victim, int dmg,
+ int corpse)
+{
+ if (beam.is_tracer)
+ return (false);
+
+ int blowgun_power = _blowgun_power_roll(beam);
+ victim->slow_down(beam.agent(), 5 + random2(blowgun_power));
+ return (true);
+}
+
+static bool _sickness_hit_victim (bolt &beam, actor* victim, int dmg,
+ int corpse)
+{
+ if (beam.is_tracer)
+ return (false);
+
+ int blowgun_power = _blowgun_power_roll(beam);
+ victim->sicken(40 + random2(blowgun_power));
+ return (true);
+}
+
+static bool _rage_hit_victim (bolt &beam, actor* victim, int dmg,
+ int corpse)
+{
+ if (beam.is_tracer)
+ return (false);
+
+ victim->go_berserk(false);
+ return (true);
+}
+
bool setup_missile_beam(const actor *agent, bolt &beam, item_def &item,
std::string &ammo_name, bool &returning)
{
@@ -2034,6 +2120,14 @@ bool setup_missile_beam(const actor *agent, bolt &beam, item_def &item,
const bool flaming = bow_brand == SPWPN_FLAME
|| ammo_brand == SPMSL_FLAME;
+ const bool paralysis = ammo_brand == SPMSL_PARALYSIS;
+ const bool slow = ammo_brand == SPMSL_SLOW;
+ const bool sleep = ammo_brand == SPMSL_SLEEP;
+ const bool confusion = ammo_brand == SPMSL_CONFUSION;
+ const bool sickness = ammo_brand == SPMSL_SICKNESS;
+ const bool rage = ammo_brand == SPMSL_RAGE;
+
+
ASSERT(!exploding || !is_artefact(item));
if (flaming && poisoned)
@@ -2117,6 +2211,19 @@ bool setup_missile_beam(const actor *agent, bolt &beam, item_def &item,
if (blessed)
beam.damage_funcs.push_back(_blessed_hit_victim);
+ if (paralysis)
+ beam.hit_funcs.push_back(_paralysis_hit_victim);
+ if (slow)
+ beam.hit_funcs.push_back(_slow_hit_victim);
+ if (sleep)
+ beam.hit_funcs.push_back(_sleep_hit_victim);
+ if (confusion)
+ beam.hit_funcs.push_back(_confusion_hit_victim);
+ if (sickness)
+ beam.hit_funcs.push_back(_sickness_hit_victim);
+ if (rage)
+ beam.hit_funcs.push_back(_rage_hit_victim);
+
if (reaping && ammo.special != SPMSL_REAPING)
{
beam.name = "shadowy " + beam.name;
diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc
index 2c0b60650d..2c1be54220 100644
--- a/crawl-ref/source/itemname.cc
+++ b/crawl-ref/source/itemname.cc
@@ -1123,7 +1123,7 @@ std::string item_def::name_aux(description_level_type desc,
case SPMSL_CURARE:
buff << ((terse) ? "curare " : "curare-tipped ");
break;
- case SPMSL_EXPLODING:
+ case SPMSL_EXPLODING:
buff << ((terse) ? "explode " : "exploding ");
break;
case SPMSL_STEEL:
@@ -1167,6 +1167,24 @@ std::string item_def::name_aux(description_level_type desc,
case SPMSL_STEEL:
case SPMSL_SILVER:
break;
+ case SPMSL_PARALYSIS:
+ buff << ((terse) ? " (paralysis)" : " of paralysis");
+ break;
+ case SPMSL_SLOW:
+ buff << ((terse) ? " (slow)" : " of slowing");
+ break;
+ case SPMSL_SLEEP:
+ buff << ((terse) ? " (sleep)" : " of sleeping");
+ break;
+ case SPMSL_CONFUSION:
+ buff << ((terse) ? " (conf)" : " of confusion");
+ break;
+ case SPMSL_SICKNESS:
+ buff << ((terse) ? " (sick)" : " of sickening");
+ break;
+ case SPMSL_RAGE:
+ buff << ((terse) ? " (wrath)" : " of wrath");
+ break;
case SPMSL_RETURNING:
buff << ((terse) ? " (return)" : " of returning");
break;
@@ -1794,6 +1812,7 @@ bool item_type_known( const item_def& item )
int ammo_brand = get_ammo_brand(item);
if (ammo_brand == SPMSL_POISONED
|| ammo_brand == SPMSL_CURARE
+ || (ammo_brand >= SPMSL_PARALYSIS && ammo_brand <= SPMSL_RAGE)
|| ammo_brand == SPMSL_STEEL
|| ammo_brand == SPMSL_SILVER)
{
diff --git a/crawl-ref/source/itemprop-enum.h b/crawl-ref/source/itemprop-enum.h
index 9947f0cbbd..624221f688 100644
--- a/crawl-ref/source/itemprop-enum.h
+++ b/crawl-ref/source/itemprop-enum.h
@@ -343,7 +343,7 @@ enum special_missile_type // to separate from weapons in general {dlb}
SPMSL_FLAME,
SPMSL_FROST,
SPMSL_POISONED,
- SPMSL_CURARE,
+ SPMSL_CURARE, // Needle-only brand
SPMSL_RETURNING, // 5
SPMSL_CHAOS,
SPMSL_PENETRATION,
@@ -353,7 +353,13 @@ enum special_missile_type // to separate from weapons in general {dlb}
SPMSL_STEEL,
SPMSL_SILVER,
SPMSL_ELECTRIC,
- NUM_SPECIAL_MISSILES // 13
+ SPMSL_PARALYSIS, // paralysis, needle only from here in
+ SPMSL_SLOW, // makes slow
+ SPMSL_SLEEP, // sleep
+ SPMSL_CONFUSION, // confusing
+ SPMSL_SICKNESS, // sickness/disease
+ SPMSL_RAGE, // berserk rage
+ NUM_SPECIAL_MISSILES // 20
};
enum special_ring_type // jewellery mitm[].special values
diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc
index 5706088677..07473975b8 100644
--- a/crawl-ref/source/makeitem.cc
+++ b/crawl-ref/source/makeitem.cc
@@ -1824,7 +1824,18 @@ static special_missile_type _determine_missile_brand(const item_def& item,
switch (item.sub_type)
{
case MI_NEEDLE:
- rc = got_curare_roll(item_level) ? SPMSL_CURARE : SPMSL_POISONED;
+ // Curare is special cased, all the others aren't.
+ if (got_curare_roll(item_level))
+ {
+ rc = SPMSL_CURARE;
+ break;
+ }
+
+ rc = static_cast<special_missile_type>(
+ random_choose_weighted(30, SPMSL_PARALYSIS, 30, SPMSL_SLOW,
+ 30, SPMSL_SLEEP, 40, SPMSL_CONFUSION,
+ 20, SPMSL_SICKNESS, 10, SPMSL_RAGE,
+ nw, SPMSL_POISONED));
break;
case MI_DART:
rc = static_cast<special_missile_type>(
@@ -1901,8 +1912,16 @@ bool is_missile_brand_ok(int type, int brand)
return (false);
// In contrast, needles should always be branded.
- if (type == MI_NEEDLE && (brand == SPMSL_POISONED || brand == SPMSL_CURARE))
- return (true);
+ if (type == MI_NEEDLE)
+ {
+ switch (brand)
+ {
+ case SPMSL_POISONED: case SPMSL_CURARE: case SPMSL_PARALYSIS:
+ case SPMSL_SLOW: case SPMSL_SLEEP: case SPMSL_CONFUSION:
+ case SPMSL_SICKNESS: case SPMSL_RAGE: return (true);
+ default: return (false);
+ }
+ }
// Everything else doesn't matter.
if (brand == SPMSL_NORMAL)
@@ -1942,6 +1961,7 @@ bool is_missile_brand_ok(int type, int brand)
case SPMSL_SILVER:
return (type == MI_BOLT || type == MI_SLING_BULLET
|| type == MI_JAVELIN || type == MI_THROWING_NET);
+ default: break;
}
// Assume yes, if we've gotten this far.
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 5eda9e7792..09b233fc53 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -3760,6 +3760,13 @@ static int str_to_ego(item_spec &spec, std::string ego_str)
"exploding",
"steel",
"silver",
+ "electric",
+ "paralysis",
+ "slow",
+ "sleep",
+ "confusion",
+ "sickness",
+ "wrath",
NULL
};