summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/player.cc
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-03-05 19:12:42 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-03-05 19:12:42 +0000
commitf92c98f617ffc96468e0fa7aaee043ac730ba697 (patch)
tree043ec8944989f1fce3a5d032ad8919a12c707f49 /crawl-ref/source/player.cc
parentac070947b0015988e4dd98ddbea2cf5aedbc71b6 (diff)
downloadcrawl-ref-f92c98f617ffc96468e0fa7aaee043ac730ba697.tar.gz
crawl-ref-f92c98f617ffc96468e0fa7aaee043ac730ba697.zip
Imported 4.1-style EV calc.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@982 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/player.cc')
-rw-r--r--crawl-ref/source/player.cc124
1 files changed, 120 insertions, 4 deletions
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index cb44baa336..a29abcd66c 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -1743,7 +1743,123 @@ size_type player_size( int psize, bool base )
return you.body_size(psize, base);
}
-int player_evasion(void)
+// New and improved 4.1 evasion model, courtesy Brent Ross.
+int player_evasion()
+{
+ // XXX: player_size() implementations are incomplete, fix.
+ const size_type size = player_size(PSIZE_BODY);
+ const size_type torso = player_size(PSIZE_TORSO);
+
+ const int size_factor = SIZE_MEDIUM - size;
+ int ev = 10 + 2 * size_factor;
+
+ // Repulsion fields and size are all that matters when paralysed.
+ if (you.paralysed())
+ {
+ ev = 2 + size_factor;
+ if (you.mutation[MUT_REPULSION_FIELD] > 0)
+ ev += (you.mutation[MUT_REPULSION_FIELD] * 2) - 1;
+ return ((ev < 1) ? 1 : ev);
+ }
+
+ // Calculate the base bonus here, but it may be reduced by heavy
+ // armour below.
+ int dodge_bonus = (skill_bump(SK_DODGING) * you.dex + 10)
+ / (20 - size_factor);
+
+ // Limit on bonus from dodging:
+ const int max_bonus = (you.skills[SK_DODGING] * (10 + size_factor)) / 9;
+ if (dodge_bonus > max_bonus)
+ dodge_bonus = max_bonus;
+
+ // Some lesser armours have small penalties now (shields, barding)
+ for (int i = EQ_CLOAK; i < EQ_BODY_ARMOUR; i++)
+ {
+ if (you.equip[i] == -1)
+ continue;
+
+ int pen = property( you.inv[ you.equip[i] ], PARM_EVASION );
+
+ // reducing penalty of larger shields for larger characters
+ if (i == EQ_SHIELD && torso > SIZE_MEDIUM)
+ pen += (torso - SIZE_MEDIUM);
+
+ if (pen < 0)
+ ev += pen;
+ }
+
+ // handle main body armour penalty
+ if (you.equip[EQ_BODY_ARMOUR] != -1)
+ {
+ // XXX: magnify arm_penalty for weak characters?
+ // Remember: arm_penalty and ev_change are negative.
+ int arm_penalty = property( you.inv[ you.equip[EQ_BODY_ARMOUR] ],
+ PARM_EVASION );
+
+ // The very large races take a penalty to AC for not being able
+ // to fully cover, and in compensation we give back some freedom
+ // of movement here. Likewise, the very small are extra encumbered
+ // by armour (which partially counteracts their size bonus above).
+ if (size < SIZE_SMALL || size > SIZE_LARGE)
+ {
+ arm_penalty -= ((size - SIZE_MEDIUM) * arm_penalty) / 4;
+
+ if (arm_penalty > 0)
+ arm_penalty = 0;
+ }
+
+ int ev_change = arm_penalty;
+ ev_change += (you.skills[SK_ARMOUR] * you.strength) / 60;
+
+ if (ev_change > arm_penalty / 2)
+ ev_change = arm_penalty / 2;
+
+ ev += ev_change;
+
+ // This reduces dodging ability in heavy armour.
+ if (!player_light_armour())
+ dodge_bonus += (arm_penalty * 30 + 15) / you.strength;
+ }
+
+ if (dodge_bonus > 0) // always a bonus
+ ev += dodge_bonus;
+
+ if (you.duration[DUR_FORESCRY])
+ ev += 8;
+
+ if (you.duration[DUR_STONEMAIL])
+ ev -= 2;
+
+ ev += player_equip( EQ_RINGS_PLUS, RING_EVASION );
+ ev += scan_randarts( RAP_EVASION );
+
+ if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_PONDEROUSNESS ))
+ ev -= 2;
+
+ if (you.mutation[MUT_REPULSION_FIELD] > 0)
+ ev += (you.mutation[MUT_REPULSION_FIELD] * 2) - 1;
+
+ // transformation penalties/bonuses not covered by size alone:
+ switch (you.attribute[ATTR_TRANSFORMATION])
+ {
+ case TRAN_STATUE:
+ ev -= 5; // stiff
+ break;
+
+ case TRAN_AIR:
+ ev += 20; // vapourous
+ break;
+
+ default:
+ break;
+ }
+
+ return (ev);
+}
+
+// Obsolete evasion calc.
+#if 0
+int old_player_evasion(void)
{
int ev = 10;
@@ -1833,6 +1949,7 @@ int player_evasion(void)
return ev;
} // end player_evasion()
+#endif
int player_magical_power( void )
{
@@ -4890,9 +5007,8 @@ int player::armour_class() const
int player::melee_evasion(const actor *act) const
{
- return (random2limit(player_evasion(), 40)
- + random2(you.dex) / 3
- - (act->visible()? 2 : 14)
+ return (player_evasion()
+ - (act->visible()? 0 : 10)
- (you_are_delayed()? 5 : 0));
}