mirror of https://github.com/OpenRCT2/OpenRCT2.git
Implement omit of ghost tile elements when saving
This commit is contained in:
parent
c9b2e9fb55
commit
d0fbd4193a
|
@ -794,8 +794,7 @@ namespace OpenRCT2
|
|||
}
|
||||
else
|
||||
{
|
||||
ReorganiseTileElements();
|
||||
const auto& tileElements = GetTileElements();
|
||||
auto tileElements = GetReorganisedTileElementsWithoutGhosts();
|
||||
cs.Write(static_cast<uint32_t>(tileElements.size()));
|
||||
cs.Write(tileElements.data(), tileElements.size() * sizeof(TileElement));
|
||||
}
|
||||
|
|
|
@ -605,67 +605,6 @@ bool scenario_prepare_for_save()
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the given S6 data so that ghost elements, rides with no track elements or unused banners / user strings are saved.
|
||||
*/
|
||||
void scenario_fix_ghosts(rct_s6_data* s6)
|
||||
{
|
||||
// Build tile pointer cache (needed to get the first element at a certain location)
|
||||
RCT12TileElement* tilePointers[MAX_TILE_TILE_ELEMENT_POINTERS];
|
||||
for (size_t i = 0; i < MAX_TILE_TILE_ELEMENT_POINTERS; i++)
|
||||
{
|
||||
tilePointers[i] = TILE_UNDEFINED_TILE_ELEMENT;
|
||||
}
|
||||
|
||||
RCT12TileElement* tileElement = s6->tile_elements;
|
||||
RCT12TileElement** tile = tilePointers;
|
||||
for (size_t y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++)
|
||||
{
|
||||
for (size_t x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++)
|
||||
{
|
||||
*tile++ = tileElement;
|
||||
while (!(tileElement++)->IsLastForTile())
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all ghost elements
|
||||
RCT12TileElement* destinationElement = s6->tile_elements;
|
||||
|
||||
for (int32_t y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++)
|
||||
{
|
||||
for (int32_t x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++)
|
||||
{
|
||||
// This is the equivalent of map_get_first_element_at(x, y), but on S6 data.
|
||||
RCT12TileElement* originalElement = tilePointers[x + y * MAXIMUM_MAP_SIZE_TECHNICAL];
|
||||
do
|
||||
{
|
||||
if (originalElement->IsGhost())
|
||||
{
|
||||
uint8_t bannerIndex = originalElement->GetBannerIndex();
|
||||
if (bannerIndex != RCT12_BANNER_INDEX_NULL)
|
||||
{
|
||||
auto banner = &s6->banners[bannerIndex];
|
||||
if (banner->type != RCT12_OBJECT_ENTRY_INDEX_NULL)
|
||||
{
|
||||
banner->type = RCT12_OBJECT_ENTRY_INDEX_NULL;
|
||||
if (is_user_string_id(banner->string_idx))
|
||||
s6->custom_strings[(banner->string_idx % RCT12_MAX_USER_STRINGS)][0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*destinationElement++ = *originalElement;
|
||||
}
|
||||
} while (!(originalElement++)->IsLastForTile());
|
||||
|
||||
// Set last element flag in case the original last element was never added
|
||||
(destinationElement - 1)->flags |= TILE_ELEMENT_FLAG_LAST_TILE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ObjectiveStatus Objective::CheckGuestsBy() const
|
||||
{
|
||||
int16_t parkRating = gParkRating;
|
||||
|
|
|
@ -459,8 +459,6 @@ uint32_t scenario_rand_max(uint32_t max);
|
|||
|
||||
bool scenario_prepare_for_save();
|
||||
int32_t scenario_save(const utf8* path, int32_t flags);
|
||||
void scenario_remove_trackless_rides(rct_s6_data* s6);
|
||||
void scenario_fix_ghosts(rct_s6_data* s6);
|
||||
void scenario_failure();
|
||||
void scenario_success();
|
||||
void scenario_success_submit_name(const char* name);
|
||||
|
|
|
@ -146,6 +146,61 @@ void SetTileElements(std::vector<TileElement>&& tileElements)
|
|||
_tileIndex = TilePointerIndex<TileElement>(MAXIMUM_MAP_SIZE_TECHNICAL, _tileElements.data());
|
||||
}
|
||||
|
||||
static TileElement GetDefaultSurfaceElement()
|
||||
{
|
||||
TileElement el;
|
||||
el.ClearAs(TILE_ELEMENT_TYPE_SURFACE);
|
||||
el.SetLastForTile(true);
|
||||
el.base_height = 14;
|
||||
el.clearance_height = 14;
|
||||
el.AsSurface()->SetWaterHeight(0);
|
||||
el.AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
|
||||
el.AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0);
|
||||
el.AsSurface()->SetOwnership(OWNERSHIP_UNOWNED);
|
||||
el.AsSurface()->SetParkFences(0);
|
||||
el.AsSurface()->SetSurfaceStyle(0);
|
||||
el.AsSurface()->SetEdgeStyle(0);
|
||||
return el;
|
||||
}
|
||||
|
||||
std::vector<TileElement> GetReorganisedTileElementsWithoutGhosts()
|
||||
{
|
||||
std::vector<TileElement> newElements;
|
||||
newElements.reserve(std::max(MIN_TILE_ELEMENTS, _tileElements.size()));
|
||||
for (int32_t y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++)
|
||||
{
|
||||
for (int32_t x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++)
|
||||
{
|
||||
auto oldSize = newElements.size();
|
||||
|
||||
// Add all non-ghost elements
|
||||
const auto* element = map_get_first_element_at(TileCoordsXY{ x, y }.ToCoordsXY());
|
||||
if (element != nullptr)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!element->IsGhost())
|
||||
{
|
||||
newElements.push_back(*element);
|
||||
}
|
||||
} while (!(element++)->IsLastForTile());
|
||||
}
|
||||
|
||||
// Insert default surface element if no elements were added
|
||||
auto newSize = newElements.size();
|
||||
if (oldSize == newSize)
|
||||
{
|
||||
newElements.push_back(GetDefaultSurfaceElement());
|
||||
}
|
||||
|
||||
// Ensure last element of tile has last flag set
|
||||
auto& lastEl = newElements.back();
|
||||
lastEl.SetLastForTile(true);
|
||||
}
|
||||
}
|
||||
return newElements;
|
||||
}
|
||||
|
||||
static void ReorganiseTileElements(size_t capacity)
|
||||
{
|
||||
context_setcurrentcursor(CursorID::ZZZ);
|
||||
|
@ -159,18 +214,7 @@ static void ReorganiseTileElements(size_t capacity)
|
|||
const auto* element = map_get_first_element_at(TileCoordsXY{ x, y }.ToCoordsXY());
|
||||
if (element == nullptr)
|
||||
{
|
||||
auto& newElement = newElements.emplace_back();
|
||||
newElement.ClearAs(TILE_ELEMENT_TYPE_SURFACE);
|
||||
newElement.SetLastForTile(true);
|
||||
newElement.base_height = 14;
|
||||
newElement.clearance_height = 14;
|
||||
newElement.AsSurface()->SetWaterHeight(0);
|
||||
newElement.AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
|
||||
newElement.AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0);
|
||||
newElement.AsSurface()->SetOwnership(OWNERSHIP_UNOWNED);
|
||||
newElement.AsSurface()->SetParkFences(0);
|
||||
newElement.AsSurface()->SetSurfaceStyle(0);
|
||||
newElement.AsSurface()->SetEdgeStyle(0);
|
||||
newElements.push_back(GetDefaultSurfaceElement());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -189,6 +189,7 @@ const std::vector<TileElement>& GetTileElements();
|
|||
void SetTileElements(std::vector<TileElement>&& tileElements);
|
||||
void StashMap();
|
||||
void UnstashMap();
|
||||
std::vector<TileElement> GetReorganisedTileElementsWithoutGhosts();
|
||||
|
||||
void map_init(int32_t size);
|
||||
|
||||
|
|
Loading…
Reference in New Issue