git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7869 c06c8d41-db1a-0410-9941-cceddc491573
FYSQ7HXDIKXZXDGYVKZMODW7HYQQLRZO52Q2HVM3PYBD37UT5B4AC
5II5YCH65EWH2SV3367AJIDFB4O4ZSOQOG7BMVYDWLP26UBITLGQC
26JV5AK6S3VRZQTX7RV65QV26JCLJ2P7VSCJTNCYLKJRZ6HOC6ZQC
6LLSWPPIKBZEAJ3FYNS77DZCJVN4N4BVESFNZ4AL4AHQKQ2SDXTAC
HCVH2CWL32UD66O6Z7ZYDUASWN3RF5TW6FSWURGMD7MELKB772FAC
NYURIMPCM2RADLMIQSN76OPKXQSK4XBLFNXD2OO53KGZI3MA6AQAC
KFULGQQOHWUTXOM3BXCCYPGGVGGY4Z6265XUFRCBPNLTZAEHJZSQC
LUD5XPFLSYPJOYZG6DDV4C5WIQUGZPE7YV6AR75ENCAIISD3LZWQC
22YVHM74WBJNJE4PA5CBEUTDWM6FAGGGILI26A4LXAURX55TNRKAC
PHBACPMH3F34GODHVDKNCMXWU373RJQGVTDLBFCCDLLWDXVYOLTAC
5BJPWUPLJFS34FUTFJVKA4A52YMIGV6EWDXLNSDCWBJWBGVSQFGQC
6PAG7GHXHIYXJPPTEK4KZQZT4CL2SJDAGTVIUDB4KK66PVSTWUMAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
XPMFRLTXS5LA4TROB43JS7NZ4FB2JAQBZZMZWS7SHPMU4SKUIYTQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
TV3ZC6WOZKSQQJQN26JIVKCHK6UK7WMDBYZDUYRWEAZ4JB4YVNAAC
}
int get_tension(god_type god)
{
ASSERT(god != GOD_NO_GOD);
int total = 0;
for (int midx = 0; midx < MAX_MONSTERS; midx++)
{
const monsters* mons = &menv[midx];
if (!mons->alive())
continue;
if (see_grid(mons->pos()))
; // Monster is nearby
else
{
// Is the monster trying to get somewhere nearby?
coord_def target;
unsigned int travel_size = mons->travel_path.size();
if (travel_size > 0)
target = mons->travel_path[travel_size - 1];
else
target = mons->target;
// Monster is neither nearby nor trying to get near us.
if (!in_bounds(target) || !see_grid(target))
continue;
}
const mon_attitude_type att = mons_attitude(mons);
if (att == ATT_GOOD_NEUTRAL)
continue;
if (mons_cannot_act(mons) || mons->asleep() || mons_is_fleeing(mons))
{
continue;
}
int exper = exper_value(mons);
if (exper <= 0)
continue;
// Almost dead monsters don't count as much.
exper *= mons->hit_points;
exper /= mons->max_hit_points;
const bool gift = mons_is_god_gift(mons, god);
if (att == ATT_HOSTILE)
{
// God is punishing you with a hostile gift, so it doesn't
// count towards tension.
if (gift)
continue;
}
else if (att == ATT_FRIENDLY)
{
// Friendly monsters being around to help you reduce tension.
exper = -exper;
// If it's a god gift it reduces tension even more, since the
// god is already helping you out.
if (gift)
exper *= 2;
}
else
// Neutral monsters aren't as much of a threat.
exper /= 2;
if (att != ATT_FRIENDLY)
{
if (!mons_player_visible(mons))
exper /= 2;
if (!player_monster_visible(mons))
exper *= 2;
}
if (mons->confused() || mons->caught())
exper /= 2;
if (mons->has_ench(ENCH_SLOW))
{
exper *= 2;
exper /= 3;
}
if (mons->has_ench(ENCH_HASTE))
{
exper *= 3;
exper /= 2;
}
if (mons->has_ench(ENCH_BERSERK))
exper *= 2;
total += exper;
}
const int scale = 1;
int tension = total;
// Tension goes up inversly proportional to the % of max hp you
// have.
tension *= (scale + 1) * you.hp_max;
tension /= you.hp_max + scale * you.hp;
// Divides by 1 at level 1, 200 at level 27.
const int exp_lev = you.get_experience_level();
const int exp_need = exp_needed(exp_lev + 1);
const int factor = ceil(sqrt(exp_need / 30.0));
const int div = 1 + factor;
tension /= div;
if (you.level_type == LEVEL_ABYSS)
tension = std::max(2, tension);
if (you.cannot_act())
{
tension *= 10;
tension = std::max(1, tension);
return (tension);
}
if (you.confused())
tension *= 2;
if (you.caught())
tension *= 2;
if (you.duration[DUR_SLOW])
{
tension *= 3;
tension /= 2;
}
if (you.duration[DUR_HASTE])
{
tension *= 2;
tension /= 3;
}
return std::max(0, tension);