From 6fdba2e9e01c86505290097b028f7197dc52d004 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Fri, 24 Nov 2006 08:48:05 +0000 Subject: [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 --- crawl-ref/source/cloud.cc | 153 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 142 insertions(+), 11 deletions(-) (limited to 'crawl-ref/source/cloud.cc') 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; -- cgit v1.2.3-54-g00ecf