Skip to content

Commit

Permalink
Merge pull request #78663 from Procyonae/FixPlaceTerrainSpecialPerfor…
Browse files Browse the repository at this point in the history
…mance

Fix place terrain special performance
  • Loading branch information
Maleclypse authored Dec 24, 2024
2 parents ab665cc + 240b881 commit 8fd2039
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 34 deletions.
11 changes: 11 additions & 0 deletions src/input_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,17 @@ std::optional<tripoint_bub_ms> input_context::get_coordinates( const catacurses:
}
#endif

std::optional<tripoint_rel_omt> input_context::get_coordinates_rel_omt( const catacurses::window
&capture_win, const point &offset, const bool center_cursor ) const
{
// Sometimes off by one with tiles but I think that's due to the centre changing with zoom level + tileset size so I don't think it can be easily fixed here
const std::optional<tripoint_bub_ms> p = get_coordinates( capture_win, offset, center_cursor );
if( p ) {
return tripoint_rel_omt( p->raw() );
}
return std::nullopt;
}

std::optional<point> input_context::get_coordinates_text( const catacurses::window
&capture_win ) const
{
Expand Down
2 changes: 2 additions & 0 deletions src/input_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ class input_context
*/
std::optional<tripoint_bub_ms> get_coordinates( const catacurses::window &capture_win_,
const point &offset = point::zero, bool center_cursor = false ) const;
std::optional<tripoint_rel_omt> get_coordinates_rel_omt( const catacurses::window &capture_win_,
const point &offset = point::zero, bool center_cursor = false ) const;

// Below here are shortcuts for registering common key combinations.
void register_directions();
Expand Down
7 changes: 3 additions & 4 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8596,7 +8596,7 @@ ter_str_id uniform_terrain( const oter_id &oter )
// Does not create or require a temporary map and does its own saving
bool generate_uniform( const tripoint_abs_sm &p, const ter_str_id &ter )
{
if( MAPBUFFER.lookup_submap( p ) ) {
if( MAPBUFFER.submap_exists( p ) ) {
return false;
}

Expand Down Expand Up @@ -8646,7 +8646,7 @@ void map::loadn( const point_bub_sm &grid, bool update_vehicles )
for( int gridy = 0; gridy <= 1; gridy++ ) {
for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
const tripoint grid_pos( gridx, gridy, gridz );
if( MAPBUFFER.lookup_submap( grid_sm_base.xy() + grid_pos ) == nullptr ) {
if( !MAPBUFFER.submap_exists( grid_sm_base.xy() + grid_pos ) ) {
map_incomplete = true;
break;
}
Expand All @@ -8662,8 +8662,7 @@ void map::loadn( const point_bub_sm &grid, bool update_vehicles )

for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
const tripoint_abs_sm pos = {grid_sm_base.xy(), gridz };
submap *tmpsub = MAPBUFFER.lookup_submap( pos );
if( tmpsub == nullptr ) {
if( !MAPBUFFER.submap_exists( pos ) ) {
dbg( D_ERROR ) << "failed to generate a submap at " << pos;
debugmsg( "failed to generate a submap at %s", pos.to_string() );
return;
Expand Down
19 changes: 19 additions & 0 deletions src/mapbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ submap *mapbuffer::lookup_submap( const tripoint_abs_sm &p )

bool mapbuffer::submap_exists( const tripoint_abs_sm &p )
{
// Could so with a second check against a std::unordered_set<tripoint_abs_sm> of already checked existing but not loaded submaps before resorting to unserializing?
const auto iter = submaps.find( p );
if( iter == submaps.end() ) {
try {
Expand All @@ -134,6 +135,24 @@ bool mapbuffer::submap_exists( const tripoint_abs_sm &p )
return true;
}

bool mapbuffer::submap_exists_approx( const tripoint_abs_sm &p )
{
const auto iter = submaps.find( p );
if( iter == submaps.end() ) {
try {
const tripoint_abs_omt om_addr = project_to<coords::omt>( p );
const cata_path dirname = find_dirname( om_addr );
cata_path quad_path = find_quad_path( dirname, om_addr );
return file_exist( quad_path );
} catch( const std::exception &err ) {
debugmsg( "Failed to load submap %s: %s", p.to_string(), err.what() );
}
return false;
}

return true;
}

void mapbuffer::save( bool delete_after_save )
{
assure_dir_exist( PATH_INFO::world_base_save_path() / "maps" );
Expand Down
3 changes: 3 additions & 0 deletions src/mapbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class mapbuffer
// Cheaper version of the above for when you only care about whether the
// submap exists or not.
bool submap_exists( const tripoint_abs_sm &p );
// Cheaper version of the above for when you don't mind some false results
bool submap_exists_approx( const tripoint_abs_sm &p );

private:
using submap_map_t = std::map<tripoint_abs_sm, std::unique_ptr<submap>>;
Expand All @@ -82,6 +84,7 @@ class mapbuffer
// if not handled carefully, this can erase in-use submaps and crash the game.
void remove_submap( const tripoint_abs_sm &addr );
submap *unserialize_submaps( const tripoint_abs_sm &p );
bool submap_file_exists( const tripoint_abs_sm &p );
void deserialize( const JsonArray &ja );
void save_quad(
const cata_path &dirname, const cata_path &filename,
Expand Down
15 changes: 7 additions & 8 deletions src/npctalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4457,18 +4457,17 @@ talk_effect_fun_t::func f_revert_location( const JsonObject &jo, std::string_vie
// maptile is 4 submaps so queue up 4 submap reverts
const tripoint_abs_sm revert_sm_base = project_to<coords::sm>( omt_pos );

if( !MAPBUFFER.submap_exists( revert_sm_base ) ) {
tinymap tm;
// This creates the submaps if they didn't already exist.
// Note that all four submaps are loaded/created by this
// call, so the submap lookup can fail at most once.
tm.load( omt_pos, true );
}
for( int x = 0; x < 2; x++ ) {
for( int y = 0; y < 2; y++ ) {
const tripoint_abs_sm revert_sm = revert_sm_base + point( x, y );
submap *sm = MAPBUFFER.lookup_submap( revert_sm );
if( sm == nullptr ) {
tinymap tm;
// This creates the submaps if they didn't already exist.
// Note that all four submaps are loaded/created by this
// call, so the submap lookup can fail at most once.
tm.load( omt_pos, true );
sm = MAPBUFFER.lookup_submap( revert_sm );
}
get_timed_events().add( timed_event_type::REVERT_SUBMAP, tif, -1,
project_to<coords::ms>( revert_sm ), 0, "",
sm->get_revert_submap(), key.evaluate( d ) );
Expand Down
4 changes: 1 addition & 3 deletions src/overmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7755,9 +7755,7 @@ bool overmap::is_omt_generated( const tripoint_om_omt &loc ) const
tripoint_abs_sm global_sm_loc =
project_to<coords::sm>( project_combine( pos(), loc ) );

const bool is_generated = MAPBUFFER.lookup_submap( global_sm_loc ) != nullptr;

return is_generated;
return MAPBUFFER.submap_exists( global_sm_loc );
}

overmap_special_id overmap_specials::create_building_from( const string_id<oter_type_t> &base )
Expand Down
51 changes: 36 additions & 15 deletions src/overmap_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,8 +543,19 @@ static bool get_and_assign_los( int &los, avatar &player_character, const tripoi
return los;
}

static void draw_ascii(
const catacurses::window &w, overmap_draw_data_t &data )
static std::unordered_map<point_abs_omt, bool> generated_omts;

bool is_generated_omt( const point_abs_omt &omp )
{
if( const auto it = generated_omts.find( omp ); it != generated_omts.end() ) {
return it->second;
}
const bool generated = MAPBUFFER.submap_exists_approx( { project_to<coords::sm>( omp ), 0 } );
generated_omts.insert( { omp, generated } );
return generated;
}

static void draw_ascii( const catacurses::window &w, overmap_draw_data_t &data )
{
const tripoint_abs_omt &orig = data.origin_pos;
const tripoint_abs_omt &cursor_pos = data.cursor_pos;
Expand Down Expand Up @@ -796,7 +807,7 @@ static void draw_ascii(
}
}
// Highlight areas that already have been generated
if( MAPBUFFER.lookup_submap( project_to<coords::sm>( omp ) ) ) {
if( is_generated_omt( omp.xy() ) ) {
ter_color = red_background( ter_color );
}
}
Expand Down Expand Up @@ -1508,6 +1519,9 @@ static void place_ter_or_special( const ui_adaptor &om_ui, tripoint_abs_omt &cur

input_context ctxt( "OVERMAP_EDITOR" );
ctxt.register_directions();
ctxt.register_action( "SELECT" );
ctxt.register_action( "LEVEL_UP" );
ctxt.register_action( "LEVEL_DOWN" );
ctxt.register_action( "zoom_in" );
ctxt.register_action( "zoom_out" );
ctxt.register_action( "CONFIRM" );
Expand Down Expand Up @@ -1558,14 +1572,14 @@ static void place_ter_or_special( const ui_adaptor &om_ui, tripoint_abs_omt &cur
_( "Highlighted regions already have map content generated. Their overmap id will change, but not their contents." ) );
if( ( terrain && uistate.place_terrain->is_rotatable() ) ||
( !terrain && uistate.place_special->is_rotatable() ) ) {
mvwprintz( w_editor, point( 1, 11 ), c_white, _( "[%s] Rotate" ),
mvwprintz( w_editor, point( 1, 10 ), c_white, _( "[%s] Rotate" ),
ctxt.get_desc( "ROTATE" ) );
}
mvwprintz( w_editor, point( 1, 12 ), c_white, _( "[%s] Place" ),
mvwprintz( w_editor, point( 1, 11 ), c_white, _( "[%s] Place" ),
ctxt.get_desc( "CONFIRM_MULTIPLE" ) );
mvwprintz( w_editor, point( 1, 13 ), c_white, _( "[%s] Place and close" ),
mvwprintz( w_editor, point( 1, 12 ), c_white, _( "[%s] Place and close" ),
ctxt.get_desc( "CONFIRM" ) );
mvwprintz( w_editor, point( 1, 14 ), c_white, _( "[ESCAPE/Q] Cancel" ) );
mvwprintz( w_editor, point( 1, 13 ), c_white, _( "[ESCAPE/Q] Cancel" ) );
wnoutrefresh( w_editor );
} );

Expand All @@ -1576,8 +1590,17 @@ static void place_ter_or_special( const ui_adaptor &om_ui, tripoint_abs_omt &cur

action = ctxt.handle_input( get_option<int>( "BLINK_SPEED" ) );

if( const std::optional<tripoint> vec = ctxt.get_direction( action ) ) {
curs += vec->xy();
if( const std::optional<tripoint_rel_omt> vec = ctxt.get_direction_rel_omt( action ) ) {
curs += *vec;
} else if( action == "LEVEL_DOWN" && curs.z() > -OVERMAP_DEPTH ) {
curs.z()--;
} else if( action == "LEVEL_UP" && curs.z() < OVERMAP_HEIGHT ) {
curs.z()++;
} else if( action == "SELECT" ) {
if( std::optional<tripoint_rel_omt> mouse_pos = ctxt.get_coordinates_rel_omt( g->w_overmap,
point::zero, true ); mouse_pos ) {
curs = curs + mouse_pos->xy();
}
} else if( action == "zoom_out" ) {
g->zoom_out_overmap();
om_ui.mark_resize();
Expand All @@ -1597,9 +1620,6 @@ static void place_ter_or_special( const ui_adaptor &om_ui, tripoint_abs_omt &cur
}
}
}
if( action == "CONFIRM" ) {
break;
}
} else if( action == "ROTATE" && can_rotate ) {
uistate.omedit_rotation = om_direction::turn_right( uistate.omedit_rotation );
if( terrain ) {
Expand All @@ -1609,7 +1629,7 @@ static void place_ter_or_special( const ui_adaptor &om_ui, tripoint_abs_omt &cur
if( uistate.overmap_blinking ) {
uistate.overmap_show_overlays = !uistate.overmap_show_overlays;
}
} while( action != "QUIT" );
} while( action != "CONFIRM" && action != "QUIT" );

uistate.place_terrain = nullptr;
uistate.place_special = nullptr;
Expand Down Expand Up @@ -1945,7 +1965,7 @@ static tripoint_abs_omt display()
std::string action;
data.show_explored = true;
int fast_scroll_offset = get_option<int>( "FAST_SCROLL_OFFSET" );
std::optional<tripoint_bub_ms> mouse_pos;
std::optional<tripoint_rel_omt> mouse_pos;
std::chrono::time_point<std::chrono::steady_clock> last_blink = std::chrono::steady_clock::now();
std::chrono::time_point<std::chrono::steady_clock> last_advance = std::chrono::steady_clock::now();
auto display_path_iter = display_path.rbegin();
Expand Down Expand Up @@ -2000,7 +2020,7 @@ static tripoint_abs_omt display()
curs += edge_scroll;
}
} else if( action == "SELECT" &&
( mouse_pos = ictxt.get_coordinates( g->w_overmap, point::zero, true ) ) ) {
( mouse_pos = ictxt.get_coordinates_rel_omt( g->w_overmap, point::zero, true ) ) ) {
curs += mouse_pos->xy().raw();
} else if( action == "look" ) {
tripoint_abs_ms pos = project_combine( curs, g->overmap_data.origin_remainder );
Expand Down Expand Up @@ -2572,6 +2592,7 @@ std::optional<city> ui::omap::select_city( uilist &cities_menu,

void ui::omap::force_quit()
{
overmap_ui::generated_omts.clear();
g->overmap_data.ui.reset();
g->overmap_data.fast_traveling = false;
}
1 change: 1 addition & 0 deletions src/overmap_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ extern tiles_redraw_info redraw_info;

weather_type_id get_weather_at_point( const tripoint_abs_omt &pos );
std::tuple<char, nc_color, size_t> get_note_display_info( std::string_view note );
bool is_generated_omt( const point_abs_omt &omp );

} // namespace overmap_ui
#endif // CATA_SRC_OVERMAP_UI_H
7 changes: 3 additions & 4 deletions src/sdltiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -918,11 +918,10 @@ void cata_tiles::draw_om( const point &dest, const tripoint_abs_omt &center_abs_
}
}

if( uistate.place_terrain || uistate.place_special ) {
if( ( uistate.place_terrain || uistate.place_special ) &&
overmap_ui::is_generated_omt( omp.xy() ) ) {
// Highlight areas that already have been generated
if( MAPBUFFER.lookup_submap( project_to<coords::sm>( omp ) ) ) {
draw_from_id_string( "highlight", omp.raw(), 0, 0, lit_level::LIT, false );
}
draw_from_id_string( "highlight", omp.raw(), 0, 0, lit_level::LIT, false );
}

if( draw_overlays && overmap_buffer.has_vehicle( omp ) ) {
Expand Down

0 comments on commit 8fd2039

Please sign in to comment.