From d0b1ebb446d3eebb41824161d7160b24d3e7cceb Mon Sep 17 00:00:00 2001 From: Matthew Cline Date: Sun, 8 Nov 2009 00:22:58 -0800 Subject: fight: Generate noise on fighting Very rough draft of "make noise when fighting". Needs extensive play-testing and tuning. Noise scales linearly with damage done, and also linearly with noise_factor, which is determined by weapon type (clubs make more noise than dagger) or monster attack type (tail slaps make more noise than stinging). Plus, a litle extra noise is added on for the flaming and electrocution brands. --- crawl-ref/source/fight.cc | 148 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 144 insertions(+), 4 deletions(-) (limited to 'crawl-ref/source/fight.cc') diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index aff99cb918..49985fa95e 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -347,7 +347,8 @@ melee_attack::melee_attack(actor *attk, actor *defn, attacker_invisible(false), defender_invisible(false), defender_starting_attitude(ATT_HOSTILE), unarmed_ok(allow_unarmed), attack_number(which_attack), to_hit(0), damage_done(0), special_damage(0), - aux_damage(0), stab_attempt(false), stab_bonus(0), weapon(NULL), + aux_damage(0), stab_attempt(false), stab_bonus(0), min_delay(0), + final_attack_delay(0), noise_factor(0), extra_noise(0), weapon(NULL), damage_brand(SPWPN_NORMAL), wpn_skill(SK_UNARMED_COMBAT), hands(HANDS_ONE), hand_half_bonus(false), art_props(0), unrand_entry(NULL), attack_verb("bug"), verb_degree(), no_damage_message(), @@ -383,8 +384,24 @@ void melee_attack::init_attack() wpn_skill = weapon ? weapon_skill(*weapon) : SK_UNARMED_COMBAT; if (weapon) + { hands = hands_reqd(*weapon, attacker->body_size()); + switch (single_damage_type(*weapon)) + { + case DAM_BLUDGEON: + case DAM_WHIP: + noise_factor = 125; + break; + case DAM_SLICE: + noise_factor = 100; + break; + case DAM_PIERCE: + noise_factor = 75; + break; + } + } + shield = attacker->shield(); if (defender) defender_shield = defender->shield(); @@ -701,6 +718,8 @@ bool melee_attack::attack() if (attacker->atype() == ACT_PLAYER) { + handle_noise(); + if (damage_brand == SPWPN_CHAOS) chaos_affects_attacker(); @@ -839,6 +858,8 @@ bool melee_attack::player_attack() if (cancel_attack) return (false); + noise_factor = 100; + player_apply_attack_delay(); player_stab_check(); @@ -1001,6 +1022,8 @@ bool melee_attack::player_aux_unarmed() for (int scount = 0; scount < 5; scount++) { + noise_factor = 100; + unarmed_attack.clear(); miss_verb.clear(); simple_miss_message = false; @@ -1068,7 +1091,8 @@ bool melee_attack::player_aux_unarmed() && (!player_mutation_level(MUT_HORNS) || coinflip())) { unarmed_attack = "peck"; - aux_damage = 6; + aux_damage = 6; + noise_factor = 75; } else { @@ -1123,7 +1147,8 @@ bool melee_attack::player_aux_unarmed() } unarmed_attack = "tail-slap"; - aux_damage = 6; + aux_damage = 6; + noise_factor = 125; if (player_mutation_level(MUT_STINGER) > 0) { @@ -1170,7 +1195,8 @@ bool melee_attack::player_aux_unarmed() if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) { unarmed_attack = "slash"; - aux_damage += 6; + aux_damage += 6; + noise_factor = 75; simple_miss_message = true; } else if (you.has_usable_claws()) @@ -1205,6 +1231,7 @@ bool melee_attack::player_aux_unarmed() simple_miss_message = true; aux_damage += player_mutation_level(MUT_FANGS) * 2 + you.skills[SK_UNARMED_COMBAT] / 5; + noise_factor = 75; if (you.species == SP_VAMPIRE) { @@ -1238,6 +1265,7 @@ bool melee_attack::player_aux_unarmed() make_hungry(2, true); + handle_noise(); alert_nearby_monsters(); // XXX We're clobbering did_hit @@ -3091,6 +3119,7 @@ bool melee_attack::apply_damage_brand() calc_elemental_brand_damage(BEAM_FIRE, res, defender->is_icy() ? "melt" : "burn"); defender->expose_to_element(BEAM_FIRE); + extra_noise += 1; break; case SPWPN_FREEZING: @@ -3114,6 +3143,7 @@ bool melee_attack::apply_damage_brand() break; case SPWPN_ELECTROCUTION: + extra_noise += 2; if (defender->airborne() || defender->res_elec() > 0) break; else if (one_chance_in(3)) @@ -3365,6 +3395,50 @@ bool melee_attack::apply_damage_brand() return (ret); } + +// XXX: +// * Noise should probably scale non-linearly with damage_done, and +// maybe even non-linearly with noise_factor. +// +// * Damage reduction via armour of the defender reduces noise, +// but shouldn't. +// +// * Damage reduction because of negative damage modifiers on the +// weapon reduce noise, but probably shouldn't. +// +// * Might want a different formula for noise generated by the +// player. +// +// Ideas: +// * Each weapon type has a noise rating, like it does an accuracy +// rating and base delay. +// +// * For player, stealth skill and/or weapon skillr reducing noise. +// +// * Randart property to make randart weapons louder or softer when +// they hit. +void melee_attack::handle_noise() +{ + // Successful stabs make no noise. + if (stab_attempt) + { + noise_factor = 0; + extra_noise = 0; + return; + } + + int level = (noise_factor * damage_done / 100 / 4) + extra_noise; + + if (noise_factor > 0) + level = std::max(1, level); + + if (level > 0) + noisy(level, defender->pos(), attacker->mindex()); + + noise_factor = 0; + extra_noise = 0; +} + // Returns true if the attack cut off a head *and* cauterized it. bool melee_attack::chop_hydra_head( int dam, int dam_type, @@ -5043,6 +5117,9 @@ void melee_attack::mons_perform_attack_rounds() monsters* def_copy = NULL; for (attack_number = 0; attack_number < nrounds; ++attack_number) { + // Handle noise from previous round. + handle_noise(); + // Monster went away? if (!defender->alive() || defender->pos() != pos) { @@ -5106,6 +5183,66 @@ void melee_attack::mons_perform_attack_rounds() if (attk.type == AT_SHOOT) continue; + if (weapon == NULL) + { + switch(attk.type) + { + case AT_HEADBUTT: + case AT_TENTACLE_SLAP: + case AT_TAIL_SLAP: + noise_factor = 150; + break; + + case AT_HIT: + case AT_PUNCH: + case AT_KICK: + case AT_CLAW: + case AT_GORE: + noise_factor = 125; + break; + + case AT_BITE: + case AT_PECK: + noise_factor = 100; + break; + + case AT_STING: + case AT_SPORE: + case AT_ENGULF: + noise_factor = 75; + break; + + case AT_TOUCH: + noise_factor = 0; + break; + + // To prevent compiler warnings. + case AT_NONE: + case AT_RANDOM: + case AT_SHOOT: + DEBUGSTR("Invalid attack flavour for noise_factor"); + break; + + default: + DEBUGSTR("Unhandled attack flavour for noise_factor"); + break; + } + + switch(attk.flavour) + { + case AF_FIRE: + noise_factor += 50; + break; + + case AF_ELEC: + noise_factor += 100; + break; + + default: + break; + } + } + damage_done = 0; mons_set_weapon(attk); to_hit = mons_to_hit(); @@ -5304,6 +5441,9 @@ void melee_attack::mons_perform_attack_rounds() } } + // Handle noise from last round. + handle_noise(); + if (def_copy) delete def_copy; -- cgit v1.2.3-54-g00ecf