diff options
author | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-11-24 08:48:05 +0000 |
---|---|---|
committer | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-11-24 08:48:05 +0000 |
commit | 6fdba2e9e01c86505290097b028f7197dc52d004 (patch) | |
tree | d4c14223f7e3cd05f9d19545ede9a9efecb5fca5 | |
parent | 179a048026b0dfea4fd95a2b71673e6a0694481c (diff) | |
download | crawl-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.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/beam.cc | 9 | ||||
-rw-r--r-- | crawl-ref/source/cloud.cc | 153 | ||||
-rw-r--r-- | crawl-ref/source/cloud.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/direct.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/files.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/initfile.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 124 | ||||
-rw-r--r-- | crawl-ref/source/misc.h | 13 | ||||
-rw-r--r-- | crawl-ref/source/mon-data.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/stuff.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/travel.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 4 |
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; |