From 24a29a8a4cd56ff924620eadfc20b5ada5d04146 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 19 Apr 2021 22:44:20 +0100 Subject: [PATCH] Add path surface object type --- .../windows/EditorObjectSelection.cpp | 11 ++- src/openrct2/EditorObjectSelectionSession.cpp | 18 ++--- src/openrct2/libopenrct2.vcxproj | 2 + src/openrct2/object/BannerObject.h | 5 -- src/openrct2/object/EntranceObject.h | 5 -- src/openrct2/object/FootpathItemObject.h | 5 -- src/openrct2/object/FootpathObject.h | 5 -- src/openrct2/object/FootpathRailingsObject.h | 5 -- src/openrct2/object/FootpathSurfaceObject.cpp | 63 ++++++++++++++++ src/openrct2/object/FootpathSurfaceObject.h | 29 ++++++++ src/openrct2/object/LargeSceneryObject.h | 5 -- src/openrct2/object/MusicObject.h | 5 -- src/openrct2/object/Object.cpp | 6 -- src/openrct2/object/Object.h | 28 ++++--- src/openrct2/object/ObjectFactory.cpp | 74 +++++++++++-------- src/openrct2/object/ObjectFactory.h | 3 +- src/openrct2/object/ObjectLimits.h | 2 + src/openrct2/object/ObjectList.cpp | 1 + src/openrct2/object/ObjectManager.cpp | 2 +- src/openrct2/object/ObjectRepository.cpp | 12 ++- src/openrct2/object/RideObject.h | 5 -- src/openrct2/object/SceneryGroupObject.cpp | 21 +++++- src/openrct2/object/SceneryGroupObject.h | 5 -- src/openrct2/object/SceneryObject.h | 4 - src/openrct2/object/SmallSceneryObject.h | 5 -- src/openrct2/object/StationObject.h | 5 -- src/openrct2/object/TerrainEdgeObject.h | 5 -- src/openrct2/object/TerrainSurfaceObject.h | 5 -- src/openrct2/object/WallObject.h | 5 -- src/openrct2/object/WaterObject.h | 5 -- src/openrct2/rct1/S4Importer.cpp | 2 +- 31 files changed, 199 insertions(+), 154 deletions(-) create mode 100644 src/openrct2/object/FootpathSurfaceObject.cpp create mode 100644 src/openrct2/object/FootpathSurfaceObject.h diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index d9a9eaa02b..7413c189cc 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -109,6 +109,7 @@ static constexpr const ObjectPageDesc ObjectSelectionPages[] = { { STR_OBJECT_SELECTION_STATIONS, SPR_TAB_PARK, false }, { STR_OBJECT_SELECTION_MUSIC, SPR_TAB_MUSIC_0, false }, { STR_OBJECT_SELECTION_FOOTPATHS, SPR_TAB_SCENERY_PATHS, false }, + { STR_OBJECT_SELECTION_FOOTPATHS, SPR_TAB_SCENERY_PATHS, false }, }; #pragma region Widgets @@ -295,8 +296,7 @@ static void visible_list_refresh(rct_window* w) { uint8_t selectionFlags = _objectSelectionFlags[i]; const ObjectRepositoryItem* item = &items[i]; - ObjectType objectType = item->ObjectEntry.GetType(); - if (objectType == get_selected_object_type(w) && !(selectionFlags & OBJECT_SELECTION_FLAG_6) && filter_source(item) + if (item->Type == get_selected_object_type(w) && !(selectionFlags & OBJECT_SELECTION_FLAG_6) && filter_source(item) && filter_string(item) && filter_chunks(item) && filter_selected(selectionFlags)) { auto filter = std::make_unique(); @@ -1425,7 +1425,7 @@ static bool filter_string(const ObjectRepositoryItem* item) // Check if the searched string exists in the name, ride type, or filename bool inName = strstr(name_lower, filter_lower) != nullptr; - bool inRideType = (item->ObjectEntry.GetType() == ObjectType::Ride) && strstr(type_lower, filter_lower) != nullptr; + bool inRideType = (item->Type == ObjectType::Ride) && strstr(type_lower, filter_lower) != nullptr; bool inPath = strstr(object_path, filter_lower) != nullptr; return inName || inRideType || inPath; @@ -1468,7 +1468,7 @@ static bool filter_source(const ObjectRepositoryItem* item) static bool filter_chunks(const ObjectRepositoryItem* item) { - if (item->ObjectEntry.GetType() == ObjectType::Ride) + if (item->Type == ObjectType::Ride) { uint8_t rideType = 0; for (int32_t i = 0; i < MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++) @@ -1498,8 +1498,7 @@ static void filter_update_counts() const ObjectRepositoryItem* item = &items[i]; if (filter_source(item) && filter_string(item) && filter_chunks(item) && filter_selected(selectionFlags[i])) { - ObjectType objectType = item->ObjectEntry.GetType(); - _filter_object_counts[EnumValue(objectType)]++; + _filter_object_counts[EnumValue(item->Type)]++; } } } diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index d5a4799545..ad49d689d6 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -55,8 +55,7 @@ static void setup_track_manager_objects() { uint8_t* selectionFlags = &_objectSelectionFlags[i]; const ObjectRepositoryItem* item = &items[i]; - ObjectType object_type = item->ObjectEntry.GetType(); - if (object_type == ObjectType::Ride) + if (item->Type == ObjectType::Ride) { *selectionFlags |= OBJECT_SELECTION_FLAG_6; @@ -85,8 +84,7 @@ static void setup_track_designer_objects() { uint8_t* selectionFlags = &_objectSelectionFlags[i]; const ObjectRepositoryItem* item = &items[i]; - ObjectType objectType = item->ObjectEntry.GetType(); - if (objectType == ObjectType::Ride) + if (item->Type == ObjectType::Ride) { *selectionFlags |= OBJECT_SELECTION_FLAG_6; @@ -271,7 +269,7 @@ void sub_6AB211() const ObjectRepositoryItem* items = object_repository_get_items(); for (int32_t i = 0; i < numObjects; i++) { - ObjectType objectType = items[i].ObjectEntry.GetType(); + auto objectType = items[i].Type; _numAvailableObjectsForType[EnumValue(objectType)]++; } @@ -445,7 +443,7 @@ void reset_selected_object_count_and_size() const ObjectRepositoryItem* items = object_repository_get_items(); for (int32_t i = 0; i < numObjects; i++) { - ObjectType objectType = items[i].ObjectEntry.GetType(); + auto objectType = items[i].Type; if (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED) { _numSelectedObjectsForType[EnumValue(objectType)]++; @@ -527,7 +525,7 @@ bool window_editor_object_selection_select_object(uint8_t isMasterObject, int32_ return false; } - ObjectType objectType = item->ObjectEntry.GetType(); + ObjectType objectType = item->Type; if (objectType == ObjectType::SceneryGroup && (flags & INPUT_FLAG_EDITOR_OBJECT_SELECT_OBJECTS_IN_SCENERY_GROUP)) { for (const auto& sgEntry : item->SceneryGroupInfo.Entries) @@ -554,7 +552,7 @@ bool window_editor_object_selection_select_object(uint8_t isMasterObject, int32_ return true; } - ObjectType objectType = item->ObjectEntry.GetType(); + ObjectType objectType = item->Type; uint16_t maxObjects = object_entry_group_counts[EnumValue(objectType)]; if (maxObjects <= _numSelectedObjectsForType[EnumValue(objectType)]) @@ -617,7 +615,7 @@ bool editor_check_object_group_at_least_one_selected(ObjectType checkObjectType) for (size_t i = 0; i < numObjects; i++) { - ObjectType objectType = items[i].ObjectEntry.GetType(); + auto objectType = items[i].Type; if (checkObjectType == objectType && (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED)) { return true; @@ -643,7 +641,7 @@ int32_t editor_remove_unused_objects() && !(_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED)) { const ObjectRepositoryItem* item = &items[i]; - ObjectType objectType = item->ObjectEntry.GetType(); + ObjectType objectType = item->Type; if (objectType >= ObjectType::SceneryGroup) { diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 55c2e6b1b4..b58ba865ef 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -254,6 +254,7 @@ + @@ -674,6 +675,7 @@ + diff --git a/src/openrct2/object/BannerObject.h b/src/openrct2/object/BannerObject.h index 1877ce6d25..840680c7b0 100644 --- a/src/openrct2/object/BannerObject.h +++ b/src/openrct2/object/BannerObject.h @@ -19,11 +19,6 @@ private: rct_scenery_entry _legacyType = {}; public: - explicit BannerObject(const rct_object_entry& entry) - : SceneryObject(entry) - { - } - void* GetLegacyData() override { return &_legacyType; diff --git a/src/openrct2/object/EntranceObject.h b/src/openrct2/object/EntranceObject.h index 45e4d8dc72..beefbce10e 100644 --- a/src/openrct2/object/EntranceObject.h +++ b/src/openrct2/object/EntranceObject.h @@ -18,11 +18,6 @@ private: rct_entrance_type _legacyType = {}; public: - explicit EntranceObject(const rct_object_entry& entry) - : Object(entry) - { - } - void* GetLegacyData() override { return &_legacyType; diff --git a/src/openrct2/object/FootpathItemObject.h b/src/openrct2/object/FootpathItemObject.h index 4bbcc8741a..a427cff15e 100644 --- a/src/openrct2/object/FootpathItemObject.h +++ b/src/openrct2/object/FootpathItemObject.h @@ -18,11 +18,6 @@ private: rct_scenery_entry _legacyType = {}; public: - explicit FootpathItemObject(const rct_object_entry& entry) - : SceneryObject(entry) - { - } - void* GetLegacyData() override { return &_legacyType; diff --git a/src/openrct2/object/FootpathObject.h b/src/openrct2/object/FootpathObject.h index 7fe5274cdb..c15fbfebe3 100644 --- a/src/openrct2/object/FootpathObject.h +++ b/src/openrct2/object/FootpathObject.h @@ -21,11 +21,6 @@ private: PathRailingsEntry _pathRailingsEntry = {}; public: - explicit FootpathObject(const rct_object_entry& entry) - : Object(entry) - { - } - void* GetLegacyData() override { return &_legacyType; diff --git a/src/openrct2/object/FootpathRailingsObject.h b/src/openrct2/object/FootpathRailingsObject.h index 2b61ec9255..4eb2c705f7 100644 --- a/src/openrct2/object/FootpathRailingsObject.h +++ b/src/openrct2/object/FootpathRailingsObject.h @@ -25,11 +25,6 @@ public: colour_t Colour{}; public: - explicit FootpathRailingsObject(const rct_object_entry& entry) - : Object(entry) - { - } - void ReadJson(IReadObjectContext* context, json_t& root) override; void Load() override; void Unload() override; diff --git a/src/openrct2/object/FootpathSurfaceObject.cpp b/src/openrct2/object/FootpathSurfaceObject.cpp new file mode 100644 index 0000000000..a160a2f744 --- /dev/null +++ b/src/openrct2/object/FootpathSurfaceObject.cpp @@ -0,0 +1,63 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#include "FootpathSurfaceObject.h" + +#include "../core/IStream.hpp" +#include "../core/Json.hpp" + +void FootpathSurfaceObject::Load() +{ + GetStringTable().Sort(); + NameStringId = language_allocate_object_string(GetName()); + + auto numImages = GetImageTable().GetCount(); + if (numImages != 0) + { + BaseImageId = gfx_object_allocate_images(GetImageTable().GetImages(), GetImageTable().GetCount()); + PreviewImageId = BaseImageId + 72; + } +} + +void FootpathSurfaceObject::Unload() +{ + language_free_object_string(NameStringId); + gfx_object_free_images(BaseImageId, GetImageTable().GetCount()); + + NameStringId = 0; + PreviewImageId = 0; + BaseImageId = 0; +} + +void FootpathSurfaceObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const +{ + auto screenCoords = ScreenCoordsXY{ width / 2 - 16, height / 2 }; + gfx_draw_sprite(dpi, BaseImageId + 3, screenCoords, 0); + gfx_draw_sprite(dpi, BaseImageId + 16, { screenCoords.x + 32, screenCoords.y - 16 }, 0); + gfx_draw_sprite(dpi, BaseImageId + 8, { screenCoords.x + 32, screenCoords.y + 16 }, 0); +} + +void FootpathSurfaceObject::ReadJson(IReadObjectContext* context, json_t& root) +{ + Guard::Assert(root.is_object(), "FootpathSurfaceObject::ReadJson expects parameter root to be object"); + + auto properties = root["properties"]; + if (properties.is_object()) + { + Flags = Json::GetFlags( + properties, + { + { "editorOnly", FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR }, + { "isQueue", FOOTPATH_ENTRY_FLAG_IS_QUEUE }, + { "noSlopeRailings", FOOTPATH_ENTRY_FLAG_NO_SLOPE_RAILINGS }, + }); + } + + PopulateTablesFromJson(context, root); +} diff --git a/src/openrct2/object/FootpathSurfaceObject.h b/src/openrct2/object/FootpathSurfaceObject.h new file mode 100644 index 0000000000..89747ee393 --- /dev/null +++ b/src/openrct2/object/FootpathSurfaceObject.h @@ -0,0 +1,29 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#include "../world/Footpath.h" +#include "Object.h" + +class FootpathSurfaceObject final : public Object +{ +public: + rct_string_id NameStringId{}; + uint32_t PreviewImageId{}; + uint32_t BaseImageId{}; + uint8_t Flags{}; + +public: + void ReadJson(IReadObjectContext* context, json_t& root) override; + void Load() override; + void Unload() override; + + void DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const override; +}; diff --git a/src/openrct2/object/LargeSceneryObject.h b/src/openrct2/object/LargeSceneryObject.h index 00e33a4670..7f9663b2aa 100644 --- a/src/openrct2/object/LargeSceneryObject.h +++ b/src/openrct2/object/LargeSceneryObject.h @@ -24,11 +24,6 @@ private: std::unique_ptr _3dFont; public: - explicit LargeSceneryObject(const rct_object_entry& entry) - : SceneryObject(entry) - { - } - void* GetLegacyData() override { return &_legacyType; diff --git a/src/openrct2/object/MusicObject.h b/src/openrct2/object/MusicObject.h index f25c448b00..2f82c7e362 100644 --- a/src/openrct2/object/MusicObject.h +++ b/src/openrct2/object/MusicObject.h @@ -41,11 +41,6 @@ private: public: rct_string_id NameStringId{}; - explicit MusicObject(const rct_object_entry& entry) - : Object(entry) - { - } - void ReadJson(IReadObjectContext* context, json_t& root) override; void Load() override; void Unload() override; diff --git a/src/openrct2/object/Object.cpp b/src/openrct2/object/Object.cpp index dd016b7aed..a7aaa77096 100644 --- a/src/openrct2/object/Object.cpp +++ b/src/openrct2/object/Object.cpp @@ -103,12 +103,6 @@ bool ObjectEntryDescriptor::operator!=(const ObjectEntryDescriptor& rhs) const return !(*this == rhs); } -Object::Object(const rct_object_entry& entry) -{ - _type = entry.GetType(); - _objectEntry = entry; -} - void* Object::GetLegacyData() { throw std::runtime_error("Not supported."); diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index 209e062489..ee2568d593 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -42,6 +42,7 @@ enum class ObjectType : uint8_t TerrainEdge, Station, Music, + FootpathSurface, FootpathRailings, Count, @@ -167,7 +168,7 @@ struct ObjectEntryDescriptor ObjectGeneration Generation = ObjectGeneration::JSON; // DAT - rct_object_entry Entry; + rct_object_entry Entry{}; // JSON ObjectType Type{}; @@ -251,9 +252,8 @@ struct IReadObjectContext class Object { private: - ObjectType _type = ObjectType::None; std::string _identifier; - rct_object_entry _objectEntry{}; + ObjectEntryDescriptor _descriptor{}; StringTable _stringTable; ImageTable _imageTable; std::vector _sourceGames; @@ -289,7 +289,6 @@ protected: std::string GetString(int32_t language, ObjectStringID index) const; public: - explicit Object(const rct_object_entry& entry); virtual ~Object() = default; std::string_view GetIdentifier() const @@ -313,29 +312,28 @@ public: ObjectType GetObjectType() const { - return _type; + return _descriptor.GetType(); } ObjectEntryDescriptor GetDescriptor() const { - if (_generation == ObjectGeneration::DAT) - { - return ObjectEntryDescriptor(_objectEntry); - } - else - { - return ObjectEntryDescriptor(_type, _identifier); - } + return _descriptor; + } + void SetDescriptor(const ObjectEntryDescriptor& value) + { + _descriptor = value; } // Legacy data structures std::string_view GetLegacyIdentifier() const { - return _objectEntry.GetName(); + return _descriptor.GetName(); } + + // TODO remove this, we should no longer assume objects have a legacy object entry const rct_object_entry& GetObjectEntry() const { - return _objectEntry; + return _descriptor.Entry; } virtual void* GetLegacyData(); diff --git a/src/openrct2/object/ObjectFactory.cpp b/src/openrct2/object/ObjectFactory.cpp index ceb4f429fd..cc53a4ac66 100644 --- a/src/openrct2/object/ObjectFactory.cpp +++ b/src/openrct2/object/ObjectFactory.cpp @@ -25,6 +25,7 @@ #include "FootpathItemObject.h" #include "FootpathObject.h" #include "FootpathRailingsObject.h" +#include "FootpathSurfaceObject.h" #include "LargeSceneryObject.h" #include "MusicObject.h" #include "Object.h" @@ -239,7 +240,7 @@ namespace ObjectFactory if (entry.GetType() != ObjectType::ScenarioText) { - result = CreateObject(entry); + result = CreateObject(entry.GetType()); utf8 objectName[DAT_NAME_LENGTH + 1] = { 0 }; object_entry_get_name_fixed(objectName, sizeof(objectName), &entry); @@ -271,9 +272,11 @@ namespace ObjectFactory Guard::ArgumentNotNull(entry, GUARD_LINE); Guard::ArgumentNotNull(data, GUARD_LINE); - auto result = CreateObject(*entry); + auto result = CreateObject(entry->GetType()); if (result != nullptr) { + result->SetDescriptor(ObjectEntryDescriptor(*entry)); + utf8 objectName[DAT_NAME_LENGTH + 1]; object_entry_get_name_fixed(objectName, sizeof(objectName), entry); @@ -293,57 +296,60 @@ namespace ObjectFactory return result; } - std::unique_ptr CreateObject(const rct_object_entry& entry) + std::unique_ptr CreateObject(ObjectType type) { std::unique_ptr result; - switch (entry.GetType()) + switch (type) { case ObjectType::Ride: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::SmallScenery: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::LargeScenery: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::Walls: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::Banners: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::Paths: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::PathBits: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::SceneryGroup: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::ParkEntrance: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::Water: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::ScenarioText: break; case ObjectType::TerrainSurface: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::TerrainEdge: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::Station: - result = std::make_unique(entry); + result = std::make_unique(); break; case ObjectType::Music: - result = std::make_unique(entry); + result = std::make_unique(); + break; + case ObjectType::FootpathSurface: + result = std::make_unique(); break; case ObjectType::FootpathRailings: - result = std::make_unique(entry); + result = std::make_unique(); break; default: throw std::runtime_error("Invalid object type"); @@ -381,6 +387,8 @@ namespace ObjectFactory return ObjectType::Station; if (s == "music") return ObjectType::Music; + if (s == "footpath_surface") + return ObjectType::FootpathSurface; if (s == "footpath_railings") return ObjectType::FootpathRailings; return ObjectType::None; @@ -476,22 +484,28 @@ namespace ObjectFactory { auto id = Json::GetString(jRoot["id"]); - rct_object_entry entry = {}; + ObjectEntryDescriptor descriptor; auto originalId = Json::GetString(jRoot["originalId"]); - auto originalName = originalId; if (originalId.length() == 8 + 1 + 8 + 1 + 8) { - entry.flags = std::stoul(originalId.substr(0, 8), nullptr, 16); - originalName = originalId.substr(9, 8); - entry.checksum = std::stoul(originalId.substr(18, 8), nullptr, 16); - } - // Always set, since originalId might be missing or incorrect. - entry.SetType(objectType); - auto minLength = std::min(8, originalName.length()); - std::memcpy(entry.name, originalName.c_str(), minLength); + auto originalName = originalId.substr(9, 8); - result = CreateObject(entry); + rct_object_entry entry = {}; + entry.flags = std::stoul(originalId.substr(0, 8), nullptr, 16); + entry.checksum = std::stoul(originalId.substr(18, 8), nullptr, 16); + entry.SetType(objectType); + auto minLength = std::min(8, originalName.length()); + std::memcpy(entry.name, originalName.c_str(), minLength); + descriptor = ObjectEntryDescriptor(entry); + } + else + { + descriptor = ObjectEntryDescriptor(objectType, id); + } + + result = CreateObject(objectType); result->SetIdentifier(id); + result->SetDescriptor(descriptor); result->MarkAsJsonObject(); auto readContext = ReadObjectContext(objectRepository, id, !gOpenRCT2NoGraphics, fileRetriever); result->ReadJson(&readContext, jRoot); diff --git a/src/openrct2/object/ObjectFactory.h b/src/openrct2/object/ObjectFactory.h index 74ea1787c7..5f8d9772e8 100644 --- a/src/openrct2/object/ObjectFactory.h +++ b/src/openrct2/object/ObjectFactory.h @@ -17,6 +17,7 @@ struct IObjectRepository; class Object; struct rct_object_entry; +enum class ObjectType : uint8_t; namespace ObjectFactory { @@ -24,7 +25,7 @@ namespace ObjectFactory std::unique_ptr CreateObjectFromLegacyData( IObjectRepository& objectRepository, const rct_object_entry* entry, const void* data, size_t dataSize); std::unique_ptr CreateObjectFromZipFile(IObjectRepository& objectRepository, std::string_view path); - std::unique_ptr CreateObject(const rct_object_entry& entry); + std::unique_ptr CreateObject(ObjectType type); std::unique_ptr CreateObjectFromJsonFile(IObjectRepository& objectRepository, const std::string& path); } // namespace ObjectFactory diff --git a/src/openrct2/object/ObjectLimits.h b/src/openrct2/object/ObjectLimits.h index 4807f46601..2f9b0eb66e 100644 --- a/src/openrct2/object/ObjectLimits.h +++ b/src/openrct2/object/ObjectLimits.h @@ -26,6 +26,7 @@ constexpr const uint16_t MAX_TERRAIN_SURFACE_OBJECTS = 100; constexpr const uint16_t MAX_TERRAIN_EDGE_OBJECTS = 100; constexpr const uint16_t MAX_STATION_OBJECTS = 100; constexpr const uint16_t MAX_MUSIC_OBJECTS = 255; +constexpr const uint16_t MAX_FOOTPATH_SURFACE_OBJECTS = 32; constexpr const uint16_t MAX_FOOTPATH_RAILINGS_OBJECTS = 32; // clang-format off @@ -45,6 +46,7 @@ constexpr const uint16_t OBJECT_ENTRY_COUNT = MAX_TERRAIN_EDGE_OBJECTS + MAX_STATION_OBJECTS + MAX_MUSIC_OBJECTS + + MAX_FOOTPATH_SURFACE_OBJECTS + MAX_FOOTPATH_RAILINGS_OBJECTS; // clang-format on diff --git a/src/openrct2/object/ObjectList.cpp b/src/openrct2/object/ObjectList.cpp index c371617607..1b06d51f6f 100644 --- a/src/openrct2/object/ObjectList.cpp +++ b/src/openrct2/object/ObjectList.cpp @@ -38,6 +38,7 @@ int32_t object_entry_group_counts[] = { MAX_TERRAIN_EDGE_OBJECTS, MAX_STATION_OBJECTS, MAX_MUSIC_OBJECTS, + MAX_FOOTPATH_SURFACE_OBJECTS, MAX_FOOTPATH_RAILINGS_OBJECTS, }; diff --git a/src/openrct2/object/ObjectManager.cpp b/src/openrct2/object/ObjectManager.cpp index 45696d3609..63c1a3ce35 100644 --- a/src/openrct2/object/ObjectManager.cpp +++ b/src/openrct2/object/ObjectManager.cpp @@ -288,7 +288,7 @@ private: loadedObject = ori->LoadedObject; if (loadedObject == nullptr) { - ObjectType objectType = ori->ObjectEntry.GetType(); + ObjectType objectType = ori->Type; if (slot) { if (_loadedObjects.size() > static_cast(*slot) && _loadedObjects[*slot] != nullptr) diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index d6b1024074..e62c33e996 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -130,6 +130,8 @@ public: protected: void Serialise(DataSerialiser& ds, ObjectRepositoryItem& item) const override { + ds << item.Type; + ds << item.Generation; ds << item.Identifier; ds << item.ObjectEntry; ds << item.Path; @@ -138,7 +140,7 @@ protected: ds << item.Sources; ds << item.Authors; - switch (item.ObjectEntry.GetType()) + switch (item.Type) { case ObjectType::Ride: ds << item.RideInfo.RideFlags; @@ -435,7 +437,10 @@ private: { _newItemMap[item.Identifier] = index; } - _itemMap[item.ObjectEntry] = index; + if (!item.ObjectEntry.IsEmpty()) + { + _itemMap[item.ObjectEntry] = index; + } return true; } else @@ -649,8 +654,7 @@ bool IsObjectCustom(const ObjectRepositoryItem* object) // Do not count our new object types as custom yet, otherwise the game // will try to pack them into saved games. - auto type = object->ObjectEntry.GetType(); - if (type > ObjectType::ScenarioText) + if (object->Type > ObjectType::ScenarioText) { return false; } diff --git a/src/openrct2/object/RideObject.h b/src/openrct2/object/RideObject.h index c7c9202781..4c14deb6b5 100644 --- a/src/openrct2/object/RideObject.h +++ b/src/openrct2/object/RideObject.h @@ -24,11 +24,6 @@ private: std::vector> _peepLoadingWaypoints[MAX_VEHICLES_PER_RIDE_ENTRY]; public: - explicit RideObject(const rct_object_entry& entry) - : Object(entry) - { - } - void* GetLegacyData() override { return &_legacyType; diff --git a/src/openrct2/object/SceneryGroupObject.cpp b/src/openrct2/object/SceneryGroupObject.cpp index 20deaaa397..9287f6230e 100644 --- a/src/openrct2/object/SceneryGroupObject.cpp +++ b/src/openrct2/object/SceneryGroupObject.cpp @@ -66,6 +66,25 @@ void SceneryGroupObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int3 gfx_draw_sprite(dpi, imageId, screenCoords - ScreenCoordsXY{ 15, 14 }, 0); } +static std::optional GetSceneryType(ObjectType type) +{ + switch (type) + { + case ObjectType::SmallScenery: + return SCENERY_TYPE_SMALL; + case ObjectType::LargeScenery: + return SCENERY_TYPE_LARGE; + case ObjectType::Walls: + return SCENERY_TYPE_WALL; + case ObjectType::Banners: + return SCENERY_TYPE_BANNER; + case ObjectType::PathBits: + return SCENERY_TYPE_PATH_ITEM; + default: + return std::nullopt; + } +} + void SceneryGroupObject::UpdateEntryIndexes() { auto context = GetContext(); @@ -84,7 +103,7 @@ void SceneryGroupObject::UpdateEntryIndexes() auto entryIndex = objectManager.GetLoadedObjectEntryIndex(ori->LoadedObject); Guard::Assert(entryIndex != OBJECT_ENTRY_INDEX_NULL, GUARD_LINE); - auto sceneryType = ori->ObjectEntry.GetSceneryType(); + auto sceneryType = GetSceneryType(ori->Type); if (sceneryType != std::nullopt) { _legacyType.scenery_entries[_legacyType.entry_count] = { *sceneryType, entryIndex }; diff --git a/src/openrct2/object/SceneryGroupObject.h b/src/openrct2/object/SceneryGroupObject.h index e3e9d889a2..d6e41a6f27 100644 --- a/src/openrct2/object/SceneryGroupObject.h +++ b/src/openrct2/object/SceneryGroupObject.h @@ -25,11 +25,6 @@ private: std::vector _items; public: - explicit SceneryGroupObject(const rct_object_entry& entry) - : Object(entry) - { - } - void* GetLegacyData() override { return &_legacyType; diff --git a/src/openrct2/object/SceneryObject.h b/src/openrct2/object/SceneryObject.h index 9c15a1c397..e4e351a59c 100644 --- a/src/openrct2/object/SceneryObject.h +++ b/src/openrct2/object/SceneryObject.h @@ -19,10 +19,6 @@ private: ObjectEntryDescriptor _primarySceneryGroupEntry = {}; public: - explicit SceneryObject(const rct_object_entry& entry) - : Object(entry) - { - } virtual ~SceneryObject() = default; const ObjectEntryDescriptor& GetPrimarySceneryGroup() const diff --git a/src/openrct2/object/SmallSceneryObject.h b/src/openrct2/object/SmallSceneryObject.h index 94289e14f5..a86a888d1c 100644 --- a/src/openrct2/object/SmallSceneryObject.h +++ b/src/openrct2/object/SmallSceneryObject.h @@ -21,11 +21,6 @@ private: std::vector _frameOffsets; public: - explicit SmallSceneryObject(const rct_object_entry& entry) - : SceneryObject(entry) - { - } - void* GetLegacyData() override { return &_legacyType; diff --git a/src/openrct2/object/StationObject.h b/src/openrct2/object/StationObject.h index 0912661414..06e7b3ddbf 100644 --- a/src/openrct2/object/StationObject.h +++ b/src/openrct2/object/StationObject.h @@ -28,11 +28,6 @@ public: int32_t Height{}; uint8_t ScrollingMode{}; - explicit StationObject(const rct_object_entry& entry) - : Object(entry) - { - } - void ReadJson(IReadObjectContext* context, json_t& root) override; void Load() override; void Unload() override; diff --git a/src/openrct2/object/TerrainEdgeObject.h b/src/openrct2/object/TerrainEdgeObject.h index d55fb84d42..269acd67d3 100644 --- a/src/openrct2/object/TerrainEdgeObject.h +++ b/src/openrct2/object/TerrainEdgeObject.h @@ -21,11 +21,6 @@ public: uint32_t NumImagesLoaded{}; bool HasDoors{}; - explicit TerrainEdgeObject(const rct_object_entry& entry) - : Object(entry) - { - } - void ReadJson(IReadObjectContext* context, json_t& root) override; void Load() override; void Unload() override; diff --git a/src/openrct2/object/TerrainSurfaceObject.h b/src/openrct2/object/TerrainSurfaceObject.h index c273ad42d6..fa50f885e9 100644 --- a/src/openrct2/object/TerrainSurfaceObject.h +++ b/src/openrct2/object/TerrainSurfaceObject.h @@ -56,11 +56,6 @@ public: uint32_t NumImagesLoaded{}; - explicit TerrainSurfaceObject(const rct_object_entry& entry) - : Object(entry) - { - } - void ReadJson(IReadObjectContext* context, json_t& root) override; void Load() override; void Unload() override; diff --git a/src/openrct2/object/WallObject.h b/src/openrct2/object/WallObject.h index 82b89ef7fa..831fa17425 100644 --- a/src/openrct2/object/WallObject.h +++ b/src/openrct2/object/WallObject.h @@ -18,11 +18,6 @@ private: rct_scenery_entry _legacyType = {}; public: - explicit WallObject(const rct_object_entry& entry) - : SceneryObject(entry) - { - } - void* GetLegacyData() override { return &_legacyType; diff --git a/src/openrct2/object/WaterObject.h b/src/openrct2/object/WaterObject.h index bac5e274b5..34275a7ea4 100644 --- a/src/openrct2/object/WaterObject.h +++ b/src/openrct2/object/WaterObject.h @@ -20,11 +20,6 @@ private: rct_water_type _legacyType = {}; public: - explicit WaterObject(const rct_object_entry& entry) - : Object(entry) - { - } - void* GetLegacyData() override { return &_legacyType; diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index a8ff14e98e..c84bb557d1 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -536,7 +536,7 @@ private: auto foundObject = objectRepository.FindObject(objectName); if (foundObject != nullptr) { - ObjectType objectType = foundObject->ObjectEntry.GetType(); + auto objectType = foundObject->Type; switch (objectType) { case ObjectType::SmallScenery: