3 * Summary: Functions non-standard unrandarts uses.
4 * Written by: Matthew Cline
8 * util/art-data.pl scans through this file to grab the functions
9 * non-standard unrandarts use and put them into the unranddata structs
10 * in art-data.h, so the function names must have the form of
11 * _UNRAND_ENUM_func_name() in order to be recognised.
15 #error "art-func.h included twice!"
19 #error "art-func.h must be included before art-data.h"
24 #include "cloud.h" // For storm bow's and robe of clouds' rain
25 #include "effects.h" // For Sceptre of Torment tormenting
26 #include "env.h" // For storm bow env.cgrid
27 #include "food.h" // For evokes
28 #include "godconduct.h" // did_god_conduct.
29 #include "mgen_data.h" // For Sceptre of Asmodeus evoke
30 #include "mon-place.h" // For Sceptre of Asmodeus evoke
31 #include "mon-stuff.h" // For Scythe of Curses cursing items
32 #include "spl-cast.h" // For evokes
33 #include "spl-miscast.h" // For Staff of Wucad Mu miscasts
34 #include "spl-summoning.h" // For Zonguldrok animating dead
35 #include "terrain.h" // For storm bow.
41 static void _equip_mpr(bool* show_msgs
, const char* msg
,
42 msg_channel_type chan
= MSGCH_PLAIN
)
46 if (show_msgs
== NULL
)
47 show_msgs
= &def_show
;
52 // Caller shouldn't give any more messages.
60 static void _ASMODEUS_melee_effect(item_def
* weapon
, actor
* attacker
,
61 actor
* defender
, bool mondied
)
63 if (attacker
->atype() == ACT_PLAYER
)
65 did_god_conduct(DID_UNHOLY
, 3);
69 static bool _evoke_sceptre_of_asmodeus()
72 if (one_chance_in(21))
74 else if (one_chance_in(20))
76 // Summon devils, maybe a Fiend.
77 const monster_type mon
= (one_chance_in(4) ? MONS_FIEND
:
78 summon_any_demon(DEMON_COMMON
));
79 const bool good_summon
= create_monster(
80 mgen_data::hostile_at(mon
,
81 "the Sceptre of Asmodeus",
82 true, 6, 0, you
.pos())) != -1;
86 if (mon
== MONS_FIEND
)
87 mpr("\"Your arrogance condemns you, mortal!\"");
89 mpr("The Sceptre summons one of its servants.");
92 mpr("The air shimmers briefly.");
96 // Cast a destructive spell.
97 const spell_type spl
= static_cast<spell_type
>(
98 random_choose_weighted(114, SPELL_BOLT_OF_FIRE
,
99 57, SPELL_LIGHTNING_BOLT
,
100 57, SPELL_BOLT_OF_DRAINING
,
103 your_spells(spl
, you
.skills
[SK_EVOCATIONS
] * 8, false);
110 static bool _ASMODEUS_evoke(item_def
*item
, int* pract
, bool* did_work
,
113 if (_evoke_sceptre_of_asmodeus())
115 make_hungry(200, false, true);
123 ////////////////////////////////////////////////////
125 // XXX: Defender's resistance to fire being temporarily downgraded is
126 // hardcoded in melee_attack::fire_res_apply_cerebov_downgrade()
128 static void _CEREBOV_melee_effect(item_def
* weapon
, actor
* attacker
,
129 actor
* defender
, bool mondied
)
131 if (attacker
->atype() == ACT_PLAYER
)
133 did_god_conduct(DID_UNHOLY
, 3);
137 ////////////////////////////////////////////////////
139 static void _CURSES_equip(item_def
*item
, bool *show_msgs
, bool unmeld
)
141 _equip_mpr(show_msgs
, "A shiver runs down your spine.");
144 static void _CURSES_world_reacts(item_def
*item
)
146 if (one_chance_in(30))
147 curse_an_item(false);
150 static void _CURSES_melee_effect(item_def
* weapon
, actor
* attacker
,
151 actor
* defender
, bool mondied
)
153 if (attacker
->atype() == ACT_PLAYER
)
155 did_god_conduct(DID_NECROMANCY
, 3);
159 /////////////////////////////////////////////////////
161 static void _DISPATER_melee_effect(item_def
* weapon
, actor
* attacker
,
162 actor
* defender
, bool mondied
)
164 if (attacker
->atype() == ACT_PLAYER
)
166 did_god_conduct(DID_UNHOLY
, 3);
170 static bool _DISPATER_evoke(item_def
*item
, int* pract
, bool* did_work
,
173 if (you
.duration
[DUR_DEATHS_DOOR
] || !enough_hp(11, true)
174 || !enough_mp(5, true))
179 mpr("You feel the staff feeding on your energy!");
181 dec_hp(5 + random2avg(19, 2), false, "Staff of Dispater");
182 dec_mp(2 + random2avg(5, 2));
183 make_hungry(100, false, true);
185 int power
= you
.skills
[SK_EVOCATIONS
] * 8;
186 your_spells(SPELL_HELLFIRE
, power
, false);
188 *pract
= (coinflip() ? 2 : 1);
194 ////////////////////////////////////////////////////
196 // XXX: Staff giving a boost to poison spells is hardcoded in
197 // player_spec_poison()
199 static void _olgreb_pluses(item_def
*item
)
201 // Giving Olgreb's staff a little lift since staves of poison have
202 // been made better. -- bwr
203 item
->plus
= you
.skills
[SK_POISON_MAGIC
] / 3;
204 item
->plus2
= item
->plus
;
207 static void _OLGREB_equip(item_def
*item
, bool *show_msgs
, bool unmeld
)
210 _equip_mpr(show_msgs
, "You smell chlorine.");
212 _equip_mpr(show_msgs
, "The staff glows a sickly green.");
214 _olgreb_pluses(item
);
217 static void _OLGREB_unequip(const item_def
*item
, bool *show_msgs
)
220 _equip_mpr(show_msgs
, "The smell of chlorine vanishes.");
222 _equip_mpr(show_msgs
, "The staff's sickly green glow vanishes.");
225 static void _OLGREB_world_reacts(item_def
*item
)
227 _olgreb_pluses(item
);
230 static bool _OLGREB_evoke(item_def
*item
, int* pract
, bool* did_work
,
233 if (!enough_mp(4, true) || you
.skills
[SK_EVOCATIONS
] < random2(6))
237 make_hungry(50, false, true);
241 int power
= 10 + you
.skills
[SK_EVOCATIONS
] * 8;
243 your_spells(SPELL_OLGREBS_TOXIC_RADIANCE
, power
, false);
245 if (x_chance_in_y(you
.skills
[SK_EVOCATIONS
] + 1, 10))
246 your_spells(SPELL_VENOM_BOLT
, power
, false);
251 static void _OLGREB_melee_effect(item_def
* weapon
, actor
* attacker
,
252 actor
* defender
, bool mondied
)
254 if (defender
->alive()
255 && (coinflip() || x_chance_in_y(you
.skills
[SK_POISON_MAGIC
], 8)))
257 defender
->poison(attacker
, 2, defender
->has_lifeforce()
258 && one_chance_in(4));
259 if (attacker
->atype() == ACT_PLAYER
)
260 did_god_conduct(DID_POISON
, 3);
264 ////////////////////////////////////////////////////
266 static void _power_pluses(item_def
*item
)
268 item
->plus
= stepdown_value(-4 + (you
.hp
/ 5), 4, 4, 4, 20);
269 item
->plus2
= item
->plus
;
272 static void _POWER_equip(item_def
*item
, bool *show_msgs
, bool unmeld
)
274 _equip_mpr(show_msgs
, "You sense an aura of extreme power.");
278 static void _POWER_world_reacts(item_def
*item
)
283 ////////////////////////////////////////////////////
285 static void _SINGING_SWORD_equip(item_def
*item
, bool *show_msgs
, bool unmeld
)
287 bool def_show
= true;
289 if (show_msgs
== NULL
)
290 show_msgs
= &def_show
;
295 if (!item_type_known(*item
))
297 mprf(MSGCH_TALK
, "%s says, \"Hi! I'm the Singing Sword!\"",
298 item
->name(DESC_CAP_THE
).c_str());
301 mpr("The Singing Sword hums in delight!", MSGCH_TALK
);
306 static void _SINGING_SWORD_unequip(const item_def
*item
, bool *show_msgs
)
308 _equip_mpr(show_msgs
, "The Singing Sword sighs.", MSGCH_TALK
);
311 ////////////////////////////////////////////////////
313 static void _PRUNE_equip(item_def
*item
, bool *show_msgs
, bool unmeld
)
315 _equip_mpr(show_msgs
, "You feel pruney.");
318 ////////////////////////////////////////////////////
320 static void _TORMENT_equip(item_def
*item
, bool *show_msgs
, bool unmeld
)
322 _equip_mpr(show_msgs
, "A terribly searing pain shoots up your arm!");
325 static void _TORMENT_world_reacts(item_def
*item
)
327 if (one_chance_in(200))
329 torment(TORMENT_SPWLD
, you
.pos());
330 did_god_conduct(DID_UNHOLY
, 1);
334 static void _TORMENT_melee_effect(item_def
* weapon
, actor
* attacker
,
335 actor
* defender
, bool mondied
)
337 if (attacker
->atype() == ACT_PLAYER
&& coinflip())
339 torment(TORMENT_SPWLD
, you
.pos());
340 did_god_conduct(DID_UNHOLY
, 5);
344 /////////////////////////////////////////////////////
346 static void _TROG_equip(item_def
*item
, bool *show_msgs
, bool unmeld
)
348 _equip_mpr(show_msgs
, "You feel bloodthirsty!");
351 static void _TROG_unequip(const item_def
*item
, bool *show_msgs
)
353 _equip_mpr(show_msgs
, "You feel less violent.");
356 static void _TROG_melee_effect(item_def
* weapon
, actor
* attacker
,
357 actor
* defender
, bool mondied
)
360 attacker
->go_berserk(false);
363 ////////////////////////////////////////////////////
365 static void _wucad_miscast(actor
* victim
, int power
,int fail
)
367 MiscastEffect(victim
, WIELD_MISCAST
, SPTYP_DIVINATION
, power
, fail
,
368 "the Staff of Wucad Mu", NH_NEVER
);
371 static void _wucad_pluses(item_def
*item
)
373 item
->plus
= std::min(you
.intel() - 3, 22);
374 item
->plus2
= std::min(you
.intel() / 2, 13);
377 static void _WUCAD_MU_equip(item_def
*item
, bool *show_msgs
, bool unmeld
)
382 static void _WUCAD_MU_world_reacts(item_def
*item
)
387 static bool _WUCAD_MU_evoke(item_def
*item
, int* pract
, bool* did_work
,
390 if (you
.magic_points
== you
.max_magic_points
391 || you
.skills
[SK_EVOCATIONS
] < random2(25))
396 mpr("Magical energy flows into your mind!");
398 inc_mp(3 + random2(5) + you
.skills
[SK_EVOCATIONS
] / 3, false);
399 make_hungry(50, false, true);
404 if (one_chance_in(3))
405 _wucad_miscast(&you
, random2(9), random2(70));
410 ///////////////////////////////////////////////////
412 // XXX: Always getting maximal vampiric drain is hardcoded in
413 // melee_attack::apply_damage_brand()
415 static void _VAMPIRES_TOOTH_equip(item_def
*item
, bool *show_msgs
, bool unmeld
)
417 if (you
.is_undead
!= US_UNDEAD
)
419 _equip_mpr(show_msgs
,
420 "You feel a strange hunger, and smell blood in the air...");
421 make_hungry(4500, false, false);
424 _equip_mpr(show_msgs
, "You feel strangely empty.");
427 ///////////////////////////////////////////////////
429 // XXX: Pluses at creation time are hardcoded in make_item_unrandart()
431 static void _VARIABILITY_world_reacts(item_def
*item
)
433 do_uncurse_item(*item
);
435 if (x_chance_in_y(2, 5))
436 item
->plus
+= (coinflip() ? +1 : -1);
438 if (x_chance_in_y(2, 5))
439 item
->plus2
+= (coinflip() ? +1 : -1);
443 else if (item
->plus
> 16)
446 if (item
->plus2
< -4)
448 else if (item
->plus2
> 16)
452 ///////////////////////////////////////////////////
454 static void _ZONGULDROK_equip(item_def
*item
, bool *show_msgs
, bool unmeld
)
456 _equip_mpr(show_msgs
, "You sense an extremely unholy aura.");
459 static void _ZONGULDROK_world_reacts(item_def
*item
)
461 if (one_chance_in(5))
463 animate_dead(&you
, 1 + random2(3), BEH_HOSTILE
, MHITYOU
, 0,
464 "the Sword of Zonguldrok");
465 did_god_conduct(DID_NECROMANCY
, 1);
466 did_god_conduct(DID_CORPSE_VIOLATION
, 1);
470 static void _ZONGULDROK_melee_effect(item_def
* weapon
, actor
* attacker
,
471 actor
* defender
, bool mondied
)
473 if (attacker
->atype() == ACT_PLAYER
)
475 did_god_conduct(DID_NECROMANCY
, 3);
476 did_god_conduct(DID_CORPSE_VIOLATION
, 3);
480 ///////////////////////////////////////////////////
482 static void _STORM_BOW_world_reacts(item_def
*item
)
484 if (!one_chance_in(300))
487 for (radius_iterator
ri(you
.pos(), 2); ri
; ++ri
)
488 if (!cell_is_solid(*ri
) && env
.cgrid(*ri
) == EMPTY_CLOUD
&& one_chance_in(5))
489 place_cloud(CLOUD_RAIN
, *ri
, random2(20), &you
, 3);
492 ///////////////////////////////////////////////////
494 static void _GONG_melee_effect(item_def
* item
, actor
* wearer
,
495 actor
* attacker
, bool dummy
)
497 if (silenced(wearer
->pos()))
500 std::string msg
= getSpeakString("shield of the gong");
502 msg
= "You hear a strange loud sound.";
503 mpr(msg
.c_str(), MSGCH_SOUND
);
505 noisy(40, wearer
->pos());
508 ///////////////////////////////////////////////////
510 static void _RCLOUDS_world_reacts(item_def
*item
)
513 if (one_chance_in(4))
518 for (radius_iterator
ri(you
.pos(), 2); ri
; ++ri
)
519 if (!cell_is_solid(*ri
) && env
.cgrid(*ri
) == EMPTY_CLOUD
520 && one_chance_in(20))
522 place_cloud(cloud
, *ri
, random2(10), &you
, 1);
526 static void _RCLOUDS_equip(item_def
*item
, bool *show_msgs
, bool unmeld
)
528 _equip_mpr(show_msgs
, "A thin mist springs up around you!");