diff --git a/src/openrct2-ui/interface/LandTool.cpp b/src/openrct2-ui/interface/LandTool.cpp index a12d50a831..728b7a53af 100644 --- a/src/openrct2-ui/interface/LandTool.cpp +++ b/src/openrct2-ui/interface/LandTool.cpp @@ -64,8 +64,8 @@ void LandTool::ShowSurfaceStyleDropdown(rct_window* w, rct_widget* widget, Objec for (size_t i = 0; i < MAX_TERRAIN_SURFACE_OBJECTS; i++) { const auto surfaceObj = static_cast(objManager.GetLoadedObject(ObjectType::TerrainSurface, i)); - // NumImagesLoaded can be 1 for RCT1 surfaces if the user does not have RCT1 linked. - if (surfaceObj != nullptr && surfaceObj->NumImagesLoaded > 1) + // If fallback images are loaded, the RCT1 styles will just look like copies of already existing styles, so hide them. + if (surfaceObj != nullptr && !surfaceObj->UsesFallbackImages()) { gDropdownItemsFormat[itemIndex] = Dropdown::FormatLandPicker; gDropdownItemsArgs[itemIndex] = surfaceObj->IconImageId; @@ -98,7 +98,8 @@ void LandTool::ShowEdgeStyleDropdown(rct_window* w, rct_widget* widget, ObjectEn for (size_t i = 0; i < MAX_TERRAIN_EDGE_OBJECTS; i++) { const auto edgeObj = static_cast(objManager.GetLoadedObject(ObjectType::TerrainEdge, i)); - if (edgeObj != nullptr && edgeObj->NumImagesLoaded > 1) + // If fallback images are loaded, the RCT1 styles will just look like copies of already existing styles, so hide them. + if (edgeObj != nullptr && !edgeObj->UsesFallbackImages()) { gDropdownItemsFormat[itemIndex] = Dropdown::FormatLandPicker; gDropdownItemsArgs[itemIndex] = edgeObj->IconImageId; diff --git a/src/openrct2/object/ImageTable.cpp b/src/openrct2/object/ImageTable.cpp index 92f0f06276..bb88e97469 100644 --- a/src/openrct2/object/ImageTable.cpp +++ b/src/openrct2/object/ImageTable.cpp @@ -443,15 +443,23 @@ std::vector> ImageTable::GetImageSources(IReadObje return result; } -void ImageTable::ReadJson(IReadObjectContext* context, json_t& root) +bool ImageTable::ReadJson(IReadObjectContext* context, json_t& root) { Guard::Assert(root.is_object(), "ImageTable::ReadJson expects parameter root to be object"); + bool usesFallbackSprites = false; + if (context->ShouldLoadImages()) { // First gather all the required images from inspecting the JSON std::vector> allImages; auto jsonImages = root["images"]; + if (!is_csg_loaded() && root.contains("noCsgImages")) + { + jsonImages = root["noCsgImages"]; + usesFallbackSprites = true; + } + auto imageSources = GetImageSources(context, jsonImages); for (auto& jsonImage : jsonImages) @@ -506,6 +514,8 @@ void ImageTable::ReadJson(IReadObjectContext* context, json_t& root) } } } + + return usesFallbackSprites; } void ImageTable::AddImage(const rct_g1_element* g1) diff --git a/src/openrct2/object/ImageTable.h b/src/openrct2/object/ImageTable.h index 2d68fbce68..5164016b54 100644 --- a/src/openrct2/object/ImageTable.h +++ b/src/openrct2/object/ImageTable.h @@ -56,7 +56,7 @@ public: /** * @note root is deliberately left non-const: json_t behaviour changes when const */ - void ReadJson(IReadObjectContext* context, json_t& root); + bool ReadJson(IReadObjectContext* context, json_t& root); const rct_g1_element* GetImages() const { return _entries.data(); diff --git a/src/openrct2/object/Object.cpp b/src/openrct2/object/Object.cpp index 985ae0441b..be7a43e268 100644 --- a/src/openrct2/object/Object.cpp +++ b/src/openrct2/object/Object.cpp @@ -116,7 +116,7 @@ void Object::ReadLegacy(IReadObjectContext* context, OpenRCT2::IStream* stream) void Object::PopulateTablesFromJson(IReadObjectContext* context, json_t& root) { _stringTable.ReadJson(root); - _imageTable.ReadJson(context, root); + _usesFallbackImages = _imageTable.ReadJson(context, root); } rct_object_entry Object::ParseObjectEntry(const std::string& s) diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index be1374529c..92d5b3ac75 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -259,6 +259,7 @@ private: std::vector _sourceGames; std::vector _authors; ObjectGeneration _generation{}; + bool _usesFallbackImages{}; protected: StringTable& GetStringTable() @@ -324,6 +325,11 @@ public: _descriptor = value; } + constexpr bool UsesFallbackImages() const + { + return _usesFallbackImages; + } + // Legacy data structures std::string_view GetLegacyIdentifier() const { diff --git a/src/openrct2/object/TerrainEdgeObject.cpp b/src/openrct2/object/TerrainEdgeObject.cpp index 1ca78c3beb..6be7c7f83e 100644 --- a/src/openrct2/object/TerrainEdgeObject.cpp +++ b/src/openrct2/object/TerrainEdgeObject.cpp @@ -59,7 +59,6 @@ void TerrainEdgeObject::ReadJson(IReadObjectContext* context, json_t& root) } PopulateTablesFromJson(context, root); - NumImagesLoaded = GetImageTable().GetCount(); } TerrainEdgeObject* TerrainEdgeObject::GetById(ObjectEntryIndex entryIndex) diff --git a/src/openrct2/object/TerrainEdgeObject.h b/src/openrct2/object/TerrainEdgeObject.h index 269acd67d3..7ab3914337 100644 --- a/src/openrct2/object/TerrainEdgeObject.h +++ b/src/openrct2/object/TerrainEdgeObject.h @@ -18,7 +18,6 @@ public: rct_string_id NameStringId{}; uint32_t IconImageId{}; uint32_t BaseImageId{}; - uint32_t NumImagesLoaded{}; bool HasDoors{}; void ReadJson(IReadObjectContext* context, json_t& root) override; diff --git a/src/openrct2/object/TerrainSurfaceObject.cpp b/src/openrct2/object/TerrainSurfaceObject.cpp index f4dca3028d..3b3f3f9ec6 100644 --- a/src/openrct2/object/TerrainSurfaceObject.cpp +++ b/src/openrct2/object/TerrainSurfaceObject.cpp @@ -125,8 +125,6 @@ void TerrainSurfaceObject::ReadJson(IReadObjectContext* context, json_t& root) } PopulateTablesFromJson(context, root); - - NumImagesLoaded = GetImageTable().GetCount(); } uint32_t TerrainSurfaceObject::GetImageId( diff --git a/src/openrct2/object/TerrainSurfaceObject.h b/src/openrct2/object/TerrainSurfaceObject.h index fa50f885e9..60ed875d6b 100644 --- a/src/openrct2/object/TerrainSurfaceObject.h +++ b/src/openrct2/object/TerrainSurfaceObject.h @@ -54,8 +54,6 @@ public: money32 Price{}; TERRAIN_SURFACE_FLAGS Flags{}; - uint32_t NumImagesLoaded{}; - void ReadJson(IReadObjectContext* context, json_t& root) override; void Load() override; void Unload() override; diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index a92ee545c7..f00ce8efe8 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -317,15 +317,6 @@ static uint32_t get_surface_image( const paint_session* session, ObjectEntryIndex index, int32_t offset, uint8_t rotation, int32_t grassLength, bool grid, bool underground) { - // Provide fallback for RCT1 surfaces if the user does have RCT1 linked. - if (!is_csg_loaded() && index >= TERRAIN_RCT2_COUNT) - { - if (index == TERRAIN_ROOF_GREY) - index = TERRAIN_ROCK; - else - index = TERRAIN_DIRT; - } - auto image = static_cast(SPR_NONE); auto obj = get_surface_object(index); if (obj != nullptr) @@ -416,7 +407,7 @@ static uint32_t get_tunnel_image(ObjectEntryIndex index, uint8_t type) if (obj != nullptr) { auto tobj = static_cast(obj); - hasDoors = tobj->HasDoors; + hasDoors = tobj->HasDoors && !tobj->UsesFallbackImages(); } if (!hasDoors && type >= REGULAR_TUNNEL_TYPE_COUNT && type < std::size(offsets)) @@ -638,9 +629,6 @@ static void viewport_surface_draw_tile_side_bottom( return; } - if (!is_csg_loaded() && edgeStyle >= TERRAIN_EDGE_RCT2_COUNT) - edgeStyle = TERRAIN_EDGE_ROCK; - uint32_t base_image_id = get_edge_image(edgeStyle, 0); if (session->ViewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) { @@ -784,9 +772,6 @@ static void viewport_surface_draw_tile_side_top( // From big Z to tiny Z height /= COORDS_Z_PER_TINY_Z; - if (!is_csg_loaded() && terrain >= TERRAIN_EDGE_RCT2_COUNT) - terrain = TERRAIN_EDGE_ROCK; - int16_t cornerHeight1, neighbourCornerHeight1, cornerHeight2, neighbourCornerHeight2; CoordsXY offset = { 0, 0 };