summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/externs.h1
-rw-r--r--crawl-ref/source/mon-util.cc21
-rw-r--r--crawl-ref/source/mstuff2.cc115
-rw-r--r--crawl-ref/source/spells1.cc16
-rw-r--r--crawl-ref/source/stuff.cc7
-rw-r--r--crawl-ref/source/stuff.h2
6 files changed, 97 insertions, 65 deletions
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index db07ab191a..4ac5b302c0 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -970,7 +970,6 @@ public:
private:
int modded_speed(const monsters *mons, int hdplus) const;
- int apply_fuzz(int dur, int lo, int hi) const;
int calc_duration(const monsters *mons, const mon_enchant *added) const;
};
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 3f3cddeb0b..ddd1e66ee4 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -4258,13 +4258,6 @@ int mon_enchant::modded_speed(const monsters *mons, int hdplus) const
return (mod_speed(mons->hit_dice + hdplus, mons->speed));
}
-int mon_enchant::apply_fuzz(int dur, int lowfuzz, int highfuzz) const
-{
- const int lfuzz = lowfuzz * dur / 100,
- hfuzz = highfuzz * dur / 100;
- return dur + random2avg(lfuzz + hfuzz + 1, 2) - lfuzz;
-}
-
int mon_enchant::calc_duration(const monsters *mons,
const mon_enchant *added) const
{
@@ -4331,18 +4324,12 @@ int mon_enchant::calc_duration(const monsters *mons,
default:
break;
}
-
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "Ench for %s: raw turn duration for %s (%d) == %d",
- mons->name(DESC_PLAIN).c_str(), std::string(*this).c_str(),
- deg, cturn);
-#endif
if (cturn < 2)
cturn = 2;
int raw_duration = (cturn * speed_to_duration(mons->speed));
- raw_duration = apply_fuzz(raw_duration, 60, 40);
+ raw_duration = fuzz_value(raw_duration, 60, 40);
if (raw_duration < 15)
raw_duration = 15;
@@ -4360,12 +4347,6 @@ void mon_enchant::set_duration(const monsters *mons, const mon_enchant *added)
duration += added->duration;
else
duration += calc_duration(mons, added);
-
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "Ench on %s: ench energy for %s: %d",
- mons->name(DESC_PLAIN).c_str(), std::string(*this).c_str(),
- duration);
-#endif
if (duration > maxduration)
maxduration = duration;
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index 63eb013342..79fa03d8b2 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -44,7 +44,7 @@
#include "stuff.h"
#include "view.h"
-static int monster_abjuration(bool friendly, int pow, bool test);
+static int monster_abjuration(const monsters *mons, bool test);
// XXX: must fix species abils to not use duration 15
// -- ummm ... who wrote this? {dlb}
@@ -332,11 +332,10 @@ void mons_trap(struct monsters *monster)
static bool mons_abjured(monsters *monster, bool nearby)
{
- const bool friendly = mons_friendly(monster);
- if (nearby && monster_abjuration(friendly, 1, true) > 0
+ if (nearby && monster_abjuration(monster, true) > 0
&& coinflip())
{
- monster_abjuration( friendly, monster->hit_dice * 10, false );
+ monster_abjuration(monster, false);
return (true);
}
@@ -1921,56 +1920,92 @@ bolt mons_spells( int spell_cast, int power )
return (beam);
} // end mons_spells()
-static int monster_abjuration(bool friendly, int pow, bool test)
+static int monster_abjure_square(const coord_def &pos,
+ int power, int test_only,
+ int friendly)
{
- int result = 0;
- monsters *monster = NULL;
+ const int mindex = mgrd(pos);
+ if (mindex == NON_MONSTER)
+ return (0);
+
+ monsters *target = &menv[mindex];
+ if (!target->alive() || friendly == mons_friendly(target))
+ return (0);
- if (!test)
- mpr("Send 'em back where they came from!");
+ mon_enchant abj = target->get_ench(ENCH_ABJ);
+ if (abj.ench == ENCH_NONE)
+ return (0);
+
+ power = std::max(20, fuzz_value(power, 40, 25));
- if (pow > 60)
- pow = 60;
+ if (test_only)
+ return (power > abj.duration? 5 : 1);
- int abjure_str = 1 + (random2(pow / 3));
- if (abjure_str > 6)
- abjure_str = 6;
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "Abj: dur: %d, pow: %d, ndur: %d",
+ abj.duration, power, abj.duration - power);
+#endif
- for (int ab = 0; ab < MAX_MONSTERS && abjure_str; ab++)
+ if ((abj.duration -= power) <= 0)
{
- monster = &menv[ab];
-
- if (!monster->alive() || !mons_near(monster))
- continue;
+ monster_die(target, KILL_RESET, 0);
+ return (5);
+ }
- if (friendly == mons_friendly(monster))
- continue;
+ simple_monster_message(target, " shudders.");
+ target->update_ench(abj);
+ return (1);
+}
- mon_enchant abjLevel = monster->get_ench(ENCH_ABJ);
- if (abjLevel.ench == ENCH_NONE)
- continue;
+static int apply_radius_around_square(
+ const coord_def &c, int radius,
+ int (*fn)(const coord_def &, int, int, int),
+ int pow, int par1, int par2)
+{
+ int res = 0;
+ for (int yi = -radius; yi <= radius; ++yi)
+ {
+ const coord_def c1(c.x - radius, c.y + yi);
+ const coord_def c2(c.x + radius, c.y + yi);
+ if (in_bounds(c1))
+ res += fn(c1, pow, par1, par2);
+ if (in_bounds(c2))
+ res += fn(c2, pow, par1, par2);
+ }
- result++;
+ for (int xi = -radius + 1; xi < radius; ++xi)
+ {
+ const coord_def c1(c.x + xi, c.y - radius);
+ const coord_def c2(c.x + xi, c.y + radius);
+ if (in_bounds(c1))
+ res += fn(c1, pow, par1, par2);
+ if (in_bounds(c2))
+ res += fn(c2, pow, par1, par2);
+ }
+ return (res);
+}
- if (test)
- continue;
+static int monster_abjuration(const monsters *caster, bool test)
+{
+ const bool friendly = mons_friendly(caster);
+ int maffected = 0;
- abjLevel.degree -= abjure_str;
+ if (!test)
+ mpr("Send 'em back where they came from!");
- if (abjLevel.degree <= 0)
- monster_die(monster, KILL_RESET, 0);
- else
- {
- simple_monster_message(monster, " shudders.");
- monster->update_ench(abjLevel);
- }
+ int pow = std::min(caster->hit_dice * 90, 2500);
- if (!(abjure_str = div_rand_round(abjure_str, 2)))
- break;
+ // Abjure radius.
+ for (int rad = 1; rad < 5 && pow >= 30; ++rad)
+ {
+ maffected +=
+ apply_radius_around_square(
+ caster->pos(), rad, monster_abjure_square,
+ pow, test, friendly);
+ pow = pow * 2 / 5;
}
-
- return result;
-} // end monster_abjuration()
+ return (maffected);
+}
bool silver_statue_effects(monsters *mons)
{
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index f9d0a86d3b..4db7987997 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -667,6 +667,9 @@ void abjuration(int pow)
mpr("Send 'em back where they came from!");
+ // Scale power into something comparable to summon lifetime.
+ const int abjdur = pow * 10;
+
for (int ab = 0; ab < MAX_MONSTERS; ab++)
{
monster = &menv[ab];
@@ -679,10 +682,15 @@ void abjuration(int pow)
mon_enchant abj = monster->get_ench(ENCH_ABJ);
if (abj.ench != ENCH_NONE)
- monster->lose_ench_levels(abj, 1 + (random2(pow) / 8));
-
- if (monster->has_ench(ENCH_ABJ))
- simple_monster_message(monster, " shudders.");
+ {
+ const int sockage = std::max(fuzz_value(abjdur, 60, 30), 40);
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "%s abj: dur: %d, abj: %d",
+ monster->name(DESC_PLAIN).c_str(), abj.duration, sockage);
+#endif
+ if (!monster->lose_ench_duration(abj, sockage))
+ simple_monster_message(monster, " shudders.");
+ }
}
} // end abjuration()
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index 1a622937d6..7a33c5684d 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -1033,6 +1033,13 @@ int letter_to_index(int the_letter)
return the_letter;
} // end letter_to_index()
+int fuzz_value(int val, int lowfuzz, int highfuzz, int naverage)
+{
+ const int lfuzz = lowfuzz * val / 100,
+ hfuzz = highfuzz * val / 100;
+ return val + random2avg(lfuzz + hfuzz + 1, naverage) - lfuzz;
+}
+
// returns 0 if the point is not near stairs
// returns 1 if the point is near unoccupied stairs
// returns 2 if the point is near player-occupied stairs
diff --git a/crawl-ref/source/stuff.h b/crawl-ref/source/stuff.h
index f72a5f9730..42009c228d 100644
--- a/crawl-ref/source/stuff.h
+++ b/crawl-ref/source/stuff.h
@@ -52,6 +52,8 @@ int stat_div( int stat_level, int value, int div = 20, int shift = 3 );
int skill_bump( int skill );
unsigned char get_ch();
+int fuzz_value(int val, int lowfuzz, int highfuzz, int naverage = 2);
+
void cio_init();
void cio_cleanup();
void end(int exit_code, bool print_err = false,