mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-18 04:23:20 +01:00
Get building of old path working
This commit is contained in:
@@ -12,15 +12,18 @@
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
#include <openrct2/Cheats.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/Game.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
#include <openrct2/actions/FootpathPlaceAction.h>
|
||||
#include <openrct2/audio/audio.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include <openrct2/object/FootpathObject.h>
|
||||
#include <openrct2/object/FootpathRailingsObject.h>
|
||||
#include <openrct2/object/FootpathSurfaceObject.h>
|
||||
#include <openrct2/object/ObjectLimits.h>
|
||||
#include <openrct2/object/ObjectManager.h>
|
||||
#include <openrct2/platform/platform.h>
|
||||
#include <openrct2/sprites.h>
|
||||
#include <openrct2/world/Footpath.h>
|
||||
@@ -32,9 +35,10 @@ static constexpr const int32_t WH = 421;
|
||||
static constexpr const int32_t WW = 106;
|
||||
static constexpr const uint16_t ARROW_PULSE_DURATION = 200;
|
||||
|
||||
static ObjectEntryIndex _selectedPath = OBJECT_ENTRY_INDEX_NULL;
|
||||
static ObjectEntryIndex _selectedQueue = OBJECT_ENTRY_INDEX_NULL;
|
||||
static ObjectEntryIndex _selectedRailings = OBJECT_ENTRY_INDEX_NULL;
|
||||
static std::vector<ObjectEntryIndex> _dropdownEntries;
|
||||
static std::vector<std::pair<ObjectType, ObjectEntryIndex>> _dropdownEntries;
|
||||
|
||||
// clang-format off
|
||||
enum
|
||||
@@ -346,16 +350,32 @@ static void window_footpath_dropdown(rct_window* w, rct_widgetindex widgetIndex,
|
||||
if (widgetIndex == WIDX_FOOTPATH_TYPE)
|
||||
{
|
||||
gFootpathSelectedType = SELECTED_PATH_TYPE_NORMAL;
|
||||
gFootpathSelectedId = entryIndex;
|
||||
if (entryIndex.first == ObjectType::Paths)
|
||||
{
|
||||
_selectedPath = entryIndex.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectedPath = OBJECT_ENTRY_INDEX_NULL;
|
||||
gFootpathSelectedId = entryIndex.second;
|
||||
}
|
||||
}
|
||||
else if (widgetIndex == WIDX_QUEUELINE_TYPE)
|
||||
{
|
||||
gFootpathSelectedType = SELECTED_PATH_TYPE_QUEUE;
|
||||
_selectedQueue = entryIndex;
|
||||
if (entryIndex.first == ObjectType::Paths)
|
||||
{
|
||||
_selectedPath = entryIndex.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectedPath = OBJECT_ENTRY_INDEX_NULL;
|
||||
_selectedQueue = entryIndex.second;
|
||||
}
|
||||
}
|
||||
else if (widgetIndex == WIDX_RAILINGS_TYPE)
|
||||
{
|
||||
_selectedRailings = entryIndex;
|
||||
_selectedRailings = entryIndex.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -429,7 +449,6 @@ static void window_footpath_toolup(rct_window* w, rct_widgetindex widgetIndex, c
|
||||
*/
|
||||
static void window_footpath_update_provisional_path_for_bridge_mode(rct_window* w)
|
||||
{
|
||||
ObjectEntryIndex type;
|
||||
int32_t slope;
|
||||
|
||||
if (gFootpathConstructionMode != PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL)
|
||||
@@ -447,10 +466,21 @@ static void window_footpath_update_provisional_path_for_bridge_mode(rct_window*
|
||||
// Update provisional bridge mode path
|
||||
if (!(gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_1))
|
||||
{
|
||||
ObjectEntryIndex type;
|
||||
ObjectEntryIndex railings = _selectedRailings;
|
||||
|
||||
CoordsXYZ footpathLoc;
|
||||
footpath_get_next_path_info(&type, footpathLoc, &slope);
|
||||
auto isQueue = gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE;
|
||||
_window_footpath_cost = footpath_provisional_set(type, _selectedRailings, footpathLoc, slope, isQueue);
|
||||
PathConstructFlags pathConstructFlags = 0;
|
||||
if (gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE)
|
||||
pathConstructFlags |= PathConstructFlag::IsQueue;
|
||||
if (_selectedPath != OBJECT_ENTRY_INDEX_NULL)
|
||||
{
|
||||
pathConstructFlags |= PathConstructFlag::IsPathObject;
|
||||
type = _selectedPath;
|
||||
}
|
||||
|
||||
_window_footpath_cost = footpath_provisional_set(type, railings, footpathLoc, slope, pathConstructFlags);
|
||||
widget_invalidate(w, WIDX_CONSTRUCT);
|
||||
}
|
||||
|
||||
@@ -463,7 +493,7 @@ static void window_footpath_update_provisional_path_for_bridge_mode(rct_window*
|
||||
|
||||
gFootpathProvisionalFlags ^= PROVISIONAL_PATH_FLAG_SHOW_ARROW;
|
||||
CoordsXYZ footpathLoc;
|
||||
footpath_get_next_path_info(&type, footpathLoc, &slope);
|
||||
footpath_get_next_path_info(nullptr, footpathLoc, &slope);
|
||||
gMapSelectArrowPosition = footpathLoc;
|
||||
gMapSelectArrowDirection = gFootpathConstructDirection;
|
||||
if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_SHOW_ARROW)
|
||||
@@ -545,31 +575,57 @@ static void window_footpath_invalidate(rct_window* w)
|
||||
? WindowWidgetType::ImgBtn
|
||||
: WindowWidgetType::Empty;
|
||||
|
||||
// Set footpath and queue type button images
|
||||
auto pathImage = static_cast<uint32_t>(SPR_NONE);
|
||||
auto queueImage = static_cast<uint32_t>(SPR_NONE);
|
||||
auto pathEntry = get_path_surface_entry(gFootpathSelectedId);
|
||||
if (pathEntry != nullptr)
|
||||
if (_selectedPath == OBJECT_ENTRY_INDEX_NULL)
|
||||
{
|
||||
pathImage = pathEntry->PreviewImageId;
|
||||
}
|
||||
// Set footpath and queue type button images
|
||||
auto pathImage = static_cast<uint32_t>(SPR_NONE);
|
||||
auto queueImage = static_cast<uint32_t>(SPR_NONE);
|
||||
auto pathEntry = get_path_surface_entry(gFootpathSelectedId);
|
||||
if (pathEntry != nullptr)
|
||||
{
|
||||
pathImage = pathEntry->PreviewImageId;
|
||||
}
|
||||
|
||||
pathEntry = get_path_surface_entry(_selectedQueue);
|
||||
if (pathEntry != nullptr)
|
||||
pathEntry = get_path_surface_entry(_selectedQueue);
|
||||
if (pathEntry != nullptr)
|
||||
{
|
||||
queueImage = pathEntry->PreviewImageId;
|
||||
}
|
||||
|
||||
window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage;
|
||||
window_footpath_widgets[WIDX_QUEUELINE_TYPE].image = queueImage;
|
||||
|
||||
// Set railing
|
||||
auto railingsImage = static_cast<uint32_t>(SPR_NONE);
|
||||
auto railingsEntry = get_path_railings_entry(_selectedRailings);
|
||||
if (railingsEntry != nullptr)
|
||||
{
|
||||
railingsImage = railingsEntry->PreviewImageId;
|
||||
}
|
||||
window_footpath_widgets[WIDX_RAILINGS_TYPE].image = railingsImage;
|
||||
window_footpath_widgets[WIDX_RAILINGS_TYPE].type = WindowWidgetType::FlatBtn;
|
||||
}
|
||||
else
|
||||
{
|
||||
queueImage = pathEntry->PreviewImageId;
|
||||
}
|
||||
auto& objManager = OpenRCT2::GetContext()->GetObjectManager();
|
||||
|
||||
window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage;
|
||||
window_footpath_widgets[WIDX_QUEUELINE_TYPE].image = queueImage;
|
||||
// Set footpath and queue type button images
|
||||
auto pathImage = static_cast<uint32_t>(SPR_NONE);
|
||||
auto queueImage = static_cast<uint32_t>(SPR_NONE);
|
||||
auto pathObj = static_cast<FootpathObject*>(objManager.GetLoadedObject(ObjectType::Paths, _selectedPath));
|
||||
if (pathObj != nullptr)
|
||||
{
|
||||
auto pathEntry = reinterpret_cast<rct_footpath_entry*>(pathObj->GetLegacyData());
|
||||
pathImage = pathEntry->image + 71;
|
||||
queueImage = pathEntry->image + 72;
|
||||
}
|
||||
|
||||
auto railingsImage = static_cast<uint32_t>(SPR_NONE);
|
||||
auto railingsEntry = get_path_railings_entry(_selectedRailings);
|
||||
if (railingsEntry != nullptr)
|
||||
{
|
||||
railingsImage = railingsEntry->PreviewImageId;
|
||||
window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage;
|
||||
window_footpath_widgets[WIDX_QUEUELINE_TYPE].image = queueImage;
|
||||
|
||||
// Hide railing button
|
||||
window_footpath_widgets[WIDX_RAILINGS_TYPE].type = WindowWidgetType::Empty;
|
||||
}
|
||||
window_footpath_widgets[WIDX_RAILINGS_TYPE].image = railingsImage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -595,12 +651,30 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi)
|
||||
slope = TILE_ELEMENT_SLOPE_E_CORNER_UP;
|
||||
}
|
||||
|
||||
auto selectedPath = gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE ? _selectedQueue : gFootpathSelectedId;
|
||||
const auto* pathType = get_path_surface_entry(selectedPath);
|
||||
if (pathType != nullptr)
|
||||
std::optional<uint32_t> baseImage;
|
||||
if (_selectedPath == OBJECT_ENTRY_INDEX_NULL)
|
||||
{
|
||||
int32_t image = ConstructionPreviewImages[slope][direction];
|
||||
image += pathType->BaseImageId;
|
||||
auto selectedPath = gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE ? _selectedQueue : gFootpathSelectedId;
|
||||
const auto* pathType = get_path_surface_entry(selectedPath);
|
||||
if (pathType != nullptr)
|
||||
{
|
||||
baseImage = pathType->BaseImageId;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& objManager = OpenRCT2::GetContext()->GetObjectManager();
|
||||
auto* pathObj = static_cast<FootpathObject*>(objManager.GetLoadedObject(ObjectType::Paths, _selectedPath));
|
||||
if (pathObj != nullptr)
|
||||
{
|
||||
auto pathEntry = reinterpret_cast<const rct_footpath_entry*>(pathObj->GetLegacyData());
|
||||
baseImage = pathEntry->image;
|
||||
}
|
||||
}
|
||||
|
||||
if (baseImage)
|
||||
{
|
||||
auto image = *baseImage + ConstructionPreviewImages[slope][direction];
|
||||
|
||||
// Draw construction image
|
||||
screenCoords = w->windowPos
|
||||
@@ -635,6 +709,8 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi)
|
||||
*/
|
||||
static void window_footpath_show_footpath_types_dialog(rct_window* w, rct_widget* widget, bool showQueues)
|
||||
{
|
||||
auto& objManager = OpenRCT2::GetContext()->GetObjectManager();
|
||||
|
||||
uint32_t numPathTypes = 0;
|
||||
// If the game is in sandbox mode, also show paths that are normally restricted to the scenario editor
|
||||
bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode);
|
||||
@@ -643,7 +719,7 @@ static void window_footpath_show_footpath_types_dialog(rct_window* w, rct_widget
|
||||
std::optional<size_t> defaultIndex;
|
||||
for (size_t i = 0; i < MAX_FOOTPATH_SURFACE_OBJECTS; i++)
|
||||
{
|
||||
const auto* pathType = get_path_surface_entry(i);
|
||||
const auto* pathType = static_cast<FootpathSurfaceObject*>(objManager.GetLoadedObject(ObjectType::FootpathSurface, i));
|
||||
if (pathType == nullptr)
|
||||
{
|
||||
continue;
|
||||
@@ -656,14 +732,39 @@ static void window_footpath_show_footpath_types_dialog(rct_window* w, rct_widget
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (i == (showQueues ? _selectedQueue : gFootpathSelectedId))
|
||||
if (_selectedPath == OBJECT_ENTRY_INDEX_NULL && i == (showQueues ? _selectedQueue : gFootpathSelectedId))
|
||||
{
|
||||
defaultIndex = numPathTypes;
|
||||
}
|
||||
|
||||
gDropdownItemsFormat[numPathTypes] = STR_NONE;
|
||||
gDropdownItemsArgs[numPathTypes] = pathType->PreviewImageId;
|
||||
_dropdownEntries.push_back(i);
|
||||
_dropdownEntries.push_back({ ObjectType::FootpathSurface, i });
|
||||
numPathTypes++;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MAX_PATH_OBJECTS; i++)
|
||||
{
|
||||
auto* pathObj = static_cast<FootpathObject*>(objManager.GetLoadedObject(ObjectType::Paths, i));
|
||||
if (pathObj == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto pathEntry = reinterpret_cast<const rct_footpath_entry*>(pathObj->GetLegacyData());
|
||||
if ((pathEntry->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) && !showEditorPaths)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_selectedPath != OBJECT_ENTRY_INDEX_NULL && _selectedPath == i)
|
||||
{
|
||||
defaultIndex = numPathTypes;
|
||||
}
|
||||
|
||||
gDropdownItemsFormat[numPathTypes] = STR_NONE;
|
||||
gDropdownItemsArgs[numPathTypes] = pathEntry->image + (showQueues ? 72 : 71);
|
||||
_dropdownEntries.push_back({ ObjectType::Paths, i });
|
||||
numPathTypes++;
|
||||
}
|
||||
|
||||
@@ -696,7 +797,7 @@ static void window_footpath_show_railings_types_dialog(rct_window* w, rct_widget
|
||||
|
||||
gDropdownItemsFormat[numRailingsTypes] = STR_NONE;
|
||||
gDropdownItemsArgs[numRailingsTypes] = railingsEntry->PreviewImageId;
|
||||
_dropdownEntries.push_back(i);
|
||||
_dropdownEntries.push_back({ ObjectType::FootpathRailings, i });
|
||||
numRailingsTypes++;
|
||||
}
|
||||
|
||||
@@ -802,9 +903,23 @@ static void window_footpath_set_provisional_path_at_point(const ScreenCoordsXY&
|
||||
z += PATH_HEIGHT_STEP;
|
||||
}
|
||||
|
||||
auto isQueue = gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE;
|
||||
auto pathType = isQueue ? _selectedQueue : gFootpathSelectedId;
|
||||
_window_footpath_cost = footpath_provisional_set(pathType, _selectedRailings, { info.Loc, z }, slope, isQueue);
|
||||
PathConstructFlags constructFlags = 0;
|
||||
auto pathType = gFootpathSelectedId;
|
||||
if (gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE)
|
||||
{
|
||||
constructFlags |= PathConstructFlag::IsQueue;
|
||||
pathType = _selectedQueue;
|
||||
}
|
||||
else
|
||||
{
|
||||
pathType = gFootpathSelectedId;
|
||||
}
|
||||
if (_selectedPath != OBJECT_ENTRY_INDEX_NULL)
|
||||
{
|
||||
constructFlags |= PathConstructFlag::IsPathObject;
|
||||
pathType = _selectedPath;
|
||||
}
|
||||
_window_footpath_cost = footpath_provisional_set(pathType, _selectedRailings, { info.Loc, z }, slope, constructFlags);
|
||||
window_invalidate_by_class(WC_FOOTPATH);
|
||||
}
|
||||
}
|
||||
@@ -897,13 +1012,23 @@ static void window_footpath_place_path_at_point(const ScreenCoordsXY& screenCoor
|
||||
slope &= ~RAISE_FOOTPATH_FLAG;
|
||||
z += PATH_HEIGHT_STEP;
|
||||
}
|
||||
auto selectedType = gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE ? _selectedQueue : gFootpathSelectedId;
|
||||
|
||||
// Try and place path
|
||||
gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE;
|
||||
auto isQueue = gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE;
|
||||
auto selectedType = gFootpathSelectedId;
|
||||
PathConstructFlags constructFlags = 0;
|
||||
if (gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE)
|
||||
{
|
||||
constructFlags |= PathConstructFlag::IsQueue;
|
||||
selectedType = _selectedQueue;
|
||||
}
|
||||
if (_selectedPath != OBJECT_ENTRY_INDEX_NULL)
|
||||
{
|
||||
constructFlags |= PathConstructFlag::IsPathObject;
|
||||
selectedType = _selectedPath;
|
||||
}
|
||||
auto footpathPlaceAction = FootpathPlaceAction(
|
||||
{ info.Loc, z }, slope, selectedType, _selectedRailings, INVALID_DIRECTION, isQueue);
|
||||
{ info.Loc, z }, slope, selectedType, _selectedRailings, INVALID_DIRECTION, constructFlags);
|
||||
footpathPlaceAction.SetCallback([](const GameAction* ga, const GameActions::Result* result) {
|
||||
if (result->Error == GameActions::Status::Ok)
|
||||
{
|
||||
@@ -993,9 +1118,16 @@ static void window_footpath_construct()
|
||||
footpath_get_next_path_info(&type, footpathLoc, &slope);
|
||||
|
||||
gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE;
|
||||
auto isQueue = gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE;
|
||||
PathConstructFlags constructFlags = 0;
|
||||
if (gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE)
|
||||
constructFlags |= PathConstructFlag::IsQueue;
|
||||
if (_selectedPath != OBJECT_ENTRY_INDEX_NULL)
|
||||
{
|
||||
constructFlags |= PathConstructFlag::IsPathObject;
|
||||
type = _selectedPath;
|
||||
}
|
||||
auto footpathPlaceAction = FootpathPlaceAction(
|
||||
footpathLoc, slope, type, _selectedRailings, gFootpathConstructDirection, isQueue);
|
||||
footpathLoc, slope, type, _selectedRailings, gFootpathConstructDirection, constructFlags);
|
||||
footpathPlaceAction.SetCallback([=](const GameAction* ga, const GameActions::Result* result) {
|
||||
if (result->Error == GameActions::Status::Ok)
|
||||
{
|
||||
@@ -1239,11 +1371,13 @@ static void footpath_get_next_path_info(ObjectEntryIndex* type, CoordsXYZ& footp
|
||||
footpathLoc.z = gFootpathConstructFromPosition.z;
|
||||
if (gFootpathSelectedType == SELECTED_PATH_TYPE_QUEUE)
|
||||
{
|
||||
*type = _selectedQueue;
|
||||
if (type != nullptr)
|
||||
*type = _selectedQueue;
|
||||
}
|
||||
else
|
||||
{
|
||||
*type = gFootpathSelectedId;
|
||||
if (type != nullptr)
|
||||
*type = gFootpathSelectedId;
|
||||
}
|
||||
*slope = TILE_ELEMENT_SLOPE_FLAT;
|
||||
if (gFootpathConstructSlope != 0)
|
||||
|
||||
@@ -27,13 +27,13 @@ using namespace OpenRCT2;
|
||||
|
||||
FootpathPlaceAction::FootpathPlaceAction(
|
||||
const CoordsXYZ& loc, uint8_t slope, ObjectEntryIndex type, ObjectEntryIndex railingsType, Direction direction,
|
||||
bool isQueue)
|
||||
PathConstructFlags constructFlags)
|
||||
: _loc(loc)
|
||||
, _slope(slope)
|
||||
, _type(type)
|
||||
, _railingsType(railingsType)
|
||||
, _direction(direction)
|
||||
, _isQueue(isQueue)
|
||||
, _constructFlags(constructFlags)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ void FootpathPlaceAction::AcceptParameters(GameActionParameterVisitor& visitor)
|
||||
visitor.Visit("railingsObject", _railingsType);
|
||||
visitor.Visit("direction", _direction);
|
||||
visitor.Visit("slope", _slope);
|
||||
visitor.Visit("isQueue", _isQueue);
|
||||
visitor.Visit("constructFlags", _constructFlags);
|
||||
}
|
||||
|
||||
uint16_t FootpathPlaceAction::GetActionFlags() const
|
||||
@@ -56,7 +56,7 @@ void FootpathPlaceAction::Serialise(DataSerialiser& stream)
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << DS_TAG(_loc) << DS_TAG(_slope) << DS_TAG(_type) << DS_TAG(_direction) << DS_TAG(_isQueue);
|
||||
stream << DS_TAG(_loc) << DS_TAG(_slope) << DS_TAG(_type) << DS_TAG(_direction) << DS_TAG(_constructFlags);
|
||||
}
|
||||
|
||||
GameActions::Result::Ptr FootpathPlaceAction::Query() const
|
||||
@@ -155,10 +155,40 @@ GameActions::Result::Ptr FootpathPlaceAction::Execute() const
|
||||
}
|
||||
}
|
||||
|
||||
bool FootpathPlaceAction::IsSameAsPathElement(const PathElement* pathElement) const
|
||||
{
|
||||
// Check if both this action and the element is queue
|
||||
if (pathElement->IsQueue() != ((_constructFlags & PathConstructFlag::IsQueue) != 0))
|
||||
return false;
|
||||
|
||||
auto footpathObj = pathElement->GetPathEntry();
|
||||
if (footpathObj == nullptr)
|
||||
{
|
||||
if (_constructFlags & PathConstructFlag::IsPathObject)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pathElement->GetSurfaceEntryIndex() == _type && pathElement->GetRailingEntryIndex() == _railingsType;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_constructFlags & PathConstructFlag::IsPathObject)
|
||||
{
|
||||
return pathElement->GetPathEntryIndex() == _type;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GameActions::Result::Ptr FootpathPlaceAction::ElementUpdateQuery(PathElement* pathElement, GameActions::Result::Ptr res) const
|
||||
{
|
||||
if (pathElement->GetSurfaceEntryIndex() != _type || pathElement->GetRailingEntryIndex() != _railingsType
|
||||
|| pathElement->IsQueue() != _isQueue)
|
||||
if (!IsSameAsPathElement(pathElement))
|
||||
{
|
||||
res->Cost += MONEY(6, 00);
|
||||
}
|
||||
@@ -172,8 +202,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementUpdateQuery(PathElement* pa
|
||||
|
||||
GameActions::Result::Ptr FootpathPlaceAction::ElementUpdateExecute(PathElement* pathElement, GameActions::Result::Ptr res) const
|
||||
{
|
||||
if (pathElement->GetSurfaceEntryIndex() != _type || pathElement->GetRailingEntryIndex() != _railingsType
|
||||
|| pathElement->IsQueue() != _isQueue)
|
||||
if (!IsSameAsPathElement(pathElement))
|
||||
{
|
||||
res->Cost += MONEY(6, 00);
|
||||
}
|
||||
@@ -185,14 +214,22 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementUpdateExecute(PathElement*
|
||||
footpath_remove_edges_at(_loc, reinterpret_cast<TileElement*>(pathElement));
|
||||
}
|
||||
|
||||
pathElement->SetSurfaceEntryIndex(_type);
|
||||
pathElement->SetRailingEntryIndex(_railingsType);
|
||||
pathElement->SetIsQueue(_isQueue);
|
||||
if (_constructFlags & PathConstructFlag::IsPathObject)
|
||||
{
|
||||
pathElement->SetPathEntryIndex(_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
pathElement->SetSurfaceEntryIndex(_type);
|
||||
pathElement->SetRailingEntryIndex(_railingsType);
|
||||
}
|
||||
|
||||
pathElement->SetIsQueue((_constructFlags & PathConstructFlag::IsQueue) != 0);
|
||||
|
||||
rct_scenery_entry* elem = pathElement->GetAdditionEntry();
|
||||
if (elem != nullptr)
|
||||
{
|
||||
if (_isQueue)
|
||||
if (_constructFlags & PathConstructFlag::IsQueue)
|
||||
{
|
||||
// remove any addition that isn't a TV or a lamp
|
||||
if ((elem->path_bit.flags & PATH_BIT_FLAG_IS_QUEUE_SCREEN) == 0 && (elem->path_bit.flags & PATH_BIT_FLAG_LAMP) == 0)
|
||||
@@ -249,8 +286,9 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertQuery(GameActions::Re
|
||||
}
|
||||
|
||||
// Do not attempt to build a crossing with a queue or a sloped.
|
||||
uint8_t crossingMode = _isQueue || (_slope != TILE_ELEMENT_SLOPE_FLAT) ? CREATE_CROSSING_MODE_NONE
|
||||
: CREATE_CROSSING_MODE_PATH_OVER_TRACK;
|
||||
auto isQueue = _constructFlags & PathConstructFlag::IsQueue;
|
||||
uint8_t crossingMode = isQueue || (_slope != TILE_ELEMENT_SLOPE_FLAT) ? CREATE_CROSSING_MODE_NONE
|
||||
: CREATE_CROSSING_MODE_PATH_OVER_TRACK;
|
||||
if (!entrancePath
|
||||
&& !map_can_construct_with_clear_at(
|
||||
{ _loc, zLow, zHigh }, &map_place_non_scenery_clear_func, quarterTile, GetFlags(), &res->Cost, crossingMode))
|
||||
@@ -313,8 +351,9 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
|
||||
}
|
||||
|
||||
// Do not attempt to build a crossing with a queue or a sloped.
|
||||
uint8_t crossingMode = _isQueue || (_slope != TILE_ELEMENT_SLOPE_FLAT) ? CREATE_CROSSING_MODE_NONE
|
||||
: CREATE_CROSSING_MODE_PATH_OVER_TRACK;
|
||||
auto isQueue = _constructFlags & PathConstructFlag::IsQueue;
|
||||
uint8_t crossingMode = isQueue || (_slope != TILE_ELEMENT_SLOPE_FLAT) ? CREATE_CROSSING_MODE_NONE
|
||||
: CREATE_CROSSING_MODE_PATH_OVER_TRACK;
|
||||
if (!entrancePath
|
||||
&& !map_can_construct_with_clear_at(
|
||||
{ _loc, zLow, zHigh }, &map_place_non_scenery_clear_func, quarterTile, GAME_COMMAND_FLAG_APPLY | GetFlags(),
|
||||
@@ -338,7 +377,14 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
|
||||
{
|
||||
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !entranceIsSamePath)
|
||||
{
|
||||
entranceElement->SetSurfaceEntryIndex(_type);
|
||||
if (_constructFlags & PathConstructFlag::IsPathObject)
|
||||
{
|
||||
entranceElement->SetPathEntryIndex(_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
entranceElement->SetSurfaceEntryIndex(_type);
|
||||
}
|
||||
map_invalidate_tile_full(_loc);
|
||||
}
|
||||
}
|
||||
@@ -348,11 +394,18 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
|
||||
Guard::Assert(pathElement != nullptr);
|
||||
|
||||
pathElement->SetClearanceZ(zHigh);
|
||||
pathElement->SetSurfaceEntryIndex(_type);
|
||||
pathElement->SetRailingEntryIndex(_railingsType);
|
||||
if (_constructFlags & PathConstructFlag::IsPathObject)
|
||||
{
|
||||
pathElement->SetPathEntryIndex(_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
pathElement->SetSurfaceEntryIndex(_type);
|
||||
pathElement->SetRailingEntryIndex(_railingsType);
|
||||
}
|
||||
pathElement->SetSlopeDirection(_slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK);
|
||||
pathElement->SetSloped(_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED);
|
||||
pathElement->SetIsQueue(_isQueue);
|
||||
pathElement->SetIsQueue(isQueue);
|
||||
pathElement->SetAddition(0);
|
||||
pathElement->SetRideIndex(RIDE_ID_NULL);
|
||||
pathElement->SetAdditionStatus(255);
|
||||
|
||||
@@ -20,14 +20,13 @@ private:
|
||||
ObjectEntryIndex _type{};
|
||||
ObjectEntryIndex _railingsType{};
|
||||
Direction _direction{ INVALID_DIRECTION };
|
||||
bool _isQueue{};
|
||||
PathConstructFlags _constructFlags{};
|
||||
|
||||
public:
|
||||
FootpathPlaceAction() = default;
|
||||
FootpathPlaceAction(
|
||||
const CoordsXYZ& loc, uint8_t slope, ObjectEntryIndex type, ObjectEntryIndex railingsType,
|
||||
Direction direction = INVALID_DIRECTION,
|
||||
bool isQueue = false);
|
||||
Direction direction = INVALID_DIRECTION, PathConstructFlags constructFlags = 0);
|
||||
|
||||
void AcceptParameters(GameActionParameterVisitor & visitor) override;
|
||||
|
||||
@@ -45,4 +44,5 @@ private:
|
||||
void AutomaticallySetPeepSpawn() const;
|
||||
void RemoveIntersectingWalls(PathElement * pathElement) const;
|
||||
PathElement* map_get_footpath_element_slope(const CoordsXYZ& footpathPos, int32_t slope) const;
|
||||
bool IsSameAsPathElement(const PathElement* pathElement) const;
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ CoordsXYZ gFootpathProvisionalPosition;
|
||||
ObjectEntryIndex gFootpathProvisionalSurfaceIndex;
|
||||
ObjectEntryIndex gFootpathProvisionalRailingsIndex;
|
||||
uint8_t gFootpathProvisionalSlope;
|
||||
bool gFootpathProvisionalIsQueue;
|
||||
PathConstructFlags gFootpathProvisionalConstructFlags;
|
||||
uint8_t gFootpathConstructionMode;
|
||||
uint16_t gFootpathSelectedId;
|
||||
uint8_t gFootpathSelectedType;
|
||||
@@ -151,13 +151,14 @@ money32 footpath_remove(const CoordsXYZ& footpathLoc, int32_t flags)
|
||||
* rct2: 0x006A76FF
|
||||
*/
|
||||
money32 footpath_provisional_set(
|
||||
ObjectEntryIndex type, ObjectEntryIndex railingsType, const CoordsXYZ& footpathLoc, int32_t slope, bool isQueue)
|
||||
ObjectEntryIndex type, ObjectEntryIndex railingsType, const CoordsXYZ& footpathLoc, int32_t slope,
|
||||
PathConstructFlags constructFlags)
|
||||
{
|
||||
money32 cost;
|
||||
|
||||
footpath_provisional_remove();
|
||||
|
||||
auto footpathPlaceAction = FootpathPlaceAction(footpathLoc, slope, type, railingsType, INVALID_DIRECTION, isQueue);
|
||||
auto footpathPlaceAction = FootpathPlaceAction(footpathLoc, slope, type, railingsType, INVALID_DIRECTION, constructFlags);
|
||||
footpathPlaceAction.SetFlags(GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED);
|
||||
auto res = GameActions::Execute(&footpathPlaceAction);
|
||||
cost = res->Error == GameActions::Status::Ok ? res->Cost : MONEY32_UNDEFINED;
|
||||
@@ -167,7 +168,7 @@ money32 footpath_provisional_set(
|
||||
gFootpathProvisionalRailingsIndex = railingsType;
|
||||
gFootpathProvisionalPosition = footpathLoc;
|
||||
gFootpathProvisionalSlope = slope;
|
||||
gFootpathProvisionalIsQueue = isQueue;
|
||||
gFootpathProvisionalConstructFlags = constructFlags;
|
||||
gFootpathProvisionalFlags |= PROVISIONAL_PATH_FLAG_1;
|
||||
|
||||
if (gFootpathGroundFlags & ELEMENT_IS_UNDERGROUND)
|
||||
|
||||
@@ -155,12 +155,19 @@ enum
|
||||
FOOTPATH_CONNECTED_MAP_EDGE_IGNORE_NO_ENTRY = (1 << 7)
|
||||
};
|
||||
|
||||
using PathConstructFlags = uint8_t;
|
||||
namespace PathConstructFlag
|
||||
{
|
||||
constexpr PathConstructFlags IsQueue = 1 << 0;
|
||||
constexpr PathConstructFlags IsPathObject = 1 << 1;
|
||||
} // namespace PathConstructFlag
|
||||
|
||||
extern uint8_t gFootpathProvisionalFlags;
|
||||
extern CoordsXYZ gFootpathProvisionalPosition;
|
||||
extern ObjectEntryIndex gFootpathProvisionalSurfaceIndex;
|
||||
extern ObjectEntryIndex gFootpathProvisionalRailingsIndex;
|
||||
extern uint8_t gFootpathProvisionalSlope;
|
||||
extern bool gFootpathProvisionalIsQueue;
|
||||
extern PathConstructFlags gFootpathProvisionalConstructFlags;
|
||||
extern uint8_t gFootpathConstructionMode;
|
||||
extern uint16_t gFootpathSelectedId;
|
||||
extern uint8_t gFootpathSelectedType;
|
||||
@@ -180,7 +187,8 @@ TileElement* map_get_footpath_element(const CoordsXYZ& coords);
|
||||
void footpath_interrupt_peeps(const CoordsXYZ& footpathPos);
|
||||
money32 footpath_remove(const CoordsXYZ& footpathLoc, int32_t flags);
|
||||
money32 footpath_provisional_set(
|
||||
ObjectEntryIndex type, ObjectEntryIndex railingsType, const CoordsXYZ& footpathLoc, int32_t slope, bool isQueue);
|
||||
ObjectEntryIndex type, ObjectEntryIndex railingsType, const CoordsXYZ& footpathLoc, int32_t slope,
|
||||
PathConstructFlags constructFlags);
|
||||
void footpath_provisional_remove();
|
||||
void footpath_provisional_update();
|
||||
CoordsXY footpath_get_coordinates_from_pos(const ScreenCoordsXY& screenCoords, int32_t* direction, TileElement** tileElement);
|
||||
|
||||
@@ -1556,7 +1556,7 @@ void map_restore_provisional_elements()
|
||||
gFootpathProvisionalFlags &= ~PROVISIONAL_PATH_FLAG_1;
|
||||
footpath_provisional_set(
|
||||
gFootpathProvisionalSurfaceIndex, gFootpathProvisionalRailingsIndex, gFootpathProvisionalPosition,
|
||||
gFootpathProvisionalSlope, gFootpathProvisionalIsQueue);
|
||||
gFootpathProvisionalSlope, gFootpathProvisionalConstructFlags);
|
||||
}
|
||||
if (window_find_by_class(WC_RIDE_CONSTRUCTION) != nullptr)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user