Skip to content

Commit

Permalink
Skip tileset tiles with same id; list them in loading report
Browse files Browse the repository at this point in the history
Workaround for tiles with same ids and
different sizes causing rendering issues
CleverRaven/Cataclysm-DDA#48819
  • Loading branch information
olanti-p committed May 10, 2021
1 parent 3aa88c3 commit 1e0f7b9
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 15 deletions.
43 changes: 36 additions & 7 deletions src/cata_tiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,11 @@ void tileset_loader::load_tilejson_from_file( const JsonObject &config )
ids = entry.get_string_array( "id" );
}
for( const std::string &t_id : ids ) {
tile_type &curr_tile = load_tile( entry, t_id );
tile_type *load_res = load_tile( entry, t_id );
if( !load_res ) {
continue;
}
tile_type &curr_tile = *load_res;
curr_tile.offset = sprite_offset;
bool t_multi = entry.get_bool( "multitile", false );
bool t_rota = entry.get_bool( "rotates", t_multi );
Expand All @@ -948,7 +952,11 @@ void tileset_loader::load_tilejson_from_file( const JsonObject &config )
for( const JsonObject &subentry : entry.get_array( "additional_tiles" ) ) {
const std::string s_id = subentry.get_string( "id" );
const std::string m_id = t_id + "_" + s_id;
tile_type &curr_subtile = load_tile( subentry, m_id );
tile_type *load_res_subtile = load_tile( subentry, m_id );
if( !load_res_subtile ) {
continue;
}
tile_type &curr_subtile = *load_res_subtile;
curr_subtile.offset = sprite_offset;
curr_subtile.rotates = true;
curr_subtile.height_3d = t_h3d;
Expand All @@ -972,18 +980,23 @@ void tileset_loader::load_tilejson_from_file( const JsonObject &config )
* The JSON data (loaded here) contains tile ids relative to the associated image.
* They are translated into global ids by adding the @p offset, which is the number of
* previously loaded tiles (excluding the tiles from the associated image).
* @param id The id of the new tile definition (which is the key in @ref tileset::tile_ids). Any existing
* definition of the same id is overridden.
* @return A reference to the loaded tile inside the @ref tileset::tile_ids map.
* @param id The id of the new tile definition (which is the key in @ref tileset::tile_ids).
* @return Pointer to the loaded tile inside the @ref tileset::tile_ids map,
* or nullptr if @p id already exists.
*/
tile_type &tileset_loader::load_tile( const JsonObject &entry, const std::string &id )
tile_type *tileset_loader::load_tile( const JsonObject &entry, const std::string &id )
{
if( ts.find_tile_type( id ) ) {
ts.duplicate_ids.insert( id );
return nullptr;
}

tile_type curr_subtile;

load_tile_spritelists( entry, curr_subtile.fg, "fg" );
load_tile_spritelists( entry, curr_subtile.bg, "bg" );

return ts.create_tile_type( id, std::move( curr_subtile ) );
return &ts.create_tile_type( id, std::move( curr_subtile ) );
}

void tileset_loader::load_tile_spritelists( const JsonObject &entry,
Expand Down Expand Up @@ -3714,6 +3727,7 @@ void cata_tiles::do_tile_loading_report()
tile_loading_report( vpart_info::all(), C_VEHICLE_PART, "vp_" );
tile_loading_report<trap>( trap::count(), C_TRAP, "" );
tile_loading_report<field_type>( field_type::count(), C_FIELD, "" );
tile_loading_report_dups();

// needed until DebugLog ostream::flush bugfix lands
DebugLog( D_INFO, DC_ALL );
Expand Down Expand Up @@ -3791,6 +3805,21 @@ void cata_tiles::tile_loading_report( const arraytype &array, int array_length,
}, category, prefix );
}

void cata_tiles::tile_loading_report_dups()
{
std::vector<std::string> dups_list;
const std::unordered_set<std::string> &dups_set = tileset_ptr->get_duplicate_ids();
std::copy( dups_set.begin(), dups_set.end(), std::back_inserter( dups_list ) );
std::sort( dups_list.begin(), dups_list.end() );

std::string res;
for( const std::string &s : dups_list ) {
res += s;
res += " ";
}
DebugLog( D_INFO, DC_ALL ) << "Have duplicates: " << res;
}

std::vector<options_manager::id_and_option> cata_tiles::build_renderer_list()
{
std::vector<options_manager::id_and_option> renderer_names;
Expand Down
19 changes: 11 additions & 8 deletions src/cata_tiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <memory>
#include <string>
#include <tuple>
#include <unordered_set>
#include <unordered_map>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -138,6 +139,8 @@ class tileset
std::vector<texture> overexposed_tile_values;
std::vector<texture> memory_tile_values;

std::unordered_set<std::string> duplicate_ids;

std::unordered_map<std::string, tile_type> tile_ids;
// caches both "default" and "_season_XXX" tile variants (to reduce the number of lookups)
// either variant can be either a `nullptr` or a pointer/reference to the real value (stored inside `tile_ids`)
Expand Down Expand Up @@ -179,6 +182,9 @@ class tileset
const texture *get_memory_tile( const size_t index ) const {
return get_if_available( index, memory_tile_values );
}
const std::unordered_set<std::string> &get_duplicate_ids() const {
return duplicate_ids;
}

tile_type &create_tile_type( const std::string &id, tile_type &&new_tile_type );
const tile_type *find_tile_type( const std::string &id ) const;
Expand Down Expand Up @@ -236,14 +242,8 @@ class tileset_loader
void add_ascii_subtile( tile_type &curr_tile, const std::string &t_id, int sprite_id,
const std::string &s_id );
void load_ascii_set( const JsonObject &entry );
/**
* Create a new tile_type, add it to tile_ids (using <B>id</B>).
* Set the fg and bg properties of it (loaded from the json object).
* Makes sure each is either -1, or in the interval [0,size).
* If it's in that interval, adds offset to it, if it's not in the
* interval (and not -1), throw an std::string error.
*/
tile_type &load_tile( const JsonObject &entry, const std::string &id );

tile_type *load_tile( const JsonObject &entry, const std::string &id );

void load_tile_spritelists( const JsonObject &entry, weighted_int_list<std::vector<int>> &vs,
const std::string &objname );
Expand Down Expand Up @@ -589,6 +589,9 @@ class cata_tiles
template<typename Iter, typename Func>
void lr_generic( Iter begin, Iter end, Func id_func, TILE_CATEGORY category,
const std::string &prefix );

void tile_loading_report_dups();

/** Lighting */
void init_light();

Expand Down

0 comments on commit 1e0f7b9

Please sign in to comment.