summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/fight.cc
diff options
context:
space:
mode:
authorMatthew Cline <zelgadis@sourceforge.net>2009-11-08 00:22:58 -0800
committerMatthew Cline <zelgadis@sourceforge.net>2009-11-08 00:25:51 -0800
commitd0b1ebb446d3eebb41824161d7160b24d3e7cceb (patch)
tree94b72d5c4019e578abc330002fa1c00f84a87605 /crawl-ref/source/fight.cc
parent5bbad271f48030ebb570045a82e17889cf6ea395 (diff)
downloadcrawl-ref-d0b1ebb446d3eebb41824161d7160b24d3e7cceb.tar.gz
crawl-ref-d0b1ebb446d3eebb41824161d7160b24d3e7cceb.zip
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.
Diffstat (limited to 'crawl-ref/source/fight.cc')
-rw-r--r--crawl-ref/source/fight.cc148
1 files changed, 144 insertions, 4 deletions
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;