summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/cloud.cc
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-07-29 22:59:35 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-07-29 22:59:35 +0000
commit63036c9e5ed0103475fea0c6710317f15e8cdb24 (patch)
treec6e731b631741fc069a6baeb80bf15c58458e9e0 /crawl-ref/source/cloud.cc
parente744cede0540585248737db8e27a8320e5476955 (diff)
downloadcrawl-ref-63036c9e5ed0103475fea0c6710317f15e8cdb24.tar.gz
crawl-ref-63036c9e5ed0103475fea0c6710317f15e8cdb24.zip
Implemented monster spell miscasts. Spell miscasting is now handled
by the MiscastEffect class, which has helper methods to make most of the non-helper code agnostic with respect to whether the miscaster is the player or a monster. Mummy death curses now affect monsters, and Zot traps now directly affect friendly and good-neutral monsters. In wizard mode you can force the player or a monster to miscast by targeting it and pressing 'M'. Todo/issues/notes: * Clouds now have a killer_type in addition to a kill_category. * There aren't any divination monster miscast effects yet. * Many of the harmless message-only miscast effects are missing monster messages. * If a monster actually miscasts a spell (not getting a mummy death curse or setting off a Zot trap) and this kills both the monster and the player then the wrong monster will be listed in hiscore entry. Since monsters can't do true spell miscasts yet, this can wait. * There was old, non-functioning code making Zot traps heal, haste or turn invisible hostile monsters that triggered it. I fixed it and then commented it out. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@6723 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/cloud.cc')
-rw-r--r--crawl-ref/source/cloud.cc135
1 files changed, 126 insertions, 9 deletions
diff --git a/crawl-ref/source/cloud.cc b/crawl-ref/source/cloud.cc
index 2e5c912bb7..a0f5b180df 100644
--- a/crawl-ref/source/cloud.cc
+++ b/crawl-ref/source/cloud.cc
@@ -46,24 +46,47 @@ static unsigned char _actual_spread_rate(cloud_type type, int spread_rate)
}
}
+static bool _killer_whose_match(kill_category whose, killer_type killer)
+{
+ switch(whose)
+ {
+ case KC_YOU:
+ return (killer == KILL_YOU_MISSILE || killer == KILL_YOU_CONF);
+
+ case KC_FRIENDLY:
+ return (killer == KILL_MON_MISSILE || killer == KILL_YOU_CONF);
+
+ case KC_OTHER:
+ return (killer == KILL_MON_MISSILE || killer == KILL_MISC);
+
+ case KC_NCATEGORIES:
+ ASSERT(false);
+ }
+ return (false);
+}
+
static void _new_cloud( int cloud, cloud_type type, const coord_def& p,
- int decay, kill_category whose,
+ int decay, kill_category whose, killer_type killer,
unsigned char spread_rate )
{
ASSERT( env.cloud[ cloud ].type == CLOUD_NONE );
+ ASSERT(_killer_whose_match(whose, killer));
+
env.cloud[ cloud ].type = type;
env.cloud[ cloud ].decay = decay;
env.cloud[ cloud ].x = p.x;
env.cloud[ cloud ].y = p.y;
env.cloud[ cloud ].whose = whose;
+ env.cloud[ cloud ].killer = killer;
env.cloud[ cloud ].spread_rate = spread_rate;
env.cgrid(p) = cloud;
env.cloud_no++;
}
static void _place_new_cloud(cloud_type cltype, const coord_def& p, int decay,
- kill_category whose, int spread_rate)
+ kill_category whose, killer_type killer,
+ int spread_rate)
{
if (env.cloud_no >= MAX_CLOUDS)
return;
@@ -73,7 +96,7 @@ static void _place_new_cloud(cloud_type cltype, const coord_def& p, int decay,
{
if (env.cloud[ci].type == CLOUD_NONE) // i.e., is empty
{
- _new_cloud( ci, cltype, p, decay, whose, spread_rate );
+ _new_cloud( ci, cltype, p, decay, whose, killer, spread_rate );
break;
}
}
@@ -102,7 +125,7 @@ static int _spread_cloud(const cloud_struct &cloud)
if (newdecay >= cloud.decay)
newdecay = cloud.decay - 1;
- _place_new_cloud( cloud.type, *ai, newdecay, cloud.whose,
+ _place_new_cloud( cloud.type, *ai, newdecay, cloud.whose, cloud.killer,
cloud.spread_rate );
extra_decay += 8;
@@ -170,6 +193,7 @@ void delete_cloud( int cloud )
env.cloud[ cloud ].x = 0;
env.cloud[ cloud ].y = 0;
env.cloud[ cloud ].whose = KC_OTHER;
+ env.cloud[ cloud ].killer = KILL_NONE;
env.cloud[ cloud ].spread_rate = 0;
env.cgrid(cloud_pos) = EMPTY_CLOUD;
env.cloud_no--;
@@ -197,10 +221,30 @@ void move_cloud( int cloud, const coord_def& newpos )
void check_place_cloud( cloud_type cl_type, const coord_def& p, int lifetime,
kill_category whose, int spread_rate )
{
+ check_place_cloud(cl_type, p, lifetime, whose,
+ cloud_struct::whose_to_killer(whose), spread_rate);
+}
+
+// Places a cloud with the given stats assuming one doesn't already
+// exist at that point.
+void check_place_cloud( cloud_type cl_type, const coord_def& p, int lifetime,
+ killer_type killer, int spread_rate )
+{
+ check_place_cloud(cl_type, p, lifetime,
+ cloud_struct::killer_to_whose(killer), killer,
+ spread_rate);
+}
+
+// Places a cloud with the given stats assuming one doesn't already
+// exist at that point.
+void check_place_cloud( cloud_type cl_type, const coord_def& p, int lifetime,
+ kill_category whose, killer_type killer,
+ int spread_rate )
+{
if (!in_bounds(p) || env.cgrid(p) != EMPTY_CLOUD)
return;
- place_cloud( cl_type, p, lifetime, whose, spread_rate );
+ place_cloud( cl_type, p, lifetime, whose, killer, spread_rate );
}
int steam_cloud_damage(const cloud_struct &cloud)
@@ -221,6 +265,26 @@ int steam_cloud_damage(const cloud_struct &cloud)
void place_cloud(cloud_type cl_type, const coord_def& ctarget, int cl_range,
kill_category whose, int _spread_rate)
{
+ place_cloud(cl_type, ctarget, cl_range, whose,
+ cloud_struct::whose_to_killer(whose), _spread_rate);
+}
+
+// Places a cloud with the given stats. May delete old clouds to
+// make way if there are too many on level. Will overwrite an old
+// cloud under some circumstances.
+void place_cloud(cloud_type cl_type, const coord_def& ctarget, int cl_range,
+ killer_type killer, int _spread_rate)
+{
+ place_cloud(cl_type, ctarget, cl_range,
+ cloud_struct::killer_to_whose(killer), killer, _spread_rate);
+}
+
+// Places a cloud with the given stats. May delete old clouds to
+// make way if there are too many on level. Will overwrite an old
+// cloud under some circumstances.
+void place_cloud(cloud_type cl_type, const coord_def& ctarget, int cl_range,
+ kill_category whose, killer_type killer, int _spread_rate)
+{
if (is_sanctuary(ctarget) && !is_harmless_cloud(cl_type))
return;
@@ -277,7 +341,7 @@ void place_cloud(cloud_type cl_type, const coord_def& ctarget, int cl_range,
if (cl_new != -1)
{
_new_cloud( cl_new, cl_type, ctarget, cl_range * 10,
- whose, spread_rate );
+ whose, killer, spread_rate );
}
else
{
@@ -287,7 +351,7 @@ void place_cloud(cloud_type cl_type, const coord_def& ctarget, int cl_range,
if (env.cloud[ci].type == CLOUD_NONE) // ie is empty
{
_new_cloud( ci, cl_type, ctarget, cl_range * 10,
- whose, spread_rate );
+ whose, killer, spread_rate );
break;
}
}
@@ -635,9 +699,62 @@ std::string cloud_name(cloud_type type)
////////////////////////////////////////////////////////////////////////
// cloud_struct
-killer_type cloud_struct::beam_thrower() const
+kill_category cloud_struct::killer_to_whose(killer_type killer)
{
- return (whose == KC_YOU ? KILL_YOU_MISSILE : KILL_MON_MISSILE);
+ switch(killer)
+ {
+ case KILL_YOU:
+ case KILL_YOU_MISSILE:
+ case KILL_YOU_CONF:
+ return (KC_YOU);
+
+ case KILL_MON:
+ case KILL_MON_MISSILE:
+ case KILL_MISC:
+ return (KC_OTHER);
+
+ default:
+ ASSERT(false);
+ }
+ return (KC_OTHER);
+}
+
+killer_type cloud_struct::whose_to_killer(kill_category whose)
+{
+ switch(whose)
+ {
+ case KC_YOU: return(KILL_YOU_MISSILE);
+ case KC_FRIENDLY: return(KILL_MON_MISSILE);
+ case KC_OTHER: return(KILL_MON_MISSILE);
+ case KC_NCATEGORIES: ASSERT(false);
+ }
+ return (KILL_NONE);
+}
+
+void cloud_struct::set_whose(kill_category _whose)
+{
+ whose = _whose;
+ killer = whose_to_killer(whose);
+}
+
+void cloud_struct::set_killer(killer_type _killer)
+{
+ killer = _killer;
+ whose = killer_to_whose(killer);
+
+ switch(killer)
+ {
+ case KILL_YOU:
+ killer = KILL_YOU_MISSILE;
+ break;
+
+ case KILL_MON:
+ killer = KILL_MON_MISSILE;
+ break;
+
+ default:
+ break;
+ }
}
//////////////////////////////////////////////////////////////////////////
// Fog machine stuff