diff options
author | Nicholas Feinberg <pleasingfung@gmail.com> | 2014-07-01 23:20:50 -0700 |
---|---|---|
committer | Nicholas Feinberg <pleasingfung@gmail.com> | 2014-07-01 23:24:51 -0700 |
commit | c22efd9fab02d2b1b0ad6a00a8bfc45475efc360 (patch) | |
tree | 512d9f5b84e188039de0d689e93f7ecee430b245 /crawl-ref/source/misc.cc | |
parent | 22f25ab0e848bb3f03d7bd4c0331fda178b879c3 (diff) | |
download | crawl-ref-c22efd9fab02d2b1b0ad6a00a8bfc45475efc360.tar.gz crawl-ref-c22efd9fab02d2b1b0ad6a00a8bfc45475efc360.zip |
Let BLOOD finally have its place in the sun
...by moving bloodspatter functions into their own file.
Death to misc.cc! Long live the new file hierarchy!
Diffstat (limited to 'crawl-ref/source/misc.cc')
-rw-r--r-- | crawl-ref/source/misc.cc | 249 |
1 files changed, 0 insertions, 249 deletions
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index c6cfa02f4d..62d96cc00b 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -97,255 +97,6 @@ string get_desc_quantity(const int quant, const int total, string whose) return "Some of " + whose; } -static bool allow_bleeding_on_square(const coord_def& where) -{ - // No bleeding onto sanctuary ground, please. - // Also not necessary if already covered in blood. - if (is_bloodcovered(where) || is_sanctuary(where)) - return false; - - // No spattering into lava or water. - if (grd(where) >= DNGN_LAVA && grd(where) < DNGN_FLOOR) - return false; - - // No spattering into fountains (other than blood). - if (grd(where) == DNGN_FOUNTAIN_BLUE - || grd(where) == DNGN_FOUNTAIN_SPARKLING) - { - return false; - } - - // The good gods like to keep their altars pristine. - if (is_good_god(feat_altar_god(grd(where)))) - return false; - - return true; -} - -bool maybe_bloodify_square(const coord_def& where) -{ - if (!allow_bleeding_on_square(where)) - return false; - - env.pgrid(where) |= FPROP_BLOODY; - return true; -} - -/** - * Rotate the wall blood splat tile, so that it is facing the source. - * - * Wall blood splat tiles are drawned with the blood dripping down. We need - * the tile to be facing an orthogonal empty space for the effect to look - * good. We choose the empty space closest to the source of the blood. - * - * @param where Coordinates of the wall where there is a blood splat. - * @param from Coordinates of the source of the blood. - * @param old_blood blood splats created at level generation are old and can - * have some blood inscriptions. Only for south facing splats, so you don't - * have to turn your head to read the inscriptions. - */ -static void _orient_wall_blood(const coord_def& where, coord_def from, - bool old_blood) -{ - if (!feat_is_wall(env.grid(where))) - return; - - if (from == INVALID_COORD) - from = where; - - coord_def closer = INVALID_COORD; - int dist = INT_MAX; - for (orth_adjacent_iterator ai(where); ai; ++ai) - { - if (in_bounds(*ai) && !cell_is_solid(*ai) - && cell_see_cell(from, *ai, LOS_SOLID) - && (distance2(*ai, from) < dist - || distance2(*ai, from) == dist && coinflip())) - { - closer = *ai; - dist = distance2(*ai, from); - } - } - - // If we didn't find anything, the wall is in a corner. - // We don't want blood tile there. - if (closer == INVALID_COORD) - { - env.pgrid(where) &= ~FPROP_BLOODY; - return; - } - - const coord_def diff = where - closer; - if (diff == coord_def(1, 0)) - env.pgrid(where) |= FPROP_BLOOD_WEST; - else if (diff == coord_def(0, 1)) - env.pgrid(where) |= FPROP_BLOOD_NORTH; - else if (diff == coord_def(-1, 0)) - env.pgrid(where) |= FPROP_BLOOD_EAST; - else if (old_blood && one_chance_in(10)) - env.pgrid(where) |= FPROP_OLD_BLOOD; -} - -static void _maybe_bloodify_square(const coord_def& where, int amount, - bool spatter = false, - bool smell_alert = true, - const coord_def& from = INVALID_COORD, - const bool old_blood = false) -{ - if (amount < 1) - return; - - bool may_bleed = allow_bleeding_on_square(where); - - bool ignite_blood = player_mutation_level(MUT_IGNITE_BLOOD) - && you.see_cell(where); - - if (ignite_blood) - amount *= 2; - - if (x_chance_in_y(amount, 20)) - { - dprf("might bleed now; square: (%d, %d); amount = %d", - where.x, where.y, amount); - if (may_bleed) - { - env.pgrid(where) |= FPROP_BLOODY; - _orient_wall_blood(where, from, old_blood); - - if (ignite_blood - && !cell_is_solid(where) - && env.cgrid(where) == EMPTY_CLOUD) - { - place_cloud(CLOUD_FIRE, where, 5 + random2(6), &you); - } - } - - // The blood spilled can be detected via blood scent even if the - // spot it would fall is prevented from becoming bloodied (for - // example, because it is water) - if (smell_alert && in_bounds(where)) - blood_smell(12, where); - - if (spatter) - { - // Smaller chance of spattering surrounding squares. - for (adjacent_iterator ai(where); ai; ++ai) - { - _maybe_bloodify_square(*ai, amount/15, false, true, from, - old_blood); - } - } - } -} - -// Currently flavour only: colour ground (and possibly adjacent squares) red. -// "damage" depends on damage taken (or hitpoints, if damage higher), -// or, for sacrifices, on the number of chunks possible to get out of a corpse. -void bleed_onto_floor(const coord_def& where, monster_type montype, - int damage, bool spatter, bool smell_alert, - const coord_def& from, const bool old_blood) -{ - ASSERT_IN_BOUNDS(where); - - if (montype == MONS_PLAYER && !you.can_bleed()) - return; - - if (montype != NUM_MONSTERS && montype != MONS_PLAYER) - { - monster m; - m.type = montype; - if (!m.can_bleed()) - return; - } - - _maybe_bloodify_square(where, damage, spatter, smell_alert, from, - old_blood); -} - -void blood_spray(const coord_def& origin, monster_type montype, int level) -{ - int tries = 0; - for (int i = 0; i < level; ++i) - { - // Blood drops are small and light and suffer a lot of wind - // resistance. - int range = random2(8) + 1; - - while (tries < 5000) - { - ++tries; - - coord_def bloody = origin; - bloody.x += random_range(-range, range); - bloody.y += random_range(-range, range); - - if (in_bounds(bloody) && cell_see_cell(origin, bloody, LOS_SOLID)) - { - bleed_onto_floor(bloody, montype, 99, false, true, origin); - break; - } - } - } -} - -static void _spatter_neighbours(const coord_def& where, int chance, - const coord_def& from = INVALID_COORD) -{ - for (adjacent_iterator ai(where, false); ai; ++ai) - { - if (!allow_bleeding_on_square(*ai)) - continue; - - if (one_chance_in(chance)) - { - env.pgrid(*ai) |= FPROP_BLOODY; - _orient_wall_blood(where, from, true); - _spatter_neighbours(*ai, chance+1, from); - } - } -} - -void generate_random_blood_spatter_on_level(const map_bitmask *susceptible_area) -{ - const int max_cluster = 7 + random2(9); - - // Lower chances for large bloodshed areas if we have many clusters, - // but increase chances if we have few. - // Chances for startprob are [1..3] for 7-9 clusters, - // ... [1..4] for 10-12 clusters, and - // ... [2..5] for 13-15 clusters. - - int min_prob = 1; - int max_prob = 4; - - if (max_cluster < 10) - max_prob--; - else if (max_cluster > 12) - min_prob++; - - for (int i = 0; i < max_cluster; ++i) - { - const coord_def c = random_in_bounds(); - - if (susceptible_area && !(*susceptible_area)(c)) - continue; - - // startprob is used to initialise the chance for neighbours - // being spattered, which will be decreased by 1 per recursion - // round. We then use one_chance_in(chance) to determine - // whether to spatter a given grid or not. Thus, startprob = 1 - // means that initially all surrounding grids will be - // spattered (3x3), and the _higher_ startprob the _lower_ the - // overall chance for spattering and the _smaller_ the - // bloodshed area. - const int startprob = min_prob + random2(max_prob); - - maybe_bloodify_square(c); - - _spatter_neighbours(c, startprob); - } -} - void search_around() { ASSERT(!crawl_state.game_is_arena()); |