Skip to content

Commit

Permalink
Retaliation from monster minotaurs.
Browse files Browse the repository at this point in the history
This makes an already very dangerous monster even more deadly though,
encouraging kiting.  We may want to investigate this.  This commit provides
consistency with players, though.
  • Loading branch information
kilobyte committed Nov 30, 2011
1 parent b502127 commit d022172
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 16 deletions.
11 changes: 10 additions & 1 deletion crawl-ref/source/hiscores.cc
Expand Up @@ -427,7 +427,7 @@ static const char *kill_method_names[] =
"tso_smiting", "petrification", "something",
"falling_down_stairs", "acid", "curare",
"beogh_smiting", "divine_wrath", "bounce", "reflect", "self_aimed",
"falling_through_gate", "disintegration",
"falling_through_gate", "disintegration", "headbutt",
};

const char *kill_method_name(kill_method_type kmt)
Expand Down Expand Up @@ -925,6 +925,7 @@ void scorefile_entry::init_death_cause(int dam, int dsrc,
}
// for death by monster
if ((death_type == KILLED_BY_MONSTER
|| death_type == KILLED_BY_HEADBUTT
|| death_type == KILLED_BY_BEAM
|| death_type == KILLED_BY_DISINT
|| death_type == KILLED_BY_SPORE
Expand Down Expand Up @@ -1649,6 +1650,14 @@ std::string scorefile_entry::death_description(death_desc_verbosity verbosity)
needs_damage = true;
break;

case KILLED_BY_HEADBUTT:
if (terse)
desc += apostrophise(death_source_desc()) + " headbutt";
else
desc += "Headbutted by " + death_source_desc();
needs_damage = true;
break;

case KILLED_BY_POISON:
if (death_source_name.empty() || terse)
{
Expand Down
60 changes: 45 additions & 15 deletions crawl-ref/source/melee_attack.cc
Expand Up @@ -387,9 +387,7 @@ bool melee_attack::handle_phase_dodged()
// TODO: Unify these, placed player_warn_miss here so I can remove
// player_attack
if (attacker->atype() == ACT_PLAYER)
{
player_warn_miss();
}
else
{
mprf("%s%s misses %s%s",
Expand All @@ -402,15 +400,17 @@ bool melee_attack::handle_phase_dodged()
}

if (attacker != defender &&
defender->atype() == ACT_PLAYER &&
grid_distance(you.pos(), attacker->as_monster()->pos()) == 1)
grid_distance(defender->pos(), attacker->pos()) == 1)
{
// Only half the normal chance of retaliation for attacks after the
// first one.
if (attacker->alive() &&
you.species == SP_MINOTAUR &&
you.can_see(attacker) &&
(effective_attack_number == 0 || coinflip()))
if (attacker->alive()
&& (defender->is_player() ?
you.species == SP_MINOTAUR :
mons_base_type(defender->as_monster()) == MONS_MINOTAUR)
&& defender->can_see(attacker)
// FIXME: player's attack is -1, even for auxes
&& effective_attack_number <= 0)
{
do_minotaur_retaliation();
}
Expand Down Expand Up @@ -4428,23 +4428,54 @@ void melee_attack::emit_foul_stench()

void melee_attack::do_minotaur_retaliation()
{
if (defender->cannot_act() || !attacker->alive())
return;

if (!defender->is_player())
{
// monsters have no STR or DEX
if (!x_chance_in_y(5, 5))
return;

int hurt = random2(20) - attacker->armour_class();
if (you.see_cell(defender->pos()))
{
const std::string defname = defender->name(DESC_THE);
mprf("%s furiously retaliates!", defname.c_str());
if (hurt <= 0)
{
mprf("%s headbutts %s, but does no damage.", defname.c_str(),
attacker->name(DESC_THE).c_str());
}
else
{
mprf("%s headbutts %s%s", defname.c_str(),
attacker->name(DESC_THE).c_str(),
get_exclams(hurt).c_str());
}
}
if (hurt > 0)
{
if (attacker->is_player())
ouch(hurt, defender->mindex(), KILLED_BY_HEADBUTT);
else
attacker->hurt(defender, hurt);
}
return;
}

if (!(you.form == TRAN_NONE || you.form == TRAN_APPENDAGE
|| you.form == TRAN_BLADE_HANDS || you.form == TRAN_STATUE
|| you.form == TRAN_LICH))
{
// You are in a non-minotaur form.
return;
}
if (you.cannot_act())
{
// You can't move.
return;
}
// This will usually be 2, but could be 3 if the player mutated more.
const int mut = player_mutation_level(MUT_HORNS);
const int slaying = slaying_bonus(PWPN_DAMAGE);

if (attacker->alive() && 5*you.strength() + 7*you.dex() > random2(600))
if (5 * you.strength() + 7 * you.dex() > random2(600))
{
// Use the same damage formula as a regular headbutt.
int dmg = 5 + mut * 3;
Expand Down Expand Up @@ -4473,7 +4504,6 @@ void melee_attack::do_minotaur_retaliation()
attacker->hurt(&you, hurt);
}
}
return;
}

bool melee_attack::do_knockback(bool trample)
Expand Down
1 change: 1 addition & 0 deletions crawl-ref/source/ouch.h
Expand Up @@ -53,6 +53,7 @@ enum kill_method_type
KILLED_BY_SELF_AIMED,
KILLED_BY_FALLING_THROUGH_GATE,
KILLED_BY_DISINT,
KILLED_BY_HEADBUTT,

NUM_KILLBY
};
Expand Down

0 comments on commit d022172

Please sign in to comment.