summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/fineff.h
blob: 1d5a9f3bc9884181b20c2198c2561b6f594a81a6 (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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/**
 * @file
 * @brief Brand/ench/etc effects that might alter something in an
 *             unexpected way.
**/

#ifndef FINEFF_H
#define FINEFF_H

class final_effect
{
public:
    final_effect(const actor *attack, const actor *defend, const coord_def &pos)
        : att(attack ? attack->mid : 0),
          def(defend ? defend->mid : 0),
          posn(pos)
    {
    }
    virtual ~final_effect() {}

    virtual bool mergeable(const final_effect &a) const = 0;
    virtual void merge(const final_effect &a)
    {
    }

    void schedule();
    virtual void fire() = 0;

protected:
    mid_t att, def;
    coord_def posn;
    actor *attacker() const { return actor_by_mid(att); }
    actor *defender() const { return actor_by_mid(def); }
};

class mirror_damage_fineff : public final_effect
{
public:
    mirror_damage_fineff(const actor *attack, const actor *defend, int dam)
        : final_effect(attack, defend, coord_def()), damage(dam)
    {
    }
    bool mergeable(const final_effect &a) const;
    void merge(const final_effect &a);
    void fire();
protected:
    int damage;
};

class trample_follow_fineff : public final_effect
{
public:
    trample_follow_fineff(const actor *attack, const coord_def &pos)
        : final_effect(attack, 0, pos)
    {
    }
    bool mergeable(const final_effect &a) const;
    void fire();
};

class blink_fineff : public final_effect
{
public:
    blink_fineff(const actor *blinker)
        : final_effect(0, blinker, coord_def())
    {
    }
    bool mergeable(const final_effect &a) const;
    void fire();
};

class distortion_tele_fineff : public final_effect
{
public:
    distortion_tele_fineff(const actor *defend)
        : final_effect(0, defend, coord_def())
    {
    }
    bool mergeable(const final_effect &a) const;
    void fire();
};

class trj_spawn_fineff : public final_effect
{
public:
    trj_spawn_fineff(const actor *attack, const actor *defend,
                     const coord_def &pos, int dam)
        : final_effect(attack, defend, pos), damage(dam)
    {
    }
    bool mergeable(const final_effect &a) const;
    void merge(const final_effect &a);
    void fire();
protected:
    int damage;
};

class blood_fineff : public final_effect
{
public:
    blood_fineff(const actor *defend, const coord_def &pos, int blood_amount)
        : final_effect(0, 0, pos), mtype(defend->type), blood(blood_amount)
    {
    }
    bool mergeable(const final_effect &a) const;
    void fire();
    void merge(const final_effect &a);
protected:
    monster_type mtype;
    int blood;
};

class deferred_damage_fineff : public final_effect
{
public:
    deferred_damage_fineff(const actor *attack, const actor *defend,
                           int dam, bool _attacker_effects, bool _fatal = true)
        : final_effect(attack, defend, coord_def()),
          damage(dam), attacker_effects(_attacker_effects), fatal(_fatal)
    {
    }
    bool mergeable(const final_effect &a) const;
    void merge(const final_effect &a);
    void fire();
protected:
    int damage;
    bool attacker_effects;
    bool fatal;
};

class starcursed_merge_fineff : public final_effect
{
public:
    starcursed_merge_fineff(const actor *merger)
            : final_effect(0, merger, coord_def())
    {
    }
    bool mergeable(const final_effect &a) const;
    void fire();
};

class shock_serpent_discharge_fineff : public final_effect
{
public:
    shock_serpent_discharge_fineff(const actor *serpent, coord_def pos, int pow)
            : final_effect(0, serpent, coord_def()), position(pos), power(pow),
                    attitude(mons_attitude(serpent->as_monster()))
    {
    }
    bool mergeable(const final_effect &a) const;
    void merge(const final_effect &a);
    void fire();
protected:
    coord_def position;
    int power;
    mon_attitude_type attitude;
};

// A fineff that triggers a daction; otherwise the daction
// occurs immediately (and then later) -- this might actually
// be too soon in some cases.
class delayed_action_fineff : public final_effect
{
public:
    delayed_action_fineff(daction_type _action, const char* _final_msg)
            : final_effect(0, 0, coord_def()),
              action(_action), final_msg(_final_msg)
    {
    }

    bool mergeable(const final_effect &a) const;
    virtual void fire();

protected:
    daction_type action;
    const char *final_msg;
};

class kirke_death_fineff : public delayed_action_fineff
{
public:
    kirke_death_fineff(const char *_final_msg)
            : delayed_action_fineff(DACT_KIRKE_HOGS, _final_msg)
    {
    }

    void fire();
};

class rakshasa_clone_fineff : public final_effect
{
public:
    rakshasa_clone_fineff(const actor *defend, const coord_def &pos)
        : final_effect(0, defend, pos)
    {
    }
    bool mergeable(const final_effect &a) const;
    void fire();
protected:
    int damage;
};
void fire_final_effects();

#endif