summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/spl-monench.cc
blob: ae1f163cfed369a781643ffd1f2ef755ebaca8e2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**
 * @file
 * @brief Monster-affecting enchantment spells.
 *           Other targeted enchantments are handled in spl-zap.cc.
**/

#include "AppHdr.h"

#include "spl-monench.h"
#include "externs.h"

#include "areas.h"
#include "env.h"
#include "message.h"
#include "random.h"
#include "spl-util.h"

#include "terrain.h"

int englaciate(coord_def where, int pow, int, actor *agent)
{
    actor *victim = actor_at(where);

    if (!victim || victim == agent)
        return 0;

    monster* mons = victim->as_monster();

    if (victim->res_cold() > 0
        || victim->is_stationary())
    {
        if (!mons)
            canned_msg(MSG_YOU_UNAFFECTED);
        else if (mons && !mons_is_firewood(mons))
            simple_monster_message(mons, " is unaffected.");
        return 0;
    }

    int duration = (roll_dice(3, pow) / 6
                    - random2(victim->get_hit_dice()))
                    * BASELINE_DELAY;

    if (duration <= 0)
    {
        if (!mons)
            canned_msg(MSG_YOU_RESIST);
        else
            simple_monster_message(mons, " resists.");
        return 0;
    }

    if ((!mons && player_genus(GENPC_DRACONIAN)) // res_cold() checked above
        || (mons && mons_class_flag(mons->type, M_COLD_BLOOD)))
    {
        duration *= 2;
    }

    if (!mons)
        return slow_player(duration);

    return do_slow_monster(mons, agent, duration);
}

spret_type cast_englaciation(int pow, bool fail)
{
    fail_check();
    mpr("You radiate an aura of cold.");
    apply_area_visible(englaciate, pow, &you);
    return SPRET_SUCCESS;
}

bool backlight_monsters(coord_def where, int pow, int garbage)
{
    UNUSED(pow);
    UNUSED(garbage);

    monster* mons = monster_at(where);
    if (mons == NULL)
        return false;

    // Already glowing, or shadowy.
    if (mons->glows_naturally() || mons_class_flag(mons->type, M_SHADOW))
        return false;

    mon_enchant bklt = mons->get_ench(ENCH_CORONA);
    mon_enchant zin_bklt = mons->get_ench(ENCH_SILVER_CORONA);
    const int lvl = bklt.degree + zin_bklt.degree;

    mons->add_ench(mon_enchant(ENCH_CORONA, 1));

    if (lvl == 0)
        simple_monster_message(mons, " is outlined in light.");
    else if (lvl == 4)
        simple_monster_message(mons, " glows brighter for a moment.");
    else
        simple_monster_message(mons, " glows brighter.");

    return true;
}

bool do_slow_monster(monster* mon, const actor* agent, int dur)
{
    if (mon->check_stasis(false))
        return true;

    if (!mon->is_stationary()
        && mon->add_ench(mon_enchant(ENCH_SLOW, 0, agent, dur)))
    {
        if (!mon->paralysed() && !mon->petrified()
            && simple_monster_message(mon, " seems to slow down."))
        {
            return true;
        }
    }

    return false;
}