summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/melee_attack.h
blob: 81060c86fde377104fba943f354b257e62ea8589 (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
#ifndef MELEE_ATTACK_H
#define MELEE_ATTACK_H

#include <list>

#include "attack.h"
#include "fight.h"
#include "random-var.h"

// Forward declaration of the struct
struct mon_attack_def;

enum unarmed_attack_type
{
    UNAT_NO_ATTACK,                    //    0
    UNAT_CONSTRICT,  // put constriction first so octopodes will use it
    UNAT_KICK,
    UNAT_HEADBUTT,
    UNAT_PECK,
    UNAT_TAILSLAP,
    UNAT_PUNCH,
    UNAT_BITE,
    UNAT_PSEUDOPODS,
    UNAT_TENTACLES,
    UNAT_FIRST_ATTACK = UNAT_CONSTRICT,
    UNAT_LAST_ATTACK = UNAT_TENTACLES
};

class melee_attack : public attack
{
public:
    // mon_attack_def stuff
    int       attack_number;
    int       effective_attack_number;

    bool         can_cleave;
    list<actor*> cleave_targets;
    bool         cleaving;        // additional attack from cleaving
    bool jumping_attack;
    bool jump_blocked;
    coord_def attack_position;

public:
    melee_attack(actor *attacker, actor *defender,
                 int attack_num = -1, int effective_attack_num = -1,
                 bool is_cleaving = false, bool is_jump_attack = false,
                 bool is_jump_blocked = false,
                 coord_def attack_pos = coord_def(0, 0));

    // Applies attack damage and other effects.
    bool attack();

    // To-hit is a function of attacker/defender, inherited from attack
    int calc_to_hit(bool random = true);

    static void chaos_affect_actor(actor *victim);

private:
    /* Attack phases */
    bool handle_phase_attempted();
    bool handle_phase_dodged();
    bool handle_phase_hit();
    bool handle_phase_damaged();
    bool handle_phase_aux();
    bool handle_phase_end();

    /* Combat Calculations */
    bool using_weapon();
    int weapon_damage();
    int calc_mon_to_hit_base();
    int apply_damage_modifiers(int damage, int damage_max, bool &half_ac);
    int calc_damage();

    /* Attack effects */
    void check_autoberserk();
    bool check_unrand_effects();

    bool attack_ignores_shield(bool verbose);

    void rot_defender(int amount, int immediate = 0);
    void splash_defender_with_acid(int strength);
    bool decapitate_hydra(int damage_done, int damage_type = -1);
    bool chop_hydra_head(int damage_done,
                         int dam_type,
                         brand_type wpn_brand);

    /* Axe cleaving */
    void cleave_setup();
    int cleave_damage_mod(int dam);

    /* Mutation Effects */
    void do_spines();
    void do_passive_freeze();
#if TAG_MAJOR_VERSION == 34
    void do_passive_heat();
#endif
    void emit_foul_stench();
    void tendril_disarm();
    /* Race Effects */
    void do_minotaur_retaliation();

    /* Brand / Attack Effects */
    void chaos_affects_attacker();
    bool do_knockback(bool trample = true);
    bool attack_warded_off();

    /* Output methods */
    void adjust_noise();
    void set_attack_verb();
    void announce_hit();

    /* Misc methods */
    void handle_noise(const coord_def & pos);
private:
    // Monster-attack specific stuff
    bool mons_attack_effects();
    void mons_apply_attack_flavour();
    string mons_attack_verb();
    string mons_attack_desc();
    // TODO: Unify do_poison and poison_monster
    bool mons_do_poison();
    void mons_do_napalm();
    void mons_do_eyeball_confusion();
    void apply_black_mark_effects();
private:
    // Player-attack specific stuff
    // Auxiliary unarmed attacks.
    bool player_aux_unarmed();
    unarmed_attack_type player_aux_choose_uc_attack();
    void player_aux_setup(unarmed_attack_type atk);
    bool player_aux_test_hit();
    bool player_aux_apply(unarmed_attack_type atk);

    int  player_aux_stat_modify_damage(int damage);
    int  player_apply_misc_modifiers(int damage);
    int  player_apply_final_multipliers(int damage);

    void player_exercise_combat_skills();
    bool player_monattk_hit_effects();
    void attacker_sustain_passive_damage();
    int  staff_damage(skill_type skill);
    void apply_staff_damage();
    void player_stab_check();
    int  player_stab_tier();
    void player_announce_aux_hit();
    string player_why_missed();
    void player_warn_miss();
    void player_weapon_upsets_god();
    void _defender_die();

    // Added in, were previously static methods of fight.cc
    bool _tran_forbid_aux_attack(unarmed_attack_type atk);
    bool _extra_aux_attack(unarmed_attack_type atk, bool is_uc);
    int calc_your_to_hit_unarmed(int uattack = UNAT_NO_ATTACK,
                                 bool vampiric = false);
    bool _player_vampire_draws_blood(const monster* mon, const int damage,
                                     bool needs_bite_msg = false,
                                     int reduction = 1);
    bool _vamp_wants_blood_from_monster(const monster* mon);

    bool can_reach();
};

#endif