Merge pull request #9938 from Gymnasiast/refactor/less-access-to-type-flags

Refactor some accessors to tile element type and flags fields
This commit is contained in:
Michael Steenbeek 2019-08-28 09:37:39 +02:00 committed by GitHub
commit 931a607fd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 127 additions and 83 deletions

View File

@ -2453,7 +2453,8 @@ static void sub_6CBCE2(
_tempTrackTileElement.SetType(TILE_ELEMENT_TYPE_TRACK);
_tempTrackTileElement.SetDirection(trackDirection);
_tempTrackTileElement.AsTrack()->SetHasChain((edx & 0x10000) != 0);
_tempTrackTileElement.flags = quarterTile.GetBaseQuarterOccupied() | TILE_ELEMENT_FLAG_LAST_TILE;
_tempTrackTileElement.SetOccupiedQuadrants(quarterTile.GetBaseQuarterOccupied());
_tempTrackTileElement.SetLastForTile(true);
_tempTrackTileElement.base_height = baseZ;
_tempTrackTileElement.clearance_height = clearanceZ;
_tempTrackTileElement.AsTrack()->SetTrackType(trackType);

View File

@ -1613,10 +1613,11 @@ static void window_tile_inspector_invalidate(rct_window* w)
w->widgets[WIDX_SCENERY_CHECK_COLLISION_S].bottom = w->widgets[WIDX_SCENERY_CHECK_COLLISION_S].top + 13;
w->widgets[WIDX_SCENERY_CHECK_COLLISION_W].top = GBBT(propertiesAnchor, 2) + 5 + 7 * 1;
w->widgets[WIDX_SCENERY_CHECK_COLLISION_W].bottom = w->widgets[WIDX_SCENERY_CHECK_COLLISION_W].top + 13;
N = (tileElement->flags & (1 << ((2 - get_current_rotation()) & 3))) != 0;
E = (tileElement->flags & (1 << ((3 - get_current_rotation()) & 3))) != 0;
S = (tileElement->flags & (1 << ((0 - get_current_rotation()) & 3))) != 0;
W = (tileElement->flags & (1 << ((1 - get_current_rotation()) & 3))) != 0;
auto occupiedQuadrants = tileElement->GetOccupiedQuadrants();
N = (occupiedQuadrants & (1 << ((2 - get_current_rotation()) & 3))) != 0;
E = (occupiedQuadrants & (1 << ((3 - get_current_rotation()) & 3))) != 0;
S = (occupiedQuadrants & (1 << ((0 - get_current_rotation()) & 3))) != 0;
W = (occupiedQuadrants & (1 << ((1 - get_current_rotation()) & 3))) != 0;
widget_set_checkbox_value(w, WIDX_SCENERY_CHECK_COLLISION_N, N);
widget_set_checkbox_value(w, WIDX_SCENERY_CHECK_COLLISION_E, E);
widget_set_checkbox_value(w, WIDX_SCENERY_CHECK_COLLISION_S, S);

View File

@ -643,7 +643,7 @@ void game_fix_save_vars()
if (surfaceElement == nullptr)
{
log_error("Null map element at x = %d and y = %d. Fixing...", x, y);
auto tileElement = tile_element_insert({ x, y, 14 }, 0);
auto tileElement = tile_element_insert({ x, y, 14 }, 0b0000);
if (tileElement == nullptr)
{
log_error("Unable to fix: Map element limit reached.");

View File

@ -137,7 +137,7 @@ public:
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE);
}
TileElement* newTileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, baseHeight }, 0);
TileElement* newTileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, baseHeight }, 0b0000);
assert(newTileElement != nullptr);
banner->flags = 0;

View File

@ -216,7 +216,7 @@ public:
uint16_t flooredX = floor2(_loc.x, 32);
uint16_t flooredY = floor2(_loc.y, 32);
tileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, baseHeight }, 0xF);
tileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, baseHeight }, 0b1111);
assert(tileElement != nullptr);
tileElement->clearance_height = clearanceHeight;

View File

@ -146,7 +146,7 @@ public:
surfaceElement->SetOwnership(OWNERSHIP_UNOWNED);
}
TileElement* newElement = tile_element_insert({ entranceLoc.x / 32, entranceLoc.y / 32, zLow }, 0xF);
TileElement* newElement = tile_element_insert({ entranceLoc.x / 32, entranceLoc.y / 32, zLow }, 0b1111);
Guard::Assert(newElement != nullptr);
newElement->SetType(TILE_ELEMENT_TYPE_ENTRANCE);
auto entranceElement = newElement->AsEntrance();

View File

@ -394,7 +394,7 @@ public:
return std::make_unique<WallPlaceActionResult>(GA_ERROR::NO_FREE_ELEMENTS, gGameCommandErrorText);
}
TileElement* tileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, targetHeight / 8 }, 0);
TileElement* tileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, targetHeight / 8 }, 0b0000);
assert(tileElement != nullptr);
map_animation_create(MAP_ANIMATION_TYPE_WALL, _loc.x, _loc.y, targetHeight / 8);
@ -643,7 +643,7 @@ private:
}
continue;
}
if ((tileElement->flags & 0x0F) == 0)
if (tileElement->GetOccupiedQuadrants() == 0)
continue;
switch (elementType)

View File

@ -393,6 +393,10 @@ template<> struct DataSerializerTraits<TileElement>
{
stream->WriteValue(tileElement.pad_04[i]);
}
for (int i = 0; i < 8; ++i)
{
stream->WriteValue(tileElement.pad_08[i]);
}
}
static void decode(IStream* stream, TileElement& tileElement)
{
@ -404,6 +408,10 @@ template<> struct DataSerializerTraits<TileElement>
{
tileElement.pad_04[i] = stream->ReadValue<uint8_t>();
}
for (int i = 0; i < 8; ++i)
{
tileElement.pad_08[i] = stream->ReadValue<uint8_t>();
}
}
static void log(IStream* stream, const TileElement& tileElement)
{

View File

@ -2015,7 +2015,7 @@ private:
void ImportTileElement(TileElement* dst, const RCT12TileElement* src)
{
// Todo: allow for changing defition of OpenRCT2 tile element types - replace with a map
// Todo: allow for changing definition of OpenRCT2 tile element types - replace with a map
uint8_t tileElementType = src->GetType();
dst->ClearAs(tileElementType);
dst->SetDirection(src->GetDirection());
@ -2694,7 +2694,7 @@ private:
for (int32_t y = 0; y < RCT1_MAX_MAP_SIZE; y++)
{
nextFreeTileElement->ClearAs(TILE_ELEMENT_TYPE_SURFACE);
nextFreeTileElement->flags = TILE_ELEMENT_FLAG_LAST_TILE;
nextFreeTileElement->SetLastForTile(true);
nextFreeTileElement->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
nextFreeTileElement->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS);
nextFreeTileElement->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK);
@ -2708,7 +2708,7 @@ private:
for (int32_t y = 0; y < 128 * 256; y++)
{
nextFreeTileElement->ClearAs(TILE_ELEMENT_TYPE_SURFACE);
nextFreeTileElement->flags = TILE_ELEMENT_FLAG_LAST_TILE;
nextFreeTileElement->SetLastForTile(true);
nextFreeTileElement->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
nextFreeTileElement->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS);
nextFreeTileElement->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK);

View File

@ -166,7 +166,7 @@ struct RCT12EightCarsCorruptElement15;
struct RCT12TileElementBase
{
uint8_t type; // 0
uint8_t flags; // 1
uint8_t flags; // 1. Upper nibble: flags. Lower nibble: occupied quadrants (one bit per quadrant).
uint8_t base_height; // 2
uint8_t clearance_height; // 3
uint8_t GetType() const;

View File

@ -2184,7 +2184,7 @@ static money32 place_maze_design(uint8_t flags, Ride* ride, uint16_t mazeEntry,
int32_t fx = floor2(x, 32);
int32_t fy = floor2(y, 32);
int32_t fz = z >> 3;
TileElement* tileElement = tile_element_insert({ fx >> 5, fy >> 5, fz }, 15);
TileElement* tileElement = tile_element_insert({ fx >> 5, fy >> 5, fz }, 0b1111);
tileElement->clearance_height = fz + 4;
tileElement->SetType(TILE_ELEMENT_TYPE_TRACK);
tileElement->AsTrack()->SetTrackType(TRACK_ELEM_MAZE);
@ -2411,7 +2411,7 @@ static void track_design_preview_clear_map()
{
TileElement* tile_element = &gTileElements[i];
tile_element->ClearAs(TILE_ELEMENT_TYPE_SURFACE);
tile_element->flags = TILE_ELEMENT_FLAG_LAST_TILE;
tile_element->SetLastForTile(true);
tile_element->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
tile_element->AsSurface()->SetWaterHeight(0);
tile_element->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS);

View File

@ -5169,18 +5169,18 @@ static TileElement* vehicle_check_collision(int16_t x, int16_t y, int16_t z)
return nullptr;
}
uint8_t bl;
uint8_t quadrant;
if ((x & 0x1F) >= 16)
{
bl = 1;
quadrant = 1;
if ((y & 0x1F) < 16)
bl = 2;
quadrant = 2;
}
else
{
bl = 4;
quadrant = 4;
if ((y & 0x1F) >= 16)
bl = 8;
quadrant = 8;
}
do
@ -5191,7 +5191,7 @@ static TileElement* vehicle_check_collision(int16_t x, int16_t y, int16_t z)
if (z / 8 >= tileElement->clearance_height)
continue;
if (tileElement->flags & bl)
if (tileElement->GetOccupiedQuadrants() & quadrant)
return tileElement;
} while (!(tileElement++)->IsLastForTile());
@ -6769,7 +6769,8 @@ static void vehicle_update_block_brakes_open_previous_section(rct_vehicle* vehic
slowY = slowTrackBeginEnd.end_y;
slowTileElement = *(slowTrackBeginEnd.begin_element);
if (slowX == x && slowY == y && slowTileElement.base_height == tileElement->base_height
&& slowTileElement.type == tileElement->type)
&& slowTileElement.GetType() == tileElement->GetType()
&& slowTileElement.GetDirection() == tileElement->GetDirection())
{
return;
}

View File

@ -310,7 +310,7 @@ void map_init(int32_t size)
{
TileElement* tile_element = &gTileElements[i];
tile_element->ClearAs(TILE_ELEMENT_TYPE_SURFACE);
tile_element->flags = TILE_ELEMENT_FLAG_LAST_TILE;
tile_element->SetLastForTile(true);
tile_element->base_height = 14;
tile_element->clearance_height = 14;
tile_element->AsSurface()->SetWaterHeight(0);
@ -957,7 +957,7 @@ void tile_element_remove(TileElement* tileElement)
}
// Mark the latest element with the last element flag.
(tileElement - 1)->flags |= TILE_ELEMENT_FLAG_LAST_TILE;
(tileElement - 1)->SetLastForTile(true);
tileElement->base_height = 0xFF;
if ((tileElement + 1) == gNextFreeTileElement)
@ -1153,9 +1153,10 @@ bool map_check_free_elements_and_reorganise(int32_t numElements)
*
* rct2: 0x0068B1F6
*/
TileElement* tile_element_insert(const TileCoordsXYZ& loc, int32_t flags)
TileElement* tile_element_insert(const TileCoordsXYZ& loc, int32_t occupiedQuadrants)
{
TileElement *originalTileElement, *newTileElement, *insertedElement;
bool isLastForTile = false;
if (!map_check_free_elements_and_reorganise(1))
{
@ -1178,11 +1179,11 @@ TileElement* tile_element_insert(const TileCoordsXYZ& loc, int32_t flags)
originalTileElement++;
newTileElement++;
if ((newTileElement - 1)->flags & TILE_ELEMENT_FLAG_LAST_TILE)
if ((newTileElement - 1)->IsLastForTile())
{
// No more elements above the insert element
(newTileElement - 1)->flags &= ~TILE_ELEMENT_FLAG_LAST_TILE;
flags |= TILE_ELEMENT_FLAG_LAST_TILE;
(newTileElement - 1)->SetLastForTile(false);
isLastForTile = true;
break;
}
}
@ -1191,13 +1192,15 @@ TileElement* tile_element_insert(const TileCoordsXYZ& loc, int32_t flags)
insertedElement = newTileElement;
newTileElement->type = 0;
newTileElement->base_height = loc.z;
newTileElement->flags = flags;
newTileElement->flags = 0;
newTileElement->SetLastForTile(isLastForTile);
newTileElement->SetOccupiedQuadrants(occupiedQuadrants);
newTileElement->clearance_height = loc.z;
std::memset(&newTileElement->pad_04, 0, sizeof(newTileElement->pad_04));
newTileElement++;
// Insert rest of map elements above insert height
if (!(flags & TILE_ELEMENT_FLAG_LAST_TILE))
if (!isLastForTile)
{
do
{
@ -1285,8 +1288,8 @@ void map_obstruction_set_error_text(TileElement* tileElement)
* bl = bl
*/
bool map_can_construct_with_clear_at(
int32_t x, int32_t y, int32_t zLow, int32_t zHigh, CLEAR_FUNC clearFunc, QuarterTile bl, uint8_t flags, money32* price,
uint8_t crossingMode)
int32_t x, int32_t y, int32_t zLow, int32_t zHigh, CLEAR_FUNC clearFunc, QuarterTile quarterTile, uint8_t flags,
money32* price, uint8_t crossingMode)
{
int32_t al, ah, bh, cl, ch, water_height;
al = ah = bh = cl = ch = water_height = 0;
@ -1312,7 +1315,7 @@ bool map_can_construct_with_clear_at(
{
if (zLow < tileElement->clearance_height && zHigh > tileElement->base_height && !(tileElement->IsGhost()))
{
if (tileElement->flags & (bl.GetBaseQuarterOccupied()))
if (tileElement->GetOccupiedQuadrants() & (quarterTile.GetBaseQuarterOccupied()))
{
goto loc_68BABC;
}
@ -1349,7 +1352,7 @@ bool map_can_construct_with_clear_at(
canBuildCrossing = true;
}
if (bl.GetZQuarterOccupied() != 0b1111)
if (quarterTile.GetZQuarterOccupied() != 0b1111)
{
if (tileElement->base_height >= zHigh)
{
@ -1390,8 +1393,8 @@ bool map_can_construct_with_clear_at(
}
bh = zLow + 4;
{
auto baseQuarter = bl.GetBaseQuarterOccupied();
auto zQuarter = bl.GetZQuarterOccupied();
auto baseQuarter = quarterTile.GetBaseQuarterOccupied();
auto zQuarter = quarterTile.GetZQuarterOccupied();
if ((!(baseQuarter & 0b0001) || ((zQuarter & 0b0001 || zLow >= al) && bh >= al))
&& (!(baseQuarter & 0b0010) || ((zQuarter & 0b0010 || zLow >= ah) && bh >= ah))
&& (!(baseQuarter & 0b0100) || ((zQuarter & 0b0100 || zLow >= cl) && bh >= cl))

View File

@ -172,15 +172,15 @@ void map_invalidate_map_selection_tiles();
void map_invalidate_selection_rect();
void map_reorganise_elements();
bool map_check_free_elements_and_reorganise(int32_t num_elements);
TileElement* tile_element_insert(const TileCoordsXYZ& loc, int32_t flags);
TileElement* tile_element_insert(const TileCoordsXYZ& loc, int32_t occupiedQuadrants);
using CLEAR_FUNC = int32_t (*)(TileElement** tile_element, int32_t x, int32_t y, uint8_t flags, money32* price);
int32_t map_place_non_scenery_clear_func(TileElement** tile_element, int32_t x, int32_t y, uint8_t flags, money32* price);
int32_t map_place_scenery_clear_func(TileElement** tile_element, int32_t x, int32_t y, uint8_t flags, money32* price);
bool map_can_construct_with_clear_at(
int32_t x, int32_t y, int32_t zLow, int32_t zHigh, CLEAR_FUNC clearFunc, QuarterTile bl, uint8_t flags, money32* price,
uint8_t crossingMode);
int32_t x, int32_t y, int32_t zLow, int32_t zHigh, CLEAR_FUNC clearFunc, QuarterTile quarterTile, uint8_t flags,
money32* price, uint8_t crossingMode);
int32_t map_can_construct_at(int32_t x, int32_t y, int32_t zLow, int32_t zHigh, QuarterTile bl);
void rotate_map_coordinates(int16_t* x, int16_t* y, int32_t rotation);

View File

@ -131,7 +131,7 @@ static bool map_animation_invalidate_queue_banner(int32_t x, int32_t y, int32_t
continue;
if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH)
continue;
if (!(tileElement->flags & 1))
if (!(tileElement->AsPath()->IsQueue()))
continue;
if (!tileElement->AsPath()->HasQueueBanner())
continue;

View File

@ -237,7 +237,7 @@ static void mapgen_place_tree(int32_t type, int32_t x, int32_t y)
}
surfaceZ = tile_element_height({ x * 32 + 16, y * 32 + 16 }) / 8;
tileElement = tile_element_insert({ x, y, surfaceZ }, (1 | 2 | 4 | 8));
tileElement = tile_element_insert({ x, y, surfaceZ }, 0b1111);
assert(tileElement != nullptr);
tileElement->clearance_height = surfaceZ + (sceneryEntry->small_scenery.height >> 3);
tileElement->SetType(TILE_ELEMENT_TYPE_SMALL_SCENERY);

View File

@ -137,7 +137,8 @@ void scenery_update_age(int32_t x, int32_t y, TileElement* tileElement)
// Check map elements above, presumably to see if map element is blocked from rain
tileElementAbove = tileElement;
while (!(tileElementAbove->flags & 7))
// Change from original: RCT2 only checked for the first three quadrants, which was very likely to be a bug.
while (!(tileElementAbove->GetOccupiedQuadrants()))
{
tileElementAbove++;

View File

@ -49,6 +49,14 @@ bool TileElementBase::IsLastForTile() const
return (this->flags & TILE_ELEMENT_FLAG_LAST_TILE) != 0;
}
void TileElementBase::SetLastForTile(bool on)
{
if (on)
flags |= TILE_ELEMENT_FLAG_LAST_TILE;
else
flags &= ~TILE_ELEMENT_FLAG_LAST_TILE;
}
bool TileElementBase::IsGhost() const
{
return (this->flags & TILE_ELEMENT_FLAG_GHOST) != 0;
@ -154,6 +162,7 @@ void TileElement::ClearAs(uint8_t newType)
base_height = 2;
clearance_height = 2;
std::fill_n(pad_04, sizeof(pad_04), 0x00);
std::fill_n(pad_08, sizeof(pad_08), 0x00);
}
void TileElementBase::Remove()
@ -204,3 +213,14 @@ const QuarterTile QuarterTile::Rotate(uint8_t amount) const
return QuarterTile{ 0 };
}
}
uint8_t TileElementBase::GetOccupiedQuadrants() const
{
return flags & TILE_ELEMENT_OCCUPIED_QUADRANTS_MASK;
}
void TileElementBase::SetOccupiedQuadrants(uint8_t quadrants)
{
flags &= ~TILE_ELEMENT_OCCUPIED_QUADRANTS_MASK;
flags |= (quadrants & TILE_ELEMENT_OCCUPIED_QUADRANTS_MASK);
}

View File

@ -61,7 +61,7 @@ struct CorruptElement;
struct TileElementBase
{
uint8_t type; // 0
uint8_t flags; // 1
uint8_t flags; // 1. Upper nibble: flags. Lower nibble: occupied quadrants (one bit per quadrant).
uint8_t base_height; // 2
uint8_t clearance_height; // 3
@ -71,9 +71,12 @@ struct TileElementBase
void SetDirection(uint8_t direction);
uint8_t GetDirectionWithOffset(uint8_t offset) const;
bool IsLastForTile() const;
void SetLastForTile(bool on);
bool IsGhost() const;
void SetGhost(bool isGhost);
void Remove();
uint8_t GetOccupiedQuadrants() const;
void SetOccupiedQuadrants(uint8_t quadrants);
};
/**
@ -123,10 +126,6 @@ public:
{
return as<BannerElement, TileElementType::Banner>();
}
CorruptElement* AsCorrupt() const
{
return as<CorruptElement, TileElementType::Corrupt>();
}
void ClearAs(uint8_t newType);
};
@ -246,8 +245,6 @@ public:
uint8_t GetAdditionStatus() const;
void SetAdditionStatus(uint8_t newStatus);
uint8_t GetRCT1PathType() const;
bool ShouldDrawPathOverSupports();
void SetShouldDrawPathOverSupports(bool on);
};
@ -604,6 +601,7 @@ enum
#define TILE_ELEMENT_QUADRANT_MASK 0b11000000
#define TILE_ELEMENT_TYPE_MASK 0b00111100
#define TILE_ELEMENT_DIRECTION_MASK 0b00000011
#define TILE_ELEMENT_OCCUPIED_QUADRANTS_MASK 0b00001111
#define TILE_ELEMENT_COLOUR_MASK 0b00011111

View File

@ -65,8 +65,8 @@ static bool map_swap_elements_at(CoordsXY loc, int16_t first, int16_t second)
// Swap the 'last map element for tile' flag if either one of them was last
if ((firstElement)->IsLastForTile() || (secondElement)->IsLastForTile())
{
firstElement->flags ^= TILE_ELEMENT_FLAG_LAST_TILE;
secondElement->flags ^= TILE_ELEMENT_FLAG_LAST_TILE;
firstElement->SetLastForTile(!firstElement->IsLastForTile());
secondElement->SetLastForTile(!secondElement->IsLastForTile());
}
return true;
@ -89,7 +89,7 @@ GameActionResult::Ptr tile_inspector_insert_corrupt_at(CoordsXY loc, int16_t ele
{
// Create new corrupt element
TileElement* corruptElement = tile_element_insert(
{ loc.x / 32, loc.y / 32, -1 }, 0); // Ugly hack: -1 guarantees this to be placed first
{ loc.x / 32, loc.y / 32, -1 }, 0b0000); // Ugly hack: -1 guarantees this to be placed first
if (corruptElement == nullptr)
{
log_warning("Failed to insert corrupt element.");
@ -320,15 +320,13 @@ GameActionResult::Ptr tile_inspector_paste_element_at(CoordsXY loc, TileElement
tile_element_set_banner_index(&element, newBannerIndex);
}
TileElement* const pastedElement = tile_element_insert({ loc.x / 32, loc.y / 32, element.base_height }, 0);
// The occupiedQuadrants will be automatically set when the element is copied over, so it's not necessary to set them
// correctly _here_.
TileElement* const pastedElement = tile_element_insert({ loc.x / 32, loc.y / 32, element.base_height }, 0b0000);
bool lastForTile = pastedElement->IsLastForTile();
*pastedElement = element;
pastedElement->flags &= ~TILE_ELEMENT_FLAG_LAST_TILE;
if (lastForTile)
{
pastedElement->flags |= TILE_ELEMENT_FLAG_LAST_TILE;
}
pastedElement->SetLastForTile(lastForTile);
map_invalidate_tile_full(loc.x, loc.y);
@ -1004,8 +1002,7 @@ GameActionResult::Ptr tile_inspector_scenery_set_quarter_location(
tileElement->AsSmallScenery()->SetSceneryQuadrant(quarterIndex);
// Update collision
tileElement->flags &= 0xF0;
tileElement->flags |= 1 << ((quarterIndex + 2) & 3);
tileElement->SetOccupiedQuadrants(1 << ((quarterIndex + 2) & 3));
map_invalidate_tile_full(loc.x, loc.y);
if ((uint32_t)(loc.x / 32) == windowTileInspectorTileX && (uint32_t)(loc.y / 32) == windowTileInspectorTileY)
@ -1027,7 +1024,9 @@ GameActionResult::Ptr tile_inspector_scenery_set_quarter_collision(
if (isExecuting)
{
tileElement->flags ^= 1 << quarterIndex;
auto occupiedQuadrants = tileElement->GetOccupiedQuadrants();
occupiedQuadrants ^= 1 << quarterIndex;
tileElement->SetOccupiedQuadrants(occupiedQuadrants);
map_invalidate_tile_full(loc.x, loc.y);
if ((uint32_t)(loc.x / 32) == windowTileInspectorTileX && (uint32_t)(loc.y / 32) == windowTileInspectorTileY)

View File

@ -160,6 +160,14 @@ bool TileElementBase::IsLastForTile() const
return (this->flags & TILE_ELEMENT_FLAG_LAST_TILE) != 0;
}
void TileElementBase::SetLastForTile(bool on)
{
if (on)
flags |= TILE_ELEMENT_FLAG_LAST_TILE;
else
flags &= ~TILE_ELEMENT_FLAG_LAST_TILE;
}
uint8_t TileElementBase::GetType() const
{
return this->type & TILE_ELEMENT_TYPE_MASK;
@ -441,3 +449,14 @@ bool rct_vehicle::IsGhost() const
auto r = get_ride(ride);
return r != nullptr && r->status == RIDE_STATUS_SIMULATING;
}
uint8_t TileElementBase::GetOccupiedQuadrants() const
{
return flags & TILE_ELEMENT_OCCUPIED_QUADRANTS_MASK;
}
void TileElementBase::SetOccupiedQuadrants(uint8_t quadrants)
{
flags &= ~TILE_ELEMENT_OCCUPIED_QUADRANTS_MASK;
flags |= (quadrants & TILE_ELEMENT_OCCUPIED_QUADRANTS_MASK);
}

View File

@ -101,14 +101,7 @@ public:
uint8_t rideType, uint8_t trackType, int variant, TileElement* tileElement, TileElement* surfaceElement, Ride* ride,
rct_ride_entry* rideEntry) override
{
if (variant == 0)
{
tileElement->type &= ~TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT;
}
else
{
tileElement->type |= TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT;
}
tileElement->AsTrack()->SetHasChain(variant != 0);
}
};
@ -269,13 +262,13 @@ static uint8_t TestTrackElementPaintCalls(uint8_t rideType, uint8_t trackType, u
TileElement tileElement = {};
tileElement.SetType(TILE_ELEMENT_TYPE_TRACK);
tileElement.flags |= TILE_ELEMENT_FLAG_LAST_TILE;
tileElement.SetLastForTile(true);
tileElement.AsTrack()->SetTrackType(trackType);
tileElement.base_height = height / 16;
g_currently_drawn_item = &tileElement;
TileElement surfaceElement = {};
surfaceElement.type = TILE_ELEMENT_TYPE_SURFACE;
surfaceElement.SetType(TILE_ELEMENT_TYPE_SURFACE);
surfaceElement.base_height = 2;
gSurfaceElement = &surfaceElement;
gDidPassSurface = true;
@ -432,13 +425,13 @@ static uint8_t TestTrackElementSegmentSupportHeight(
TileElement tileElement = {};
tileElement.SetType(TILE_ELEMENT_TYPE_TRACK);
tileElement.flags |= TILE_ELEMENT_FLAG_LAST_TILE;
tileElement.SetLastForTile(true);
tileElement.AsTrack()->SetTrackType(trackType);
tileElement.base_height = height / 16;
g_currently_drawn_item = &tileElement;
TileElement surfaceElement = {};
surfaceElement.type = TILE_ELEMENT_TYPE_SURFACE;
surfaceElement.SetType(TILE_ELEMENT_TYPE_SURFACE);
surfaceElement.base_height = 2;
gSurfaceElement = &surfaceElement;
gDidPassSurface = true;
@ -519,13 +512,13 @@ static uint8_t TestTrackElementGeneralSupportHeight(
TileElement tileElement = {};
tileElement.SetType(TILE_ELEMENT_TYPE_TRACK);
tileElement.flags |= TILE_ELEMENT_FLAG_LAST_TILE;
tileElement.SetLastForTile(true);
tileElement.AsTrack()->SetTrackType(trackType);
tileElement.base_height = height / 16;
g_currently_drawn_item = &tileElement;
TileElement surfaceElement = {};
surfaceElement.type = TILE_ELEMENT_TYPE_SURFACE;
surfaceElement.SetType(TILE_ELEMENT_TYPE_SURFACE);
surfaceElement.base_height = 2;
gSurfaceElement = &surfaceElement;
gDidPassSurface = true;
@ -620,13 +613,13 @@ static uint8_t TestTrackElementSideTunnels(uint8_t rideType, uint8_t trackType,
TileElement tileElement = {};
tileElement.SetType(TILE_ELEMENT_TYPE_TRACK);
tileElement.flags |= TILE_ELEMENT_FLAG_LAST_TILE;
tileElement.SetLastForTile(true);
tileElement.AsTrack()->SetTrackType(trackType);
tileElement.base_height = height / 16;
g_currently_drawn_item = &tileElement;
TileElement surfaceElement = {};
surfaceElement.type = TILE_ELEMENT_TYPE_SURFACE;
surfaceElement.SetType(TILE_ELEMENT_TYPE_SURFACE);
surfaceElement.base_height = 2;
gSurfaceElement = &surfaceElement;
gDidPassSurface = true;
@ -748,13 +741,13 @@ static uint8_t TestTrackElementVerticalTunnels(uint8_t rideType, uint8_t trackTy
TileElement tileElement = {};
tileElement.SetType(TILE_ELEMENT_TYPE_TRACK);
tileElement.flags |= TILE_ELEMENT_FLAG_LAST_TILE;
tileElement.SetLastForTile(true);
tileElement.AsTrack()->SetTrackType(trackType);
tileElement.base_height = height / 16;
g_currently_drawn_item = &tileElement;
TileElement surfaceElement = {};
surfaceElement.type = TILE_ELEMENT_TYPE_SURFACE;
surfaceElement.SetType(TILE_ELEMENT_TYPE_SURFACE);
surfaceElement.base_height = 2;
gSurfaceElement = &surfaceElement;
gDidPassSurface = true;

View File

@ -446,7 +446,7 @@ private:
{
TileElement tileElement = {};
tileElement.SetType(TILE_ELEMENT_TYPE_TRACK);
tileElement.flags |= TILE_ELEMENT_FLAG_LAST_TILE;
tileElement.SetLastForTile(true);
tileElement.AsTrack()->SetTrackType(trackType);
tileElement.base_height = 3;
if (_invertedTrack)
@ -482,7 +482,7 @@ private:
}
// Get chain lift calls
tileElement.type |= 0x80;
tileElement.AsTrack()->SetHasChain(true);
PaintIntercept::ClearCalls();
CallOriginal(trackType, direction, trackSequence, height, &tileElement);
numCalls = PaintIntercept::GetCalls(callBuffer);