summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/art-func.h
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2009-06-27 09:58:49 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2009-06-27 09:58:49 +0000
commit7aa3305f41d2f073710d9a732bd29572b704bc49 (patch)
tree374aa17118ecb68bc4c237176506dbaf9aafb0b7 /crawl-ref/source/art-func.h
parent3cc681e30ac236f7b88adece29f194cb30138ec8 (diff)
downloadcrawl-ref-7aa3305f41d2f073710d9a732bd29572b704bc49.tar.gz
crawl-ref-7aa3305f41d2f073710d9a732bd29572b704bc49.zip
* Moved most hard-coded non-standard unrandart behaviour to art-func.h,
specifically code for equipping, unequpping, an equipped unrandart doing something every time world_reacts() is called (special wield effects), melee hit effects, and evoking. Left hardcoded outside of art-func.h: * Sword of Cerebov temproarily downgrading the defender's fire resistance. * Staff of Olgreb boosting poison spells, as if it were a staff of poison. * Vampire's Tooth always getting maximal vampiric drain. * Mace of Variablity's initial pluses being chosen at creation time. * Since what used to be special wield effects is now handled very differently, noisy weapons and the lantern of shadows effects are handled with player attributes rather than SPWLD_NOISES and SPWLD_SHADOW. * Unrandarts can now have an elemental colour for their colour (currently only used for the Mace of Variability). * Unrandarts' value modification, being special, and being evil are now handled in art-data.txt rather than being hardcoded. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@10055 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/art-func.h')
-rw-r--r--crawl-ref/source/art-func.h484
1 files changed, 484 insertions, 0 deletions
diff --git a/crawl-ref/source/art-func.h b/crawl-ref/source/art-func.h
new file mode 100644
index 0000000000..20d5694e8d
--- /dev/null
+++ b/crawl-ref/source/art-func.h
@@ -0,0 +1,484 @@
+/*
+ * File: art-func.h
+ * Summary: Functions non-standard unrandarts uses.
+ * Written by: Matthew Cline
+ *
+ * Modified for Crawl Reference by $Author$ on $Date$
+ */
+
+/*
+ * util/art-data.pl scans through this file to grab the functions
+ * non-standard unrandarts use and put them into the unranddata structs
+ * in art-data.h, so the function names must have the form of
+ * _UNRAND_ENUM_func_name() in order to be recognized.
+ */
+
+#ifdef ART_FUNC_H
+#error "art-func.h included twice!"
+#endif
+
+#ifdef ART_DATA_H
+#error "art-func.h must be included before art-data.h"
+#endif
+
+#define ART_FUNC_H
+
+#include "effects.h" // For Sceptre of Torment tormenting
+#include "food.h" // For evokes
+#include "monplace.h" // For Sceptre of Asmodeus evoke
+#include "monstuff.h" // For Scythe of Curses cursing items
+#include "spells3.h" // For Zonguldrok animating dead
+#include "spl-cast.h" // For evokes
+#include "spl-mis.h" // For Staff of Wucad Mu miscasts
+
+/*******************
+ * Helper functions.
+ *******************/
+
+static void _equip_mpr(bool* show_msgs, const char* msg,
+ msg_channel_type chan = MSGCH_PLAIN)
+{
+ bool def_show = true;
+
+ if (show_msgs == NULL)
+ show_msgs = &def_show;
+
+ if (*show_msgs)
+ mpr(msg, chan);
+
+ // Caller shouldn't give any more messages.
+ *show_msgs = false;
+}
+
+/*******************
+ * Unrand functions.
+ *******************/
+
+static void _ASMODEUS_melee_effect(item_def* weapon, actor* attacker,
+ actor* defender, bool mondied)
+{
+ if (attacker->atype() == ACT_PLAYER)
+ {
+ did_god_conduct(DID_UNHOLY, 3);
+ }
+}
+
+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 _ASMODEUS_evoke(item_def *item, int* pract, bool* did_work,
+ bool* unevokable)
+{
+ if (_evoke_sceptre_of_asmodeus())
+ {
+ make_hungry(200, false, true);
+ *did_work = true;
+ *pract = 1;
+ }
+
+ return (false);
+}
+
+////////////////////////////////////////////////////
+
+// XXX: Defender's resistance to fire being temporarily downgraded is
+// hardcoded in melee_attack::fire_res_apply_cerebov_downgrade()
+
+static void _CEREBOV_melee_effect(item_def* weapon, actor* attacker,
+ actor* defender, bool mondied)
+{
+ if (attacker->atype() == ACT_PLAYER)
+ {
+ did_god_conduct(DID_UNHOLY, 3);
+ }
+}
+
+////////////////////////////////////////////////////
+
+static void _CURSES_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ _equip_mpr(show_msgs, "A shiver runs down your spine.");
+}
+
+static void _CURSES_world_reacts(item_def *item)
+{
+ if (one_chance_in(30))
+ curse_an_item(false);
+}
+
+static void _CURSES_melee_effect(item_def* weapon, actor* attacker,
+ actor* defender, bool mondied)
+{
+ if (attacker->atype() == ACT_PLAYER)
+ {
+ did_god_conduct(DID_NECROMANCY, 3);
+ }
+}
+
+/////////////////////////////////////////////////////
+
+static void _DISPATER_melee_effect(item_def* weapon, actor* attacker,
+ actor* defender, bool mondied)
+{
+ if (attacker->atype() == ACT_PLAYER)
+ {
+ did_god_conduct(DID_UNHOLY, 3);
+ }
+}
+
+static bool _DISPATER_evoke(item_def *item, int* pract, bool* did_work,
+ bool* unevokable)
+{
+ if (you.duration[DUR_DEATHS_DOOR] || !enough_hp(11, true)
+ || !enough_mp(5, true))
+ {
+ return (false);
+ }
+
+ 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);
+
+ int power = you.skills[SK_EVOCATIONS] * 8;
+ your_spells( SPELL_HELLFIRE, power, false );
+
+ *pract = (coinflip() ? 2 : 1);
+ *did_work = true;
+
+ return (false);
+}
+
+////////////////////////////////////////////////////
+
+// XXX: Staff giving a boost to poison spells is hardocded in
+// player_spec_poison()
+
+static void _olgreb_pluses(item_def *item)
+{
+ // Giving Olgreb's staff a little lift since staves of poison have
+ // been made better. -- bwr
+ item->plus = you.skills[SK_POISON_MAGIC] / 3;
+ item->plus2 = item->plus;
+}
+
+static void _OLGREB_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ if (player_can_smell())
+ _equip_mpr(show_msgs, "You smell chlorine.");
+ else
+ _equip_mpr(show_msgs, "The staff glows a sickly green.");
+
+ _olgreb_pluses(item);
+}
+
+static void _OLGREB_unequip(const item_def *item, bool *show_msgs)
+{
+ if (player_can_smell())
+ _equip_mpr(show_msgs, "The smell of chlorine vanishes.");
+ else
+ _equip_mpr(show_msgs, "The staff's sickly green glow vanishes.");
+}
+
+static void _OLGREB_world_reacts(item_def *item)
+{
+ _olgreb_pluses(item);
+}
+
+static bool _OLGREB_evoke(item_def *item, int* pract, bool* did_work,
+ bool* unevokable)
+{
+ if (!enough_mp( 4, true ) || you.skills[SK_EVOCATIONS] < random2(6))
+ return (false);
+
+ dec_mp(4);
+ make_hungry(50, false, true);
+ *pract = 1;
+ *did_work = true;
+
+ int 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 );
+
+ return (false);
+}
+
+////////////////////////////////////////////////////
+
+static void _power_pluses(item_def *item)
+{
+ item->plus = stepdown_value( -4 + (you.hp / 5), 4, 4, 4, 20 );
+ item->plus2 = item->plus;
+}
+
+static void _POWER_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ _equip_mpr(show_msgs, "You sense an aura of extreme power.");
+ _power_pluses(item);
+}
+
+static void _POWER_world_reacts(item_def *item)
+{
+ _power_pluses(item);
+}
+
+////////////////////////////////////////////////////
+
+static void _SINGING_SWORD_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ bool def_show = true;
+
+ if (show_msgs == NULL)
+ show_msgs = &def_show;
+
+ if (!*show_msgs)
+ return;
+
+ if (item_type_known(*item))
+ {
+ mprf(MSGCH_TALK, "%s says, \"Hi! I'm the Singing Sword!\"",
+ item->name(DESC_CAP_THE).c_str());
+ }
+ else
+ mpr("The Singing Sword hums in delight!", MSGCH_TALK);
+
+ *show_msgs = false;
+
+ // Make noisy_equipment() use a special speech database key.
+ item->props[ART_NOISE_KEY] = "Singing Sword";
+}
+
+static void _SINGING_SWORD_unequip(const item_def *item, bool *show_msgs)
+{
+ _equip_mpr(show_msgs, "The Singing Sword sighs.", MSGCH_TALK);
+}
+
+////////////////////////////////////////////////////
+
+static void _PRUNE_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ _equip_mpr(show_msgs, "You feel pruney.");
+}
+
+////////////////////////////////////////////////////
+
+static void _TORMENT_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ _equip_mpr(show_msgs, "A terribly searing pain shoots up your arm!");
+}
+
+static void _TORMENT_world_reacts(item_def *item)
+{
+ if (one_chance_in(200))
+ {
+ torment(TORMENT_SPWLD, you.pos());
+ did_god_conduct(DID_UNHOLY, 1);
+ }
+}
+
+static void _TORMENT_melee_effect(item_def* weapon, actor* attacker,
+ actor* defender, bool mondied)
+{
+ if (attacker->atype() == ACT_PLAYER && coinflip())
+ {
+ torment(TORMENT_SPWLD, you.pos());
+ did_god_conduct(DID_UNHOLY, 5);
+ }
+}
+
+/////////////////////////////////////////////////////
+
+static void _TROG_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ _equip_mpr(show_msgs, "You feel bloodthirsty!");
+}
+
+static void _TROG_unequip(const item_def *item, bool *show_msgs)
+{
+ _equip_mpr(show_msgs, "You feel less violent.");
+}
+
+static void _TROG_melee_effect(item_def* weapon, actor* attacker,
+ actor* defender, bool mondied)
+{
+ if (coinflip())
+ attacker->go_berserk(false);
+}
+
+////////////////////////////////////////////////////
+
+static void _wucad_miscast(actor* victim, int power,int fail)
+{
+ MiscastEffect(victim, WIELD_MISCAST, SPTYP_DIVINATION, power, fail,
+ "the Staff of Wucad Mu", NH_NEVER);
+}
+
+static void _wucad_pluses(item_def *item)
+{
+ item->plus = std::min(you.intel - 3, 22);
+ item->plus2 = std::min(you.intel / 2, 13);
+}
+
+static void _WUCAD_MU_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ _wucad_miscast(&you, 9, 90);
+ _wucad_pluses(item);
+}
+
+static void _WUCAD_MU_unequip(const item_def *item, bool *show_msgs)
+{
+ _wucad_miscast(&you, 9, 90);
+}
+
+static void _WUCAD_MU_world_reacts(item_def *item)
+{
+ _wucad_pluses(item);
+}
+
+static void _WUCAD_MU_melee_effect(item_def* weapon, actor* attacker,
+ actor* defender, bool mondied)
+{
+ if (one_chance_in(9))
+ _wucad_miscast(attacker, random2(9), random2(70));
+}
+
+static bool _WUCAD_MU_evoke(item_def *item, int* pract, bool* did_work,
+ bool* unevokable)
+{
+ if (you.magic_points == you.max_magic_points
+ || you.skills[SK_EVOCATIONS] < random2(25))
+ {
+ return (false);
+ }
+
+ 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))
+ _wucad_miscast(&you, random2(9), random2(70));
+
+ return (false);
+}
+
+///////////////////////////////////////////////////
+
+// XXX: Always getting maximal vampiric drain is harcoded in
+// melee_attack::apply_damage_brand()
+
+static void _VAMPIRES_TOOTH_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ if (you.is_undead != US_UNDEAD)
+ {
+ _equip_mpr(show_msgs,
+ "You feel a strange hunger, and smell blood in the air...");
+ }
+ else
+ _equip_mpr(show_msgs, "You feel strangely empty.");
+
+ // Vampire's Tooth imposes more hunger than a normal vampiric
+ // weapon. Like other vampiric weapons, the hunger is less for
+ // vampires than for other species.
+ if (you.species != SP_VAMPIRE)
+ artefact_set_property(*item, ARTP_METABOLISM, 3);
+ else
+ artefact_set_property(*item, ARTP_METABOLISM, 1);
+}
+
+///////////////////////////////////////////////////
+
+// XXX: Pluses at creation time are hardcoded in make_item_unrandart()
+
+static void _VARIABILITY_world_reacts(item_def *item)
+{
+ do_uncurse_item(*item);
+
+ if (x_chance_in_y(2, 5))
+ item->plus += (coinflip() ? +1 : -1);
+
+ if (x_chance_in_y(2, 5))
+ item->plus2 += (coinflip() ? +1 : -1);
+
+ if (item->plus < -4)
+ item->plus = -4;
+ else if (item->plus > 16)
+ item->plus = 16;
+
+ if (item->plus2 < -4)
+ item->plus2 = -4;
+ else if (item->plus2 > 16)
+ item->plus2 = 16;
+}
+
+///////////////////////////////////////////////////
+
+static void _ZONGULDROK_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ _equip_mpr(show_msgs, "You sense an extremely unholy aura.");
+}
+
+static void _ZONGULDROK_world_reacts(item_def *item)
+{
+ if (one_chance_in(5))
+ {
+ animate_dead(&you, 1 + random2(3), BEH_HOSTILE, MHITYOU);
+ did_god_conduct(DID_NECROMANCY, 1);
+ }
+}
+
+static void _ZONGULDROK_melee_effect(item_def* weapon, actor* attacker,
+ actor* defender, bool mondied)
+{
+ if (attacker->atype() == ACT_PLAYER)
+ {
+ did_god_conduct(DID_NECROMANCY, 3);
+ }
+}
+
+///////////////////////////////////////////////////
+