summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/spells1.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/spells1.cc')
-rw-r--r--crawl-ref/source/spells1.cc127
1 files changed, 108 insertions, 19 deletions
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index 8b65313412..354be9f688 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -42,6 +42,7 @@
#include "mon-util.h"
#include "player.h"
#include "randart.h"
+#include "religion.h"
#include "skills2.h"
#include "spells3.h"
#include "spells4.h"
@@ -571,32 +572,86 @@ int cast_big_c(int pow, cloud_type cty, kill_category whose, bolt &beam)
big_cloud( cty, whose,
beam.target_x, beam.target_y, pow, 8 + random2(3) );
return (1);
-} // end cast_big_c()
+}
void big_cloud(cloud_type cl_type, kill_category whose,
int cl_x, int cl_y, int pow, int size, int spread_rate)
{
apply_area_cloud(make_a_normal_cloud, cl_x, cl_y, pow, size,
cl_type, whose, spread_rate);
-} // end big_cloud()
+}
+
+static bool _mons_hostile(const monsters *mon)
+{
+ // needs to be done this way because of friendly/neutral enchantments
+ return (!mons_friendly(mon) && !mons_neutral(mon));
+}
+
+static bool _can_pacify_monster(const monsters *mon, const int healed)
+{
+ ASSERT(you.religion == GOD_ELYVILON);
+
+ if (healed < 1)
+ return false;
+
+ if (mons_friendly(mon) || mons_neutral(mon))
+ return false;
+
+ // Ely only cares about natural monsters
+ if (mons_holiness(mon) != MH_NATURAL)
+ return false;
+
+ if (mons_intel(mon->type) <= I_PLANT) // no self-awareness
+ return false;
+
+ if (mons_is_sleeping(mon)) // not aware of what is happening
+ return false;
-static int healing_spell( int healed )
+ const int factor = (mons_intel(mon->type) <= I_ANIMAL) ? 3 : // animals
+ (is_player_same_species(mon->type)) ? 2 // same species
+ : 1; // other
+
+ const int random_factor = random2(you.skills[SK_INVOCATIONS] * healed/3);
+
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS,
+ "pacifying %s? max hp: %d, factor: %d, Inv: %d, healed: %d, rnd: %d",
+ mon->name(DESC_PLAIN).c_str(), mon->max_hit_points, factor,
+ you.skills[SK_INVOCATIONS], healed, random_factor);
+#endif
+
+ if (mon->max_hit_points < factor * random_factor)
+ return true;
+
+ return false;
+}
+
+static int _healing_spell( int healed, int dir_x = 100, int dir_y = 100)
{
+ ASSERT(healed >= 1);
+
int mgr = 0;
struct monsters *monster = 0; // NULL {dlb}
struct dist bmove;
- mpr("Which direction?", MSGCH_PROMPT);
- direction( bmove, DIR_DIR, TARG_FRIEND );
-
+ if (dir_x == 100 || dir_y == 100)
+ {
+ mpr("Which direction?", MSGCH_PROMPT);
+ direction( bmove, DIR_DIR, TARG_FRIEND );
+ }
+ else
+ {
+ bmove.dx = dir_x;
+ bmove.dy = dir_y;
+ bmove.isValid = true;
+ }
+
if (!bmove.isValid)
{
canned_msg( MSG_OK );
return 0;
}
- mgr = mgrd[you.x_pos + bmove.dx][you.y_pos + bmove.dy];
-
if (bmove.dx == 0 && bmove.dy == 0)
{
mpr("You are healed.");
@@ -604,6 +659,8 @@ static int healing_spell( int healed )
return 1;
}
+ mgr = mgrd[you.x_pos + bmove.dx][you.y_pos + bmove.dy];
+
if (mgr == NON_MONSTER)
{
mpr("There isn't anything there!");
@@ -611,7 +668,16 @@ static int healing_spell( int healed )
}
monster = &menv[mgr];
+
+ // don't heal monster you can't pacify
+ if (you.religion == GOD_ELYVILON && _mons_hostile(monster)
+ && !_can_pacify_monster(monster, healed))
+ {
+ canned_msg(MSG_NOTHING_HAPPENS);
+ return -1;
+ }
+ bool nothing_happens = true;
if (heal_monster(monster, healed, false))
{
mprf("You heal %s.", monster->name(DESC_NOCAP_THE).c_str());
@@ -623,38 +689,61 @@ static int healing_spell( int healed )
const monsters *mons = static_cast<const monsters*>(monster);
print_wounds(mons);
}
+
+ if (you.religion == GOD_ELYVILON && !_mons_hostile(monster))
+ {
+ simple_god_message(" appreciates the healing of a fellow creature.");
+ if (one_chance_in(8))
+ gain_piety(1);
+ return 1;
+ }
+ nothing_happens = false;
}
- else
+
+ if (you.religion == GOD_ELYVILON && _mons_hostile(monster))
{
- canned_msg(MSG_NOTHING_HAPPENS);
+ simple_god_message(" supports your offer of peace.");
+ simple_monster_message( monster, " turns neutral." );
+ monster->attitude = ATT_NEUTRAL;
+ monster->flags |= MF_WAS_NEUTRAL;
+
+ // give half of the monster's xp
+ unsigned int exp_gain = 0, avail_gain = 0;
+ gain_exp( exper_value(monster) / 2 + 1, &exp_gain, &avail_gain );
+ monster->flags |= MF_GOT_HALF_XP;
+
+ // finally give a small piety return
+ gain_piety(1 + random2(healed/15));
}
+ else if (nothing_happens)
+ canned_msg(MSG_NOTHING_HAPPENS);
return 1;
-} // end healing_spell()
+} // end _healing_spell()
#if 0
char cast_lesser_healing( int pow )
{
- return healing_spell(5 + random2avg(7, 2));
-} // end lesser healing()
+ return _healing_spell(5 + random2avg(7, 2));
+}
char cast_greater_healing( int pow )
{
- return healing_spell(15 + random2avg(29, 2));
-} // end cast_greater_healing()
+ return _healing_spell(15 + random2avg(29, 2));
+}
char cast_greatest_healing( int pow )
{
- return healing_spell(50 + random2avg(49, 2));
-} // end cast_greatest_healing()
+ return _healing_spell(50 + random2avg(49, 2));
+}
#endif
-int cast_healing( int pow )
+int cast_healing( int pow, int dir_x, int dir_y )
{
if (pow > 50)
pow = 50;
- return (healing_spell( pow + roll_dice( 2, pow ) - 2 ));
+ return (_healing_spell( pow + roll_dice( 2, pow ) - 2, dir_x, dir_y ));
}
int cast_revitalisation( int pow )