1 /**
2 * @file
3 * @brief Monster-affecting enchantment spells.
4 * Other targeted enchantments are handled in spl-zap.cc.
5 **/
6
7 #include "AppHdr.h"
8
9 #include "spl-monench.h"
10
11 #include "env.h"
12 #include "message.h"
13 #include "spl-util.h"
14 #include "terrain.h"
15
englaciate(coord_def where,int pow,actor * agent)16 int englaciate(coord_def where, int pow, actor *agent)
17 {
18 actor *victim = actor_at(where);
19
20 if (!victim || victim == agent)
21 return 0;
22
23 if (agent->is_monster() && mons_aligned(agent, victim))
24 return 0; // don't let monsters hit friendlies
25
26 monster* mons = victim->as_monster();
27
28 if (victim->res_cold() > 0
29 || victim->is_stationary())
30 {
31 if (!mons)
32 canned_msg(MSG_YOU_UNAFFECTED);
33 else if (!mons_is_firewood(*mons))
34 simple_monster_message(*mons, " is unaffected.");
35 return 0;
36 }
37
38 int duration = (roll_dice(3, pow) / 6
39 - victim->get_hit_dice() / 2)
40 * BASELINE_DELAY;
41
42 if (duration <= 0)
43 {
44 if (!mons)
45 canned_msg(MSG_YOU_RESIST);
46 else
47 simple_monster_message(*mons, " resists.");
48 return 0;
49 }
50
51 if ((!mons && you.get_mutation_level(MUT_COLD_BLOODED))
52 || (mons && mons_class_flag(mons->type, M_COLD_BLOOD)))
53 {
54 duration *= 2;
55 }
56
57 if (!mons)
58 return slow_player(duration);
59
60 return do_slow_monster(*mons, agent, duration);
61 }
62
cast_englaciation(int pow,bool fail)63 spret cast_englaciation(int pow, bool fail)
64 {
65 fail_check();
66 mpr("You radiate an aura of cold.");
67 apply_area_visible([pow] (coord_def where) {
68 return englaciate(where, pow, &you);
69 }, you.pos());
70 return spret::success;
71 }
72
73 /** Corona a monster.
74 *
75 * @param mons the monster to get a backlight.
76 * @returns true if it got backlit (even if it was already).
77 */
backlight_monster(monster * mons)78 bool backlight_monster(monster* mons)
79 {
80 const mon_enchant bklt = mons->get_ench(ENCH_CORONA);
81 const mon_enchant zin_bklt = mons->get_ench(ENCH_SILVER_CORONA);
82 const int lvl = bklt.degree + zin_bklt.degree;
83
84 mons->add_ench(mon_enchant(ENCH_CORONA, 1));
85
86 if (lvl == 0)
87 simple_monster_message(*mons, " is outlined in light.");
88 else if (lvl == 4)
89 simple_monster_message(*mons, " glows brighter for a moment.");
90 else
91 simple_monster_message(*mons, " glows brighter.");
92
93 return true;
94 }
95
do_slow_monster(monster & mon,const actor * agent,int dur)96 bool do_slow_monster(monster& mon, const actor* agent, int dur)
97 {
98 if (mon.stasis())
99 return true;
100
101 if (!mon.is_stationary()
102 && mon.add_ench(mon_enchant(ENCH_SLOW, 0, agent, dur)))
103 {
104 if (!mon.paralysed() && !mon.petrified()
105 && simple_monster_message(mon, " seems to slow down."))
106 {
107 return true;
108 }
109 }
110
111 return false;
112 }
113