mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #14397 from Gymnasiast/refactor/hardcoded-terrain-constants
Remove hardcoded terrain style constants from RCT1 and MapGen
This commit is contained in:
commit
9ee3c81768
|
@ -1299,7 +1299,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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "../localisation/StringIds.h"
|
||||
#include "../world/Scenery.h"
|
||||
#include "ObjectLimits.h"
|
||||
#include "ObjectRepository.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
@ -301,6 +302,20 @@ std::unique_ptr<IStream> ObjectAsset::GetStream() const
|
|||
return {};
|
||||
}
|
||||
|
||||
ObjectEntryDescriptor::ObjectEntryDescriptor(const ObjectRepositoryItem& ori)
|
||||
{
|
||||
if (!ori.Identifier.empty())
|
||||
{
|
||||
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
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
using ObjectEntryIndex = uint16_t;
|
||||
constexpr const ObjectEntryIndex OBJECT_ENTRY_INDEX_NULL = std::numeric_limits<ObjectEntryIndex>::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;
|
||||
|
|
|
@ -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<const Object*>(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<void*>(loadedObject);
|
||||
return loadedObject;
|
||||
}
|
||||
|
||||
void object_manager_unload_objects(const std::vector<rct_object_entry>& entries)
|
||||
|
|
|
@ -46,9 +46,10 @@ struct IObjectManager
|
|||
std::unique_ptr<IObjectManager> 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<rct_object_entry>& entries);
|
||||
void object_manager_unload_all_objects();
|
||||
rct_string_id object_manager_get_source_game_string(const ObjectSourceGame sourceGame);
|
||||
|
|
|
@ -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,10 @@ void TerrainEdgeObject::ReadJson(IReadObjectContext* context, json_t& root)
|
|||
PopulateTablesFromJson(context, root);
|
||||
NumImagesLoaded = GetImageTable().GetCount();
|
||||
}
|
||||
|
||||
TerrainEdgeObject* TerrainEdgeObject::GetById(ObjectEntryIndex entryIndex)
|
||||
{
|
||||
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
|
||||
auto obj = objMgr.GetLoadedObject(ObjectType::TerrainSurface, entryIndex);
|
||||
return obj != nullptr ? static_cast<TerrainEdgeObject*>(obj) : nullptr;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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,10 @@ uint32_t TerrainSurfaceObject::GetImageId(
|
|||
}
|
||||
return EntryBaseImageId + (result * NUM_IMAGES_IN_ENTRY) + offset;
|
||||
}
|
||||
|
||||
TerrainSurfaceObject* TerrainSurfaceObject::GetById(ObjectEntryIndex entryIndex)
|
||||
{
|
||||
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
|
||||
auto obj = objMgr.GetLoadedObject(ObjectType::TerrainSurface, entryIndex);
|
||||
return obj != nullptr ? static_cast<TerrainSurfaceObject*>(obj) : nullptr;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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<int32_t>(edgeStyle) >= object_entry_group_counts[EnumValue(ObjectType::TerrainEdge)])
|
||||
{
|
||||
log_verbose("edgeStyle: %d", edgeStyle);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 std::string_view 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<size_t>(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 std::string_view 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<size_t>(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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.empty())
|
||||
floorTexture = BaseTerrain[util_rand() % std::size(BaseTerrain)];
|
||||
|
||||
if (wallTexture == -1)
|
||||
if (edgeTexture.empty())
|
||||
{
|
||||
// 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)
|
||||
|
|
Loading…
Reference in New Issue