summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/cloud.cc
diff options
context:
space:
mode:
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