/* * File: fight.h * Summary: Functions used during combat. * Written by: Linley Henzell */ #ifndef FIGHT_H #define FIGHT_H #include "externs.h" #include "artefact.h" #include "mon-util.h" enum unarmed_attack_type { UNAT_NO_ATTACK, // 0 UNAT_KICK, UNAT_HEADBUTT, UNAT_TAILSLAP, UNAT_PUNCH, UNAT_BITE }; enum unchivalric_attack_type { UCAT_NO_ATTACK, // 0 UCAT_DISTRACTED, UCAT_CONFUSED, UCAT_FLEEING, UCAT_INVISIBLE, UCAT_HELD_IN_NET, UCAT_PETRIFYING, UCAT_PETRIFIED, UCAT_PARALYSED, UCAT_SLEEPING }; enum attack_final_effect_flavor { FINEFF_LIGHTNING_DISCHARGE }; struct attack_final_effect { attack_final_effect_flavor flavor; coord_def location; }; struct mon_attack_def; int effective_stat_bonus( int wepType = -1 ); int resist_adjust_damage(actor *defender, beam_type flavour, int res, int rawdamage, bool ranged = false); int weapon_str_weight( object_class_type wpn_class, int wpn_type ); bool you_attack(int monster_attacked, bool unarmed_attacks); bool monster_attack_actor(monsters *attacker, actor *defender, bool allow_unarmed); bool monster_attack(monsters* attacker, bool allow_unarmed = true); bool monsters_fight(monsters* attacker, monsters* attacked, bool allow_unarmed = true); bool wielded_weapon_check(item_def *weapon, bool no_message = false); int calc_your_to_hit(bool random_factor); int calc_heavy_armour_penalty(bool random_factor); unchivalric_attack_type is_unchivalric_attack(const actor *attacker, const actor *defender); class melee_attack { public: actor *attacker, *defender; monsters* attacker_as_monster() { return dynamic_cast(attacker); } monsters* defender_as_monster() { return dynamic_cast(defender); } bool cancel_attack; bool did_hit, perceived_attack, obvious_effect; // If all or part of the action is visible to the player, we need a message. bool needs_message; bool attacker_visible, defender_visible; bool attacker_invisible, defender_invisible; // What was the monster's attitude when the attack began? mon_attitude_type defender_starting_attitude; bool unarmed_ok; int attack_number; int to_hit; int damage_done; int special_damage; int aux_damage; bool stab_attempt; int stab_bonus; int min_delay; int final_attack_delay; int noise_factor; int extra_noise; // Attacker's damage output potential: item_def *weapon; int damage_brand; // Can be special even if unarmed (transforms) int wpn_skill, hands; bool hand_half_bonus; // If weapon is an artefact, its properties. artefact_properties_t art_props; // If a weapon is an unrandart, its unrandart entry. unrandart_entry *unrand_entry; // Attack messages std::string attack_verb, verb_degree; std::string no_damage_message; std::string special_damage_message; std::string unarmed_attack; beam_type special_damage_flavour; item_def *shield; item_def *defender_shield; // Armour penalties? int heavy_armour_penalty; bool can_do_unarmed; // Attacker uses watery terrain to advantage vs defender. Implies that // both attacker and defender are in water. bool water_attack; // Miscast to cause after special damage is done. If miscast_level == 0 // the miscast is discarded if special_damage_message isn't empty. int miscast_level; int miscast_type; actor* miscast_target; public: melee_attack(actor *attacker, actor *defender, bool allow_unarmed = true, int attack_num = -1); // Applies attack damage and other effects. bool attack(); int calc_to_hit(bool random = true); static std::string anon_name(description_level_type desc, bool actor_invisible); static std::string actor_name(const actor *a, description_level_type desc, bool actor_visible, bool actor_invisible); static std::string pronoun(const actor *a, pronoun_type ptyp, bool actor_visible); static std::string anon_pronoun(pronoun_type ptyp); private: void init_attack(); bool is_banished(const actor *) const; bool is_water_attack(const actor *, const actor *) const; void check_hand_half_bonus_eligible(); void check_autoberserk(); bool check_unrand_effects(bool mondied = false); void emit_nodmg_hit_message(); void identify_mimic(actor *mon); std::string debug_damage_number(); std::string special_attack_punctuation(); std::string attack_strength_punctuation(); std::string atk_name(description_level_type desc) const; std::string def_name(description_level_type desc) const; std::string wep_name(description_level_type desc = DESC_NOCAP_YOUR, unsigned long ignore_flags = ISFLAG_KNOW_CURSE | ISFLAG_KNOW_PLUSES) const; bool attack_shield_blocked(bool verbose); bool apply_damage_brand(); void calc_elemental_brand_damage(beam_type flavour, int res, const char *verb); int fire_res_apply_cerebov_downgrade(int res); void drain_defender(); void rot_defender(int amount, int immediate = 0); void check_defender_train_armour(); void check_defender_train_dodging(); void splash_defender_with_acid(int strength); void splash_monster_with_acid(int strength); bool decapitate_hydra(int damage_done, int damage_type = -1); bool chop_hydra_head( int damage_done, int dam_type, int wpn_brand ); // Returns true if the defender is banished. bool distortion_affects_defender(); void chaos_affects_defender(); void chaos_affects_attacker(); void chaos_killed_defender(monsters* def_copy); int random_chaos_brand(); void do_miscast(); std::vector final_effects; void handle_noise(const coord_def & pos); private: // Monster-attack specific stuff bool mons_attack_you(); bool mons_attack_mons(); int mons_to_hit(); bool mons_self_destructs(); bool mons_attack_warded_off(); int mons_attk_delay(); int mons_calc_damage(const mon_attack_def &attk); void mons_apply_attack_flavour(const mon_attack_def &attk); int mons_apply_defender_ac(int damage, int damage_max); bool mons_perform_attack(); void mons_perform_attack_rounds(); void mons_check_attack_perceived(); std::string mons_attack_verb(const mon_attack_def &attk); std::string mons_attack_desc(const mon_attack_def &attk); void mons_announce_hit(const mon_attack_def &attk); void mons_announce_dud_hit(const mon_attack_def &attk); void mons_set_weapon(const mon_attack_def &attk); void mons_do_poison(const mon_attack_def &attk); void mons_do_napalm(); std::string mons_defender_name(); void wasp_paralyse_defender(); mon_attack_flavour random_chaos_attack_flavour(); private: // Player-attack specific stuff bool player_attack(); bool player_aux_unarmed(); bool player_apply_aux_unarmed(); int player_stat_modify_damage(int damage); int player_aux_stat_modify_damage(int damage); int player_to_hit(bool random_factor); void player_apply_attack_delay(); int player_apply_water_attack_bonus(int damage); int player_apply_weapon_bonuses(int damage); int player_apply_weapon_skill(int damage); int player_apply_fighting_skill(int damage, bool aux); int player_apply_misc_modifiers(int damage); int player_apply_monster_ac(int damage); void player_weapon_auto_id(); int player_stab_weapon_bonus(int damage); int player_stab(int damage); int player_weapon_type_modify(int damage); bool player_hits_monster(); int player_calc_base_weapon_damage(); int player_calc_base_unarmed_damage(); void player_exercise_combat_skills(); bool player_monattk_final_hit_effects(bool mondied); bool player_monattk_hit_effects(bool mondied); void player_sustain_passive_damage(); int player_staff_damage(int skill); void player_apply_staff_damage(); bool player_check_monster_died(); void player_calc_hit_damage(); void player_stab_check(); int player_weapon_speed(); int player_unarmed_speed(); int player_apply_shield_delay(int attack_delay); void player_announce_hit(); std::string player_why_missed(); void player_warn_miss(); void player_check_weapon_effects(); void _monster_die(monsters *monster, killer_type killer, int killer_index); }; #endif