From ae1fc2f77fec9c5f3689b4d130b49c1f2d22a1b0 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Sat, 23 Nov 2024 14:37:49 +0000 Subject: [PATCH 1/8] Only rebuild vision transparency cache when transparency cache is dirty --- src/lightmap.cpp | 86 ++++++++++++++++++++++++++++-------------------- src/map.cpp | 8 ++--- src/mapdata.cpp | 18 ++++++---- src/mapdata.h | 1 + 4 files changed, 65 insertions(+), 48 deletions(-) diff --git a/src/lightmap.cpp b/src/lightmap.cpp index f65c48cf09c55..4af5fd5e25c0e 100644 --- a/src/lightmap.cpp +++ b/src/lightmap.cpp @@ -187,65 +187,81 @@ bool map::build_transparency_cache( const int zlev ) } } } - map_cache.transparency_cache_dirty.reset(); + //build_vision_transparency_cache copies the transparency_cache so don't reset transparency_cache_dirty until it's resolved return true; } bool map::build_vision_transparency_cache( int zlev ) { level_cache &map_cache = get_cache( zlev ); - cata::mdarray &transparency_cache = map_cache.transparency_cache; - cata::mdarray &vision_transparency_cache = map_cache.vision_transparency_cache; - - Character &player_character = get_player_character(); - const tripoint_bub_ms p = player_character.pos_bub(); - if( p.z() != zlev ) { - // Just copy the transparency cache and be done with it. - memcpy( &vision_transparency_cache, &transparency_cache, sizeof( transparency_cache ) ); + // We copy the transparency_cache so we need to recalc if it's dirty + if( map_cache.transparency_cache_dirty.none() /*&& !map_cache.vision_transparency_cache_dirty.none()*/ ) { return false; } + const cata::mdarray &transparency_cache = map_cache.transparency_cache; + cata::mdarray &vision_transparency_cache = map_cache.vision_transparency_cache; + + // TODO: Should only copy if transparency_cache was dirty + memcpy( &vision_transparency_cache, &transparency_cache, sizeof( transparency_cache ) ); + + const Character &player_character = get_player_character(); + const tripoint_bub_ms p = player_character.pos_bub(); + const bool is_player_z = p.z() == zlev; + bool dirty = false; - std::vector solid_tiles; - - // This segment handles vision when the player is crouching or prone. It only checks adjacent tiles. - // If you change this, also consider creature::sees and map::obstacle_coverage. - const bool is_crouching = player_character.is_crouching(); - const bool low_profile = player_character.has_effect( effect_quadruped_full ) && - player_character.is_running(); - const bool is_prone = player_character.is_prone(); - - if( is_crouching || is_prone || low_profile ) { - for( const tripoint_bub_ms &loc : points_in_radius( p, 1 ) ) { - if( loc != p && coverage( loc ) >= 30 ) { - // If we're crouching or prone behind an obstacle, we can't see past it. - dirty |= vision_transparency_cache[loc.x()][loc.y()] != LIGHT_TRANSPARENCY_SOLID; - solid_tiles.emplace_back( loc ); + if( is_player_z ) { + // This segment handles vision when the player is crouching or prone. It only checks adjacent tiles. + // If you change this, also consider creature::sees and map::obstacle_coverage. + const bool is_crouching = player_character.is_crouching(); + const bool low_profile = player_character.has_effect( effect_quadruped_full ) && + player_character.is_running(); + const bool is_prone = player_character.is_prone(); + if( is_crouching || is_prone || low_profile ) { + for( const tripoint_bub_ms &loc : points_in_radius( p, 1 ) ) { + if( loc != p && coverage( loc ) >= 30 ) { + // If we're crouching or prone behind an obstacle, we can't see past it. + dirty |= vision_transparency_cache[loc.x()][loc.y()] != LIGHT_TRANSPARENCY_SOLID; + vision_transparency_cache[loc.x()][loc.y()] = LIGHT_TRANSPARENCY_SOLID; + } } } } - memcpy( &vision_transparency_cache, &transparency_cache, sizeof( transparency_cache ) ); - // This segment handles blocking vision through TRANSLUCENT flagged terrain. - // We don't need to deal with cache dirtying, because that was handled when the terrain was changed. - for( const tripoint_bub_ms &loc : points_in_radius( p, MAX_VIEW_DISTANCE ) ) { - if( map::ter( loc ).obj().has_flag( ter_furn_flag::TFLAG_TRANSLUCENT ) && loc != p ) { - vision_transparency_cache[loc.x()][loc.y()] = LIGHT_TRANSPARENCY_SOLID; + // Traverse the submaps in order (else map::ter() calls get_submap each time) + for( int smx = 0; smx < my_MAPSIZE; ++smx ) { + for( int smy = 0; smy < my_MAPSIZE; ++smy ) { + const submap *cur_submap = get_submap_at_grid( tripoint_rel_sm{smx, smy, zlev} ); + if( cur_submap == nullptr ) { + debugmsg( "Tried to build transparency cache at (%d,%d,%d) but the submap is not loaded", smx, smy, + zlev ); + continue; + } + if( !map_cache.transparency_cache_dirty[smx * MAPSIZE + smy] ) { + continue; + } + for( int smi = 0; smi < SEEX; smi++ ) { + for( int smj = 0; smj < SEEY; smj++ ) { + if( cur_submap->get_ter( point_sm_ms{smi, smj} ).obj().translucent ) { + const int i = smi + ( smx * SEEX ); + const int j = smj + ( smy * SEEY ); + dirty |= vision_transparency_cache[i][j] != LIGHT_TRANSPARENCY_SOLID; + vision_transparency_cache[i][j] = LIGHT_TRANSPARENCY_SOLID; + } + } + } } } // The tile player is standing on should always be visible - if( inbounds( p ) ) { + if( is_player_z && inbounds( p ) ) { vision_transparency_cache[p.x()][p.y()] = LIGHT_TRANSPARENCY_OPEN_AIR; } - for( const tripoint_bub_ms loc : solid_tiles ) { - vision_transparency_cache[loc.x()][loc.y()] = LIGHT_TRANSPARENCY_SOLID; - } - + map_cache.transparency_cache_dirty.reset(); return dirty; } diff --git a/src/map.cpp b/src/map.cpp index bfeeb255c4967..ddb801148b775 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1848,9 +1848,7 @@ bool map::furn_set( const tripoint_bub_ms &p, const furn_id &new_furniture, cons if( !new_f.emissions.empty() ) { field_furn_locs.push_back( p ); } - if( old_f.transparent != new_f.transparent || - old_f.has_flag( ter_furn_flag::TFLAG_TRANSLUCENT ) != new_f.has_flag( - ter_furn_flag::TFLAG_TRANSLUCENT ) ) { + if( old_f.transparent != new_f.transparent || old_f.translucent != new_f.translucent ) { set_transparency_cache_dirty( p ); set_seen_cache_dirty( p ); } @@ -2354,9 +2352,7 @@ bool map::ter_set( const tripoint_bub_ms &p, const ter_id &new_terrain, bool avo if( !new_t.emissions.empty() ) { field_ter_locs.push_back( p ); } - if( old_t.transparent != new_t.transparent || - old_t.has_flag( ter_furn_flag::TFLAG_TRANSLUCENT ) != new_t.has_flag( - ter_furn_flag::TFLAG_TRANSLUCENT ) ) { + if( old_t.transparent != new_t.transparent || old_t.translucent != new_t.translucent ) { set_transparency_cache_dirty( p ); set_seen_cache_dirty( p ); } diff --git a/src/mapdata.cpp b/src/mapdata.cpp index 6bbad4ffa1df3..a16388a8abd44 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -778,8 +778,8 @@ void map_data_common_t::set_flag( const std::string &flag ) std::optional f = io::string_to_enum_optional( flag ); if( f.has_value() ) { bitflags.set( f.value() ); - transparent |= f.value() == ter_furn_flag::TFLAG_TRANSPARENT || - f.value() == ter_furn_flag::TFLAG_TRANSLUCENT; + translucent |= f.value() == ter_furn_flag::TFLAG_TRANSLUCENT; + transparent |= f.value() == ter_furn_flag::TFLAG_TRANSPARENT || translucent; } } @@ -787,7 +787,8 @@ void map_data_common_t::set_flag( const ter_furn_flag flag ) { flags.insert( io::enum_to_string( flag ) ); bitflags.set( flag ); - transparent |= flag == ter_furn_flag::TFLAG_TRANSPARENT || flag == ter_furn_flag::TFLAG_TRANSLUCENT; + translucent |= flag == ter_furn_flag::TFLAG_TRANSLUCENT; + transparent |= flag == ter_furn_flag::TFLAG_TRANSPARENT || translucent; } void map_data_common_t::unset_flag( const std::string &flag ) @@ -798,8 +799,11 @@ void map_data_common_t::unset_flag( const std::string &flag ) std::optional f = io::string_to_enum_optional( flag ); if( f.has_value() ) { bitflags.reset( f.value() ); - if( transparent ) { - transparent = f.value() != ter_furn_flag::TFLAG_TRANSPARENT; + if( translucent ) { + translucent = f.value() != ter_furn_flag::TFLAG_TRANSLUCENT; + if( transparent ) { + transparent = f.value() != ter_furn_flag::TFLAG_TRANSPARENT; + } } } } @@ -808,7 +812,8 @@ void map_data_common_t::unset_flags() { flags.clear(); bitflags.reset(); - transparent = false; //? + transparent = false; + translucent = false; } void map_data_common_t::set_connect_groups( const std::vector @@ -1031,7 +1036,6 @@ void map_data_common_t::load( const JsonObject &jo, const std::string &src ) shoot = cata::make_value(); shoot->load( jo, "shoot", was_loaded ); } - } bool ter_t::is_null() const diff --git a/src/mapdata.h b/src/mapdata.h index 5ce0cd1d08e4c..2f0fb595e8dfb 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -565,6 +565,7 @@ struct map_data_common_t { }; bool transparent = false; + bool translucent = false; const std::set &get_flags() const { return flags; From d7f7cbac7348dca3da967d8c451ebd06812f8c27 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Sat, 23 Nov 2024 18:53:50 +0000 Subject: [PATCH 2/8] Decided the flag check isn't expensive enough to warrant change --- src/lightmap.cpp | 3 ++- src/map.cpp | 8 ++++++-- src/mapdata.cpp | 18 +++++++----------- src/mapdata.h | 1 - 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/lightmap.cpp b/src/lightmap.cpp index 4af5fd5e25c0e..9d1dc8be36949 100644 --- a/src/lightmap.cpp +++ b/src/lightmap.cpp @@ -245,7 +245,8 @@ bool map::build_vision_transparency_cache( int zlev ) } for( int smi = 0; smi < SEEX; smi++ ) { for( int smj = 0; smj < SEEY; smj++ ) { - if( cur_submap->get_ter( point_sm_ms{smi, smj} ).obj().translucent ) { + if( cur_submap->get_ter( point_sm_ms{smi, smj} ).obj().has_flag( + ter_furn_flag::TFLAG_TRANSLUCENT ) ) { const int i = smi + ( smx * SEEX ); const int j = smj + ( smy * SEEY ); dirty |= vision_transparency_cache[i][j] != LIGHT_TRANSPARENCY_SOLID; diff --git a/src/map.cpp b/src/map.cpp index ddb801148b775..bfeeb255c4967 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1848,7 +1848,9 @@ bool map::furn_set( const tripoint_bub_ms &p, const furn_id &new_furniture, cons if( !new_f.emissions.empty() ) { field_furn_locs.push_back( p ); } - if( old_f.transparent != new_f.transparent || old_f.translucent != new_f.translucent ) { + if( old_f.transparent != new_f.transparent || + old_f.has_flag( ter_furn_flag::TFLAG_TRANSLUCENT ) != new_f.has_flag( + ter_furn_flag::TFLAG_TRANSLUCENT ) ) { set_transparency_cache_dirty( p ); set_seen_cache_dirty( p ); } @@ -2352,7 +2354,9 @@ bool map::ter_set( const tripoint_bub_ms &p, const ter_id &new_terrain, bool avo if( !new_t.emissions.empty() ) { field_ter_locs.push_back( p ); } - if( old_t.transparent != new_t.transparent || old_t.translucent != new_t.translucent ) { + if( old_t.transparent != new_t.transparent || + old_t.has_flag( ter_furn_flag::TFLAG_TRANSLUCENT ) != new_t.has_flag( + ter_furn_flag::TFLAG_TRANSLUCENT ) ) { set_transparency_cache_dirty( p ); set_seen_cache_dirty( p ); } diff --git a/src/mapdata.cpp b/src/mapdata.cpp index a16388a8abd44..6bbad4ffa1df3 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -778,8 +778,8 @@ void map_data_common_t::set_flag( const std::string &flag ) std::optional f = io::string_to_enum_optional( flag ); if( f.has_value() ) { bitflags.set( f.value() ); - translucent |= f.value() == ter_furn_flag::TFLAG_TRANSLUCENT; - transparent |= f.value() == ter_furn_flag::TFLAG_TRANSPARENT || translucent; + transparent |= f.value() == ter_furn_flag::TFLAG_TRANSPARENT || + f.value() == ter_furn_flag::TFLAG_TRANSLUCENT; } } @@ -787,8 +787,7 @@ void map_data_common_t::set_flag( const ter_furn_flag flag ) { flags.insert( io::enum_to_string( flag ) ); bitflags.set( flag ); - translucent |= flag == ter_furn_flag::TFLAG_TRANSLUCENT; - transparent |= flag == ter_furn_flag::TFLAG_TRANSPARENT || translucent; + transparent |= flag == ter_furn_flag::TFLAG_TRANSPARENT || flag == ter_furn_flag::TFLAG_TRANSLUCENT; } void map_data_common_t::unset_flag( const std::string &flag ) @@ -799,11 +798,8 @@ void map_data_common_t::unset_flag( const std::string &flag ) std::optional f = io::string_to_enum_optional( flag ); if( f.has_value() ) { bitflags.reset( f.value() ); - if( translucent ) { - translucent = f.value() != ter_furn_flag::TFLAG_TRANSLUCENT; - if( transparent ) { - transparent = f.value() != ter_furn_flag::TFLAG_TRANSPARENT; - } + if( transparent ) { + transparent = f.value() != ter_furn_flag::TFLAG_TRANSPARENT; } } } @@ -812,8 +808,7 @@ void map_data_common_t::unset_flags() { flags.clear(); bitflags.reset(); - transparent = false; - translucent = false; + transparent = false; //? } void map_data_common_t::set_connect_groups( const std::vector @@ -1036,6 +1031,7 @@ void map_data_common_t::load( const JsonObject &jo, const std::string &src ) shoot = cata::make_value(); shoot->load( jo, "shoot", was_loaded ); } + } bool ter_t::is_null() const diff --git a/src/mapdata.h b/src/mapdata.h index 2f0fb595e8dfb..5ce0cd1d08e4c 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -565,7 +565,6 @@ struct map_data_common_t { }; bool transparent = false; - bool translucent = false; const std::set &get_flags() const { return flags; From 932c0e9c4266bb6d28a4075beb43a676548268c8 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Sat, 23 Nov 2024 21:22:10 +0000 Subject: [PATCH 3/8] Added the needed extra cache dirtying --- src/avatar.cpp | 4 +++- src/avatar_action.cpp | 11 +++++++++++ src/lightmap.cpp | 8 +++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/avatar.cpp b/src/avatar.cpp index 1915de0bd29c4..cdcde60c41a6d 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -1302,7 +1302,9 @@ void avatar::set_movement_mode( const move_mode_id &new_mode ) // Enchantments based on move modes can stack inappropriately without a recalc here recalculate_enchantment_cache(); // crouching affects visibility - get_map().set_seen_cache_dirty( pos().z ); + //TODO: Replace with dirtying vision_transparency_cache + get_map().set_transparency_cache_dirty( pos_bub() ); + get_map().set_seen_cache_dirty( pos_bub().z() ); recoil = MAX_RECOIL; } else { add_msg( new_mode->change_message( false, get_steed_type() ) ); diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index 976c6c692e99b..33ec2575e134b 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -70,6 +70,7 @@ static const efftype_id effect_incorporeal( "incorporeal" ); static const efftype_id effect_onfire( "onfire" ); static const efftype_id effect_pet( "pet" ); static const efftype_id effect_psi_stunned( "psi_stunned" ); +static const efftype_id effect_quadruped_full( "quadruped_full" ); static const efftype_id effect_ridden( "ridden" ); static const efftype_id effect_stunned( "stunned" ); static const efftype_id effect_winded( "winded" ); @@ -187,6 +188,16 @@ bool avatar_action::move( avatar &you, map &m, const tripoint &d ) return false; } + //TODO: Replace with dirtying vision_transparency_cache + //TODO: Really ugly bc we're not sure we're moving anywhere yet + const bool is_crouching = you.is_crouching(); + const bool low_profile = you.has_effect( effect_quadruped_full ) && + you.is_running(); + const bool is_prone = you.is_prone(); + if( is_crouching || is_prone || low_profile ) { + m.set_transparency_cache_dirty( d.z ); + } + // If any leg broken without crutches and not already on the ground topple over if( ( !you.enough_working_legs() && !you.is_prone() && !( you.get_wielded_item() && you.get_wielded_item()->has_flag( flag_CRUTCHES ) ) ) ) { diff --git a/src/lightmap.cpp b/src/lightmap.cpp index 9d1dc8be36949..e2c8e662a851a 100644 --- a/src/lightmap.cpp +++ b/src/lightmap.cpp @@ -196,7 +196,7 @@ bool map::build_vision_transparency_cache( int zlev ) level_cache &map_cache = get_cache( zlev ); // We copy the transparency_cache so we need to recalc if it's dirty - if( map_cache.transparency_cache_dirty.none() /*&& !map_cache.vision_transparency_cache_dirty.none()*/ ) { + if( map_cache.transparency_cache_dirty.none() /*&& map_cache.vision_transparency_cache_dirty.none()*/ ) { return false; } @@ -215,6 +215,11 @@ bool map::build_vision_transparency_cache( int zlev ) if( is_player_z ) { // This segment handles vision when the player is crouching or prone. It only checks adjacent tiles. // If you change this, also consider creature::sees and map::obstacle_coverage. + // TODO: Is fairly nonsense because it changes vision for everyone only (eg if you @ crouch behind the window W then the NPC N and monster M can't see each other bc the window is counted as opaque) + // .N. + // .@. + // #W# + // .M. const bool is_crouching = player_character.is_crouching(); const bool low_profile = player_character.has_effect( effect_quadruped_full ) && player_character.is_running(); @@ -258,6 +263,7 @@ bool map::build_vision_transparency_cache( int zlev ) } // The tile player is standing on should always be visible + // Shouldn't this be handled in the player's seen cache instead?? if( is_player_z && inbounds( p ) ) { vision_transparency_cache[p.x()][p.y()] = LIGHT_TRANSPARENCY_OPEN_AIR; } From c85620bc5c8cc87b9642a3ae57389a5657cca1fb Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:56:38 +0000 Subject: [PATCH 4/8] Update lightmap.cpp --- src/lightmap.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/lightmap.cpp b/src/lightmap.cpp index e2c8e662a851a..89563170da06c 100644 --- a/src/lightmap.cpp +++ b/src/lightmap.cpp @@ -262,12 +262,6 @@ bool map::build_vision_transparency_cache( int zlev ) } } - // The tile player is standing on should always be visible - // Shouldn't this be handled in the player's seen cache instead?? - if( is_player_z && inbounds( p ) ) { - vision_transparency_cache[p.x()][p.y()] = LIGHT_TRANSPARENCY_OPEN_AIR; - } - map_cache.transparency_cache_dirty.reset(); return dirty; } From eb60a7b83dfefdd87c0808ce0d1485552db94c7d Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 27 Nov 2024 11:18:01 +0000 Subject: [PATCH 5/8] Appease our clang overlords --- src/avatar_action.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index 33ec2575e134b..93cf4f2ab78a1 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -195,7 +195,7 @@ bool avatar_action::move( avatar &you, map &m, const tripoint &d ) you.is_running(); const bool is_prone = you.is_prone(); if( is_crouching || is_prone || low_profile ) { - m.set_transparency_cache_dirty( d.z ); + m.set_transparency_cache_dirty( d.z() ); } // If any leg broken without crutches and not already on the ground topple over From 376908c7f80ba6c6c2e9824eb4499fc4ddd9efde Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 27 Nov 2024 23:43:28 +0000 Subject: [PATCH 6/8] Clang is just wrong? --- src/avatar_action.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index 93cf4f2ab78a1..33ec2575e134b 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -195,7 +195,7 @@ bool avatar_action::move( avatar &you, map &m, const tripoint &d ) you.is_running(); const bool is_prone = you.is_prone(); if( is_crouching || is_prone || low_profile ) { - m.set_transparency_cache_dirty( d.z() ); + m.set_transparency_cache_dirty( d.z ); } // If any leg broken without crutches and not already on the ground topple over From 9a8d3a6f84cdedbac11ba5b16bedb8dae83daa47 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 27 Nov 2024 23:43:54 +0000 Subject: [PATCH 7/8] Add back the filthy hack --- src/lightmap.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lightmap.cpp b/src/lightmap.cpp index 89563170da06c..e2c8e662a851a 100644 --- a/src/lightmap.cpp +++ b/src/lightmap.cpp @@ -262,6 +262,12 @@ bool map::build_vision_transparency_cache( int zlev ) } } + // The tile player is standing on should always be visible + // Shouldn't this be handled in the player's seen cache instead?? + if( is_player_z && inbounds( p ) ) { + vision_transparency_cache[p.x()][p.y()] = LIGHT_TRANSPARENCY_OPEN_AIR; + } + map_cache.transparency_cache_dirty.reset(); return dirty; } From 84a103c69517f3db2ba43a8c0680a43dd2daeee8 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Thu, 28 Nov 2024 09:50:53 +0000 Subject: [PATCH 8/8] Oh it's a tripoint_rel_ms on upstream master --- src/avatar_action.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index 33ec2575e134b..93cf4f2ab78a1 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -195,7 +195,7 @@ bool avatar_action::move( avatar &you, map &m, const tripoint &d ) you.is_running(); const bool is_prone = you.is_prone(); if( is_crouching || is_prone || low_profile ) { - m.set_transparency_cache_dirty( d.z ); + m.set_transparency_cache_dirty( d.z() ); } // If any leg broken without crutches and not already on the ground topple over