diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1b01363a10..c88b53a36b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,9 +61,9 @@ set(TITLE_SEQUENCE_VERSION "0.1.2c")
set(TITLE_SEQUENCE_URL "https://github.com/OpenRCT2/title-sequences/releases/download/v${TITLE_SEQUENCE_VERSION}/title-sequences.zip")
set(TITLE_SEQUENCE_SHA1 "304d13a126c15bf2c86ff13b81a2f2cc1856ac8d")
-set(OBJECTS_VERSION "1.2.2")
+set(OBJECTS_VERSION "1.2.4")
set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v${OBJECTS_VERSION}/objects.zip")
-set(OBJECTS_SHA1 "a808fd47e9bc35d105dc371428a55888e6a86860")
+set(OBJECTS_SHA1 "c82605035f120188b7334a781a786ced9588e9af")
set(REPLAYS_VERSION "0.0.60")
set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v${REPLAYS_VERSION}/replays.zip")
diff --git a/openrct2.proj b/openrct2.proj
index 50527a1c30..ac81e980a6 100644
--- a/openrct2.proj
+++ b/openrct2.proj
@@ -46,8 +46,8 @@
058b9df80244c03f1633cb06e9f70471a29ebb8e
https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2c/title-sequences.zip
304d13a126c15bf2c86ff13b81a2f2cc1856ac8d
- https://github.com/OpenRCT2/objects/releases/download/v1.2.2/objects.zip
- a808fd47e9bc35d105dc371428a55888e6a86860
+ https://github.com/OpenRCT2/objects/releases/download/v1.2.4/objects.zip
+ c82605035f120188b7334a781a786ced9588e9af
https://github.com/OpenRCT2/replays/releases/download/v0.0.60/replays.zip
1EB460BB3C71BD21CCBE778BEF1E8CD593241A18
diff --git a/shell.nix b/shell.nix
index 2e0b444f59..ea2fb5fc47 100644
--- a/shell.nix
+++ b/shell.nix
@@ -15,8 +15,8 @@ let
objects-src = pkgs.fetchFromGitHub {
owner = "OpenRCT2";
repo = "objects";
- rev = "v1.2.2";
- sha256 = "2c77023068831c68423eb51f96251d1a06f58253414e4563ca17407d654ed96b";
+ rev = "v1.2.4";
+ sha256 = "d01e5f1d2c95ba8ee295c457ae6215c048728ab07adc3db58a08f3cf2b1fa179";
};
title-sequences-src = pkgs.fetchFromGitHub {
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 };