diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 01a4386a447d9..1d6729a54b092 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -582,6 +582,7 @@ void activity_handlers::game_do_turn( player_activity *act, Character *you ) void activity_handlers::pickaxe_do_turn( player_activity *act, Character * ) { + map &here = get_map(); const tripoint_bub_ms &pos = get_map().get_bub( act->placement ); sfx::play_activity_sound( "tool", "pickaxe", sfx::get_heard_volume( pos ) ); // each turn is too much @@ -589,6 +590,12 @@ void activity_handlers::pickaxe_do_turn( player_activity *act, Character * ) //~ Sound of a Pickaxe at work! sounds::sound( pos, 30, sounds::sound_t::destructive_activity, _( "CHNK! CHNK! CHNK!" ) ); } + if( calendar::once_every( 5_minutes ) ) { + const int max_damage_to_set = here.bash_resistance( pos, true ); + const int existing_damage = here.get_map_damage( pos ); + const int set_damage_to = std::min( existing_damage + 1, max_damage_to_set ); + here.set_map_damage( pos, set_damage_to ); + } } void activity_handlers::pickaxe_finish( player_activity *act, Character *you ) @@ -2232,13 +2239,20 @@ void activity_handlers::eat_menu_finish( player_activity *, Character * ) void activity_handlers::jackhammer_do_turn( player_activity *act, Character * ) { map &here = get_map(); + const tripoint_bub_ms &pos = get_map().get_bub( act->placement ); sfx::play_activity_sound( "tool", "jackhammer", - sfx::get_heard_volume( here.get_bub( act->placement ) ) ); + sfx::get_heard_volume( pos ) ); if( calendar::once_every( 1_minutes ) ) { - sounds::sound( here.get_bub( act->placement ), 15, sounds::sound_t::destructive_activity, + sounds::sound( pos, 15, sounds::sound_t::destructive_activity, //~ Sound of a jackhammer at work! _( "TATATATATATATAT!" ) ); } + if( calendar::once_every( 5_minutes ) ) { + const int max_damage_to_set = here.bash_resistance( pos, true ); + const int existing_damage = here.get_map_damage( pos ); + const int set_damage_to = std::min( existing_damage + 1, max_damage_to_set ); + here.set_map_damage( pos, set_damage_to ); + } } void activity_handlers::jackhammer_finish( player_activity *act, Character *you ) diff --git a/src/game.cpp b/src/game.cpp index 0b3d3f76c2943..c4822ab2b481b 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -6756,6 +6756,17 @@ void game::print_visibility_info( const catacurses::window &w_look, int column, line += 2; } +static int percent_terfurn_damage( const tripoint_bub_ms &lp ) +{ + const map &here = get_map(); + const double damage_range = + std::max( here.bash_strength( lp, true ) - here.bash_resistance( lp, true ), 1 ); + const double existing_damage = here.get_map_damage( lp ); + const int percent_damage = std::min( std::round( ( existing_damage / damage_range ) * 100.0 ), + 100.0 ); + return percent_damage; +} + void game::print_terrain_info( const tripoint_bub_ms &lp, const catacurses::window &w_look, const std::string &area_name, int column, int &line ) { @@ -6763,9 +6774,18 @@ void game::print_terrain_info( const tripoint_bub_ms &lp, const catacurses::wind const int max_width = getmaxx( w_look ) - column - 1; - // Print OMT type and terrain type on first two lines - // if can't fit in one line. std::string tile = uppercase_first_letter( here.tername( lp ) ); + // Show saved bash damage. + // Furniture takes priority, so we don't even check for map damage if a furniture is present. + if( !here.has_furn( lp ) ) { + + const int percent_existing_damage = percent_terfurn_damage( lp ); + if( percent_existing_damage > 0 ) { + //~Terrain name (% damaged) + tile = string_format( _( "%s (%d%% damaged)" ), + uppercase_first_letter( here.tername( lp ) ), percent_existing_damage ); + } + } std::string area = uppercase_first_letter( area_name ); if( const timed_event *e = get_timed_events().get( timed_event_type::OVERRIDE_PLACE ) ) { area = e->string_id; @@ -6862,6 +6882,13 @@ void game::print_furniture_info( const tripoint_bub_ms &lp, const catacurses::wi // Print furniture name in white std::string desc = uppercase_first_letter( here.furnname( lp ) ); + // Show saved bash damage. + const int percent_existing_damage = percent_terfurn_damage( lp ); + if( percent_existing_damage > 0 ) { + //~Furniture name (% damaged) + desc = string_format( _( "%s (%d%% damaged)" ), + uppercase_first_letter( here.furnname( lp ) ), percent_existing_damage ); + } mvwprintz( w_look, point( column, line++ ), c_white, desc ); // Print each line of furniture description in gray diff --git a/src/iuse.cpp b/src/iuse.cpp index b7ac6ae8cf020..d754fffd10305 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -3143,14 +3143,19 @@ static std::optional dig_tool( Character *p, item *it, const tripoint_bub_m return std::nullopt; } - // FIXME: Activity is interruptable but progress is not saved! - time_duration digging_time = 30_minutes; + time_duration digging_time = using_jackhammer ? 2_hours : 8_hours; if( here.has_flag( ter_furn_flag::TFLAG_FLAT, pnt ) ) { // We're breaking up some flat surface like pavement, which is much easier digging_time /= 2; } + // The act increments map damage by 1 for every 5 minutes, so we discount 5 minutes of activity for every existing map damage. + // As an added bonus, this also allows **mixing and matching** of smashing and mining. + // You could mine a wall for a bit until it's weak and then bash your way through what's left. Or the reverse! + const int existing_damage = here.get_map_damage( pnt ); + digging_time = digging_time - ( existing_damage * 5_minutes ); + p->assign_activity( activity, to_moves( digging_time ) ); p->activity.targets.emplace_back( *p, it ); p->activity.placement = here.get_abs( pnt ); diff --git a/src/mapdata.cpp b/src/mapdata.cpp index 657a08d43d88a..a9d7f5546a734 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -768,6 +768,7 @@ std::vector map_data_common_t::extended_description() const { std::vector tmp; + // FIXME: Does not show map damage. tmp.emplace_back( string_format( _( "
That is a %s.
" ), name() ) ); tmp.emplace_back( description.translated() );