mirror of
https://github.com/OpenRCT2/OpenRCT2.git
synced 2025-01-22 18:31:59 -05:00
Merge pull request #13998 from ZehMatt/refactor/tileelementsview-4
Use TileElementsView and minor cleanups
This commit is contained in:
commit
27b7657d1d
12 changed files with 325 additions and 457 deletions
|
@ -13,8 +13,11 @@
|
|||
#include "../world/Banner.h"
|
||||
#include "../world/MapAnimation.h"
|
||||
#include "../world/Scenery.h"
|
||||
#include "../world/TileElementsView.h"
|
||||
#include "GameAction.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
BannerPlaceAction::BannerPlaceAction(const CoordsXYZD& loc, uint8_t bannerType, BannerIndex bannerIndex, uint8_t primaryColour)
|
||||
: _loc(loc)
|
||||
, _bannerType(bannerType)
|
||||
|
@ -165,17 +168,8 @@ GameActions::Result::Ptr BannerPlaceAction::Execute() const
|
|||
|
||||
PathElement* BannerPlaceAction::GetValidPathElement() const
|
||||
{
|
||||
TileElement* tileElement = map_get_first_element_at(_loc);
|
||||
do
|
||||
for (auto* pathElement : TileElementsView<PathElement>(_loc))
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH)
|
||||
continue;
|
||||
|
||||
auto pathElement = tileElement->AsPath();
|
||||
|
||||
if (pathElement->GetBaseZ() != _loc.z && pathElement->GetBaseZ() != _loc.z - PATH_HEIGHT_STEP)
|
||||
continue;
|
||||
|
||||
|
@ -186,6 +180,7 @@ PathElement* BannerPlaceAction::GetValidPathElement() const
|
|||
continue;
|
||||
|
||||
return pathElement;
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,11 @@
|
|||
#include "../world/Banner.h"
|
||||
#include "../world/MapAnimation.h"
|
||||
#include "../world/Scenery.h"
|
||||
#include "../world/TileElementsView.h"
|
||||
#include "GameAction.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
BannerRemoveAction::BannerRemoveAction(const CoordsXYZD& loc)
|
||||
: _loc(loc)
|
||||
{
|
||||
|
@ -124,24 +127,18 @@ GameActions::Result::Ptr BannerRemoveAction::Execute() const
|
|||
|
||||
BannerElement* BannerRemoveAction::GetBannerElementAt() const
|
||||
{
|
||||
TileElement* tileElement = map_get_first_element_at(_loc);
|
||||
|
||||
// Find the banner element at known z and position
|
||||
do
|
||||
for (auto* bannerElement : TileElementsView<BannerElement>(_loc))
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_BANNER)
|
||||
if (bannerElement->GetBaseZ() != _loc.z)
|
||||
continue;
|
||||
if (tileElement->GetBaseZ() != _loc.z)
|
||||
if (bannerElement->IsGhost() && !(GetFlags() & GAME_COMMAND_FLAG_GHOST))
|
||||
continue;
|
||||
if (tileElement->IsGhost() && !(GetFlags() & GAME_COMMAND_FLAG_GHOST))
|
||||
continue;
|
||||
if (tileElement->AsBanner()->GetPosition() != _loc.direction)
|
||||
if (bannerElement->GetPosition() != _loc.direction)
|
||||
continue;
|
||||
|
||||
return tileElement->AsBanner();
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
return bannerElement;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -20,8 +20,11 @@
|
|||
#include "../world/Park.h"
|
||||
#include "../world/Scenery.h"
|
||||
#include "../world/Surface.h"
|
||||
#include "../world/TileElementsView.h"
|
||||
#include "../world/Wall.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
FootpathPlaceAction::FootpathPlaceAction(const CoordsXYZ& loc, uint8_t slope, ObjectEntryIndex type, Direction direction)
|
||||
: _loc(loc)
|
||||
, _slope(slope)
|
||||
|
@ -435,20 +438,19 @@ void FootpathPlaceAction::RemoveIntersectingWalls(PathElement* pathElement) cons
|
|||
|
||||
PathElement* FootpathPlaceAction::map_get_footpath_element_slope(const CoordsXYZ& footpathPos, int32_t slope) const
|
||||
{
|
||||
TileElement* tileElement;
|
||||
bool isSloped = slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED;
|
||||
const bool isSloped = slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED;
|
||||
const auto slopeDirection = slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK;
|
||||
|
||||
tileElement = map_get_first_element_at(footpathPos);
|
||||
do
|
||||
for (auto* pathElement : TileElementsView<PathElement>(footpathPos))
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH && tileElement->GetBaseZ() == footpathPos.z
|
||||
&& (tileElement->AsPath()->IsSloped() == isSloped)
|
||||
&& (tileElement->AsPath()->GetSlopeDirection() == (slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK)))
|
||||
{
|
||||
return tileElement->AsPath();
|
||||
}
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
if (pathElement->GetBaseZ() != footpathPos.z)
|
||||
continue;
|
||||
if (pathElement->IsSloped() != isSloped)
|
||||
continue;
|
||||
if (pathElement->GetSlopeDirection() != slopeDirection)
|
||||
continue;
|
||||
return pathElement;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include "../world/SmallScenery.h"
|
||||
#include "../world/Sprite.h"
|
||||
#include "../world/Surface.h"
|
||||
#include "../world/TileElementsView.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
LandSetHeightAction::LandSetHeightAction(const CoordsXY& coords, uint8_t height, uint8_t style)
|
||||
: _coords(coords)
|
||||
|
@ -211,43 +214,40 @@ rct_string_id LandSetHeightAction::CheckParameters() const
|
|||
|
||||
TileElement* LandSetHeightAction::CheckTreeObstructions() const
|
||||
{
|
||||
TileElement* tileElement = map_get_first_element_at(_coords);
|
||||
do
|
||||
for (auto* sceneryElement : TileElementsView<SmallSceneryElement>(_coords))
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_SMALL_SCENERY)
|
||||
if (_height > sceneryElement->clearance_height)
|
||||
continue;
|
||||
if (_height > tileElement->clearance_height)
|
||||
if (_height + 4 < sceneryElement->base_height)
|
||||
continue;
|
||||
if (_height + 4 < tileElement->base_height)
|
||||
|
||||
rct_scenery_entry* sceneryEntry = sceneryElement->GetEntry();
|
||||
if (!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_IS_TREE))
|
||||
continue;
|
||||
rct_scenery_entry* sceneryEntry = tileElement->AsSmallScenery()->GetEntry();
|
||||
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_IS_TREE))
|
||||
{
|
||||
return tileElement;
|
||||
}
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
|
||||
return sceneryElement->as<TileElement>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
money32 LandSetHeightAction::GetSmallSceneryRemovalCost() const
|
||||
{
|
||||
money32 cost{ 0 };
|
||||
TileElement* tileElement = map_get_first_element_at(_coords);
|
||||
do
|
||||
|
||||
for (auto* sceneryElement : TileElementsView<SmallSceneryElement>(_coords))
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_SMALL_SCENERY)
|
||||
if (_height > sceneryElement->clearance_height)
|
||||
continue;
|
||||
if (_height > tileElement->clearance_height)
|
||||
if (_height + 4 < sceneryElement->base_height)
|
||||
continue;
|
||||
if (_height + 4 < tileElement->base_height)
|
||||
|
||||
rct_scenery_entry* sceneryEntry = sceneryElement->GetEntry();
|
||||
if (sceneryEntry == nullptr)
|
||||
continue;
|
||||
rct_scenery_entry* sceneryEntry = tileElement->AsSmallScenery()->GetEntry();
|
||||
|
||||
cost += MONEY(sceneryEntry->small_scenery.removal_price, 0);
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
@ -270,34 +270,30 @@ void LandSetHeightAction::SmallSceneryRemoval() const
|
|||
|
||||
rct_string_id LandSetHeightAction::CheckRideSupports() const
|
||||
{
|
||||
TileElement* tileElement = map_get_first_element_at(_coords);
|
||||
do
|
||||
for (auto* trackElement : TileElementsView<TrackElement>(_coords))
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
if (tileElement->GetType() == TILE_ELEMENT_TYPE_TRACK)
|
||||
ride_id_t rideIndex = trackElement->GetRideIndex();
|
||||
|
||||
auto ride = get_ride(rideIndex);
|
||||
if (ride == nullptr)
|
||||
continue;
|
||||
|
||||
rct_ride_entry* rideEntry = ride->GetRideEntry();
|
||||
if (rideEntry == nullptr)
|
||||
continue;
|
||||
|
||||
int32_t maxHeight = rideEntry->max_height;
|
||||
if (maxHeight == 0)
|
||||
{
|
||||
ride_id_t rideIndex = tileElement->AsTrack()->GetRideIndex();
|
||||
auto ride = get_ride(rideIndex);
|
||||
if (ride != nullptr)
|
||||
{
|
||||
rct_ride_entry* rideEntry = ride->GetRideEntry();
|
||||
if (rideEntry != nullptr)
|
||||
{
|
||||
int32_t maxHeight = rideEntry->max_height;
|
||||
if (maxHeight == 0)
|
||||
{
|
||||
maxHeight = ride->GetRideTypeDescriptor().Heights.MaxHeight;
|
||||
}
|
||||
int32_t zDelta = tileElement->clearance_height - _height;
|
||||
if (zDelta >= 0 && zDelta / 2 > maxHeight)
|
||||
{
|
||||
return STR_SUPPORTS_CANT_BE_EXTENDED;
|
||||
}
|
||||
}
|
||||
}
|
||||
maxHeight = ride->GetRideTypeDescriptor().Heights.MaxHeight;
|
||||
}
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
|
||||
int32_t zDelta = trackElement->clearance_height - _height;
|
||||
if (zDelta >= 0 && zDelta / 2 > maxHeight)
|
||||
{
|
||||
return STR_SUPPORTS_CANT_BE_EXTENDED;
|
||||
}
|
||||
}
|
||||
return STR_NONE;
|
||||
}
|
||||
|
||||
|
@ -327,11 +323,8 @@ TileElement* LandSetHeightAction::CheckFloatingStructures(TileElement* surfaceEl
|
|||
|
||||
TileElement* LandSetHeightAction::CheckUnremovableObstructions(TileElement* surfaceElement, uint8_t zCorner) const
|
||||
{
|
||||
TileElement* tileElement = map_get_first_element_at(_coords);
|
||||
do
|
||||
for (auto* tileElement : TileElementsView(_coords))
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
int32_t elementType = tileElement->GetType();
|
||||
|
||||
// Wall's and Small Scenery are removed and therefore do not need checked
|
||||
|
@ -355,7 +348,7 @@ TileElement* LandSetHeightAction::CheckUnremovableObstructions(TileElement* surf
|
|||
{
|
||||
return tileElement;
|
||||
}
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#include "../world/Scenery.h"
|
||||
#include "../world/Sprite.h"
|
||||
#include "../world/Surface.h"
|
||||
#include "../world/TileElementsView.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
LandSetRightsAction::LandSetRightsAction(const MapRange& range, LandSetRightSetting setting, uint8_t ownership)
|
||||
: _range(range)
|
||||
|
@ -160,16 +163,9 @@ GameActions::Result::Ptr LandSetRightsAction::map_buy_land_rights_for_tile(const
|
|||
return res;
|
||||
}
|
||||
|
||||
TileElement* tileElement = map_get_first_element_at(loc);
|
||||
do
|
||||
for (auto* entranceElement : TileElementsView<EntranceElement>(loc))
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE)
|
||||
continue;
|
||||
|
||||
if (tileElement->AsEntrance()->GetEntranceType() != ENTRANCE_TYPE_PARK_ENTRANCE)
|
||||
if (entranceElement->GetEntranceType() != ENTRANCE_TYPE_PARK_ENTRANCE)
|
||||
continue;
|
||||
|
||||
// Do not allow ownership of park entrance.
|
||||
|
@ -180,11 +176,13 @@ GameActions::Result::Ptr LandSetRightsAction::map_buy_land_rights_for_tile(const
|
|||
// There is no need to check the height if _ownership is 0 (unowned and no rights available).
|
||||
if (_ownership == OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED || _ownership == OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE)
|
||||
{
|
||||
if (tileElement->base_height - 3 > surfaceElement->base_height
|
||||
|| tileElement->base_height < surfaceElement->base_height)
|
||||
if (entranceElement->base_height - 3 > surfaceElement->base_height
|
||||
|| entranceElement->base_height < surfaceElement->base_height)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
}
|
||||
|
||||
res->Cost = gLandPrice;
|
||||
if (isExecuting)
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
#include "../world/Park.h"
|
||||
#include "../world/SmallScenery.h"
|
||||
#include "../world/Sprite.h"
|
||||
#include "../world/TileElementsView.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
LargeSceneryRemoveAction::LargeSceneryRemoveAction(const CoordsXYZD& location, uint16_t tileIndex)
|
||||
: _loc(location)
|
||||
|
@ -59,7 +62,7 @@ GameActions::Result::Ptr LargeSceneryRemoveAction::Query() const
|
|||
res->Expenditure = ExpenditureType::Landscaping;
|
||||
res->Cost = 0;
|
||||
|
||||
TileElement* tileElement = FindLargeSceneryElement();
|
||||
TileElement* tileElement = FindLargeSceneryElement(_loc, _tileIndex);
|
||||
if (tileElement == nullptr)
|
||||
{
|
||||
log_warning("Invalid game command for scenery removal, x = %d, y = %d", _loc.x, _loc.y);
|
||||
|
@ -123,8 +126,6 @@ GameActions::Result::Ptr LargeSceneryRemoveAction::Execute() const
|
|||
{
|
||||
GameActions::Result::Ptr res = std::make_unique<GameActions::Result>();
|
||||
|
||||
const uint32_t flags = GetFlags();
|
||||
|
||||
int32_t z = tile_element_height(_loc);
|
||||
res->Position.x = _loc.x + 16;
|
||||
res->Position.y = _loc.y + 16;
|
||||
|
@ -132,7 +133,7 @@ GameActions::Result::Ptr LargeSceneryRemoveAction::Execute() const
|
|||
res->Expenditure = ExpenditureType::Landscaping;
|
||||
res->Cost = 0;
|
||||
|
||||
TileElement* tileElement = FindLargeSceneryElement();
|
||||
TileElement* tileElement = FindLargeSceneryElement(_loc, _tileIndex);
|
||||
if (tileElement == nullptr)
|
||||
{
|
||||
log_warning("Invalid game command for scenery removal, x = %d, y = %d", _loc.x, _loc.y);
|
||||
|
@ -171,37 +172,13 @@ GameActions::Result::Ptr LargeSceneryRemoveAction::Execute() const
|
|||
}
|
||||
}
|
||||
|
||||
TileElement* sceneryElement = map_get_first_element_at(currentTile);
|
||||
bool element_found = false;
|
||||
auto* sceneryElement = FindLargeSceneryElement(currentTile, i);
|
||||
if (sceneryElement != nullptr)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (sceneryElement->GetType() != TILE_ELEMENT_TYPE_LARGE_SCENERY)
|
||||
continue;
|
||||
|
||||
if (sceneryElement->GetDirection() != _loc.direction)
|
||||
continue;
|
||||
|
||||
if (sceneryElement->AsLargeScenery()->GetSequenceIndex() != i)
|
||||
continue;
|
||||
|
||||
if (sceneryElement->GetBaseZ() != currentTile.z)
|
||||
continue;
|
||||
|
||||
// If we are removing ghost elements
|
||||
if ((flags & GAME_COMMAND_FLAG_GHOST) && sceneryElement->IsGhost() == false)
|
||||
continue;
|
||||
|
||||
map_invalidate_tile_full(currentTile);
|
||||
tile_element_remove(sceneryElement);
|
||||
|
||||
element_found = true;
|
||||
break;
|
||||
} while (!(sceneryElement++)->IsLastForTile());
|
||||
map_invalidate_tile_full(currentTile);
|
||||
tile_element_remove(sceneryElement);
|
||||
}
|
||||
|
||||
if (element_found == false)
|
||||
else
|
||||
{
|
||||
log_error("Tile not found when trying to remove element!");
|
||||
}
|
||||
|
@ -212,33 +189,25 @@ GameActions::Result::Ptr LargeSceneryRemoveAction::Execute() const
|
|||
return res;
|
||||
}
|
||||
|
||||
TileElement* LargeSceneryRemoveAction::FindLargeSceneryElement() const
|
||||
TileElement* LargeSceneryRemoveAction::FindLargeSceneryElement(const CoordsXYZ& pos, int32_t sequenceIndex) const
|
||||
{
|
||||
TileElement* tileElement = map_get_first_element_at(_loc);
|
||||
if (tileElement == nullptr)
|
||||
return nullptr;
|
||||
|
||||
do
|
||||
for (auto* sceneryElement : TileElementsView<LargeSceneryElement>(pos))
|
||||
{
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_LARGE_SCENERY)
|
||||
continue;
|
||||
|
||||
if (tileElement->GetBaseZ() != _loc.z)
|
||||
continue;
|
||||
|
||||
if (tileElement->AsLargeScenery()->GetSequenceIndex() != _tileIndex)
|
||||
continue;
|
||||
|
||||
if (tileElement->GetDirection() != _loc.direction)
|
||||
continue;
|
||||
|
||||
// If we are removing ghost elements
|
||||
if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) && tileElement->IsGhost() == false)
|
||||
if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) && sceneryElement->IsGhost() == false)
|
||||
continue;
|
||||
|
||||
return tileElement;
|
||||
if (sceneryElement->GetDirection() != _loc.direction)
|
||||
continue;
|
||||
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
if (sceneryElement->GetSequenceIndex() != sequenceIndex)
|
||||
continue;
|
||||
|
||||
if (sceneryElement->GetBaseZ() != pos.z)
|
||||
continue;
|
||||
|
||||
return sceneryElement->as<TileElement>();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -30,5 +30,5 @@ public:
|
|||
GameActions::Result::Ptr Execute() const override;
|
||||
|
||||
private:
|
||||
TileElement* FindLargeSceneryElement() const;
|
||||
TileElement* FindLargeSceneryElement(const CoordsXYZ& pos, int32_t sequenceIndex) const;
|
||||
};
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include "../ride/Ride.h"
|
||||
#include "../ride/Station.h"
|
||||
#include "../world/Entrance.h"
|
||||
#include "../world/TileElementsView.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
RideEntranceExitRemoveAction::RideEntranceExitRemoveAction(
|
||||
const CoordsXY& loc, ride_id_t rideIndex, StationIndex stationNum, bool isExit)
|
||||
|
@ -42,6 +45,28 @@ void RideEntranceExitRemoveAction::Serialise(DataSerialiser& stream)
|
|||
stream << DS_TAG(_loc) << DS_TAG(_rideIndex) << DS_TAG(_stationNum) << DS_TAG(_isExit);
|
||||
}
|
||||
|
||||
static TileElement* FindEntranceElement(
|
||||
const CoordsXY& loc, ride_id_t rideIndex, int32_t stationNum, int32_t entranceType, bool ghost)
|
||||
{
|
||||
for (auto* entranceElement : TileElementsView<EntranceElement>(loc))
|
||||
{
|
||||
if (entranceElement->IsGhost() != ghost)
|
||||
continue;
|
||||
|
||||
if (entranceElement->GetRideIndex() != rideIndex)
|
||||
continue;
|
||||
|
||||
if (entranceElement->GetStationIndex() != stationNum)
|
||||
continue;
|
||||
|
||||
if (entranceElement->GetEntranceType() != entranceType)
|
||||
continue;
|
||||
|
||||
return entranceElement->as<TileElement>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GameActions::Result::Ptr RideEntranceExitRemoveAction::Query() const
|
||||
{
|
||||
auto ride = get_ride(_rideIndex);
|
||||
|
@ -66,40 +91,12 @@ GameActions::Result::Ptr RideEntranceExitRemoveAction::Query() const
|
|||
return MakeResult(GameActions::Status::InvalidParameters, STR_LAND_NOT_OWNED_BY_PARK);
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
TileElement* tileElement = map_get_first_element_at(_loc);
|
||||
const bool isGhost = GetFlags() & GAME_COMMAND_FLAG_GHOST;
|
||||
|
||||
do
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
auto* entranceElement = FindEntranceElement(
|
||||
_loc, _rideIndex, _stationNum, _isExit ? ENTRANCE_TYPE_RIDE_EXIT : ENTRANCE_TYPE_RIDE_ENTRANCE, isGhost);
|
||||
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE)
|
||||
continue;
|
||||
|
||||
if (tileElement->GetRideIndex() != _rideIndex)
|
||||
continue;
|
||||
|
||||
if (tileElement->AsEntrance()->GetStationIndex() != _stationNum)
|
||||
continue;
|
||||
|
||||
if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) && !(tileElement->IsGhost()))
|
||||
continue;
|
||||
|
||||
if (tileElement->AsEntrance()->GetEntranceType() == ENTRANCE_TYPE_PARK_ENTRANCE)
|
||||
continue;
|
||||
|
||||
if (tileElement->AsEntrance()->GetEntranceType() == ENTRANCE_TYPE_RIDE_ENTRANCE && _isExit)
|
||||
continue;
|
||||
|
||||
if (tileElement->AsEntrance()->GetEntranceType() == ENTRANCE_TYPE_RIDE_EXIT && !_isExit)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
break;
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
|
||||
if (!found)
|
||||
if (entranceElement == nullptr)
|
||||
{
|
||||
log_warning(
|
||||
"Track Element not found. x = %d, y = %d, ride = %d, station = %d", _loc.x, _loc.y,
|
||||
|
@ -119,47 +116,18 @@ GameActions::Result::Ptr RideEntranceExitRemoveAction::Execute() const
|
|||
return std::make_unique<GameActions::Result>(GameActions::Status::InvalidParameters, STR_NONE);
|
||||
}
|
||||
|
||||
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST))
|
||||
const bool isGhost = GetFlags() & GAME_COMMAND_FLAG_GHOST;
|
||||
if (!isGhost)
|
||||
{
|
||||
ride_clear_for_construction(ride);
|
||||
ride_remove_peeps(ride);
|
||||
invalidate_test_results(ride);
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
TileElement* tileElement = map_get_first_element_at(_loc);
|
||||
auto* entranceElement = FindEntranceElement(
|
||||
_loc, _rideIndex, _stationNum, _isExit ? ENTRANCE_TYPE_RIDE_EXIT : ENTRANCE_TYPE_RIDE_ENTRANCE, isGhost);
|
||||
|
||||
do
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE)
|
||||
continue;
|
||||
|
||||
if (tileElement->GetRideIndex() != _rideIndex)
|
||||
continue;
|
||||
|
||||
if (tileElement->AsEntrance()->GetStationIndex() != _stationNum)
|
||||
continue;
|
||||
|
||||
if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) && !tileElement->IsGhost())
|
||||
continue;
|
||||
|
||||
if (tileElement->AsEntrance()->GetEntranceType() == ENTRANCE_TYPE_PARK_ENTRANCE)
|
||||
continue;
|
||||
|
||||
if (tileElement->AsEntrance()->GetEntranceType() == ENTRANCE_TYPE_RIDE_ENTRANCE && _isExit)
|
||||
continue;
|
||||
|
||||
if (tileElement->AsEntrance()->GetEntranceType() == ENTRANCE_TYPE_RIDE_EXIT && !_isExit)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
break;
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
|
||||
if (!found)
|
||||
if (entranceElement == nullptr)
|
||||
{
|
||||
log_warning(
|
||||
"Track Element not found. x = %d, y = %d, ride = %d, station = %d", _loc.x, _loc.y,
|
||||
|
@ -173,10 +141,10 @@ GameActions::Result::Ptr RideEntranceExitRemoveAction::Execute() const
|
|||
res->Position.z = tile_element_height(res->Position);
|
||||
|
||||
footpath_queue_chain_reset();
|
||||
maze_entrance_hedge_replacement({ _loc, tileElement });
|
||||
footpath_remove_edges_at(_loc, tileElement);
|
||||
maze_entrance_hedge_replacement({ _loc, entranceElement });
|
||||
footpath_remove_edges_at(_loc, entranceElement);
|
||||
|
||||
tile_element_remove(tileElement);
|
||||
tile_element_remove(entranceElement);
|
||||
|
||||
if (_isExit)
|
||||
{
|
||||
|
|
|
@ -21,9 +21,12 @@
|
|||
#include "../world/Park.h"
|
||||
#include "../world/SmallScenery.h"
|
||||
#include "../world/Sprite.h"
|
||||
#include "../world/TileElementsView.h"
|
||||
#include "GameAction.h"
|
||||
#include "SmallSceneryPlaceAction.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
SmallSceneryRemoveAction::SmallSceneryRemoveAction(const CoordsXYZ& location, uint8_t quadrant, ObjectEntryIndex sceneryType)
|
||||
: _loc(location)
|
||||
, _quadrant(quadrant)
|
||||
|
@ -132,26 +135,18 @@ GameActions::Result::Ptr SmallSceneryRemoveAction::Execute() const
|
|||
|
||||
TileElement* SmallSceneryRemoveAction::FindSceneryElement() const
|
||||
{
|
||||
TileElement* tileElement = map_get_first_element_at(_loc);
|
||||
if (!tileElement)
|
||||
return nullptr;
|
||||
|
||||
do
|
||||
const bool isGhost = GetFlags() & GAME_COMMAND_FLAG_GHOST;
|
||||
for (auto* sceneryElement : TileElementsView<SmallSceneryElement>(_loc))
|
||||
{
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_SMALL_SCENERY)
|
||||
if (sceneryElement->IsGhost() != isGhost)
|
||||
continue;
|
||||
if ((tileElement->AsSmallScenery()->GetSceneryQuadrant()) != _quadrant)
|
||||
if (sceneryElement->GetSceneryQuadrant() != _quadrant)
|
||||
continue;
|
||||
if (tileElement->GetBaseZ() != _loc.z)
|
||||
if (sceneryElement->GetBaseZ() != _loc.z)
|
||||
continue;
|
||||
if (tileElement->AsSmallScenery()->GetEntryIndex() != _sceneryType)
|
||||
if (sceneryElement->GetEntryIndex() != _sceneryType)
|
||||
continue;
|
||||
if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) && tileElement->IsGhost() == false)
|
||||
continue;
|
||||
|
||||
return tileElement;
|
||||
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
|
||||
return sceneryElement->as<TileElement>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -16,8 +16,11 @@
|
|||
#include "../localisation/StringIds.h"
|
||||
#include "../management/Finance.h"
|
||||
#include "../world/Location.hpp"
|
||||
#include "../world/TileElementsView.h"
|
||||
#include "../world/Wall.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
WallRemoveAction::WallRemoveAction(const CoordsXYZD& loc)
|
||||
: _loc(loc)
|
||||
{
|
||||
|
@ -93,22 +96,16 @@ GameActions::Result::Ptr WallRemoveAction::Execute() const
|
|||
|
||||
TileElement* WallRemoveAction::GetFirstWallElementAt(const CoordsXYZD& location, bool isGhost) const
|
||||
{
|
||||
TileElement* tileElement = map_get_first_element_at(location);
|
||||
if (!tileElement)
|
||||
return nullptr;
|
||||
|
||||
do
|
||||
for (auto* wallElement : TileElementsView<WallElement>(location))
|
||||
{
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_WALL)
|
||||
if (wallElement->GetBaseZ() != location.z)
|
||||
continue;
|
||||
if (tileElement->GetBaseZ() != location.z)
|
||||
if (wallElement->GetDirection() != location.direction)
|
||||
continue;
|
||||
if (tileElement->GetDirection() != location.direction)
|
||||
continue;
|
||||
if (tileElement->IsGhost() != isGhost)
|
||||
if (wallElement->IsGhost() != isGhost)
|
||||
continue;
|
||||
|
||||
return tileElement;
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
return wallElement->as<TileElement>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "../util/Util.h"
|
||||
#include "../world/Location.hpp"
|
||||
#include "../world/Map.h"
|
||||
#include "../world/TileElementsView.h"
|
||||
#include "Paint.h"
|
||||
#include "VirtualFloor.h"
|
||||
#include "tile_element/Paint.TileElement.h"
|
||||
|
@ -24,6 +25,8 @@
|
|||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
static uint16_t _virtualFloorBaseSize = 5 * 32;
|
||||
static uint16_t _virtualFloorHeight = 0;
|
||||
static CoordsXYZ _virtualFloorLastMinPos;
|
||||
|
@ -241,10 +244,7 @@ static void virtual_floor_get_tile_properties(
|
|||
// * Surfaces, which may put us underground
|
||||
// * Walls / banners, which are displayed as occupied edges
|
||||
// * Ghost objects, which are displayed as lit squares
|
||||
TileElement* tileElement = map_get_first_element_at(loc);
|
||||
if (tileElement == nullptr)
|
||||
return;
|
||||
do
|
||||
for (auto* tileElement : TileElementsView(loc))
|
||||
{
|
||||
int32_t elementType = tileElement->GetType();
|
||||
|
||||
|
@ -285,7 +285,7 @@ static void virtual_floor_get_tile_properties(
|
|||
}
|
||||
|
||||
*outOccupied = true;
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
}
|
||||
}
|
||||
|
||||
void virtual_floor_paint(paint_session* session)
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "../world/Scenery.h"
|
||||
#include "../world/Sprite.h"
|
||||
#include "../world/Surface.h"
|
||||
#include "../world/TileElementsView.h"
|
||||
#include "GuestPathfinding.h"
|
||||
#include "Peep.h"
|
||||
#include "Staff.h"
|
||||
|
@ -43,6 +44,8 @@
|
|||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
// Locations of the spiral slide platform that a peep walks from the entrance of the ride to the
|
||||
// entrance of the slide. Up to 4 waypoints for each 4 sides that an ride entrance can be located
|
||||
// and 4 different rotations of the ride. 4 * 4 * 4 = 64 locations.
|
||||
|
@ -944,29 +947,24 @@ void Guest::Tick128UpdateGuest(int32_t index)
|
|||
{
|
||||
/* Peep happiness is affected once the peep has been waiting
|
||||
* too long in a queue. */
|
||||
TileElement* tileElement = map_get_first_element_at(NextLoc);
|
||||
bool found = false;
|
||||
do
|
||||
for (auto* pathElement : TileElementsView<PathElement>(NextLoc))
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH)
|
||||
continue;
|
||||
if (tileElement->GetBaseZ() != NextLoc.z)
|
||||
if (pathElement->GetBaseZ() != NextLoc.z)
|
||||
continue;
|
||||
|
||||
// Check if the footpath has a queue line TV monitor on it
|
||||
if (tileElement->AsPath()->HasAddition() && !tileElement->AsPath()->AdditionIsGhost())
|
||||
if (pathElement->HasAddition() && !pathElement->AdditionIsGhost())
|
||||
{
|
||||
auto pathSceneryIndex = tileElement->AsPath()->GetAdditionEntryIndex();
|
||||
auto pathSceneryIndex = pathElement->GetAdditionEntryIndex();
|
||||
rct_scenery_entry* sceneryEntry = get_footpath_item_entry(pathSceneryIndex);
|
||||
if (sceneryEntry != nullptr && sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_QUEUE_SCREEN)
|
||||
if (sceneryEntry != nullptr && (sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_QUEUE_SCREEN))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
|
@ -1678,20 +1676,14 @@ std::bitset<MAX_RIDES> Guest::FindRidesToGoOn()
|
|||
{
|
||||
for (int32_t tileY = cy - radius; tileY <= cy + radius; tileY += COORDS_XY_STEP)
|
||||
{
|
||||
if (map_is_location_valid({ tileX, tileY }))
|
||||
auto location = CoordsXY{ tileX, tileY };
|
||||
if (!map_is_location_valid(location))
|
||||
continue;
|
||||
|
||||
for (auto* trackElement : TileElementsView<TrackElement>(location))
|
||||
{
|
||||
auto tileElement = map_get_first_element_at({ tileX, tileY });
|
||||
if (tileElement != nullptr)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (tileElement->GetType() == TILE_ELEMENT_TYPE_TRACK)
|
||||
{
|
||||
auto rideIndex = tileElement->AsTrack()->GetRideIndex();
|
||||
rideConsideration[rideIndex] = true;
|
||||
}
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
}
|
||||
auto rideIndex = trackElement->GetRideIndex();
|
||||
rideConsideration[rideIndex] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2705,10 +2697,7 @@ static PeepThoughtType peep_assess_surroundings(int16_t centre_x, int16_t centre
|
|||
{
|
||||
for (int16_t y = initial_y; y < final_y; y += COORDS_XY_STEP)
|
||||
{
|
||||
TileElement* tileElement = map_get_first_element_at({ x, y });
|
||||
if (tileElement == nullptr)
|
||||
continue;
|
||||
do
|
||||
for (auto* tileElement : TileElementsView({ x, y }))
|
||||
{
|
||||
Ride* ride;
|
||||
rct_scenery_entry* scenery;
|
||||
|
@ -2770,7 +2759,7 @@ static PeepThoughtType peep_assess_surroundings(int16_t centre_x, int16_t centre
|
|||
}
|
||||
break;
|
||||
}
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2939,24 +2928,21 @@ template<typename T> static void peep_head_for_nearest_ride(Guest* peep, bool co
|
|||
{
|
||||
for (auto y = cy - searchRadius; y <= cy + searchRadius; y += COORDS_XY_STEP)
|
||||
{
|
||||
if (map_is_location_valid({ x, y }))
|
||||
auto location = CoordsXY{ x, y };
|
||||
if (!map_is_location_valid(location))
|
||||
continue;
|
||||
|
||||
for (auto* trackElement : TileElementsView<TrackElement>(location))
|
||||
{
|
||||
auto tileElement = map_get_first_element_at({ x, y });
|
||||
if (tileElement != nullptr)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (tileElement->GetType() == TILE_ELEMENT_TYPE_TRACK)
|
||||
{
|
||||
auto rideIndex = tileElement->AsTrack()->GetRideIndex();
|
||||
auto ride = get_ride(rideIndex);
|
||||
if (ride != nullptr && predicate(*ride))
|
||||
{
|
||||
rideConsideration[rideIndex] = true;
|
||||
}
|
||||
}
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
}
|
||||
auto rideIndex = trackElement->GetRideIndex();
|
||||
auto ride = get_ride(rideIndex);
|
||||
if (ride == nullptr)
|
||||
continue;
|
||||
|
||||
if (!predicate(*ride))
|
||||
continue;
|
||||
|
||||
rideConsideration[rideIndex] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3936,19 +3922,20 @@ void Guest::UpdateRideLeaveVehicle()
|
|||
if (trackType == TrackElemType::Flat || trackType > TrackElemType::MiddleStation)
|
||||
continue;
|
||||
|
||||
TileElement* inner_map = map_get_first_element_at(vehicle->TrackLocation);
|
||||
if (inner_map == nullptr)
|
||||
continue;
|
||||
for (;; inner_map++)
|
||||
bool foundStation = false;
|
||||
for (auto* trackElement : TileElementsView<TrackElement>(vehicle->TrackLocation))
|
||||
{
|
||||
if (inner_map->GetType() != TILE_ELEMENT_TYPE_TRACK)
|
||||
if (trackElement->GetBaseZ() != vehicle->TrackLocation.z)
|
||||
continue;
|
||||
if (inner_map->GetBaseZ() == vehicle->TrackLocation.z)
|
||||
break;
|
||||
|
||||
if (trackElement->GetStationIndex() != CurrentRideStation)
|
||||
continue;
|
||||
|
||||
foundStation = true;
|
||||
break;
|
||||
}
|
||||
|
||||
auto stationIndex = inner_map->AsTrack()->GetStationIndex();
|
||||
if (stationIndex == CurrentRideStation)
|
||||
if (foundStation)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4773,17 +4760,10 @@ void Guest::UpdateRideLeaveExit()
|
|||
CoordsXY targetLoc = { x, y };
|
||||
|
||||
// Find the station track element
|
||||
TileElement* tileElement = map_get_first_element_at(targetLoc);
|
||||
if (tileElement == nullptr)
|
||||
return;
|
||||
do
|
||||
for (auto* pathElement : TileElementsView<PathElement>(targetLoc))
|
||||
{
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH)
|
||||
continue;
|
||||
|
||||
int16_t height = map_height_from_slope(
|
||||
targetLoc, tileElement->AsPath()->GetSlopeDirection(), tileElement->AsPath()->IsSloped());
|
||||
height += tileElement->GetBaseZ();
|
||||
int16_t height = map_height_from_slope(targetLoc, pathElement->GetSlopeDirection(), pathElement->IsSloped());
|
||||
height += pathElement->GetBaseZ();
|
||||
|
||||
int16_t z_diff = z - height;
|
||||
if (z_diff > 0 || z_diff < -16)
|
||||
|
@ -4791,7 +4771,7 @@ void Guest::UpdateRideLeaveExit()
|
|||
|
||||
MoveTo({ x, y, height });
|
||||
return;
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5598,51 +5578,30 @@ void Guest::UpdateUsingBin()
|
|||
return;
|
||||
}
|
||||
|
||||
TileElement* tileElement = map_get_first_element_at(NextLoc);
|
||||
if (tileElement == nullptr)
|
||||
return;
|
||||
|
||||
bool found = false;
|
||||
do
|
||||
PathElement* foundElement = nullptr;
|
||||
for (auto* pathElement : TileElementsView<PathElement>(NextLoc))
|
||||
{
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH)
|
||||
{
|
||||
if (pathElement->GetBaseZ() != NextLoc.z)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tileElement->GetBaseZ() == NextLoc.z)
|
||||
{
|
||||
found = true;
|
||||
if (!pathElement->HasAddition())
|
||||
break;
|
||||
}
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
|
||||
if (!found)
|
||||
{
|
||||
StateReset();
|
||||
return;
|
||||
rct_scenery_entry* sceneryEntry = pathElement->GetAdditionEntry();
|
||||
if (!(sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BIN))
|
||||
break;
|
||||
|
||||
if (pathElement->IsBroken())
|
||||
break;
|
||||
|
||||
if (pathElement->AdditionIsGhost())
|
||||
break;
|
||||
|
||||
foundElement = pathElement;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!tileElement->AsPath()->HasAddition())
|
||||
{
|
||||
StateReset();
|
||||
return;
|
||||
}
|
||||
|
||||
rct_scenery_entry* sceneryEntry = tileElement->AsPath()->GetAdditionEntry();
|
||||
if (!(sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BIN))
|
||||
{
|
||||
StateReset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (tileElement->AsPath()->IsBroken())
|
||||
{
|
||||
StateReset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (tileElement->AsPath()->AdditionIsGhost())
|
||||
if (foundElement == nullptr)
|
||||
{
|
||||
StateReset();
|
||||
return;
|
||||
|
@ -5652,7 +5611,7 @@ void Guest::UpdateUsingBin()
|
|||
uint8_t selectedBin = Var37 * 2;
|
||||
|
||||
// This counts down 2 = No rubbish, 0 = full
|
||||
uint8_t spaceLeftInBin = 0x3 & (tileElement->AsPath()->GetAdditionStatus() >> selectedBin);
|
||||
uint8_t spaceLeftInBin = 0x3 & (foundElement->GetAdditionStatus() >> selectedBin);
|
||||
uint64_t emptyContainers = GetEmptyContainerFlags();
|
||||
|
||||
for (uint8_t curContainer = 0; curContainer < 64; curContainer++)
|
||||
|
@ -5686,14 +5645,14 @@ void Guest::UpdateUsingBin()
|
|||
UpdateSpriteType();
|
||||
}
|
||||
|
||||
uint8_t additionStatus = tileElement->AsPath()->GetAdditionStatus();
|
||||
uint8_t additionStatus = foundElement->GetAdditionStatus();
|
||||
// Place new amount in bin by first clearing the value
|
||||
additionStatus &= ~(3 << selectedBin);
|
||||
// Then placing the new value.
|
||||
additionStatus |= spaceLeftInBin << selectedBin;
|
||||
tileElement->AsPath()->SetAdditionStatus(additionStatus);
|
||||
foundElement->SetAdditionStatus(additionStatus);
|
||||
|
||||
map_invalidate_tile_zoom0({ NextLoc, tileElement->GetBaseZ(), tileElement->GetClearanceZ() });
|
||||
map_invalidate_tile_zoom0({ NextLoc, foundElement->GetBaseZ(), foundElement->GetClearanceZ() });
|
||||
StateReset();
|
||||
break;
|
||||
}
|
||||
|
@ -5730,6 +5689,32 @@ bool Guest::ShouldFindBench()
|
|||
return !GetNextIsSurface() && !GetNextIsSloped();
|
||||
}
|
||||
|
||||
static PathElement* FindBench(const CoordsXYZ& loc)
|
||||
{
|
||||
for (auto* pathElement : TileElementsView<PathElement>(loc))
|
||||
{
|
||||
if (pathElement->GetBaseZ() != loc.z)
|
||||
continue;
|
||||
|
||||
if (!pathElement->HasAddition())
|
||||
continue;
|
||||
|
||||
rct_scenery_entry* sceneryEntry = pathElement->GetAdditionEntry();
|
||||
if (sceneryEntry == nullptr || !(sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BENCH))
|
||||
continue;
|
||||
|
||||
if (pathElement->IsBroken())
|
||||
continue;
|
||||
|
||||
if (pathElement->AdditionIsGhost())
|
||||
continue;
|
||||
|
||||
return pathElement;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00690582
|
||||
|
@ -5740,40 +5725,13 @@ bool Guest::UpdateWalkingFindBench()
|
|||
if (!ShouldFindBench())
|
||||
return false;
|
||||
|
||||
TileElement* tileElement = map_get_first_element_at(NextLoc);
|
||||
if (tileElement == nullptr)
|
||||
auto* pathElement = FindBench(NextLoc);
|
||||
if (pathElement == nullptr)
|
||||
return false;
|
||||
|
||||
for (;; tileElement++)
|
||||
{
|
||||
if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH)
|
||||
{
|
||||
if (NextLoc.z == tileElement->GetBaseZ())
|
||||
break;
|
||||
}
|
||||
if (tileElement->IsLastForTile())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tileElement->AsPath()->HasAddition())
|
||||
return false;
|
||||
rct_scenery_entry* sceneryEntry = tileElement->AsPath()->GetAdditionEntry();
|
||||
|
||||
if (sceneryEntry == nullptr || !(sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BENCH))
|
||||
return false;
|
||||
|
||||
if (tileElement->AsPath()->IsBroken())
|
||||
return false;
|
||||
|
||||
if (tileElement->AsPath()->AdditionIsGhost())
|
||||
return false;
|
||||
|
||||
int32_t edges = (tileElement->AsPath()->GetEdges()) ^ 0xF;
|
||||
int32_t edges = pathElement->GetEdges() ^ 0xF;
|
||||
if (edges == 0)
|
||||
return false;
|
||||
|
||||
uint8_t chosen_edge = scenario_rand() & 0x3;
|
||||
|
||||
for (; !(edges & (1 << chosen_edge));)
|
||||
|
@ -5822,6 +5780,32 @@ bool Guest::UpdateWalkingFindBench()
|
|||
return true;
|
||||
}
|
||||
|
||||
static PathElement* FindBin(const CoordsXYZ& loc)
|
||||
{
|
||||
for (auto* pathElement : TileElementsView<PathElement>(loc))
|
||||
{
|
||||
if (pathElement->GetBaseZ() != loc.z)
|
||||
continue;
|
||||
|
||||
if (!pathElement->HasAddition())
|
||||
continue;
|
||||
|
||||
rct_scenery_entry* sceneryEntry = pathElement->GetAdditionEntry();
|
||||
if (sceneryEntry == nullptr || !(sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BIN))
|
||||
continue;
|
||||
|
||||
if (pathElement->IsBroken())
|
||||
continue;
|
||||
|
||||
if (pathElement->AdditionIsGhost())
|
||||
continue;
|
||||
|
||||
return pathElement;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Guest::UpdateWalkingFindBin()
|
||||
{
|
||||
auto peep = this;
|
||||
|
@ -5831,48 +5815,18 @@ bool Guest::UpdateWalkingFindBin()
|
|||
if (peep->GetNextIsSurface())
|
||||
return false;
|
||||
|
||||
TileElement* tileElement = map_get_first_element_at(peep->NextLoc);
|
||||
if (tileElement == nullptr)
|
||||
auto* pathElement = FindBin(peep->NextLoc);
|
||||
if (pathElement == nullptr)
|
||||
return false;
|
||||
|
||||
for (;; tileElement++)
|
||||
{
|
||||
if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH)
|
||||
{
|
||||
if (peep->NextLoc.z == tileElement->GetBaseZ())
|
||||
break;
|
||||
}
|
||||
if (tileElement->IsLastForTile())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tileElement->AsPath()->HasAddition())
|
||||
return false;
|
||||
rct_scenery_entry* sceneryEntry = tileElement->AsPath()->GetAdditionEntry();
|
||||
if (sceneryEntry == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BIN))
|
||||
return false;
|
||||
|
||||
if (tileElement->AsPath()->IsBroken())
|
||||
return false;
|
||||
|
||||
if (tileElement->AsPath()->AdditionIsGhost())
|
||||
return false;
|
||||
|
||||
int32_t edges = (tileElement->AsPath()->GetEdges()) ^ 0xF;
|
||||
int32_t edges = (pathElement->GetEdges()) ^ 0xF;
|
||||
if (edges == 0)
|
||||
return false;
|
||||
|
||||
uint8_t chosen_edge = scenario_rand() & 0x3;
|
||||
|
||||
// Note: Bin quantity is inverted 0 = full, 3 = empty
|
||||
uint8_t bin_quantities = tileElement->AsPath()->GetAdditionStatus();
|
||||
uint8_t bin_quantities = pathElement->GetAdditionStatus();
|
||||
|
||||
// Rotate the bin to the correct edge. Makes it easier for next calc.
|
||||
bin_quantities = ror8(ror8(bin_quantities, chosen_edge), chosen_edge);
|
||||
|
@ -5906,6 +5860,32 @@ bool Guest::UpdateWalkingFindBin()
|
|||
return true;
|
||||
}
|
||||
|
||||
static PathElement* FindBreakableElement(const CoordsXYZ& loc)
|
||||
{
|
||||
for (auto* pathElement : TileElementsView<PathElement>(loc))
|
||||
{
|
||||
if (pathElement->GetBaseZ() != loc.z)
|
||||
continue;
|
||||
|
||||
if (!pathElement->HasAddition())
|
||||
continue;
|
||||
|
||||
rct_scenery_entry* sceneryEntry = pathElement->GetAdditionEntry();
|
||||
if (sceneryEntry == nullptr || !(sceneryEntry->path_bit.flags & PATH_BIT_FLAG_BREAKABLE))
|
||||
continue;
|
||||
|
||||
if (pathElement->IsBroken())
|
||||
continue;
|
||||
|
||||
if (pathElement->AdditionIsGhost())
|
||||
continue;
|
||||
|
||||
return pathElement;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00690848
|
||||
|
@ -5934,37 +5914,11 @@ static void peep_update_walking_break_scenery(Peep* peep)
|
|||
if (peep->GetNextIsSurface())
|
||||
return;
|
||||
|
||||
TileElement* tileElement = map_get_first_element_at(peep->NextLoc);
|
||||
auto* tileElement = FindBreakableElement(peep->NextLoc);
|
||||
if (tileElement == nullptr)
|
||||
return;
|
||||
|
||||
for (;; tileElement++)
|
||||
{
|
||||
if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH)
|
||||
{
|
||||
if (peep->NextLoc.z == tileElement->GetBaseZ())
|
||||
break;
|
||||
}
|
||||
if (tileElement->IsLastForTile())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tileElement->AsPath()->HasAddition())
|
||||
return;
|
||||
rct_scenery_entry* sceneryEntry = tileElement->AsPath()->GetAdditionEntry();
|
||||
|
||||
if (!(sceneryEntry->path_bit.flags & PATH_BIT_FLAG_BREAKABLE))
|
||||
return;
|
||||
|
||||
if (tileElement->AsPath()->IsBroken())
|
||||
return;
|
||||
|
||||
if (tileElement->AsPath()->AdditionIsGhost())
|
||||
return;
|
||||
|
||||
int32_t edges = tileElement->AsPath()->GetEdges();
|
||||
int32_t edges = tileElement->GetEdges();
|
||||
if (edges == 0xF)
|
||||
return;
|
||||
|
||||
|
@ -5994,7 +5948,7 @@ static void peep_update_walking_break_scenery(Peep* peep)
|
|||
return;
|
||||
}
|
||||
|
||||
tileElement->AsPath()->SetIsBroken(true);
|
||||
tileElement->SetIsBroken(true);
|
||||
|
||||
map_invalidate_tile_zoom1({ peep->NextLoc, tileElement->GetBaseZ(), tileElement->GetBaseZ() + 32 });
|
||||
|
||||
|
|
Loading…
Reference in a new issue