summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--crawl-ref/source/acr.cc3
-rw-r--r--crawl-ref/source/beam.cc9
-rw-r--r--crawl-ref/source/cloud.cc153
-rw-r--r--crawl-ref/source/cloud.h3
-rw-r--r--crawl-ref/source/direct.cc5
-rw-r--r--crawl-ref/source/enum.h2
-rw-r--r--crawl-ref/source/files.cc2
-rw-r--r--crawl-ref/source/initfile.cc2
-rw-r--r--crawl-ref/source/misc.cc124
-rw-r--r--crawl-ref/source/misc.h13
-rw-r--r--crawl-ref/source/mon-data.h2
-rw-r--r--crawl-ref/source/stuff.cc4
-rw-r--r--crawl-ref/source/travel.cc3
-rw-r--r--crawl-ref/source/view.cc4
14 files changed, 262 insertions, 67 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 3596b0959b..0e5dda5ef9 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -71,6 +71,7 @@
#include "abl-show.h"
#include "abyss.h"
#include "chardump.h"
+#include "cloud.h"
#include "clua.h"
#include "command.h"
#include "debug.h"
@@ -2073,6 +2074,8 @@ static void world_reacts() {
if (you.num_turns != -1)
you.num_turns++;
+ run_environment_effects();
+
//if (random2(10) < you.skills [SK_TRAPS_DOORS] + 2) search_around();
stealth = check_stealth();
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 71c70980a5..f87f644de4 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -2722,13 +2722,18 @@ static int affect_place_clouds(struct bolt &beam, int x, int y)
// FIRE/COLD over water/lava
if ( (grd[x][y] == DNGN_LAVA && beam.flavour == BEAM_COLD)
- || ((grd[x][y] == DNGN_DEEP_WATER || grd[x][y] == DNGN_SHALLOW_WATER)
- && beam.flavour == BEAM_FIRE) )
+ || (grid_is_watery(grd[x][y]) && beam.flavour == BEAM_FIRE) )
{
cloud_type = YOU_KILL(beam.thrower) ? CLOUD_STEAM : CLOUD_STEAM_MON;
place_cloud( cloud_type, x, y, 2 + random2(5) );
}
+ if (beam.flavour == BEAM_COLD && grid_is_watery(grd[x][y]))
+ {
+ cloud_type = YOU_KILL(beam.thrower) ? CLOUD_COLD : CLOUD_COLD_MON;
+ place_cloud( cloud_type, x, y, 2 + random2(5) );
+ }
+
// ORB OF ENERGY
if (beam.name == "orb of energy")
place_cloud( CLOUD_PURP_SMOKE, x, y, random2(5) + 1 );
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;
diff --git a/crawl-ref/source/cloud.h b/crawl-ref/source/cloud.h
index e11535ca8c..62f8d93ce2 100644
--- a/crawl-ref/source/cloud.h
+++ b/crawl-ref/source/cloud.h
@@ -17,6 +17,9 @@
void delete_cloud( int cloud );
void move_cloud( int cloud, int new_x, int new_y );
+void check_place_cloud( int cl_type, int x, int y, int lifetime );
void place_cloud(unsigned char cl_type, unsigned char ctarget_x, unsigned char ctarget_y, unsigned char cl_range);
+void manage_clouds(void);
+
#endif
diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc
index a517eb68ab..b35f3b3b6d 100644
--- a/crawl-ref/source/direct.cc
+++ b/crawl-ref/source/direct.cc
@@ -1541,8 +1541,9 @@ static void describe_cell(int mx, int my)
(cloud_type == CLOUD_MIASMA
|| cloud_type == CLOUD_MIASMA_MON) ? "foul pestilence" :
(cloud_type == CLOUD_BLACK_SMOKE
- || cloud_type == CLOUD_BLACK_SMOKE_MON) ? "black smoke"
- : "buggy goodness");
+ || cloud_type == CLOUD_BLACK_SMOKE_MON) ? "black smoke" :
+ (cloud_type == CLOUD_MIST)? "thin mist" :
+ "buggy goodness");
strcat(info, " here.");
mpr(info);
}
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 062eac939c..8b1caa093b 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -530,6 +530,7 @@ enum cloud_type
CLOUD_STEAM, // 8
CLOUD_MIASMA = 9, // 9: found 11jan2000 {dlb}
CLOUD_BLACK_SMOKE = 10, //was: CLOUD_STICKY_FLAME and wrong 19jan2000 {dlb}
+ CLOUD_MIST,
CLOUD_RANDOM = 98,
CLOUD_DEBUGGING = 99, // 99: used once as 'nonexistent cloud' {dlb}
// if env.cloud_type > 100, it is a monster's cloud {dlb}
@@ -1158,6 +1159,7 @@ enum element_type
EC_FLOOR, // colour of the area's floor
EC_ROCK, // colour of the area's rock
EC_STONE, // colour of the area's stone
+ EC_MIST, // colour of mist
EC_RANDOM // any colour (except BLACK)
};
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 03b145a45b..daea1295d9 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -1118,6 +1118,8 @@ found_stair:
// Save the created/updated level out to disk:
save_level( you.your_level, (you.level_type != LEVEL_DUNGEON),
you.where_are_you );
+
+ setup_environment_effects();
} // end load()
void save_level(int level_saved, bool was_a_labyrinth, char where_were_you)
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 1846407171..c8bfbfe033 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -68,7 +68,7 @@ int str_to_colour( const std::string &str, int default_colour )
"magic", "mutagenic", "warp", "enchant", "heal", "holy", "dark",
"death", "necro", "unholy", "vehumet", "crystal", "blood", "smoke",
"slime", "jewel", "elven", "dwarven", "orcish", "gila", "floor",
- "rock", "stone", "random"
+ "rock", "stone", "mist", "random"
};
for (ret = 0; ret < 16; ret++)
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index c0aa8783b0..f08840d5bf 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -162,6 +162,11 @@ bool grid_is_water( int grid )
return (grid == DNGN_SHALLOW_WATER || grid == DNGN_DEEP_WATER);
}
+bool grid_is_watery( int grid )
+{
+ return (grid_is_water(grid) || grid == DNGN_BLUE_FOUNTAIN);
+}
+
bool grid_destroys_items( int grid )
{
return (grid == DNGN_LAVA || grid == DNGN_DEEP_WATER);
@@ -1579,48 +1584,6 @@ void disarm_trap( struct dist &disa )
exercise(SK_TRAPS_DOORS, 1 + random2(5) + (you.your_level / 5));
} // end disarm_trap()
-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;
-
- // apply calculated rate to the actual cloud:
- env.cloud[cc].decay -= dissipate;
-
- // check for total dissipatation and handle accordingly:
- if (env.cloud[cc].decay < 1)
- delete_cloud( cc );
- }
-
- return;
-} // end manage_clouds()
-
void weird_writing(char stringy[40])
{
int temp_rand = 0; // for probability determinations {dlb}
@@ -2194,3 +2157,80 @@ int subdungeon_depth(unsigned char branch, int depth)
return curr_subdungeon_level;
}
+
+////////////////////////////////////////////////////////////////////////////
+// Living breathing dungeon stuff.
+//
+
+static std::vector<coord_def> sfx_seeds;
+
+void setup_environment_effects()
+{
+ sfx_seeds.clear();
+
+ for (int x = X_BOUND_1; x <= X_BOUND_2; ++x)
+ {
+ for (int y = Y_BOUND_1; y <= Y_BOUND_2; ++y)
+ {
+ if (!in_bounds(x, y))
+ continue;
+
+ const int grid = grd[x][y];
+ if (grid == DNGN_LAVA
+ || (grid == DNGN_SHALLOW_WATER
+ && you.where_are_you == BRANCH_SWAMP))
+ {
+ coord_def c = { x, y };
+ sfx_seeds.push_back(c);
+ }
+ }
+ }
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "%u environment effect seeds", sfx_seeds.size());
+#endif
+}
+
+static void apply_environment_effect(const coord_def &c)
+{
+ const int grid = grd[c.x][c.y];
+ if (grid == DNGN_LAVA)
+ check_place_cloud( CLOUD_BLACK_SMOKE_MON,
+ c.x, c.y, random_range( 4, 8 ) );
+ else if (grid == DNGN_SHALLOW_WATER)
+ check_place_cloud( CLOUD_MIST,
+ c.x, c.y, random_range( 2, 5 ) );
+}
+
+static const int Base_Sfx_Chance = 5;
+void run_environment_effects()
+{
+ if (!you.time_taken)
+ return;
+
+ // Each square in sfx_seeds has this chance of doing something special
+ // per turn.
+ const int sfx_chance = Base_Sfx_Chance * you.time_taken / 10;
+ const int nseeds = sfx_seeds.size();
+
+ // If there is a large number of seeds, speed things up by fudging the
+ // numbers.
+ if (nseeds > 100)
+ {
+ int nsels = div_rand_round( sfx_seeds.size() * sfx_chance, 100 );
+ if (one_chance_in(5))
+ nsels += random2(nsels * 3);
+
+ for (int i = 0; i < nsels; ++i)
+ apply_environment_effect( sfx_seeds[ random2(nseeds) ] );
+ }
+ else
+ {
+ for (int i = 0; i < nseeds; ++i)
+ {
+ if (random2(100) >= sfx_chance)
+ continue;
+
+ apply_environment_effect( sfx_seeds[i] );
+ }
+ }
+}
diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h
index a11d043940..9f6252fd70 100644
--- a/crawl-ref/source/misc.h
+++ b/crawl-ref/source/misc.h
@@ -36,13 +36,6 @@ void search_around(void);
/* ***********************************************************************
* called from: acr
* *********************************************************************** */
-void manage_clouds(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
void disarm_trap(struct dist &disa);
@@ -139,6 +132,7 @@ bool grid_is_wall(int grid);
bool grid_is_opaque(int grid);
bool grid_is_solid(int grid);
bool grid_is_water(int grid);
+bool grid_is_watery( int grid );
god_type grid_altar_god( unsigned char grid );
bool grid_is_branch_stairs( unsigned char grid );
int grid_secret_door_appearance( int gx, int gy );
@@ -150,6 +144,11 @@ void curare_hits_player(int agent, int degree);
bool i_feel_safe();
+void setup_environment_effects();
+
+// Lava smokes, swamp water mists.
+void run_environment_effects();
+
//////////////////////////////////////////////////////////////////////
// Places and names
//
diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h
index 0ba9523678..b1a2480e05 100644
--- a/crawl-ref/source/mon-data.h
+++ b/crawl-ref/source/mon-data.h
@@ -3665,7 +3665,7 @@
900, 10, MONS_DRACONIAN, MONS_PALE_DRACONIAN, MH_NATURAL, -2,
{ 20, 0, 0, 0 },
{ 14, 5, 4, 0 },
- 9, 14, 12, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
+ 9, 14, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
MONUSE_STARTING_EQUIPMENT
}
,
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index e9b97624ea..bb9c8214dd 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -1098,6 +1098,10 @@ int element_colour( int element, bool no_random )
ret = LIGHTGREY;
break;
+ case EC_MIST:
+ ret = tmp_rand < 100? CYAN : BLUE;
+ break;
+
case EC_RANDOM:
ret = 1 + random2(15); // always random
break;
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index 85898db5ba..fde93fa9c6 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -456,7 +456,8 @@ static bool is_safe(int x, int y)
cloud_type == CLOUD_PURP_SMOKE ||
cloud_type == CLOUD_PURP_SMOKE_MON ||
cloud_type == CLOUD_BLACK_SMOKE ||
- cloud_type == CLOUD_BLACK_SMOKE_MON;
+ cloud_type == CLOUD_BLACK_SMOKE_MON ||
+ cloud_type == CLOUD_MIST;
}
static bool player_is_permalevitating()
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 21e5e69dd2..d1ff9a3ef8 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -890,6 +890,10 @@ void cloud_grid(void)
which_colour = DARKGREY;
break;
+ case CLOUD_MIST:
+ which_colour = EC_MIST;
+ break;
+
default:
which_colour = LIGHTGREY;
break;