summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/cloud.cc
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-24 08:48:05 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-24 08:48:05 +0000
commit6fdba2e9e01c86505290097b028f7197dc52d004 (patch)
treed4c14223f7e3cd05f9d19545ede9a9efecb5fca5 /crawl-ref/source/cloud.cc
parent179a048026b0dfea4fd95a2b71673e6a0694481c (diff)
downloadcrawl-ref-6fdba2e9e01c86505290097b028f7197dc52d004.tar.gz
crawl-ref-6fdba2e9e01c86505290097b028f7197dc52d004.zip
[1601595] Lava smokes, swamp shallow water tends to mist.
Cold spells fired over water trail freezing cloud. Smoke/steam spreads out a bit as it dissipates. I can't seem to make this look as pretty as I imagined it. :-( MAX_CLOUDS is still on 100. We may want to increase this. Monster pale draconians are pegged back to speed 10 (was 12). git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@486 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/cloud.cc')
-rw-r--r--crawl-ref/source/cloud.cc153
1 files changed, 142 insertions, 11 deletions
diff --git a/crawl-ref/source/cloud.cc b/crawl-ref/source/cloud.cc
index 7217240c57..633bd331ce 100644
--- a/crawl-ref/source/cloud.cc
+++ b/crawl-ref/source/cloud.cc
@@ -16,21 +16,23 @@
#include "externs.h"
#include "cloud.h"
+#include "misc.h"
#include "stuff.h"
-void delete_cloud( int cloud )
+// Returns true if this cloud spreads out as it dissipates.
+static bool cloud_spreads(const cloud_struct &cloud)
{
- if (env.cloud[ cloud ].type != CLOUD_NONE)
+ switch (cloud.type)
{
- const int cloud_x = env.cloud[ cloud ].x;
- const int cloud_y = env.cloud[ cloud ].y;
-
- env.cloud[ cloud ].type = CLOUD_NONE;
- env.cloud[ cloud ].decay = 0;
- env.cloud[ cloud ].x = 0;
- env.cloud[ cloud ].y = 0;
- env.cgrid[ cloud_x ][ cloud_y ] = EMPTY_CLOUD;
- env.cloud_no--;
+ case CLOUD_STEAM:
+ case CLOUD_STEAM_MON:
+ case CLOUD_GREY_SMOKE:
+ case CLOUD_BLACK_SMOKE:
+ case CLOUD_GREY_SMOKE_MON:
+ case CLOUD_BLACK_SMOKE_MON:
+ return (true);
+ default:
+ return (false);
}
}
@@ -46,6 +48,123 @@ static void new_cloud( int cloud, int type, int x, int y, int decay )
env.cloud_no++;
}
+static void place_new_cloud(int cltype, int x, int y, int decay)
+{
+ if (env.cloud_no >= MAX_CLOUDS)
+ return;
+
+ // find slot for cloud
+ for (int ci = 0; ci < MAX_CLOUDS; ci++)
+ {
+ if (env.cloud[ci].type == CLOUD_NONE) // ie is empty
+ {
+ new_cloud( ci, cltype, x, y, decay );
+ break;
+ }
+ }
+}
+
+static int spread_cloud(const cloud_struct &cloud)
+{
+ const int spreadch = cloud.decay > 30? 80 :
+ cloud.decay > 20? 50 :
+ 30;
+ int extra_decay = 0;
+
+ for (int yi = -1; yi <= 1; ++yi)
+ {
+ for (int xi = -1; xi <= 1; ++xi)
+ {
+ if ((!xi && !yi) || random2(100) >= spreadch)
+ continue;
+
+ const int x = cloud.x + xi;
+ const int y = cloud.y + yi;
+
+ if (!in_bounds(x, y)
+ || env.cgrid[x][y] != EMPTY_CLOUD
+ || grid_is_solid(grd[x][y]))
+ continue;
+
+ int newdecay = cloud.decay / 2 + 1;
+ if (newdecay >= cloud.decay)
+ newdecay = cloud.decay - 1;
+
+ place_new_cloud( cloud.type, x, y, newdecay );
+
+ extra_decay += 8;
+ }
+ }
+
+ return (extra_decay);
+}
+
+static void dissipate_cloud(int cc, cloud_struct &cloud, int dissipate)
+{
+ // apply calculated rate to the actual cloud:
+ cloud.decay -= dissipate;
+
+ if (cloud_spreads(cloud) && cloud.decay > 10 && one_chance_in(5))
+ cloud.decay -= spread_cloud(cloud);
+
+ // check for total dissipation and handle accordingly:
+ if (cloud.decay < 1)
+ delete_cloud( cc );
+}
+
+void manage_clouds(void)
+{
+ // amount which cloud dissipates - must be unsigned! {dlb}
+ unsigned int dissipate = 0;
+
+ for (unsigned char cc = 0; cc < MAX_CLOUDS; cc++)
+ {
+ if (env.cloud[cc].type == CLOUD_NONE) // no cloud -> next iteration
+ continue;
+
+ dissipate = you.time_taken;
+
+ // water -> flaming clouds:
+ // lava -> freezing clouds:
+ if ((env.cloud[cc].type == CLOUD_FIRE
+ || env.cloud[cc].type == CLOUD_FIRE_MON)
+ && grd[env.cloud[cc].x][env.cloud[cc].y] == DNGN_DEEP_WATER)
+ {
+ dissipate *= 4;
+ }
+ else if ((env.cloud[cc].type == CLOUD_COLD
+ || env.cloud[cc].type == CLOUD_COLD_MON)
+ && grd[env.cloud[cc].x][env.cloud[cc].y] == DNGN_LAVA)
+ {
+ dissipate *= 4;
+ }
+
+ // double the amount when slowed - must be applied last(!):
+ if (you.slow)
+ dissipate *= 2;
+
+ dissipate_cloud( cc, env.cloud[cc], dissipate );
+ }
+
+ return;
+} // end manage_clouds()
+
+void delete_cloud( int cloud )
+{
+ if (env.cloud[ cloud ].type != CLOUD_NONE)
+ {
+ const int cloud_x = env.cloud[ cloud ].x;
+ const int cloud_y = env.cloud[ cloud ].y;
+
+ env.cloud[ cloud ].type = CLOUD_NONE;
+ env.cloud[ cloud ].decay = 0;
+ env.cloud[ cloud ].x = 0;
+ env.cloud[ cloud ].y = 0;
+ env.cgrid[ cloud_x ][ cloud_y ] = EMPTY_CLOUD;
+ env.cloud_no--;
+ }
+}
+
// The current use of this function is for shifting in the abyss, so
// that clouds get moved along with the rest of the map.
void move_cloud( int cloud, int new_x, int new_y )
@@ -62,6 +181,16 @@ void move_cloud( int cloud, int new_x, int new_y )
}
}
+// Places a cloud with the given stats assuming one doesn't already
+// exist at that point.
+void check_place_cloud( int cl_type, int x, int y, int lifetime )
+{
+ if (!in_bounds(x, y) || env.cgrid[x][y] != EMPTY_CLOUD)
+ return;
+
+ place_cloud( cl_type, x, y, lifetime );
+}
+
// Places a cloud with the given stats. May delete old clouds to make way
// if there are too many (MAX_CLOUDS == 30) on level. Will overwrite an old
// cloud under some circumstances.
@@ -80,6 +209,7 @@ void place_cloud(unsigned char cl_type, unsigned char ctarget_x,
&& env.cloud[ target_cgrid ].type <= CLOUD_STEAM)
|| env.cloud[ target_cgrid ].type == CLOUD_STINK
|| env.cloud[ target_cgrid ].type == CLOUD_BLACK_SMOKE
+ || env.cloud[ target_cgrid ].type == CLOUD_MIST
|| env.cloud[ target_cgrid ].decay <= 20) //soon gone
{
cl_new = env.cgrid[ ctarget_x ][ ctarget_y ];
@@ -103,6 +233,7 @@ void place_cloud(unsigned char cl_type, unsigned char ctarget_x,
&& env.cloud[ ci ].type <= CLOUD_STEAM)
|| env.cloud[ ci ].type == CLOUD_STINK
|| env.cloud[ ci ].type == CLOUD_BLACK_SMOKE
+ || env.cloud[ ci ].type == CLOUD_MIST
|| env.cloud[ ci ].decay <= 20) //soon gone
{
cl_del = ci;