diff options
author | Charles Otto <ottochar@gmail.com> | 2009-11-06 00:15:09 -0500 |
---|---|---|
committer | Charles Otto <ottochar@gmail.com> | 2009-11-06 00:15:50 -0500 |
commit | 8c0f2ef1e0ca14dfbe4dc5263ce9d1dddd674758 (patch) | |
tree | 0ce03d9fbc4370b46372c0cb25ff0e33d21712c7 | |
parent | 2cd18cf91603ca59471842721b584b8a7521f103 (diff) | |
download | crawl-ref-8c0f2ef1e0ca14dfbe4dc5263ce9d1dddd674758.tar.gz crawl-ref-8c0f2ef1e0ca14dfbe4dc5263ce9d1dddd674758.zip |
Add haste other as a monster spell
-rw-r--r-- | crawl-ref/source/acr.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/goditem.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/mon-cast.cc | 52 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 41 | ||||
-rw-r--r-- | crawl-ref/source/spl-data.h | 13 |
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, |