summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Otto <ottochar@gmail.com>2009-11-06 00:15:09 -0500
committerCharles Otto <ottochar@gmail.com>2009-11-06 00:15:50 -0500
commit8c0f2ef1e0ca14dfbe4dc5263ce9d1dddd674758 (patch)
tree0ce03d9fbc4370b46372c0cb25ff0e33d21712c7
parent2cd18cf91603ca59471842721b584b8a7521f103 (diff)
downloadcrawl-ref-8c0f2ef1e0ca14dfbe4dc5263ce9d1dddd674758.tar.gz
crawl-ref-8c0f2ef1e0ca14dfbe4dc5263ce9d1dddd674758.zip
Add haste other as a monster spell
-rw-r--r--crawl-ref/source/acr.cc2
-rw-r--r--crawl-ref/source/enum.h3
-rw-r--r--crawl-ref/source/goditem.cc3
-rw-r--r--crawl-ref/source/mon-cast.cc52
-rw-r--r--crawl-ref/source/mon-util.cc41
-rw-r--r--crawl-ref/source/spl-data.h13
6 files changed, 111 insertions, 3 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 1976e1405b..2a7ef4c6ee 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -4370,7 +4370,7 @@ static void _compile_time_asserts()
COMPILE_CHECK(SP_VAMPIRE == 30 , c3);
COMPILE_CHECK(SPELL_DEBUGGING_RAY == 103 , c4);
COMPILE_CHECK(SPELL_PETRIFY == 156 , c5);
- COMPILE_CHECK(NUM_SPELLS == 202 , c6);
+ COMPILE_CHECK(NUM_SPELLS == 203 , c6);
//jmf: NEW ASSERTS: we ought to do a *lot* of these
COMPILE_CHECK(NUM_SPECIES < SP_UNKNOWN , c7);
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 98ed77e78f..025b3cb869 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -2887,8 +2887,9 @@ enum spell_type
SPELL_KRAKEN_TENTACLES,
SPELL_TOMB_OF_DOROKLOHE, // 200
SPELL_SUMMON_EYEBALLS,
+ SPELL_HASTE_OTHER,
- NUM_SPELLS // 202
+ NUM_SPELLS // 203
};
enum slot_select_mode
diff --git a/crawl-ref/source/goditem.cc b/crawl-ref/source/goditem.cc
index d4515724e2..ab9268ec0f 100644
--- a/crawl-ref/source/goditem.cc
+++ b/crawl-ref/source/goditem.cc
@@ -274,7 +274,8 @@ bool is_hasty_spell(spell_type spell, god_type god)
return (spell == SPELL_HASTE
|| spell == SPELL_SWIFTNESS
- || spell == SPELL_BERSERKER_RAGE);
+ || spell == SPELL_BERSERKER_RAGE
+ || spell == SPELL_HASTE_OTHER);
}
// The default suitable() function for is_spellbook_type().
diff --git a/crawl-ref/source/mon-cast.cc b/crawl-ref/source/mon-cast.cc
index cd1ae62f50..1a7e53ee76 100644
--- a/crawl-ref/source/mon-cast.cc
+++ b/crawl-ref/source/mon-cast.cc
@@ -87,6 +87,45 @@ static spell_type _draco_type_to_breath(int drac_type)
return (SPELL_DRACONIAN_BREATH);
}
+// Find an allied monster to cast a beneficial beam spell at.
+// Only used for haste other at the moment.
+static bool _set_allied_target(monsters * caster, bolt & pbolt)
+{
+ monsters * selected_target = NULL;
+ int min_distance = INT_MAX;
+
+ monster_type caster_genus = mons_genus(caster->type);
+
+ for (int i = 0; i < MAX_MONSTERS; i++)
+ {
+ monsters * targ = &menv[i];
+ if (i != caster->mindex()
+ && targ->alive()
+ && caster->can_see(targ)
+ && mons_genus(targ->type) == caster_genus
+ && targ->attitude == caster->attitude
+ && !targ->has_ench(ENCH_CHARM)
+ && !targ->has_ench(ENCH_HASTE))
+ {
+ int targ_distance = grid_distance(targ->pos(), caster->pos());
+ if (targ_distance < min_distance && targ_distance < pbolt.range)
+ {
+ min_distance = targ_distance;
+ selected_target = targ;
+ }
+ }
+ }
+
+ if (selected_target)
+ {
+ pbolt.target = selected_target->pos();
+ return (true);
+ }
+
+ // Didn't find a target
+ return (false);
+}
+
bolt mons_spells( monsters *mons, spell_type spell_cast, int power )
{
ASSERT(power > 0);
@@ -172,6 +211,11 @@ bolt mons_spells( monsters *mons, spell_type spell_cast, int power )
beam.is_beam = true;
break;
+ case SPELL_HASTE_OTHER:
+ beam.flavour = BEAM_HASTE;
+ beam.is_beam = true;
+ break;
+
case SPELL_HASTE: // (self)
beam.flavour = BEAM_HASTE;
break;
@@ -1055,6 +1099,14 @@ bool handle_mon_spell(monsters *monster, bolt &beem)
// Setup the spell.
setup_mons_cast(monster, beem, spell_cast);
+ // Try to find a nearby ally to haste
+ if (spell_cast == SPELL_HASTE_OTHER
+ && !_set_allied_target(monster, beem))
+ {
+ spell_cast = SPELL_NO_SPELL;
+ continue;
+ }
+
// beam-type spells requiring tracers
if (spell_needs_tracer(spell_cast))
{
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index b60b9924b7..53f1a11e94 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -2180,6 +2180,42 @@ void mons_pacify(monsters *mon)
behaviour_event(mon, ME_EVAL);
}
+static bool _mons_should_fire_beneficial(bolt &beam)
+{
+ // Should monster haste other be able to target the player?
+ // Saying no for now. -cao
+ if (beam.target == you.pos())
+ return false;
+
+ // Assuming all beneficial beams are enchantments if a foe is in
+ // the path the beam will definitely hit them so we shouldn't fire
+ // in that case.
+ if (beam.friend_info.count == 0
+ || beam.foe_info.count != 0)
+ return (false);
+
+ // Should beneficial monster enchantment beams be allowed in a
+ // sanctuary? -cao
+ if (is_sanctuary(you.pos()) || is_sanctuary(beam.source))
+ return (false);
+
+ return (true);
+}
+
+static bool _beneficial_beam_flavour(beam_type flavour)
+{
+ switch(flavour)
+ {
+ case BEAM_HASTE:
+ case BEAM_HEALING:
+ case BEAM_INVISIBILITY:
+ return (true);
+
+ default:
+ return (false);
+ }
+}
+
bool mons_should_fire(struct bolt &beam)
{
#ifdef DEBUG_DIAGNOSTICS
@@ -2191,6 +2227,11 @@ bool mons_should_fire(struct bolt &beam)
beam.foe_ratio, beam.smart_monster ? "yes" : "no");
#endif
+ // Use different evaluation criteria if the beam is a beneficial
+ // enchantment (haste other).
+ if (_beneficial_beam_flavour(beam.flavour))
+ return _mons_should_fire_beneficial(beam);
+
// Friendly monsters shouldn't be targetting you: this will happen
// often because the default behaviour for charmed monsters is to
// have you as a target. While foe_ratio will handle this, we
diff --git a/crawl-ref/source/spl-data.h b/crawl-ref/source/spl-data.h
index d54e992954..52d543ce1e 100644
--- a/crawl-ref/source/spl-data.h
+++ b/crawl-ref/source/spl-data.h
@@ -2395,6 +2395,19 @@
},
{
+ SPELL_HASTE_OTHER, "Haste Other",
+ SPTYP_ENCHANTMENT,
+ SPFLAG_DIR_OR_TARGET | SPFLAG_HELPFUL,
+ 6,
+ 200,
+ LOS_RADIUS, LOS_RADIUS,
+ 0,
+ NULL,
+ true,
+ false
+},
+
+{
SPELL_NO_SPELL, "nonexistent spell",
0,
SPFLAG_TESTING,