From b3bbdcbfd53b38e7a7966c4d11801e6ed681e2d3 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 27 Mar 2021 13:48:27 +0100 Subject: [PATCH] Remove hardcoded terrain style constants from RCT1 and MapGen --- .../windows/EditorObjectSelection.cpp | 2 +- src/openrct2-ui/windows/InstallTrack.cpp | 2 +- src/openrct2-ui/windows/MapGen.cpp | 4 +- src/openrct2/CmdlineSprite.cpp | 2 +- src/openrct2/interface/InteractiveConsole.cpp | 2 +- src/openrct2/object/Object.cpp | 15 +++ src/openrct2/object/Object.h | 3 + src/openrct2/object/ObjectManager.cpp | 18 ++- src/openrct2/object/ObjectManager.h | 7 +- src/openrct2/object/TerrainEdgeObject.cpp | 14 ++ src/openrct2/object/TerrainEdgeObject.h | 2 + src/openrct2/object/TerrainSurfaceObject.cpp | 14 ++ src/openrct2/object/TerrainSurfaceObject.h | 2 + .../paint/tile_element/Paint.Surface.cpp | 8 +- src/openrct2/rct1/RCT1.h | 2 + src/openrct2/rct1/Tables.cpp | 90 +++++++------ src/openrct2/rct1/Tables.h | 4 +- src/openrct2/ride/TrackDesign.cpp | 4 +- src/openrct2/world/Map.cpp | 8 +- src/openrct2/world/MapGen.cpp | 122 ++++++++++-------- 20 files changed, 204 insertions(+), 121 deletions(-) diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index f96e268cb2..fe38730113 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -1298,7 +1298,7 @@ static void editor_load_selected_objects() { const ObjectRepositoryItem* item = &items[i]; const rct_object_entry* entry = &item->ObjectEntry; - void* loadedObject = object_manager_get_loaded_object(entry); + const auto* loadedObject = object_manager_get_loaded_object(ObjectEntryDescriptor(*item)); if (loadedObject == nullptr) { loadedObject = object_manager_load_object(entry); diff --git a/src/openrct2-ui/windows/InstallTrack.cpp b/src/openrct2-ui/windows/InstallTrack.cpp index 992e619a4b..8dec3f851c 100644 --- a/src/openrct2-ui/windows/InstallTrack.cpp +++ b/src/openrct2-ui/windows/InstallTrack.cpp @@ -242,7 +242,7 @@ static void window_install_track_paint(rct_window* w, rct_drawpixelinfo* dpi) { auto ft = Formatter(); - void* objectEntry = object_manager_load_object(&td6->vehicle_object); + const auto* objectEntry = object_manager_load_object(&td6->vehicle_object); if (objectEntry != nullptr) { auto groupIndex = object_manager_get_loaded_object_entry_index(objectEntry); diff --git a/src/openrct2-ui/windows/MapGen.cpp b/src/openrct2-ui/windows/MapGen.cpp index 0acc3d61a4..f6bd1cb2ee 100644 --- a/src/openrct2-ui/windows/MapGen.cpp +++ b/src/openrct2-ui/windows/MapGen.cpp @@ -421,8 +421,8 @@ static void window_mapgen_draw_tab_images(rct_drawpixelinfo* dpi, rct_window* w) static int32_t _mapSize = 150; static int32_t _baseHeight = 12; static int32_t _waterLevel = 6; -static int32_t _floorTexture = TERRAIN_GRASS; -static int32_t _wallTexture = TERRAIN_EDGE_ROCK; +static int32_t _floorTexture = 0; +static int32_t _wallTexture = 0; static bool _randomTerrain = true; static int32_t _placeTrees = 1; diff --git a/src/openrct2/CmdlineSprite.cpp b/src/openrct2/CmdlineSprite.cpp index 9c4a7daa9d..8d44a95546 100644 --- a/src/openrct2/CmdlineSprite.cpp +++ b/src/openrct2/CmdlineSprite.cpp @@ -436,7 +436,7 @@ int32_t cmdline_for_sprite(const char** argv, int32_t argc) } const rct_object_entry* entry = &ori->ObjectEntry; - void* loadedObject = object_manager_load_object(entry); + const auto* loadedObject = object_manager_load_object(entry); if (loadedObject == nullptr) { fprintf(stderr, "Unable to load object.\n"); diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index c7bb455dc3..634ef1d91f 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -1071,7 +1071,7 @@ static int32_t cc_load_object(InteractiveConsole& console, const arguments_t& ar } const rct_object_entry* entry = &ori->ObjectEntry; - void* loadedObject = object_manager_get_loaded_object(entry); + const auto* loadedObject = object_manager_get_loaded_object(ObjectEntryDescriptor(*ori)); if (loadedObject != nullptr) { console.WriteLineError("Object is already in scenario."); diff --git a/src/openrct2/object/Object.cpp b/src/openrct2/object/Object.cpp index 7c1d400bd4..a4ef63fc9e 100644 --- a/src/openrct2/object/Object.cpp +++ b/src/openrct2/object/Object.cpp @@ -20,6 +20,7 @@ #include "../localisation/StringIds.h" #include "../world/Scenery.h" #include "ObjectLimits.h" +#include "ObjectRepository.h" #include #include @@ -301,6 +302,20 @@ std::unique_ptr ObjectAsset::GetStream() const return {}; } +ObjectEntryDescriptor::ObjectEntryDescriptor(const ObjectRepositoryItem& ori) +{ + if (ori.Identifier != "") + { + Generation = ObjectGeneration::JSON; + Identifier = std::string(ori.Identifier); + } + else + { + Generation = ObjectGeneration::DAT; + Entry = ori.ObjectEntry; + } +} + #ifdef __WARN_SUGGEST_FINAL_METHODS__ # pragma GCC diagnostic pop #endif diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index 03c91e7966..47e9ee87d5 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -22,6 +22,7 @@ using ObjectEntryIndex = uint16_t; constexpr const ObjectEntryIndex OBJECT_ENTRY_INDEX_NULL = std::numeric_limits::max(); +struct ObjectRepositoryItem; // First 0xF of rct_object_entry->flags enum class ObjectType : uint8_t @@ -180,6 +181,8 @@ struct ObjectEntryDescriptor Generation = ObjectGeneration::JSON; Identifier = std::string(newIdentifier); } + + explicit ObjectEntryDescriptor(const ObjectRepositoryItem& ori); }; struct IObjectRepository; diff --git a/src/openrct2/object/ObjectManager.cpp b/src/openrct2/object/ObjectManager.cpp index 079637aff0..0ca24b767e 100644 --- a/src/openrct2/object/ObjectManager.cpp +++ b/src/openrct2/object/ObjectManager.cpp @@ -816,26 +816,30 @@ Object* object_manager_get_loaded_object_by_index(size_t index) return loadedObject; } -Object* object_manager_get_loaded_object(const rct_object_entry* entry) +Object* object_manager_get_loaded_object(const ObjectEntryDescriptor& entry) { auto& objectManager = OpenRCT2::GetContext()->GetObjectManager(); - Object* loadedObject = objectManager.GetLoadedObject(ObjectEntryDescriptor(*entry)); + Object* loadedObject = objectManager.GetLoadedObject(entry); return loadedObject; } -ObjectEntryIndex object_manager_get_loaded_object_entry_index(const void* loadedObject) +ObjectEntryIndex object_manager_get_loaded_object_entry_index(const Object* loadedObject) { auto& objectManager = OpenRCT2::GetContext()->GetObjectManager(); - const Object* object = static_cast(loadedObject); - auto entryIndex = objectManager.GetLoadedObjectEntryIndex(object); + auto entryIndex = objectManager.GetLoadedObjectEntryIndex(loadedObject); return entryIndex; } -void* object_manager_load_object(const rct_object_entry* entry) +ObjectEntryIndex object_manager_get_loaded_object_entry_index(const ObjectEntryDescriptor& entry) +{ + return object_manager_get_loaded_object_entry_index(object_manager_get_loaded_object(entry)); +} + +Object* object_manager_load_object(const rct_object_entry* entry) { auto& objectManager = OpenRCT2::GetContext()->GetObjectManager(); Object* loadedObject = objectManager.LoadObject(entry); - return static_cast(loadedObject); + return loadedObject; } void object_manager_unload_objects(const std::vector& entries) diff --git a/src/openrct2/object/ObjectManager.h b/src/openrct2/object/ObjectManager.h index c8ee13d853..37f54cfb05 100644 --- a/src/openrct2/object/ObjectManager.h +++ b/src/openrct2/object/ObjectManager.h @@ -46,9 +46,10 @@ struct IObjectManager std::unique_ptr CreateObjectManager(IObjectRepository& objectRepository); Object* object_manager_get_loaded_object_by_index(size_t index); -Object* object_manager_get_loaded_object(const rct_object_entry* entry); -ObjectEntryIndex object_manager_get_loaded_object_entry_index(const void* loadedObject); -void* object_manager_load_object(const rct_object_entry* entry); +Object* object_manager_get_loaded_object(const ObjectEntryDescriptor& entry); +ObjectEntryIndex object_manager_get_loaded_object_entry_index(const Object* loadedObject); +ObjectEntryIndex object_manager_get_loaded_object_entry_index(const ObjectEntryDescriptor& entry); +Object* object_manager_load_object(const rct_object_entry* entry); void object_manager_unload_objects(const std::vector& entries); void object_manager_unload_all_objects(); rct_string_id object_manager_get_source_game_string(const ObjectSourceGame sourceGame); diff --git a/src/openrct2/object/TerrainEdgeObject.cpp b/src/openrct2/object/TerrainEdgeObject.cpp index 3e26972f03..ae45c86596 100644 --- a/src/openrct2/object/TerrainEdgeObject.cpp +++ b/src/openrct2/object/TerrainEdgeObject.cpp @@ -9,11 +9,13 @@ #include "TerrainEdgeObject.h" +#include "../Context.h" #include "../core/IStream.hpp" #include "../core/Json.hpp" #include "../core/String.hpp" #include "../drawing/Drawing.h" #include "../localisation/Localisation.h" +#include "ObjectManager.h" void TerrainEdgeObject::Load() { @@ -58,3 +60,15 @@ void TerrainEdgeObject::ReadJson(IReadObjectContext* context, json_t& root) PopulateTablesFromJson(context, root); NumImagesLoaded = GetImageTable().GetCount(); } + +TerrainEdgeObject* TerrainEdgeObject::GetById(ObjectEntryIndex entryIndex) +{ + TerrainEdgeObject* result = nullptr; + auto& objMgr = OpenRCT2::GetContext()->GetObjectManager(); + auto obj = objMgr.GetLoadedObject(ObjectType::TerrainSurface, entryIndex); + if (obj != nullptr) + { + result = static_cast(obj); + } + return result; +} diff --git a/src/openrct2/object/TerrainEdgeObject.h b/src/openrct2/object/TerrainEdgeObject.h index f275736b7e..d55fb84d42 100644 --- a/src/openrct2/object/TerrainEdgeObject.h +++ b/src/openrct2/object/TerrainEdgeObject.h @@ -31,4 +31,6 @@ public: void Unload() override; void DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const override; + + static TerrainEdgeObject* GetById(ObjectEntryIndex entryIndex); }; diff --git a/src/openrct2/object/TerrainSurfaceObject.cpp b/src/openrct2/object/TerrainSurfaceObject.cpp index 26dda7ca95..443c385311 100644 --- a/src/openrct2/object/TerrainSurfaceObject.cpp +++ b/src/openrct2/object/TerrainSurfaceObject.cpp @@ -11,12 +11,14 @@ #include "TerrainSurfaceObject.h" +#include "../Context.h" #include "../core/IStream.hpp" #include "../core/Json.hpp" #include "../core/String.hpp" #include "../drawing/Drawing.h" #include "../localisation/Localisation.h" #include "../world/Location.hpp" +#include "ObjectManager.h" void TerrainSurfaceObject::Load() { @@ -145,3 +147,15 @@ uint32_t TerrainSurfaceObject::GetImageId( } return EntryBaseImageId + (result * NUM_IMAGES_IN_ENTRY) + offset; } + +TerrainSurfaceObject* TerrainSurfaceObject::GetById(ObjectEntryIndex entryIndex) +{ + TerrainSurfaceObject* result = nullptr; + auto& objMgr = OpenRCT2::GetContext()->GetObjectManager(); + auto obj = objMgr.GetLoadedObject(ObjectType::TerrainSurface, entryIndex); + if (obj != nullptr) + { + result = static_cast(obj); + } + return result; +} diff --git a/src/openrct2/object/TerrainSurfaceObject.h b/src/openrct2/object/TerrainSurfaceObject.h index 85a53afa97..c273ad42d6 100644 --- a/src/openrct2/object/TerrainSurfaceObject.h +++ b/src/openrct2/object/TerrainSurfaceObject.h @@ -69,4 +69,6 @@ public: uint32_t GetImageId( const CoordsXY& position, int32_t length, int32_t rotation, int32_t offset, bool grid, bool underground) const; + + static TerrainSurfaceObject* GetById(ObjectEntryIndex entryIndex); }; diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index f3aab4c743..e79a308e9e 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -304,7 +304,7 @@ static const TerrainSurfaceObject* get_surface_object(size_t index) } static uint32_t get_surface_image( - const paint_session* session, uint8_t index, int32_t offset, uint8_t rotation, int32_t grassLength, bool grid, + 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. @@ -971,7 +971,7 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c const auto zoomLevel = dpi->zoom_level; const uint8_t rotation = session->CurrentRotation; - const uint32_t terrain_type = tileElement->AsSurface()->GetSurfaceStyle(); + const auto terrain_type = tileElement->AsSurface()->GetSurfaceStyle(); const uint8_t surfaceShape = viewport_surface_paint_setup_get_relative_slope(tileElement, rotation); const CoordsXY& base = session->SpritePosition; const corner_height& cornerHeights = corner_heights[surfaceShape]; @@ -1279,8 +1279,8 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c if (!(session->ViewFlags & VIEWPORT_FLAG_HIDE_VERTICAL)) { - const uint32_t edgeStyle = tileElement->AsSurface()->GetEdgeStyle(); - if (edgeStyle >= TERRAIN_EDGE_COUNT) + const auto edgeStyle = tileElement->AsSurface()->GetEdgeStyle(); + if (static_cast(edgeStyle) >= object_entry_group_counts[EnumValue(ObjectType::TerrainEdge)]) { log_verbose("edgeStyle: %d", edgeStyle); } diff --git a/src/openrct2/rct1/RCT1.h b/src/openrct2/rct1/RCT1.h index 94d3e916f7..3e759b6ce8 100644 --- a/src/openrct2/rct1/RCT1.h +++ b/src/openrct2/rct1/RCT1.h @@ -30,6 +30,8 @@ constexpr const uint8_t RCT1_MAX_BANNERS = 100; constexpr int32_t RCT1_COORDS_Z_STEP = 4; constexpr const uint32_t RCT1_NUM_LL_CSG_ENTRIES = 69917; constexpr const uint32_t RCT1_LL_CSG1_DAT_FILE_SIZE = 41402869; +constexpr const uint32_t RCT1_NUM_TERRAIN_SURFACES = 16; +constexpr const uint32_t RCT1_NUM_TERRAIN_EDGES = 15; struct ParkLoadResult; diff --git a/src/openrct2/rct1/Tables.cpp b/src/openrct2/rct1/Tables.cpp index b0882fd014..f86d9364ab 100644 --- a/src/openrct2/rct1/Tables.cpp +++ b/src/openrct2/rct1/Tables.cpp @@ -12,6 +12,7 @@ #include "../common.h" #include "../core/Guard.hpp" #include "../interface/Colour.h" +#include "../object/ObjectManager.h" #include "../ride/Ride.h" #include "../ride/RideData.h" #include "../world/Surface.h" @@ -115,54 +116,63 @@ namespace RCT1 return map[rct1SpriteType]; } - uint8_t GetTerrain(uint8_t terrain) + ObjectEntryIndex GetTerrain(uint8_t terrainSurface) { - static constexpr const uint8_t map[] = + static constexpr const char* map[RCT1_NUM_TERRAIN_SURFACES] = { - TERRAIN_GRASS, - TERRAIN_SAND, - TERRAIN_DIRT, - TERRAIN_ROCK, - TERRAIN_MARTIAN, - TERRAIN_CHECKERBOARD, - TERRAIN_GRASS_CLUMPS, - TERRAIN_ROOF_BROWN, - TERRAIN_ICE, - TERRAIN_ROOF_LOG, - TERRAIN_ROOF_IRON, - TERRAIN_ROOF_GREY, - TERRAIN_GRID_RED, - TERRAIN_GRID_YELLOW, - TERRAIN_GRID_BLUE, - TERRAIN_GRID_GREEN + "rct2.surface.grass", + "rct2.surface.sand", + "rct2.surface.dirt", + "rct2.surface.rock", + "rct2.surface.martian", + "rct2.surface.chequerboard", + "rct2.surface.grassclumps", + "rct1.aa.surface.roofred", + "rct2.surface.ice", + "rct1.ll.surface.wood", + "rct1.ll.surface.rust", + "rct1.ll.surface.roofgrey", + "rct2.surface.gridred", + "rct2.surface.gridyellow", + "rct2.surface.gridpurple", + "rct2.surface.gridgreen", }; - Guard::ArgumentInRange(terrain, 0, std::size(map), "Unsupported RCT1 terrain type."); - return map[terrain]; + std::string selectedSurface = "rct2.surface.grass"; + if (terrainSurface < std::size(map)) + { + selectedSurface = map[terrainSurface]; + } + + return object_manager_get_loaded_object_entry_index(ObjectEntryDescriptor(selectedSurface)); } - uint8_t GetTerrainEdge(uint8_t terrainEdge) + ObjectEntryIndex GetTerrainEdge(uint8_t terrainEdge) { - static constexpr const uint8_t map[] = + static constexpr const char* map[RCT1_NUM_TERRAIN_EDGES] = { - TERRAIN_EDGE_ROCK, // rct2.edge.rock - TERRAIN_EDGE_BRICK, // rct1.edge.brick - TERRAIN_EDGE_IRON, // rct1.edge.iron - TERRAIN_EDGE_WOOD_RED, // rct2.edge.woodred - TERRAIN_EDGE_GREY, // rct1.aa.edge.grey - TERRAIN_EDGE_YELLOW, // rct1.aa.edge.yellow - TERRAIN_EDGE_WOOD_BLACK, // rct2.edge.woodblack - TERRAIN_EDGE_RED, // rct1.aa.edge.red - TERRAIN_EDGE_ICE, // rct2.edge.ice - TERRAIN_EDGE_PURPLE, // rct1.ll.edge.purple - TERRAIN_EDGE_GREEN, // rct1.ll.edge.green - TERRAIN_EDGE_STONE_BROWN, // rct1.ll.edge.stonebrown - TERRAIN_EDGE_STONE_GREY, // rct1.ll.edge.stonegrey - TERRAIN_EDGE_SKYSCRAPER_A, // rct1.ll.edge.skyscrapera - TERRAIN_EDGE_SKYSCRAPER_B, // rct1.ll.edge.skyscraperb - TERRAIN_EDGE_ROCK // rct2.edge.rock (Unused) + "rct2.edge.rock", + "rct1.edge.brick", + "rct1.edge.iron", + "rct2.edge.woodred", + "rct1.aa.edge.grey", + "rct1.aa.edge.yellow", + "rct2.edge.woodblack", + "rct1.aa.edge.red", + "rct2.edge.ice", + "rct1.ll.edge.purple", + "rct1.ll.edge.green", + "rct1.ll.edge.stonebrown", + "rct1.ll.edge.stonegrey", + "rct1.ll.edge.skyscrapera", + "rct1.ll.edge.skyscraperb", }; - Guard::ArgumentInRange(terrainEdge, 0, std::size(map), "Unsupported RCT1 terrain edge."); - return map[terrainEdge]; + std::string selectedEdge = "rct2.edge.rock"; + if (terrainEdge < std::size(map)) + { + selectedEdge = map[terrainEdge]; + } + + return object_manager_get_loaded_object_entry_index(ObjectEntryDescriptor(selectedEdge)); } uint8_t GetRideType(uint8_t rideType, uint8_t vehicleType) diff --git a/src/openrct2/rct1/Tables.h b/src/openrct2/rct1/Tables.h index 708fbadeb9..acb0db2006 100644 --- a/src/openrct2/rct1/Tables.h +++ b/src/openrct2/rct1/Tables.h @@ -23,8 +23,8 @@ namespace RCT1 colour_t GetColour(colour_t colour); PeepSpriteType GetPeepSpriteType(uint8_t rct1SpriteType); - uint8_t GetTerrain(uint8_t terrain); - uint8_t GetTerrainEdge(uint8_t terrainEdge); + ObjectEntryIndex GetTerrain(uint8_t terrain); + ObjectEntryIndex GetTerrainEdge(uint8_t terrainEdge); uint8_t GetRideType(uint8_t rideType, uint8_t vehicleType); RCT1VehicleColourSchemeCopyDescriptor GetColourSchemeCopyDescriptor(uint8_t vehicleType); diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 57bdd88321..8338af9e42 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -2144,8 +2144,8 @@ static void track_design_preview_clear_map() tile_element->SetLastForTile(true); tile_element->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT); tile_element->AsSurface()->SetWaterHeight(0); - tile_element->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS); - tile_element->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK); + tile_element->AsSurface()->SetSurfaceStyle(0); + tile_element->AsSurface()->SetEdgeStyle(0); tile_element->AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0); tile_element->AsSurface()->SetOwnership(OWNERSHIP_OWNED); tile_element->AsSurface()->SetParkFences(0); diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 9b1be4a87f..c11694c9c3 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -268,8 +268,8 @@ void map_init(int32_t size) tile_element->AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0); tile_element->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED); tile_element->AsSurface()->SetParkFences(0); - tile_element->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS); - tile_element->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK); + tile_element->AsSurface()->SetSurfaceStyle(0); + tile_element->AsSurface()->SetEdgeStyle(0); } gGrassSceneryTileLoopPosition = 0; @@ -1682,8 +1682,8 @@ static void clear_element_at(const CoordsXY& loc, TileElement** elementPtr) element->clearance_height = MINIMUM_LAND_HEIGHT; element->owner = 0; element->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT); - element->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS); - element->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK); + element->AsSurface()->SetSurfaceStyle(0); + element->AsSurface()->SetEdgeStyle(0); element->AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0); element->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED); element->AsSurface()->SetParkFences(0); diff --git a/src/openrct2/world/MapGen.cpp b/src/openrct2/world/MapGen.cpp index 548af4f5e9..42f3410e64 100644 --- a/src/openrct2/world/MapGen.cpp +++ b/src/openrct2/world/MapGen.cpp @@ -18,6 +18,9 @@ #include "../localisation/Localisation.h" #include "../localisation/StringIds.h" #include "../object/Object.h" +#include "../object/ObjectManager.h" +#include "../object/TerrainEdgeObject.h" +#include "../object/TerrainSurfaceObject.h" #include "../platform/platform.h" #include "../util/Util.h" #include "Map.h" @@ -82,7 +85,8 @@ static constexpr const char* SnowTrees[] = { #pragma endregion // Randomly chosen base terrains. We rarely want a whole map made out of chequerboard or rock. -static constexpr const uint8_t BaseTerrain[] = { TERRAIN_GRASS, TERRAIN_SAND, TERRAIN_SAND_LIGHT, TERRAIN_DIRT, TERRAIN_ICE }; +static constexpr const std::string_view BaseTerrain[] = { "rct2.surface.grass", "rct2.surface.sand", "rct2.surface.sandbrown", + "rct2.surface.dirt", "rct2.surface.ice" }; static void mapgen_place_trees(); static void mapgen_set_water_level(int32_t waterLevel); @@ -134,46 +138,43 @@ void mapgen_generate_blank(mapgen_settings* settings) void mapgen_generate(mapgen_settings* settings) { - int32_t x, y, mapSize, floorTexture, wallTexture, waterLevel; + auto mapSize = settings->mapSize; + auto waterLevel = settings->water_level; + const auto selectedFloor = TerrainSurfaceObject::GetById(settings->floor); + std::string floorTexture = selectedFloor != nullptr ? std::string(selectedFloor->GetIdentifier()) : ""; + const auto selectedEdge = TerrainEdgeObject::GetById(settings->wall); + std::string edgeTexture = selectedFloor != nullptr ? std::string(selectedEdge->GetIdentifier()) : ""; - mapSize = settings->mapSize; - floorTexture = settings->floor; - wallTexture = settings->wall; - waterLevel = settings->water_level; - - if (floorTexture == -1) + if (floorTexture == "") floorTexture = BaseTerrain[util_rand() % std::size(BaseTerrain)]; - if (wallTexture == -1) + if (edgeTexture == "") { // Base edge type on surface type - switch (floorTexture) - { - case TERRAIN_DIRT: - wallTexture = TERRAIN_EDGE_WOOD_RED; - break; - case TERRAIN_ICE: - wallTexture = TERRAIN_EDGE_ICE; - break; - default: - wallTexture = TERRAIN_EDGE_ROCK; - break; - } + if (floorTexture == "rct2.surface.dirt") + edgeTexture = "rct2.edge.woodred"; + else if (floorTexture == "rct2.surface.ice") + edgeTexture = "rct2.edge.ice"; + else + edgeTexture = "rct2.edge.rock"; } + auto floorTextureId = object_manager_get_loaded_object_entry_index(ObjectEntryDescriptor(floorTexture)); + auto edgeTextureId = object_manager_get_loaded_object_entry_index(ObjectEntryDescriptor(edgeTexture)); + map_clear_all_elements(); // Initialise the base map map_init(mapSize); - for (y = 1; y < mapSize - 1; y++) + for (auto y = 1; y < mapSize - 1; y++) { - for (x = 1; x < mapSize - 1; x++) + for (auto x = 1; x < mapSize - 1; x++) { auto surfaceElement = map_get_surface_element_at(TileCoordsXY{ x, y }.ToCoordsXY()); if (surfaceElement != nullptr) { - surfaceElement->SetSurfaceStyle(floorTexture); - surfaceElement->SetEdgeStyle(wallTexture); + surfaceElement->SetSurfaceStyle(floorTextureId); + surfaceElement->SetEdgeStyle(edgeTextureId); surfaceElement->base_height = settings->height; surfaceElement->clearance_height = settings->height; } @@ -201,27 +202,29 @@ void mapgen_generate(mapgen_settings* settings) mapgen_set_water_level(waterLevel); // Add sandy beaches - int32_t beachTexture = floorTexture; - if (settings->floor == -1 && floorTexture == TERRAIN_GRASS) + std::string beachTexture = std::string(floorTexture); + if (settings->floor == -1 && floorTexture == "rct2.surface.grass") { switch (util_rand() % 4) { case 0: - beachTexture = TERRAIN_SAND; + beachTexture = "rct2.surface.sand"; break; case 1: - beachTexture = TERRAIN_SAND_LIGHT; + beachTexture = "rct2.surface.sandbrown"; break; } } - for (y = 1; y < mapSize - 1; y++) + auto beachTextureId = object_manager_get_loaded_object_entry_index(ObjectEntryDescriptor(beachTexture)); + + for (auto y = 1; y < mapSize - 1; y++) { - for (x = 1; x < mapSize - 1; x++) + for (auto x = 1; x < mapSize - 1; x++) { auto surfaceElement = map_get_surface_element_at(TileCoordsXY{ x, y }.ToCoordsXY()); if (surfaceElement != nullptr && surfaceElement->base_height < waterLevel + 6) - surfaceElement->SetSurfaceStyle(beachTexture); + surfaceElement->SetSurfaceStyle(beachTextureId); } } @@ -252,6 +255,24 @@ static void mapgen_place_tree(int32_t type, const CoordsXY& loc) sceneryElement->SetPrimaryColour(COLOUR_YELLOW); } +static bool MapGenSurfaceTakesGrassTrees(const TerrainSurfaceObject& surface) +{ + const auto& id = surface.GetIdentifier(); + return id == "rct2.surface.grass" || id == "rct2.surface.grassclumps" || id == "rct2.surface.dirt"; +} + +static bool MapGenSurfaceTakesSandTrees(const TerrainSurfaceObject& surface) +{ + const auto& id = surface.GetIdentifier(); + return id == "rct2.surface.sand" || id == "rct2.surface.sandbrown" || id == "rct2.surface.sandred"; +} + +static bool MapGenSurfaceTakesSnowTrees(const TerrainSurfaceObject& surface) +{ + const auto& id = surface.GetIdentifier(); + return id == "rct2.surface.ice"; +} + /** * Randomly places a selection of preset trees on the map. Picks the right tree for the terrain it is placing it on. */ @@ -353,33 +374,28 @@ static void mapgen_place_trees() auto* surfaceElement = map_get_surface_element_at(pos.ToCoordsXY()); if (surfaceElement == nullptr) continue; - switch (surfaceElement->GetSurfaceStyle()) + const auto* object = TerrainSurfaceObject::GetById(surfaceElement->GetSurfaceStyle()); + if (MapGenSurfaceTakesGrassTrees(*object)) { - case TERRAIN_GRASS: - case TERRAIN_DIRT: - case TERRAIN_GRASS_CLUMPS: - if (grassTreeIds.empty()) - break; - - type = grassTreeIds[util_rand() % grassTreeIds.size()]; + if (grassTreeIds.empty()) break; - case TERRAIN_SAND: - case TERRAIN_SAND_DARK: - case TERRAIN_SAND_LIGHT: - if (desertTreeIds.empty()) - break; - - if (util_rand() % 4 == 0) - type = desertTreeIds[util_rand() % desertTreeIds.size()]; + type = grassTreeIds[util_rand() % grassTreeIds.size()]; + } + else if (MapGenSurfaceTakesSandTrees(*object)) + { + if (desertTreeIds.empty()) break; - case TERRAIN_ICE: - if (snowTreeIds.empty()) - break; - - type = snowTreeIds[util_rand() % snowTreeIds.size()]; + if (util_rand() % 4 == 0) + type = desertTreeIds[util_rand() % desertTreeIds.size()]; + } + else if (MapGenSurfaceTakesSnowTrees(*object)) + { + if (snowTreeIds.empty()) break; + + type = snowTreeIds[util_rand() % snowTreeIds.size()]; } if (type != -1)