From 18a94062a4fdde6994e4c4ad1598e38d79c24ee4 Mon Sep 17 00:00:00 2001 From: dolorous Date: Sat, 17 May 2008 18:04:46 +0000 Subject: Enable handling of long-distance unchivalric attacks, and increase the penalty from 4 to 5 for consistency with similar attacks frowned upon by the good gods. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5100 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/beam.cc | 8 ++- crawl-ref/source/fight.cc | 117 ++++++++++++++++++++++++++++---------------- crawl-ref/source/fight.h | 16 ++++++ crawl-ref/source/spells2.cc | 4 ++ crawl-ref/source/spells3.cc | 7 +++ 5 files changed, 110 insertions(+), 42 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 8ceae7a4a6..ffde1cb65f 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -3770,6 +3770,9 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) did_god_conduct(DID_ATTACK_FRIEND, 5, true, mon); else if (mons_neutral(mon)) did_god_conduct(DID_ATTACK_NEUTRAL, 5, true, mon); + + if (is_unchivalric_attack(&you, mon, mon)) + did_god_conduct(DID_UNCHIVALRIC_ATTACK, 5, true, mon); } if (mons_is_holy(mon)) @@ -3944,8 +3947,11 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) else if (mons_neutral(mon)) conduct.set(DID_ATTACK_NEUTRAL, 5, !okay, mon); + if (is_unchivalric_attack(&you, mon, mon)) + conduct.set(DID_UNCHIVALRIC_ATTACK, 5, !okay, mon); + if (mons_is_holy(mon)) - conduct.set( DID_ATTACK_HOLY, mon->hit_dice, !okay, mon ); + conduct.set(DID_ATTACK_HOLY, mon->hit_dice, !okay, mon); } if (you.religion == GOD_BEOGH && mons_species(mon->type) == MONS_ORC diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 656b11f8d3..01e01795e8 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -283,6 +283,55 @@ static bool player_fights_well_unarmed(int heavy_armour_penalty) && random2(1 + heavy_armour_penalty) < 2); } +unchivalric_attack_type is_unchivalric_attack(const actor *attacker, + const actor *defender, + const monsters *def) +{ + unchivalric_attack_type unchivalric = UCAT_NO_ATTACK; + + // distracted (but not batty) + if (def->foe != MHITYOU && !testbits(def->flags, MF_BATTY)) + unchivalric = UCAT_DISTRACTED; + + // confused (but not perma-confused) + if (def->has_ench(ENCH_CONFUSION) + && !mons_class_flag(def->type, M_CONFUSED)) + { + unchivalric = UCAT_CONFUSED; + } + + // fleeing + if (def->behaviour == BEH_FLEE) + unchivalric = UCAT_FLEEING; + + // invisible + if (attacker->invisible() && !defender->can_see_invisible()) + unchivalric = UCAT_INVISIBLE; + + // held in a net + if (def->has_ench(ENCH_HELD)) + unchivalric = UCAT_NET_HELD; + + // paralysed + if (def->has_ench(ENCH_PARALYSIS)) + unchivalric = UCAT_PARALYSED; + + // sleeping + if (def->behaviour == BEH_SLEEP) + unchivalric = UCAT_SLEEPING; + + // no unchivalric attacks on monsters that cannot fight + // (plants, etc.) + if (defender->cannot_fight()) + unchivalric = UCAT_NO_ATTACK; + + // no unchivalric attacks on invisible monsters + if (!player_monster_visible(def)) + unchivalric = UCAT_NO_ATTACK; + + return unchivalric; +} + ////////////////////////////////////////////////////////////////////////// // Melee attack @@ -2774,67 +2823,57 @@ int melee_attack::player_to_hit(bool random_factor) void melee_attack::player_stab_check() { + unchivalric_attack_type unchivalric = + is_unchivalric_attack(attacker, defender, def); + bool roll_needed = true; int roll = 155; // This ordering is important! - // not paying attention (but not batty) - if (def->foe != MHITYOU && !testbits(def->flags, MF_BATTY)) + switch (unchivalric) { - stab_attempt = true; - stab_bonus = 3; - } + default: + case UCAT_NO_ATTACK: + stab_attempt = false; + stab_bonus = 0; + break; - // confused (but not perma-confused) - if (def->has_ench(ENCH_CONFUSION) - && !mons_class_flag(def->type, M_CONFUSED)) - { + case UCAT_DISTRACTED: stab_attempt = true; - stab_bonus = 2; - } + stab_bonus = 3; + break; - // fleeing - if (def->behaviour == BEH_FLEE) - { + case UCAT_CONFUSED: + case UCAT_FLEEING: stab_attempt = true; stab_bonus = 2; - } + break; - if (attacker->invisible() && !defender->can_see_invisible()) - { + case UCAT_INVISIBLE: stab_attempt = true; if (!mons_sense_invis(def)) roll -= 15; stab_bonus = 2; - } + break; - // trapped in a net or paralysed - if (def->has_ench(ENCH_HELD) || def->has_ench(ENCH_PARALYSIS)) - { + case UCAT_NET_HELD: + case UCAT_PARALYSED: stab_attempt = true; stab_bonus = 1; - } + break; - // sleeping - if (def->behaviour == BEH_SLEEP) - { + case UCAT_SLEEPING: stab_attempt = true; roll_needed = false; stab_bonus = 1; + break; } - // helpless (plants, etc.) - if (defender->cannot_fight()) - stab_attempt = false; - - // check for invisibility - no stabs on invisible monsters. - if (!player_monster_visible( def )) - { - stab_attempt = false; - stab_bonus = 0; - } + // see if we need to roll against dexterity / stabbing + if (stab_attempt && roll_needed) + stab_attempt = (random2(roll) <= you.skills[SK_STABBING] + you.dex); - if (stab_attempt && you.religion == GOD_SHINING_ONE) + if (unchivalric && you.religion == GOD_SHINING_ONE) { // check for the would-be-stabbed monster's being alive, in case // it was abjured as a result of the attack @@ -2848,12 +2887,8 @@ void melee_attack::player_stab_check() cancel_attack = true; } else - did_god_conduct(DID_UNCHIVALRIC_ATTACK, 4); + did_god_conduct(DID_UNCHIVALRIC_ATTACK, 5); } - - // see if we need to roll against dexterity / stabbing - if (stab_attempt && roll_needed) - stab_attempt = (random2(roll) <= you.skills[SK_STABBING] + you.dex); } void melee_attack::player_apply_attack_delay() diff --git a/crawl-ref/source/fight.h b/crawl-ref/source/fight.h index 3200888154..83d79d2efd 100644 --- a/crawl-ref/source/fight.h +++ b/crawl-ref/source/fight.h @@ -28,6 +28,18 @@ enum unarmed_attack_type UNAT_BITE }; +enum unchivalric_attack_type +{ + UCAT_NO_ATTACK, // 0 + UCAT_DISTRACTED, + UCAT_CONFUSED, + UCAT_FLEEING, + UCAT_INVISIBLE, + UCAT_NET_HELD, + UCAT_PARALYSED, + UCAT_SLEEPING +}; + struct mon_attack_def; // added Sept 18, 2000 -- bwr @@ -70,6 +82,10 @@ 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, + const monsters *def); + class melee_attack { public: diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index 42c7243687..8fa47a82be 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -35,6 +35,7 @@ #include "directn.h" #include "dungeon.h" #include "effects.h" +#include "fight.h" #include "itemname.h" #include "itemprop.h" #include "items.h" @@ -1213,6 +1214,9 @@ char burn_freeze(int pow, beam_type flavour) else if (mons_neutral(monster)) did_god_conduct(DID_ATTACK_NEUTRAL, 5, true, monster); + if (is_unchivalric_attack(&you, monster, monster)) + did_god_conduct(DID_UNCHIVALRIC_ATTACK, 5, true, monster); + if (mons_holiness(monster) == MH_HOLY) did_god_conduct(DID_ATTACK_HOLY, monster->hit_dice); } diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index 144d9bffae..4e56db545b 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -31,6 +31,7 @@ #include "debug.h" #include "delay.h" #include "effects.h" // holy word +#include "fight.h" #include "food.h" #include "itemname.h" #include "itemprop.h" @@ -220,6 +221,9 @@ int cast_smiting(int power, dist &beam) else if (mons_neutral(monster)) did_god_conduct(DID_ATTACK_NEUTRAL, 5, true, monster); + if (is_unchivalric_attack(&you, monster, monster)) + did_god_conduct(DID_UNCHIVALRIC_ATTACK, 5, true, monster); + if (mons_is_holy(monster)) did_god_conduct(DID_ATTACK_HOLY, monster->hit_dice, true, monster); @@ -279,6 +283,9 @@ int airstrike(int power, dist &beam) else if (mons_neutral(monster)) did_god_conduct(DID_ATTACK_NEUTRAL, 5, true, monster); + if (is_unchivalric_attack(&you, monster, monster)) + did_god_conduct(DID_UNCHIVALRIC_ATTACK, 5, true, monster); + if (mons_is_holy(monster)) did_god_conduct(DID_ATTACK_HOLY, monster->hit_dice, true, monster); -- cgit v1.2.3-54-g00ecf