summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-19 20:29:26 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-19 20:29:26 +0000
commitf4cd5aede38a820cc5ab7137b8cc1a0927ae7f3e (patch)
treecdb7c880be5448aecba4bcb1925531cc7e51d3fd /crawl-ref
parent86da4aff359e1be8b6cacc7ae340b42ec7d676a4 (diff)
downloadcrawl-ref-f4cd5aede38a820cc5ab7137b8cc1a0927ae7f3e.tar.gz
crawl-ref-f4cd5aede38a820cc5ab7137b8cc1a0927ae7f3e.zip
First draft of god tension, and of Xom using tension.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7869 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/acr.cc8
-rw-r--r--crawl-ref/source/religion.cc148
-rw-r--r--crawl-ref/source/religion.h1
-rw-r--r--crawl-ref/source/xom.cc29
4 files changed, 177 insertions, 9 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 357ad38069..c64a720a74 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -3034,6 +3034,9 @@ static void _decrement_durations()
if (_decrement_a_duration(DUR_DIVINE_STAMINA))
remove_divine_stamina();
+
+ _decrement_a_duration(DUR_REPEL_STAIRS_MOVE);
+ _decrement_a_duration(DUR_REPEL_STAIRS_CLIMB);
}
static void _check_banished()
@@ -3240,6 +3243,11 @@ static void _world_reacts()
if (you.cannot_act() && any_messages())
more();
+
+#if DEBUG_TENSION || DEBUG_RELIGION
+ if (you.religion != GOD_NO_GOD)
+ mprf(MSGCH_DIAGNOSTICS, "TENSION = %d", get_tension());
+#endif
}
#ifdef DGL_SIMPLE_MESSAGING
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 1dddb3e31c..4dfead400b 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -6692,3 +6692,151 @@ bool tso_unchivalric_attack_safe_monster(const monsters *mon)
|| mons_is_evil(mon)
|| (holiness != MH_NATURAL && holiness != MH_HOLY));
}
+
+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);
+}
diff --git a/crawl-ref/source/religion.h b/crawl-ref/source/religion.h
index 1c8a4bac95..7390fdad73 100644
--- a/crawl-ref/source/religion.h
+++ b/crawl-ref/source/religion.h
@@ -139,4 +139,5 @@ bool god_likes_items(god_type god);
void religion_turn_start();
+int get_tension(god_type god = you.religion);
#endif
diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc
index 28d0f3dbcc..befb2ac002 100644
--- a/crawl-ref/source/xom.cc
+++ b/crawl-ref/source/xom.cc
@@ -707,7 +707,7 @@ static monster_type _xom_random_demon(int sever, bool use_greater_demons = true)
}
// The nicer stuff. Note: these things are not necessarily nice.
-static bool _xom_is_good(int sever)
+static bool _xom_is_good(int sever, int tension)
{
bool done = false;
@@ -720,7 +720,8 @@ static bool _xom_is_good(int sever)
// This series of random calls produces a poisson-looking
// distribution: initial hump, plus a long-ish tail.
- if (x_chance_in_y(2, sever))
+ // Don't make player berserk if there's no danger.
+ if (tension > 0 && x_chance_in_y(2, sever))
{
potion_type pot =
static_cast<potion_type>(
@@ -769,7 +770,8 @@ static bool _xom_is_good(int sever)
}
}
}
- else if (x_chance_in_y(5, sever))
+ // Pointless to send in help if there's no danger.
+ else if (tension > 0 && x_chance_in_y(5, sever))
{
// XXX: Can we clean up this ugliness, please?
const int numdemons =
@@ -1012,7 +1014,8 @@ static bool _xom_is_good(int sever)
}
}
}
- else if (x_chance_in_y(14, sever))
+ // Pointless to send in help if there's no danger.
+ else if (tension > 0 && x_chance_in_y(14, sever))
{
monster_type mon = _xom_random_demon(sever);
const bool is_demonic = (mons_class_holiness(mon) == MH_DEMONIC);
@@ -1089,7 +1092,7 @@ static bool _xom_is_good(int sever)
return (done);
}
-static bool _xom_is_bad(int sever)
+static bool _xom_is_bad(int sever, int tension)
{
bool done = false;
@@ -1264,7 +1267,8 @@ static bool _xom_is_bad(int sever)
}
}
}
- else if (x_chance_in_y(11, sever))
+ // Pointless to confuse player if there's no danger nearby.
+ else if (tension > 0 && x_chance_in_y(11, sever))
{
std::string speech = _get_xom_speech("confusion");
if (confuse_player(random2(sever)+1, false)) {
@@ -1395,11 +1399,12 @@ void xom_acts(bool niceness, int sever)
sever = std::max(1, sever);
+ god_type which_god = GOD_XOM;
// Drawing the Xom card from Nemelex's decks of oddities or punishment.
if (crawl_state.is_god_acting()
&& crawl_state.which_god_acting() != GOD_XOM)
{
- god_type which_god = crawl_state.which_god_acting();
+ which_god = crawl_state.which_god_acting();
if (crawl_state.is_god_retribution())
{
@@ -1414,6 +1419,12 @@ void xom_acts(bool niceness, int sever)
}
}
+ const int tension = get_tension(which_god);
+
+#if DEBUG_RELIGION || DEBUG_XOM || DEBUG_TENSION
+ mprf(MSGCH_DIAGNOSTICS, "xom tension: %d", tension);
+#endif
+
const dungeon_feature_type orig_feat = grd(you.pos());
const int orig_hp = you.hp;
@@ -1428,13 +1439,13 @@ void xom_acts(bool niceness, int sever)
if (niceness && !one_chance_in(5))
{
// Good stuff.
- while (!_xom_is_good(sever))
+ while (!_xom_is_good(sever, tension))
;
}
else
{
// Bad mojo.
- while (!_xom_is_bad(sever))
+ while (!_xom_is_bad(sever, tension))
;
}