summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mislead.cc
blob: 790a84886bf024e9bddc87fc529d1a315045af05 (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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*  File:       mislead.cc
 *  Summary:    Handling of Mara's Mislead spell and stats, plus fakes.
 */

#include "AppHdr.h"
#include "mislead.h"

#include "enum.h"
#include "env.h"
#include "message.h"
#include "monster.h"
#include "mon-iter.h"
#include "mon-util.h"
#include "view.h"
#include "random.h"
#include "tutorial.h"
#include "xom.h"

bool unsuitable_misled_monster(monster_type mons)
{
    return (mons_is_unique(mons) || mons_is_mimic(mons) 
            || mons_class_is_stationary(mons) || mons_genus(mons) == MONS_DRACONIAN
            || mons == MONS_DANCING_WEAPON || mons == MONS_UGLY_THING 
            || mons == MONS_VERY_UGLY_THING || mons == MONS_ZOMBIE_SMALL
            || mons == MONS_ZOMBIE_LARGE || mons == MONS_SKELETON_SMALL
            || mons == MONS_SKELETON_LARGE || mons == MONS_SIMULACRUM_SMALL
            || mons == MONS_SIMULACRUM_LARGE || mons == MONS_SPECTRAL_THING
            || mons == MONS_SLIME_CREATURE || mons == MONS_BALLISTOMYCETE 
            || mons == MONS_HYDRA || mons == MONS_PLAYER_GHOST 
            || mons == MONS_SHAPESHIFTER || mons == MONS_PANDEMONIUM_DEMON 
            || mons == MONS_KILLER_KLOWN || mons == MONS_KRAKEN 
            || mons == MONS_KRAKEN_TENTACLE
            || mons == MONS_GLOWING_SHAPESHIFTER
            || mons == MONS_GIANT_BAT);
}

monster_type get_misled_monster (monsters *monster)
{
    monster_type mons = random_monster_at_grid(monster->pos());
    if (unsuitable_misled_monster(mons))
        mons = random_monster_at_grid(monster->pos());

    if (unsuitable_misled_monster(mons))
        return (MONS_GIANT_BAT);

    return mons;
}

bool update_mislead_monster(monsters* monster)
{
    // Don't affect uniques, named monsters, and monsters with special tiles.
    if (mons_is_unique(monster->type) || !monster->mname.empty()
        || monster->props.exists("monster_tile")
        || monster->props.exists("mislead_as"))
    {
        return (false);
    }

    short misled_as = get_misled_monster(monster);
    monster->props["mislead_as"] = misled_as;

    if (misled_as == MONS_GIANT_BAT)
        return (false);

    return (true);
}

int update_mislead_monsters(monsters* caster)
{
    int count = 0;

    for (monster_iterator mi; mi; ++mi)
        if (*mi != caster && update_mislead_monster(*mi))
            count++;

    return count;
}

void mons_cast_mislead(monsters *monster)
{
    // This really only affects the player; it causes confusion when cast on
    // non-player foes, but that is dealt with inside ye-great-Switch-of-Doom.
    if (monster->foe != MHITYOU)
        return;

    // We deal with pointless misleads in the right place now.

    if (wearing_amulet(AMU_CLARITY))
    {
        mpr("Your vision blurs momentarily.");
        return;
    }

    update_mislead_monsters(monster);

    const int old_value = you.duration[DUR_MISLED];
    you.increase_duration(DUR_MISLED, monster->hit_dice * 12 / 3, 50);
    if (you.duration[DUR_MISLED] > old_value)
    {
        you.check_awaken(500);

        if (old_value <= 0)
        {
            mpr("But for a moment, strange images dance in front of your eyes.", MSGCH_WARN);
#ifdef USE_TILE
            tiles.add_overlay(you.pos(), tileidx_zap(MAGENTA));
            update_screen();
#else
            flash_view(MAGENTA);
#endif
            more();
        }
        else
            mpr("You are even more misled!", MSGCH_WARN);

        learned_something_new(TUT_YOU_ENCHANTED);

        xom_is_stimulated((you.duration[DUR_MISLED] - old_value)
                           / BASELINE_DELAY);
    }

    return;
}

int count_mara_fakes()
{
    int count = 0;
    for (monster_iterator mi; mi; ++mi)
    {
        if (mi->type == MONS_MARA_FAKE)
            count++;
    }

    return count;
}