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
ZP2KE7A2LE7Z2S7AC45WE4CXDSEVDTWIMV2EM4IBUKXYJIDU6R7QC
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()
}
////////////////////////////////////////////////////////////////////////////
// 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] );
}
}
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);
// 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--;
}
}