00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifdef ART_FUNC_H
00015 #error "art-func.h included twice!"
00016 #endif
00017
00018 #ifdef ART_DATA_H
00019 #error "art-func.h must be included before art-data.h"
00020 #endif
00021
00022 #define ART_FUNC_H
00023
00024 #include "cloud.h"
00025 #include "effects.h"
00026 #include "env.h"
00027 #include "food.h"
00028 #include "godconduct.h"
00029 #include "mgen_data.h"
00030 #include "mon-place.h"
00031 #include "mon-stuff.h"
00032 #include "spl-cast.h"
00033 #include "spl-miscast.h"
00034 #include "spl-summoning.h"
00035 #include "terrain.h"
00036
00037
00038
00039
00040
00041 static void _equip_mpr(bool* show_msgs, const char* msg,
00042 msg_channel_type chan = MSGCH_PLAIN)
00043 {
00044 bool def_show = true;
00045
00046 if (show_msgs == NULL)
00047 show_msgs = &def_show;
00048
00049 if (*show_msgs)
00050 mpr(msg, chan);
00051
00052
00053 *show_msgs = false;
00054 }
00055
00056
00057
00058
00059
00060 static void _ASMODEUS_melee_effect(item_def* weapon, actor* attacker,
00061 actor* defender, bool mondied)
00062 {
00063 if (attacker->atype() == ACT_PLAYER)
00064 {
00065 did_god_conduct(DID_UNHOLY, 3);
00066 }
00067 }
00068
00069 static bool _evoke_sceptre_of_asmodeus()
00070 {
00071 bool rc = true;
00072 if (one_chance_in(21))
00073 rc = false;
00074 else if (one_chance_in(20))
00075 {
00076
00077 const monster_type mon = (one_chance_in(4) ? MONS_FIEND :
00078 summon_any_demon(DEMON_COMMON));
00079 const bool good_summon = create_monster(
00080 mgen_data::hostile_at(mon,
00081 "the Sceptre of Asmodeus",
00082 true, 6, 0, you.pos())) != -1;
00083
00084 if (good_summon)
00085 {
00086 if (mon == MONS_FIEND)
00087 mpr("\"Your arrogance condemns you, mortal!\"");
00088 else
00089 mpr("The Sceptre summons one of its servants.");
00090 }
00091 else
00092 mpr("The air shimmers briefly.");
00093 }
00094 else
00095 {
00096
00097 const spell_type spl = static_cast<spell_type>(
00098 random_choose_weighted(114, SPELL_BOLT_OF_FIRE,
00099 57, SPELL_LIGHTNING_BOLT,
00100 57, SPELL_BOLT_OF_DRAINING,
00101 12, SPELL_HELLFIRE,
00102 0));
00103 your_spells(spl, you.skills[SK_EVOCATIONS] * 8, false);
00104 }
00105
00106 return (rc);
00107 }
00108
00109
00110 static bool _ASMODEUS_evoke(item_def *item, int* pract, bool* did_work,
00111 bool* unevokable)
00112 {
00113 if (_evoke_sceptre_of_asmodeus())
00114 {
00115 make_hungry(200, false, true);
00116 *did_work = true;
00117 *pract = 1;
00118 }
00119
00120 return (false);
00121 }
00122
00124
00125
00126
00127
00128 static void _CEREBOV_melee_effect(item_def* weapon, actor* attacker,
00129 actor* defender, bool mondied)
00130 {
00131 if (attacker->atype() == ACT_PLAYER)
00132 {
00133 did_god_conduct(DID_UNHOLY, 3);
00134 }
00135 }
00136
00138
00139 static void _CURSES_equip(item_def *item, bool *show_msgs, bool unmeld)
00140 {
00141 _equip_mpr(show_msgs, "A shiver runs down your spine.");
00142 }
00143
00144 static void _CURSES_world_reacts(item_def *item)
00145 {
00146 if (one_chance_in(30))
00147 curse_an_item(false);
00148 }
00149
00150 static void _CURSES_melee_effect(item_def* weapon, actor* attacker,
00151 actor* defender, bool mondied)
00152 {
00153 if (attacker->atype() == ACT_PLAYER)
00154 {
00155 did_god_conduct(DID_NECROMANCY, 3);
00156 }
00157 }
00158
00160
00161 static void _DISPATER_melee_effect(item_def* weapon, actor* attacker,
00162 actor* defender, bool mondied)
00163 {
00164 if (attacker->atype() == ACT_PLAYER)
00165 {
00166 did_god_conduct(DID_UNHOLY, 3);
00167 }
00168 }
00169
00170 static bool _DISPATER_evoke(item_def *item, int* pract, bool* did_work,
00171 bool* unevokable)
00172 {
00173 if (you.duration[DUR_DEATHS_DOOR] || !enough_hp(11, true)
00174 || !enough_mp(5, true))
00175 {
00176 return (false);
00177 }
00178
00179 mpr("You feel the staff feeding on your energy!");
00180
00181 dec_hp(5 + random2avg(19, 2), false, "Staff of Dispater");
00182 dec_mp(2 + random2avg(5, 2));
00183 make_hungry(100, false, true);
00184
00185 int power = you.skills[SK_EVOCATIONS] * 8;
00186 your_spells(SPELL_HELLFIRE, power, false);
00187
00188 *pract = (coinflip() ? 2 : 1);
00189 *did_work = true;
00190
00191 return (false);
00192 }
00193
00195
00196
00197
00198
00199 static void _olgreb_pluses(item_def *item)
00200 {
00201
00202
00203 item->plus = you.skills[SK_POISON_MAGIC] / 3;
00204 item->plus2 = item->plus;
00205 }
00206
00207 static void _OLGREB_equip(item_def *item, bool *show_msgs, bool unmeld)
00208 {
00209 if (you.can_smell())
00210 _equip_mpr(show_msgs, "You smell chlorine.");
00211 else
00212 _equip_mpr(show_msgs, "The staff glows a sickly green.");
00213
00214 _olgreb_pluses(item);
00215 }
00216
00217 static void _OLGREB_unequip(const item_def *item, bool *show_msgs)
00218 {
00219 if (you.can_smell())
00220 _equip_mpr(show_msgs, "The smell of chlorine vanishes.");
00221 else
00222 _equip_mpr(show_msgs, "The staff's sickly green glow vanishes.");
00223 }
00224
00225 static void _OLGREB_world_reacts(item_def *item)
00226 {
00227 _olgreb_pluses(item);
00228 }
00229
00230 static bool _OLGREB_evoke(item_def *item, int* pract, bool* did_work,
00231 bool* unevokable)
00232 {
00233 if (!enough_mp(4, true) || you.skills[SK_EVOCATIONS] < random2(6))
00234 return (false);
00235
00236 dec_mp(4);
00237 make_hungry(50, false, true);
00238 *pract = 1;
00239 *did_work = true;
00240
00241 int power = 10 + you.skills[SK_EVOCATIONS] * 8;
00242
00243 your_spells(SPELL_OLGREBS_TOXIC_RADIANCE, power, false);
00244
00245 if (x_chance_in_y(you.skills[SK_EVOCATIONS] + 1, 10))
00246 your_spells(SPELL_VENOM_BOLT, power, false);
00247
00248 return (false);
00249 }
00250
00251 static void _OLGREB_melee_effect(item_def* weapon, actor* attacker,
00252 actor* defender, bool mondied)
00253 {
00254 if (defender->alive()
00255 && (coinflip() || x_chance_in_y(you.skills[SK_POISON_MAGIC], 8)))
00256 {
00257 defender->poison(attacker, 2, defender->has_lifeforce()
00258 && one_chance_in(4));
00259 if (attacker->atype() == ACT_PLAYER)
00260 did_god_conduct(DID_POISON, 3);
00261 }
00262 }
00263
00265
00266 static void _power_pluses(item_def *item)
00267 {
00268 item->plus = stepdown_value(-4 + (you.hp / 5), 4, 4, 4, 20);
00269 item->plus2 = item->plus;
00270 }
00271
00272 static void _POWER_equip(item_def *item, bool *show_msgs, bool unmeld)
00273 {
00274 _equip_mpr(show_msgs, "You sense an aura of extreme power.");
00275 _power_pluses(item);
00276 }
00277
00278 static void _POWER_world_reacts(item_def *item)
00279 {
00280 _power_pluses(item);
00281 }
00282
00284
00285 static void _SINGING_SWORD_equip(item_def *item, bool *show_msgs, bool unmeld)
00286 {
00287 bool def_show = true;
00288
00289 if (show_msgs == NULL)
00290 show_msgs = &def_show;
00291
00292 if (!*show_msgs)
00293 return;
00294
00295 if (!item_type_known(*item))
00296 {
00297 mprf(MSGCH_TALK, "%s says, \"Hi! I'm the Singing Sword!\"",
00298 item->name(DESC_CAP_THE).c_str());
00299 }
00300 else
00301 mpr("The Singing Sword hums in delight!", MSGCH_TALK);
00302
00303 *show_msgs = false;
00304 }
00305
00306 static void _SINGING_SWORD_unequip(const item_def *item, bool *show_msgs)
00307 {
00308 _equip_mpr(show_msgs, "The Singing Sword sighs.", MSGCH_TALK);
00309 }
00310
00312
00313 static void _PRUNE_equip(item_def *item, bool *show_msgs, bool unmeld)
00314 {
00315 _equip_mpr(show_msgs, "You feel pruney.");
00316 }
00317
00319
00320 static void _TORMENT_equip(item_def *item, bool *show_msgs, bool unmeld)
00321 {
00322 _equip_mpr(show_msgs, "A terribly searing pain shoots up your arm!");
00323 }
00324
00325 static void _TORMENT_world_reacts(item_def *item)
00326 {
00327 if (one_chance_in(200))
00328 {
00329 torment(TORMENT_SPWLD, you.pos());
00330 did_god_conduct(DID_UNHOLY, 1);
00331 }
00332 }
00333
00334 static void _TORMENT_melee_effect(item_def* weapon, actor* attacker,
00335 actor* defender, bool mondied)
00336 {
00337 if (attacker->atype() == ACT_PLAYER && coinflip())
00338 {
00339 torment(TORMENT_SPWLD, you.pos());
00340 did_god_conduct(DID_UNHOLY, 5);
00341 }
00342 }
00343
00345
00346 static void _TROG_equip(item_def *item, bool *show_msgs, bool unmeld)
00347 {
00348 _equip_mpr(show_msgs, "You feel bloodthirsty!");
00349 }
00350
00351 static void _TROG_unequip(const item_def *item, bool *show_msgs)
00352 {
00353 _equip_mpr(show_msgs, "You feel less violent.");
00354 }
00355
00356 static void _TROG_melee_effect(item_def* weapon, actor* attacker,
00357 actor* defender, bool mondied)
00358 {
00359 if (coinflip())
00360 attacker->go_berserk(false);
00361 }
00362
00364
00365 static void _wucad_miscast(actor* victim, int power,int fail)
00366 {
00367 MiscastEffect(victim, WIELD_MISCAST, SPTYP_DIVINATION, power, fail,
00368 "the Staff of Wucad Mu", NH_NEVER);
00369 }
00370
00371 static void _wucad_pluses(item_def *item)
00372 {
00373 item->plus = std::min(you.intel() - 3, 22);
00374 item->plus2 = std::min(you.intel() / 2, 13);
00375 }
00376
00377 static void _WUCAD_MU_equip(item_def *item, bool *show_msgs, bool unmeld)
00378 {
00379 _wucad_miscast(&you, 9, 90);
00380 _wucad_pluses(item);
00381 }
00382
00383 static void _WUCAD_MU_unequip(const item_def *item, bool *show_msgs)
00384 {
00385 _wucad_miscast(&you, 9, 90);
00386 }
00387
00388 static void _WUCAD_MU_world_reacts(item_def *item)
00389 {
00390 _wucad_pluses(item);
00391 }
00392
00393 static void _WUCAD_MU_melee_effect(item_def* weapon, actor* attacker,
00394 actor* defender, bool mondied)
00395 {
00396 if (one_chance_in(9))
00397 _wucad_miscast(attacker, random2(9), random2(70));
00398 }
00399
00400 static bool _WUCAD_MU_evoke(item_def *item, int* pract, bool* did_work,
00401 bool* unevokable)
00402 {
00403 if (you.magic_points == you.max_magic_points
00404 || you.skills[SK_EVOCATIONS] < random2(25))
00405 {
00406 return (false);
00407 }
00408
00409 mpr("Magical energy flows into your mind!");
00410
00411 inc_mp(3 + random2(5) + you.skills[SK_EVOCATIONS] / 3, false);
00412 make_hungry(50, false, true);
00413
00414 *pract = 1;
00415 *did_work = true;
00416
00417 if (one_chance_in(3))
00418 _wucad_miscast(&you, random2(9), random2(70));
00419
00420 return (false);
00421 }
00422
00424
00425
00426
00427
00428 static void _VAMPIRES_TOOTH_equip(item_def *item, bool *show_msgs, bool unmeld)
00429 {
00430 if (you.is_undead != US_UNDEAD)
00431 {
00432 _equip_mpr(show_msgs,
00433 "You feel a strange hunger, and smell blood in the air...");
00434 make_hungry(4500, false, false);
00435 }
00436 else
00437 _equip_mpr(show_msgs, "You feel strangely empty.");
00438 }
00439
00441
00442
00443
00444 static void _VARIABILITY_world_reacts(item_def *item)
00445 {
00446 do_uncurse_item(*item);
00447
00448 if (x_chance_in_y(2, 5))
00449 item->plus += (coinflip() ? +1 : -1);
00450
00451 if (x_chance_in_y(2, 5))
00452 item->plus2 += (coinflip() ? +1 : -1);
00453
00454 if (item->plus < -4)
00455 item->plus = -4;
00456 else if (item->plus > 16)
00457 item->plus = 16;
00458
00459 if (item->plus2 < -4)
00460 item->plus2 = -4;
00461 else if (item->plus2 > 16)
00462 item->plus2 = 16;
00463 }
00464
00466
00467 static void _ZONGULDROK_equip(item_def *item, bool *show_msgs, bool unmeld)
00468 {
00469 _equip_mpr(show_msgs, "You sense an extremely unholy aura.");
00470 }
00471
00472 static void _ZONGULDROK_world_reacts(item_def *item)
00473 {
00474 if (one_chance_in(5))
00475 {
00476 animate_dead(&you, 1 + random2(3), BEH_HOSTILE, MHITYOU, 0,
00477 "the Sword of Zonguldrok");
00478 did_god_conduct(DID_NECROMANCY, 1);
00479 did_god_conduct(DID_CORPSE_VIOLATION, 1);
00480 }
00481 }
00482
00483 static void _ZONGULDROK_melee_effect(item_def* weapon, actor* attacker,
00484 actor* defender, bool mondied)
00485 {
00486 if (attacker->atype() == ACT_PLAYER)
00487 {
00488 did_god_conduct(DID_NECROMANCY, 3);
00489 did_god_conduct(DID_CORPSE_VIOLATION, 3);
00490 }
00491 }
00492
00494
00495 static void _STORM_BOW_world_reacts(item_def *item)
00496 {
00497 if (!one_chance_in(300))
00498 return;
00499
00500 for (radius_iterator ri(you.pos(), 2); ri; ++ri)
00501 if (!cell_is_solid(*ri) && env.cgrid(*ri) == EMPTY_CLOUD && one_chance_in(5))
00502 place_cloud(CLOUD_RAIN, *ri, random2(20), &you, 3);
00503 }
00504
00506
00507 static void _GONG_melee_effect(item_def* item, actor* wearer,
00508 actor* attacker, bool dummy)
00509 {
00510 if (silenced(wearer->pos()))
00511 return;
00512
00513 std::string msg = getSpeakString("shield of the gong");
00514 if (msg.empty())
00515 msg = "You hear a strange loud sound.";
00516 mpr(msg.c_str(), MSGCH_SOUND);
00517
00518 noisy(40, wearer->pos());
00519 }
00520
00522
00523 static void _RCLOUDS_world_reacts(item_def *item)
00524 {
00525 cloud_type cloud;
00526 if (one_chance_in(4))
00527 cloud = CLOUD_RAIN;
00528 else
00529 cloud = CLOUD_MIST;
00530
00531 for (radius_iterator ri(you.pos(), 2); ri; ++ri)
00532 if (!cell_is_solid(*ri) && env.cgrid(*ri) == EMPTY_CLOUD
00533 && one_chance_in(20))
00534 {
00535 place_cloud(cloud, *ri, random2(10), &you, 1);
00536 }
00537 }
00538
00539 static void _RCLOUDS_equip(item_def *item, bool *show_msgs, bool unmeld)
00540 {
00541 _equip_mpr(show_msgs, "A thin mist springs up around you!");
00542 }