File: attack.h

package info (click to toggle)
crawl 2%3A0.34.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 100,188 kB
  • sloc: cpp: 363,709; ansic: 27,765; javascript: 9,516; python: 8,463; perl: 3,293; java: 3,132; xml: 2,380; makefile: 1,835; sh: 611; objc: 250; cs: 15; sed: 9; lisp: 3
file content (202 lines) | stat: -rw-r--r-- 6,548 bytes parent folder | download | duplicates (2)
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
#pragma once

#include "artefact.h"
#include "item-prop-enum.h"
#include "item-status-flag-type.h"
#include "mon-enum.h"
#include "kill-method-type.h"
#include "pronoun-type.h"
#include "spl-util.h" // spschool type definition

// Used throughout inheriting classes, define them here for universal access
const int HIT_WEAK   = 7;
const int HIT_MED    = 18;
const int HIT_STRONG = 36;

const int BACKLIGHT_TO_HIT_BONUS = 5;
const int UMBRA_TO_HIT_MALUS = -3;
const int CONFUSION_TO_HIT_MALUS = -5;
const int TRANSLUCENT_SKIN_TO_HIT_MALUS = -2;

const int BULLSEYE_TO_HIT_DIV = 6;

const int REPEL_MISSILES_EV_BONUS = 15;     // Players
const int DEFLECT_MISSILES_EV_BONUS = 24;   // Monsters

class attack
{
// Public Properties
public:
    // General attack properties, set on instantiation or through a normal
    // thread of execution
    actor   *attacker, *defender;
    // Who is morally responsible for the attack? Could be YOU_FAULTLESS
    // or a monster if this is a reflected ranged attack.
    actor *responsible;

    bool    cancel_attack;
    bool    did_hit;
    bool    needs_message;
    bool    attacker_visible, defender_visible;
    bool    perceived_attack, obvious_effect;


    int     to_hit;
    int     damage_done;
    int     special_damage; // TODO: We'll see if we can remove this
    int     aux_damage;     // TODO: And this too

    beam_type special_damage_flavour;

    bool    stab_attempt;
    int     stab_bonus;

    // Fetched/Calculated from the attacker, stored to save execution time
    int             ev_margin;

    // TODO: Expand the implementation of attack_type/attack_flavour to be used
    // by players as well as monsters. It could be a good middle ground for
    // brands and attack types (presently, players don't really have an attack
    // type)
    attack_type     attk_type;
    attack_flavour  attk_flavour;
    int             attk_damage;

    const item_def  *weapon;
    brand_type      damage_brand;
    skill_type      wpn_skill;

    // If a weapon is an unrandart, its unrandart entry.
    const unrandart_entry *unrand_entry;

    int     attacker_to_hit_penalty;

    // Attack messages
    string     attack_verb, verb_degree;
    string     no_damage_message;
    string     special_damage_message;
    string     aux_attack, aux_verb;

    item_def        *defender_shield;

    bool simu;

// Public Methods
public:
    attack(actor *attk, actor *defn, actor *blame = 0);

    // To-hit is a function of attacker/defender, defined in sub-classes
    virtual int calc_to_hit(bool random);
    int calc_pre_roll_to_hit(bool random);
    virtual int post_roll_to_hit_modifiers(int mhit, bool random);

    // Exact copies of their melee_attack predecessors
    string actor_name(const actor *a, description_level_type desc,
                      bool actor_visible);
    string actor_pronoun(const actor *a, pronoun_type ptyp, bool actor_visible);
    string anon_name(description_level_type desc);
    string anon_pronoun(pronoun_type ptyp);

    // TODO: Definitely want to get rid of this, which we can't really do
    // until we refactor the whole pronoun / desc usage from these lowly
    // classes all the way up to monster/player (and actor) classes.
    string defender_name(bool allow_reflexive);

// Private Properties
    string aux_source;
    kill_method_type kill_type;

// Private Methods
protected:
    virtual void init_attack(int attack_number);

    /* Attack Phases */
    virtual bool handle_phase_attempted();
    virtual void handle_phase_dodged() = 0;
    virtual void handle_phase_blocked();
    virtual bool handle_phase_hit() = 0;
    virtual bool handle_phase_damaged();
    virtual void handle_phase_killed();
    virtual void handle_phase_end();

    /* Combat Calculations */
    virtual bool using_weapon() const = 0;
    virtual int weapon_damage() const = 0;
    int adjusted_weapon_damage() const;
    virtual int get_weapon_plus();
    virtual int calc_base_unarmed_damage() const;
    virtual int calc_mon_to_hit_base() = 0;
    virtual int apply_damage_modifiers(int damage) = 0;
    int apply_rev_penalty(int damage) const;
    virtual int calc_damage();
    int lighting_effects();
    int test_hit(int to_hit, int ev, bool randomise_ev);
    int apply_defender_ac(int damage, int damage_max = 0,
                          ac_type ac_rule = ac_type::normal) const;
    // Determine if we're blocking (partially or entirely)
    virtual bool attack_shield_blocked();
    virtual bool ignores_shield()
    {
        return false;
    }
    virtual bool apply_damage_brand(const char *what = nullptr);
    void calc_elemental_brand_damage(beam_type flavour,
                                     const char *verb,
                                     const char *what = nullptr);

    /* Weapon Effects */
    virtual bool check_unrand_effects() = 0;

    /* Attack Effects */
    virtual bool mons_attack_effects() = 0;
    void alert_defender();
    bool distortion_affects_defender();
    void antimagic_affects_defender(int pow);
    void pain_affects_defender();
    brand_type random_chaos_brand();
    void drain_defender();
    void drain_defender_speed();
    void maybe_trigger_jinxbite();
    void maybe_trigger_fugue_wail(const coord_def pos);
    void maybe_trigger_autodazzler();

    bool paragon_defends_player();

    virtual int inflict_damage(int dam, beam_type flavour = NUM_BEAMS,
                               bool clean = false);

    /* Output */
    string debug_damage_number();
    string evasion_margin_adverb();

    virtual void set_attack_verb(int damage) = 0;
    virtual void announce_hit() = 0;

    void stab_message();

    void handle_noise(const coord_def & pos);

    string atk_name(description_level_type desc);
    string def_name(description_level_type desc);

    attack_flavour random_chaos_attack_flavour();
    bool apply_poison_damage_brand();

    virtual int  player_apply_misc_modifiers(int damage);
    virtual int  player_apply_slaying_bonuses(int damage, bool aux);
    virtual int  player_apply_final_multipliers(int damage,
                                                bool /*aux*/ = false);
    virtual int player_apply_postac_multipliers(int damage);

    virtual void player_exercise_combat_skills();

    virtual bool player_good_stab() = 0;
    virtual int  player_stab_weapon_bonus(int damage);
    virtual int  player_stab(int damage);
    virtual void player_stab_check();

private:
    actor &stat_source() const;
};

string attack_strength_punctuation(int dmg);