summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/it_use3.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/it_use3.cc')
-rw-r--r--crawl-ref/source/it_use3.cc394
1 files changed, 110 insertions, 284 deletions
diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc
index 79fa14e527..bbaf27f11d 100644
--- a/crawl-ref/source/it_use3.cc
+++ b/crawl-ref/source/it_use3.cc
@@ -34,9 +34,8 @@ REVISION("$Rev$");
#include "itemprop.h"
#include "mapmark.h"
#include "message.h"
-#include "misc.h"
#include "monplace.h"
-#include "monstuff.h"
+#include "misc.h"
#include "overmap.h"
#include "player.h"
#include "religion.h"
@@ -44,198 +43,136 @@ REVISION("$Rev$");
#include "skills2.h"
#include "spells1.h"
#include "spells2.h"
-#include "spells3.h"
#include "spl-book.h"
#include "spl-cast.h"
-#include "spl-mis.h"
#include "spl-util.h"
#include "state.h"
#include "stuff.h"
#include "view.h"
#include "xom.h"
-void special_wielded()
+// TODO: Let artefacts besides weapons generate noise.
+void noisy_equipment()
{
- item_def& weapon = *you.weapon();
- const int old_plus = weapon.plus;
- const int old_plus2 = weapon.plus2;
- const char old_colour = weapon.colour;
+ if (silenced(you.pos()) || !one_chance_in(20))
+ return;
+
+ std::string msg;
- switch (you.unrand_reacts)
+ const item_def* weapon = you.weapon();
+
+ if (weapon && weapon->props.exists(ART_NOISE_KEY))
{
- case SPWLD_SING:
- case SPWLD_NOISE:
+ const std::string key = weapon->props[ART_NOISE_KEY];
+ msg = getSpeakString(key);
+ if (!msg.empty())
+ {
+ // "Your Singing Sword" sounds disrespectful
+ // (as if there could be more than one!)
+ msg = replace_all(msg, "@Your_weapon@", "@The_weapon@");
+ msg = replace_all(msg, "@your_weapon@", "@the_weapon@");
+ }
+ }
+ else
{
- if (!silenced(you.pos()) && one_chance_in(20))
+ msg = getSpeakString("noisy weapon");
+ if (!msg.empty())
{
- std::string msg;
-
- if (you.unrand_reacts == SPWLD_SING)
- {
- msg = getSpeakString("Singing Sword");
- if (!msg.empty())
- {
- // "Your Singing Sword" sounds disrespectful
- // (as if there could be more than one!)
- msg = replace_all(msg, "@Your_weapon@", "@The_weapon@");
- msg = replace_all(msg, "@your_weapon@", "@the_weapon@");
- }
- }
- else // SPWLD_NOISE
- {
- msg = getSpeakString("noisy weapon");
- if (!msg.empty())
- {
- msg = replace_all(msg, "@Your_weapon@", "Your @weapon@");
- msg = replace_all(msg, "@your_weapon@", "your @weapon@");
- }
- }
-
- // Set appropriate channel (will usually be TALK).
- msg_channel_type channel = MSGCH_TALK;
-
- // Disallow anything with VISUAL in it.
- if (!msg.empty() && msg.find("VISUAL") != std::string::npos)
- msg = "";
-
- if (!msg.empty())
- {
- std::string param = "";
- std::string::size_type pos = msg.find(":");
-
- if (pos != std::string::npos)
- param = msg.substr(0, pos);
-
- if (!param.empty())
- {
- bool match = true;
-
- if (param == "DANGER")
- channel = MSGCH_DANGER;
- else if (param == "WARN")
- channel = MSGCH_WARN;
- else if (param == "SOUND")
- channel = MSGCH_SOUND;
- else if (param == "PLAIN")
- channel = MSGCH_PLAIN;
- else if (param == "SPELL" || param == "ENCHANT")
- msg = ""; // disallow these as well, channel stays TALK
- else if (param != "TALK")
- match = false;
-
- if (match && !msg.empty())
- msg = msg.substr(pos + 1);
- }
- }
-
- if (msg.empty()) // give default noises
- {
- if (you.unrand_reacts == SPWLD_SING)
- msg = "@The_weapon@ sings.";
- else
- {
- channel = MSGCH_SOUND;
- msg = "You hear a strange noise.";
- }
- }
-
- // replace weapon references
- msg = replace_all(msg, "@The_weapon@", "The @weapon@");
- msg = replace_all(msg, "@the_weapon@", "the @weapon@");
- msg = replace_all(msg, "@weapon@", weapon.name(DESC_BASENAME));
- // replace references to player name and god
- msg = replace_all(msg, "@player_name@", you.your_name);
- msg = replace_all(msg, "@player_god@",
- you.religion == GOD_NO_GOD ? "atheism"
- : god_name(you.religion, coinflip()));
-
- mpr(msg.c_str(), channel);
-
- noisy(25, you.pos());
+ msg = replace_all(msg, "@Your_weapon@", "Your @weapon@");
+ msg = replace_all(msg, "@your_weapon@", "your @weapon@");
}
- break;
}
- case SPWLD_CURSE:
- if (one_chance_in(30))
- curse_an_item(false);
- break;
-
- case SPWLD_VARIABLE:
- do_uncurse_item(weapon);
-
- if (x_chance_in_y(2, 5))
- weapon.plus += (coinflip() ? +1 : -1);
+ // Set appropriate channel (will usually be TALK).
+ msg_channel_type channel = MSGCH_TALK;
- if (x_chance_in_y(2, 5))
- weapon.plus2 += (coinflip() ? +1 : -1);
+ // Disallow anything with VISUAL in it.
+ if (!msg.empty() && msg.find("VISUAL") != std::string::npos)
+ msg = "";
- if (weapon.plus < -4)
- weapon.plus = -4;
- else if (weapon.plus > 16)
- weapon.plus = 16;
-
- if (weapon.plus2 < -4)
- weapon.plus2 = -4;
- else if (weapon.plus2 > 16)
- weapon.plus2 = 16;
+ if (!msg.empty())
+ {
+ std::string param = "";
+ std::string::size_type pos = msg.find(":");
- weapon.colour = random_colour();
- break;
+ if (pos != std::string::npos)
+ param = msg.substr(0, pos);
- case SPWLD_TORMENT:
- if (one_chance_in(200))
+ if (!param.empty())
{
- torment(TORMENT_SPWLD, you.pos());
- did_god_conduct(DID_UNHOLY, 1);
+ bool match = true;
+
+ if (param == "DANGER")
+ channel = MSGCH_DANGER;
+ else if (param == "WARN")
+ channel = MSGCH_WARN;
+ else if (param == "SOUND")
+ channel = MSGCH_SOUND;
+ else if (param == "PLAIN")
+ channel = MSGCH_PLAIN;
+ else if (param == "SPELL" || param == "ENCHANT")
+ msg = ""; // disallow these as well, channel stays TALK
+ else if (param != "TALK")
+ match = false;
+
+ if (match && !msg.empty())
+ msg = msg.substr(pos + 1);
}
- break;
+ }
- case SPWLD_ZONGULDROK:
- if (one_chance_in(5))
- {
- animate_dead(&you, 1 + random2(3), BEH_HOSTILE, MHITYOU);
- did_god_conduct(DID_NECROMANCY, 1);
- }
- break;
+ if (msg.empty()) // give default noises
+ {
+ channel = MSGCH_SOUND;
+ msg = "You hear a strange noise.";
+ }
- case SPWLD_POWER:
- weapon.plus = stepdown_value( -4 + (you.hp / 5), 4, 4, 4, 20 );
- weapon.plus2 = weapon.plus;
- break;
+ // replace weapon references
+ if (weapon)
+ {
+ msg = replace_all(msg, "@The_weapon@", "The @weapon@");
+ msg = replace_all(msg, "@the_weapon@", "the @weapon@");
+ msg = replace_all(msg, "@weapon@", weapon->name(DESC_BASENAME));
+ }
+ // replace references to player name and god
+ msg = replace_all(msg, "@player_name@", you.your_name);
+ msg = replace_all(msg, "@player_god@",
+ you.religion == GOD_NO_GOD ? "atheism"
+ : god_name(you.religion, coinflip()));
- case SPWLD_OLGREB:
- // Giving Olgreb's staff a little lift since staves of poison have
- // been made better. -- bwr
- weapon.plus = you.skills[SK_POISON_MAGIC] / 3;
- weapon.plus2 = weapon.plus;
- break;
+ mpr(msg.c_str(), channel);
- case SPWLD_WUCAD_MU:
- weapon.plus = std::min(you.intel - 3, 22);
- weapon.plus2 = std::min(you.intel / 2, 13);
- break;
+ noisy(25, you.pos());
+}
+
+void shadow_lantern_effect()
+{
+ if (x_chance_in_y(player_spec_death() + 1, 8))
+ {
+ create_monster(mgen_data(MONS_SHADOW, BEH_FRIENDLY, 2, 0, you.pos(),
+ MHITYOU));
+ did_god_conduct(DID_NECROMANCY, 1);
+ }
+}
+
+void unrand_reacts()
+{
+ item_def* weapon = you.weapon();
+ const int old_plus = weapon ? weapon->plus : 0;
+ const int old_plus2 = weapon ? weapon->plus2 : 0;
- case SPWLD_SHADOW:
- if (x_chance_in_y(player_spec_death() + 1, 8))
+ for (int i = 0; i < NUM_EQUIP; i++)
+ {
+ if (you.unrand_reacts & (1 << i))
{
- create_monster(
- mgen_data(MONS_SHADOW, BEH_FRIENDLY, 2, 0, you.pos(), MHITYOU));
- did_god_conduct(DID_NECROMANCY, 1);
- }
- break;
+ item_def& item = you.inv[you.equip[i]];
+ unrandart_entry* entry = get_unrand_entry(item.special);
- //case SPWLD_PRUNE:
- default:
- return;
+ entry->world_reacts_func(&item);
+ }
}
- if (old_plus != weapon.plus
- || old_plus2 != weapon.plus2
- || old_colour != weapon.colour)
- {
+ if (weapon && (old_plus != weapon->plus || old_plus2 != weapon->plus2))
you.wield_change = true;
- }
}
static bool _reaching_weapon_attack(const item_def& wpn)
@@ -390,45 +327,6 @@ static bool evoke_horn_of_geryon()
return (rc);
}
-static bool evoke_sceptre_of_asmodeus()
-{
- bool rc = true;
- if (one_chance_in(21))
- rc = false;
- else if (one_chance_in(20))
- {
- // Summon devils, maybe a Fiend.
- const monster_type mon = (one_chance_in(4) ? MONS_FIEND :
- summon_any_demon(DEMON_COMMON));
- const bool good_summon = create_monster(
- mgen_data::hostile_at(mon,
- you.pos(), 6, 0, true)) != -1;
-
- if (good_summon)
- {
- if (mon == MONS_FIEND)
- mpr("\"Your arrogance condemns you, mortal!\"");
- else
- mpr("The Sceptre summons one of its servants.");
- }
- else
- mpr("The air shimmers briefly.");
- }
- else
- {
- // Cast a destructive spell.
- const spell_type spl = static_cast<spell_type>(
- random_choose_weighted(114, SPELL_BOLT_OF_FIRE,
- 57, SPELL_LIGHTNING_BOLT,
- 57, SPELL_BOLT_OF_DRAINING,
- 12, SPELL_HELLFIRE,
- 0));
- your_spells(spl, you.skills[SK_EVOCATIONS] * 8, false);
- }
-
- return (rc);
-}
-
static bool _efreet_flask(int slot)
{
bool friendly = x_chance_in_y(10 + you.skills[SK_EVOCATIONS] / 3, 20);
@@ -825,12 +723,20 @@ bool evoke_item(int slot)
if (!item_is_evokable(item, false, false, true))
return (false);
- int power = 0;
int pract = 0; // By how much Evocations is practised.
bool did_work = false; // Used for default "nothing happens" message.
bool unevokable = false;
- switch (item.base_type)
+ const unrandart_entry *entry = is_unrandom_artefact(item)
+ ? get_unrand_entry(item.special) : NULL;
+
+ if (entry && entry->evoke_func)
+ {
+ ASSERT(item_is_equipped(item));
+ if (entry->evoke_func(&item, &pract, &did_work, &unevokable))
+ return (did_work);
+ }
+ else switch (item.base_type)
{
case OBJ_WANDS:
zap_wand(slot);
@@ -843,92 +749,12 @@ bool evoke_item(int slot)
{
if (_reaching_weapon_attack(item))
{
- pract = 0;
+ pract = 0;
did_work = true;
}
else
return (false);
}
- else if (is_unrandom_artefact(item))
- {
- switch (item.special)
- {
- case UNRAND_DISPATER:
- if (you.duration[DUR_DEATHS_DOOR] || !enough_hp(11, true)
- || !enough_mp(5, true))
- {
- break;
- }
-
- mpr("You feel the staff feeding on your energy!");
-
- dec_hp( 5 + random2avg(19, 2), false, "Staff of Dispater" );
- dec_mp( 2 + random2avg(5, 2) );
- make_hungry(100, false, true);
-
- power = you.skills[SK_EVOCATIONS] * 8;
- your_spells( SPELL_HELLFIRE, power, false );
- pract = (coinflip() ? 2 : 1);
- did_work = true;
- break;
-
- case UNRAND_ASMODEUS:
- if (evoke_sceptre_of_asmodeus())
- {
- make_hungry(200, false, true);
- did_work = true;
- pract = 1;
- }
- break;
-
- case UNRAND_OLGREB:
- if (!enough_mp( 4, true )
- || you.skills[SK_EVOCATIONS] < random2(6))
- {
- break;
- }
-
- dec_mp(4);
- make_hungry(50, false, true);
- pract = 1;
- did_work = true;
-
- power = 10 + you.skills[SK_EVOCATIONS] * 8;
-
- your_spells( SPELL_OLGREBS_TOXIC_RADIANCE, power, false );
-
- if (x_chance_in_y(you.skills[SK_EVOCATIONS] + 1, 10))
- your_spells( SPELL_VENOM_BOLT, power, false );
- break;
-
- case UNRAND_WUCAD_MU:
- if (you.magic_points == you.max_magic_points
- || you.skills[SK_EVOCATIONS] < random2(25))
- {
- break;
- }
-
- mpr("Magical energy flows into your mind!");
-
- inc_mp( 3 + random2(5) + you.skills[SK_EVOCATIONS] / 3, false );
- make_hungry(50, false, true);
- pract = 1;
- did_work = true;
-
- if (one_chance_in(3))
- {
- // NH_NEVER prevents "nothing happens" messages.
- MiscastEffect( &you, NON_MONSTER, SPTYP_DIVINATION,
- random2(9), random2(70),
- "the Staff of Wucad Mu", NH_NEVER );
- }
- break;
-
- default:
- unevokable = true;
- break;
- }
- }
else
unevokable = true;
break;