diff options
Diffstat (limited to 'crawl-ref')
-rw-r--r-- | crawl-ref/source/describe.cc | 20 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 107 | ||||
-rw-r--r-- | crawl-ref/source/itemname.cc | 21 | ||||
-rw-r--r-- | crawl-ref/source/itemprop-enum.h | 10 | ||||
-rw-r--r-- | crawl-ref/source/makeitem.cc | 26 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.cc | 7 |
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 }; |