summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/spells3.cc
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-12-30 20:31:38 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-12-30 20:31:38 +0000
commite864f4d3b84c1efe09175652a9830dddbc0bd6a5 (patch)
tree7322d1cc0393f62adb256204a714cdcd976a2d62 /crawl-ref/source/spells3.cc
parent7554b6525e58b192f168e50233479f3fb1d19f5e (diff)
downloadcrawl-ref-e864f4d3b84c1efe09175652a9830dddbc0bd6a5.tar.gz
crawl-ref-e864f4d3b84c1efe09175652a9830dddbc0bd6a5.zip
A completely reworked version of Zin as per the lengthy
discussion in October/November. Zin effects: - protection from harm (like all good gods) - feeding when starving (as before) - mutation resistance (chance of piety/200) Zin restrictions: - no cannibalism (like all good gods) - no attacking friends - no eating of intelligent beings' corpses - no deliberate mutating Zin invocations: - Smiting (general priestly ability?) - Revitalisation (Minor Healing + 5 mp) - Sanctuary (protection from attacks) git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3164 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/spells3.cc')
-rw-r--r--crawl-ref/source/spells3.cc123
1 files changed, 123 insertions, 0 deletions
diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc
index 08f9d4cffe..a930ba8652 100644
--- a/crawl-ref/source/spells3.cc
+++ b/crawl-ref/source/spells3.cc
@@ -43,7 +43,9 @@
#include "place.h"
#include "player.h"
#include "randart.h"
+#include "religion.h"
#include "spells1.h"
+#include "spells2.h" // holy word
#include "spells4.h"
#include "spl-cast.h"
#include "spl-util.h"
@@ -798,6 +800,127 @@ bool entomb(int powc)
return (number_built > 0);
} // end entomb()
+bool remove_sanctuary(bool did_attack)
+{
+ if (env.sanctuary_time)
+ env.sanctuary_time = 0;
+
+ if (env.sanctuary_x < 0 || env.sanctuary_y < 0)
+ return false;
+
+ const int radius = 5;
+ bool seen_change = false;
+ for (int x=-radius; x<=radius; x++)
+ for (int y=-radius; y<=radius; y++)
+ {
+ int posx = env.sanctuary_x + x;
+ int posy = env.sanctuary_y + y;
+
+ if (posx <= 0 || posx > GXM || posy <= 0 || posy > GYM)
+ continue;
+
+ if (is_sanctuary(posx, posy))
+ {
+ env.map[posx][posy].property = FPROP_NONE;
+ if (see_grid(coord_def(posx,posy)))
+ seen_change = true;
+ }
+ }
+
+// do not reset so as to allow monsters to see if their fleeing source
+// used to be the centre of a sanctuary
+// env.sanctuary_x = env.sanctuary_y = -1;
+
+ if (did_attack)
+ {
+ if (seen_change)
+ simple_god_message(" revokes the gift of sanctuary.", GOD_ZIN);
+ did_god_conduct(DID_FRIEND_DIES, 3);
+ }
+ else if (seen_change)
+ {
+ mpr("The air around you flickers and hums.");
+ if (is_resting())
+ stop_running();
+ }
+
+ return true;
+}
+
+bool cast_sanctuary(const int power)
+{
+ // first get rid of old sanctuary
+ remove_sanctuary();
+
+ if (!silenced(you.x_pos, you.y_pos))
+ mpr("You hear a choir sing!");
+ else
+ mpr("You are suddenly bathed in radiance!");
+
+ you.flash_colour = WHITE;
+ viewwindow( true, false );
+ holy_word( 100, true );
+ delay(1000);
+
+ env.sanctuary_x = you.x_pos;
+ env.sanctuary_y = you.y_pos;
+ env.sanctuary_time = 15;
+
+ const int radius = 5;
+ const int pattern = random2(4);
+ int count = 0;
+ int monster = -1;
+
+ for (int x=-radius; x<=radius; x++)
+ for (int y=-radius; y<=radius; y++)
+ {
+ int posx = you.x_pos + x;
+ int posy = you.y_pos + y;
+
+ if (posx <= 0 || posx > GXM || posy <= 0 || posy > GYM)
+ continue;
+
+ int dist = distance(posx, posy, you.x_pos, you.y_pos);
+ if (dist > radius*radius)
+ continue;
+
+ // scare all hostile monsters inside sanctuary
+ if (mgrd[posx][posy] != NON_MONSTER)
+ {
+ monster = mgrd[posx][posy];
+ monsters *mon = &menv[monster];
+
+ if (!mons_friendly(mon)
+ && mon->add_ench(mon_enchant(ENCH_FEAR, 0, KC_YOU)))
+ {
+ behaviour_event(mon, ME_SCARE, MHITYOU);
+ count++;
+ }
+ }
+
+ // forming patterns
+ if (pattern == 0
+ && (x == 0 || y == 0 || x == y || x == -y)
+ || pattern == 1
+ && (dist >= (radius-1)*(radius-1) && dist <= radius*radius)
+ || pattern == 2
+ && (x%2 == 0 || y%2 == 0)
+ || pattern == 3
+ && (abs(x)+abs(y) < 5 && x != y && x != -y))
+ {
+ env.map[posx][posy].property = FPROP_SANCTUARY_1;
+ }
+ else
+ env.map[posx][posy].property = FPROP_SANCTUARY_2;
+ }
+ if (count == 1)
+ simple_monster_message(&menv[monster], " turns to flee the light!");
+ else if (count > 0)
+ mpr("The monsters scatter in all directions!");
+
+ return (true);
+}
+
void cast_poison_ammo(void)
{
const int ammo = you.equip[EQ_WEAPON];