mirror of https://github.com/OpenRCT2/OpenRCT2.git
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:
commit
931a607fd6
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue