From 5dda84c89117be95d954d2b1afe187e360e09139 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sat, 1 Feb 2025 16:52:39 +0100 Subject: [PATCH] Implement scaffolding for climate objects --- data/language/en-GB.txt | 1 + .../windows/EditorObjectSelection.cpp | 20 ++++++++----- src/openrct2/interface/InteractiveConsole.cpp | 1 + src/openrct2/libopenrct2.vcxproj | 2 ++ src/openrct2/localisation/StringIds.h | 2 ++ src/openrct2/object/ClimateObject.cpp | 30 +++++++++++++++++++ src/openrct2/object/ClimateObject.h | 24 +++++++++++++++ src/openrct2/object/DefaultObjects.cpp | 3 ++ src/openrct2/object/DefaultObjects.h | 2 +- src/openrct2/object/ObjectFactory.cpp | 6 ++++ src/openrct2/object/ObjectLimits.h | 1 + src/openrct2/object/ObjectList.cpp | 1 + src/openrct2/object/ObjectTypes.cpp | 3 +- src/openrct2/object/ObjectTypes.h | 3 +- 14 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 src/openrct2/object/ClimateObject.cpp create mode 100644 src/openrct2/object/ClimateObject.h diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 75d36380ad..6214a83538 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3801,3 +3801,4 @@ STR_6739 :{WINDOW_COLOUR_2}Date: {BLACK}{STRINGID} STR_6740 :{WINDOW_COLOUR_2}Cash: {BLACK}{CURRENCY2DP} STR_6741 :{WINDOW_COLOUR_2}Num. rides: {BLACK}{UINT16} STR_6742 :{WINDOW_COLOUR_2}Num. guests: {BLACK}{UINT16} +STR_6743 :Climate diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index e1ee3028d4..79195175e1 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -165,6 +165,7 @@ namespace OpenRCT2::Ui::Windows { STR_OBJECT_SELECTION_TERRAIN_SURFACES, ObjectType::terrainSurface, FILTER_NONE, SPR_G2_TAB_LAND, 1, 1 }, { STR_OBJECT_SELECTION_TERRAIN_EDGES, ObjectType::terrainEdge, FILTER_NONE, SPR_G2_TERRAIN_EDGE_TAB, 1, 1 }, { STR_OBJECT_SELECTION_WATER, ObjectType::water, FILTER_NONE, SPR_TAB_WATER, 1, 1 }, + { STR_OBJECT_SELECTION_CLIMATE, ObjectType::climate, FILTER_NONE, SPR_WEATHER_SUN_CLOUD, 1, 1 }, }; static ObjectSubTab kPeepObjectSubTabs[] = { @@ -173,13 +174,13 @@ namespace OpenRCT2::Ui::Windows }; static constexpr ObjectPageDesc ObjectSelectionPages[] = { - { STR_OBJECT_SELECTION_RIDE_VEHICLES_ATTRACTIONS, ObjectType::ride, SPR_TAB_RIDE_16, kRideObjectSubTabs }, - { STR_OBJECT_SELECTION_SCENERY_GROUPS, ObjectType::sceneryGroup, SPR_TAB_SCENERY_STATUES, kSceneryObjectSubTabs }, - { STR_OBJECT_SELECTION_FOOTPATH_SURFACES, ObjectType::footpathSurface, SPR_G2_LEGACY_PATH_TAB, kPathObjectSubTabs }, - { STR_OBJECT_SELECTION_PARK_ENTRANCE, ObjectType::parkEntrance, SPR_TAB_PARK, kEntrancesObjectSubTabs }, - { STR_OBJECT_SELECTION_TERRAIN_SURFACES, ObjectType::terrainSurface, SPR_G2_TAB_LAND, kTerrainObjectSubTabs }, - { STR_OBJECT_SELECTION_MUSIC, ObjectType::music, SPR_TAB_MUSIC_0, {} }, - { STR_OBJECT_SELECTION_PEEP_NAMES, ObjectType::peepNames, SPR_TAB_GUESTS_0, kPeepObjectSubTabs }, + { STR_OBJECT_SELECTION_RIDE_VEHICLES_ATTRACTIONS, ObjectType::ride, SPR_TAB_RIDE_16, kRideObjectSubTabs }, + { STR_OBJECT_SELECTION_SCENERY_GROUPS, ObjectType::sceneryGroup, SPR_TAB_SCENERY_STATUES, kSceneryObjectSubTabs }, + { STR_OBJECT_SELECTION_FOOTPATH_SURFACES, ObjectType::footpathSurface, SPR_G2_LEGACY_PATH_TAB, kPathObjectSubTabs }, + { STR_OBJECT_SELECTION_PARK_ENTRANCE, ObjectType::parkEntrance, SPR_TAB_PARK, kEntrancesObjectSubTabs }, + { STR_OBJECT_SELECTION_TERRAIN_SURFACES, ObjectType::terrainSurface, SPR_G2_MAP_GEN_TERRAIN_TAB, kTerrainObjectSubTabs }, + { STR_OBJECT_SELECTION_MUSIC, ObjectType::music, SPR_TAB_MUSIC_0, {} }, + { STR_OBJECT_SELECTION_PEEP_NAMES, ObjectType::peepNames, SPR_TAB_GUESTS_0, kPeepObjectSubTabs }, }; // clang-format on @@ -1021,7 +1022,6 @@ namespace OpenRCT2::Ui::Windows continue; auto& subTabDef = currentPage.subTabs[i]; - int32_t spriteIndex = subTabDef.baseImage; int32_t frame = 0; if (subTabDef.animationLength > 1 && _selectedSubTab == i) { @@ -1029,12 +1029,16 @@ namespace OpenRCT2::Ui::Windows } // TODO: generalise this? + int32_t spriteIndex = subTabDef.baseImage; if (currentPage.Caption == STR_OBJECT_SELECTION_RIDE_VEHICLES_ATTRACTIONS && i == 4) spriteIndex += kThrillRidesTabAnimationSequence[frame]; else spriteIndex += frame; auto screenPos = windowPos + ScreenCoordsXY{ widget.left, widget.top }; + if (spriteIndex == SPR_WEATHER_SUN_CLOUD) + screenPos += { 2, 4 }; + GfxDrawSprite(dpi, ImageId(spriteIndex, colours[1].colour), screenPos); } } diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 0ab5732b0b..5aafff73fd 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -1171,6 +1171,7 @@ constexpr auto _objectTypeNames = std::to_array({ STR_OBJECT_SELECTION_MUSIC, STR_OBJECT_SELECTION_PEEP_NAMES, STR_OBJECT_SELECTION_PEEP_ANIMATIONS, + STR_OBJECT_SELECTION_CLIMATE, }); static_assert(_objectTypeNames.size() == EnumValue(ObjectType::count)); diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 567a99d60e..6e387fc8d8 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -327,6 +327,7 @@ + @@ -872,6 +873,7 @@ + diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index eca57ead66..91427aef25 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -1724,6 +1724,8 @@ enum : StringId STR_DIVE_LOOP_LEFT = 6727, STR_DIVE_LOOP_RIGHT = 6728, + STR_OBJECT_SELECTION_CLIMATE = 6743, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working /* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings }; diff --git a/src/openrct2/object/ClimateObject.cpp b/src/openrct2/object/ClimateObject.cpp new file mode 100644 index 0000000000..8622b03d7b --- /dev/null +++ b/src/openrct2/object/ClimateObject.cpp @@ -0,0 +1,30 @@ +/***************************************************************************** + * Copyright (c) 2014-2025 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 "ClimateObject.h" + +#include "../core/Guard.hpp" +#include "../core/IStream.hpp" +#include "../core/Json.hpp" + +using namespace OpenRCT2; + +void ClimateObject::Load() +{ +} + +void ClimateObject::Unload() +{ +} + +void ClimateObject::ReadJson(IReadObjectContext* context, json_t& root) +{ + Guard::Assert(root.is_object(), "ClimateObject::ReadJson expects parameter root to be an object"); + PopulateTablesFromJson(context, root); +} diff --git a/src/openrct2/object/ClimateObject.h b/src/openrct2/object/ClimateObject.h new file mode 100644 index 0000000000..bc2ebe9295 --- /dev/null +++ b/src/openrct2/object/ClimateObject.h @@ -0,0 +1,24 @@ +/***************************************************************************** + * Copyright (c) 2014-2025 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 "Object.h" + +struct IReadObjectContext; + +class ClimateObject final : public Object +{ +public: + static constexpr ObjectType kObjectType = ObjectType::climate; + + void ReadJson(IReadObjectContext* context, json_t& root) override; + void Load() override; + void Unload() override; +}; diff --git a/src/openrct2/object/DefaultObjects.cpp b/src/openrct2/object/DefaultObjects.cpp index c91af29341..4decf215b7 100644 --- a/src/openrct2/object/DefaultObjects.cpp +++ b/src/openrct2/object/DefaultObjects.cpp @@ -153,6 +153,9 @@ const std::string_view DefaultSelectedObjects[] = { "rct2.peep_animations.handyman", "rct2.peep_animations.mechanic", "rct2.peep_animations.security", + + // Climate object + "rct2.climate.warm", }; const std::string_view DesignerSelectedObjects[] = { diff --git a/src/openrct2/object/DefaultObjects.h b/src/openrct2/object/DefaultObjects.h index dc8c378179..4f43c4b25f 100644 --- a/src/openrct2/object/DefaultObjects.h +++ b/src/openrct2/object/DefaultObjects.h @@ -12,5 +12,5 @@ #include "Object.h" extern const std::string_view MinimumRequiredObjects[2]; -extern const std::string_view DefaultSelectedObjects[119]; +extern const std::string_view DefaultSelectedObjects[120]; extern const std::string_view DesignerSelectedObjects[39]; diff --git a/src/openrct2/object/ObjectFactory.cpp b/src/openrct2/object/ObjectFactory.cpp index 33b625675f..627c3e901e 100644 --- a/src/openrct2/object/ObjectFactory.cpp +++ b/src/openrct2/object/ObjectFactory.cpp @@ -26,6 +26,7 @@ #include "../rct12/SawyerChunkReader.h" #include "AudioObject.h" #include "BannerObject.h" +#include "ClimateObject.h" #include "EntranceObject.h" #include "FootpathObject.h" #include "FootpathRailingsObject.h" @@ -394,6 +395,9 @@ namespace OpenRCT2::ObjectFactory case ObjectType::peepAnimations: result = std::make_unique(); break; + case ObjectType::climate: + result = std::make_unique(); + break; default: throw std::runtime_error("Invalid object type"); } @@ -440,6 +444,8 @@ namespace OpenRCT2::ObjectFactory return ObjectType::peepNames; if (s == "peep_animations") return ObjectType::peepAnimations; + if (s == "climate") + return ObjectType::climate; return ObjectType::none; } diff --git a/src/openrct2/object/ObjectLimits.h b/src/openrct2/object/ObjectLimits.h index 634a450de4..51ae09fd5e 100644 --- a/src/openrct2/object/ObjectLimits.h +++ b/src/openrct2/object/ObjectLimits.h @@ -33,5 +33,6 @@ constexpr uint16_t kMaxFootpathRailingsObjects = 255; constexpr uint16_t kMaxAudioObjects = 255; constexpr uint16_t kMaxPeepNamesObjects = 1; constexpr uint16_t kMaxPeepAnimationsObjects = 255; +constexpr uint16_t kMaxClimateObjects = 1; constexpr uint8_t kDatNameLength = 8; diff --git a/src/openrct2/object/ObjectList.cpp b/src/openrct2/object/ObjectList.cpp index db3379afa9..b5d83f0227 100644 --- a/src/openrct2/object/ObjectList.cpp +++ b/src/openrct2/object/ObjectList.cpp @@ -37,6 +37,7 @@ static constexpr std::array kObjectEntryG kMaxTerrainSurfaceObjects, kMaxTerrainEdgeObjects, kMaxStationObjects, kMaxMusicObjects, kMaxFootpathSurfaceObjects, kMaxFootpathRailingsObjects, kMaxAudioObjects, kMaxPeepNamesObjects, kMaxPeepAnimationsObjects, + kMaxClimateObjects, }; static_assert(std::size(kObjectEntryGroupCounts) == EnumValue(ObjectType::count)); diff --git a/src/openrct2/object/ObjectTypes.cpp b/src/openrct2/object/ObjectTypes.cpp index 38e4a5e934..b7ccee39c0 100644 --- a/src/openrct2/object/ObjectTypes.cpp +++ b/src/openrct2/object/ObjectTypes.cpp @@ -35,6 +35,7 @@ constexpr std::array kAllObjectTypes = { ObjectType::audio, ObjectType::peepNames, ObjectType::peepAnimations, + ObjectType::climate, }; static_assert(kAllObjectTypes.size() == EnumValue(ObjectType::count)); @@ -45,7 +46,7 @@ static constexpr std::array kTransie ObjectType::banners, ObjectType::paths, ObjectType::pathAdditions, ObjectType::sceneryGroup, ObjectType::parkEntrance, ObjectType::water, ObjectType::terrainSurface, ObjectType::terrainEdge, ObjectType::station, ObjectType::music, ObjectType::footpathSurface, ObjectType::footpathRailings, - ObjectType::peepNames, ObjectType::peepAnimations, + ObjectType::peepNames, ObjectType::peepAnimations, ObjectType::climate, }; // Object types that cannot be saved in a park file. diff --git a/src/openrct2/object/ObjectTypes.h b/src/openrct2/object/ObjectTypes.h index d7428e1bd2..247f796dae 100644 --- a/src/openrct2/object/ObjectTypes.h +++ b/src/openrct2/object/ObjectTypes.h @@ -41,12 +41,13 @@ enum class ObjectType : uint8_t audio, peepNames, peepAnimations, + climate, count, none = 255 }; -static constexpr size_t kNumTransientObjectTypes = 18; +static constexpr size_t kNumTransientObjectTypes = 19; static constexpr size_t kNumIntransientObjectTypes = 2; bool ObjectTypeIsTransient(ObjectType type);