Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix place terrain special performance #78663

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading