Skip to content

Commit

Permalink
Separate caches for light and vision transparency
Browse files Browse the repository at this point in the history
Crouching affects your ability to see past adjacent obstacles.
Previously this was implemented by altering the transparency cache.
However, this also stops light passing the tile, and means that
crouching by a window can cause a room to fall dark.

Fix by separating the transparency cache into two, one for light and one
for vision.  The latter is a copy of the former, except with tweaks for
crouching and with the avatar's tile forced to be transparent.
  • Loading branch information
jbytheway committed Feb 23, 2020
1 parent 6c56d93 commit e5fd233
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 19 deletions.
38 changes: 36 additions & 2 deletions src/lightmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,40 @@ bool map::build_transparency_cache( const int zlev )
return true;
}

bool map::build_vision_transparency_cache( const int zlev )
{
auto &map_cache = get_cache( zlev );
auto &transparency_cache = map_cache.transparency_cache;
auto &vision_transparency_cache = map_cache.vision_transparency_cache;

memcpy( &vision_transparency_cache, &transparency_cache, sizeof( transparency_cache ) );

const tripoint &p = g->u.pos();

if( p.z != zlev ) {
return false;
}

bool dirty = false;

bool is_crouching = g->u.movement_mode_is( CMM_CROUCH );
for( const tripoint &loc : points_in_radius( p, 1 ) ) {
if( loc == p ) {
// The tile player is standing on should always be visible
if( ( has_furn( p ) && !furn( p )->transparent ) || !ter( p )->transparent ) {
vision_transparency_cache[p.x][p.y] = LIGHT_TRANSPARENCY_CLEAR;
}
} else if( is_crouching && coverage( loc ) >= 30 ) {
// If we're crouching behind an obstacle, we can't see past it.
vision_transparency_cache[loc.x][loc.y] = LIGHT_TRANSPARENCY_SOLID;
map_cache.transparency_cache_dirty = true;
dirty = true;
}
}

return dirty;
}

void map::apply_character_light( player &p )
{
if( p.has_effect( effect_onfire ) ) {
Expand Down Expand Up @@ -1102,7 +1136,7 @@ castLightAll<fragment_cloud, fragment_cloud, shrapnel_calc, shrapnel_check,
void map::build_seen_cache( const tripoint &origin, const int target_z )
{
auto &map_cache = get_cache( target_z );
float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vision_transparency_cache;
float ( &seen_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.seen_cache;
float ( &camera_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.camera_cache;

Expand All @@ -1125,7 +1159,7 @@ void map::build_seen_cache( const tripoint &origin, const int target_z )
array_of_grids_of<const bool> floor_caches;
for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
auto &cur_cache = get_cache( z );
transparency_caches[z + OVERMAP_DEPTH] = &cur_cache.transparency_cache;
transparency_caches[z + OVERMAP_DEPTH] = &cur_cache.vision_transparency_cache;
seen_caches[z + OVERMAP_DEPTH] = &cur_cache.seen_cache;
floor_caches[z + OVERMAP_DEPTH] = &cur_cache.floor_cache;
std::uninitialized_fill_n(
Expand Down
21 changes: 4 additions & 17 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7714,33 +7714,19 @@ void map::build_map_cache( const int zlev, bool skip_lightmap )
for( int z = minz; z <= maxz; z++ ) {
build_outside_cache( z );
seen_cache_dirty |= build_transparency_cache( z );
seen_cache_dirty |= build_vision_transparency_cache( zlev );
seen_cache_dirty |= build_floor_cache( z );
do_vehicle_caching( z );
}

const tripoint &p = g->u.pos();
bool is_crouching = g->u.movement_mode_is( CMM_CROUCH );
for( const tripoint &loc : points_in_radius( p, 1 ) ) {
if( loc == p ) {
// The tile player is standing on should always be transparent
if( ( has_furn( p ) && !furn( p ).obj().transparent ) || !ter( p ).obj().transparent ) {
get_cache( p.z ).transparency_cache[p.x][p.y] = LIGHT_TRANSPARENCY_CLEAR;
}
} else if( is_crouching && coverage( loc ) >= 30 ) {
// If we're crouching behind an obstacle, we can't see past it.
get_cache( loc.z ).transparency_cache[loc.x][loc.y] = LIGHT_TRANSPARENCY_SOLID;
get_cache( loc.z ).transparency_cache_dirty = true;
seen_cache_dirty = true;
}
}

if( seen_cache_dirty ) {
skew_vision_cache.clear();
}
// Initial value is illegal player position.
const tripoint &p = g->u.pos();
static tripoint player_prev_pos;
if( seen_cache_dirty || player_prev_pos != p ) {
build_seen_cache( g->u.pos(), zlev );
build_seen_cache( p, zlev );
player_prev_pos = p;
}
if( !skip_lightmap ) {
Expand Down Expand Up @@ -8239,6 +8225,7 @@ level_cache::level_cache()
std::fill_n( &outside_cache[0][0], map_dimensions, false );
std::fill_n( &floor_cache[0][0], map_dimensions, false );
std::fill_n( &transparency_cache[0][0], map_dimensions, 0.0f );
std::fill_n( &vision_transparency_cache[0][0], map_dimensions, 0.0f );
std::fill_n( &seen_cache[0][0], map_dimensions, 0.0f );
std::fill_n( &camera_cache[0][0], map_dimensions, 0.0f );
std::fill_n( &visibility_cache[0][0], map_dimensions, LL_DARK );
Expand Down
2 changes: 2 additions & 0 deletions src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ struct level_cache {
bool outside_cache[MAPSIZE_X][MAPSIZE_Y];
bool floor_cache[MAPSIZE_X][MAPSIZE_Y];
float transparency_cache[MAPSIZE_X][MAPSIZE_Y];
float vision_transparency_cache[MAPSIZE_X][MAPSIZE_Y];
float seen_cache[MAPSIZE_X][MAPSIZE_Y];
float camera_cache[MAPSIZE_X][MAPSIZE_Y];
lit_level visibility_cache[MAPSIZE_X][MAPSIZE_Y];
Expand Down Expand Up @@ -1559,6 +1560,7 @@ class map
// Builds a transparency cache and returns true if the cache was invalidated.
// Used to determine if seen cache should be rebuilt.
bool build_transparency_cache( int zlev );
bool build_vision_transparency_cache( int zlev );
void build_sunlight_cache( int zlev );
public:
void build_outside_cache( int zlev );
Expand Down

0 comments on commit e5fd233

Please sign in to comment.