1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-19 04:53:12 +01:00
Files
OpenRCT2/src/openrct2/actions/WaterSetHeightAction.cpp
Tulio Leao 9ef4931982 Move remaining game actions logic from header to source (#13573)
* Moving all definitions from R...Actions to source

* Moving all definitions from S...Actions to source

* Moving all definitions from T...Actions to source

* Moving all definitions from W...Actions to source
2020-12-12 07:18:38 +00:00

153 lines
4.3 KiB
C++

/*****************************************************************************
* Copyright (c) 2014-2020 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include "WaterSetHeightAction.h"
#include "../OpenRCT2.h"
#include "../management/Finance.h"
#include "../world/Park.h"
#include "../world/Surface.h"
WaterSetHeightAction::WaterSetHeightAction(const CoordsXY& coords, uint8_t height)
: _coords(coords)
, _height(height)
{
}
uint16_t WaterSetHeightAction::GetActionFlags() const
{
return GameAction::GetActionFlags();
}
void WaterSetHeightAction::Serialise(DataSerialiser& stream)
{
GameAction::Serialise(stream);
stream << DS_TAG(_coords) << DS_TAG(_height);
}
GameActions::Result::Ptr WaterSetHeightAction::Query() const
{
auto res = MakeResult();
res->Expenditure = ExpenditureType::Landscaping;
res->Position = { _coords, _height * COORDS_Z_STEP };
if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode
&& gParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES)
{
return MakeResult(GameActions::Status::Disallowed, STR_NONE, STR_FORBIDDEN_BY_THE_LOCAL_AUTHORITY);
}
rct_string_id errorMsg = CheckParameters();
if (errorMsg != STR_NONE)
{
return MakeResult(GameActions::Status::InvalidParameters, STR_NONE, errorMsg);
}
if (!LocationValid(_coords))
{
return MakeResult(GameActions::Status::NotOwned, STR_NONE, STR_LAND_NOT_OWNED_BY_PARK);
}
if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode)
{
if (!map_is_location_in_park(_coords))
{
return MakeResult(GameActions::Status::Disallowed, STR_NONE, STR_LAND_NOT_OWNED_BY_PARK);
}
}
SurfaceElement* surfaceElement = map_get_surface_element_at(_coords);
if (surfaceElement == nullptr)
{
log_error("Could not find surface element at: x %u, y %u", _coords.x, _coords.y);
return MakeResult(GameActions::Status::Unknown, STR_NONE);
}
int32_t zHigh = surfaceElement->GetBaseZ();
int32_t zLow = _height * COORDS_Z_STEP;
if (surfaceElement->GetWaterHeight() > 0)
{
zHigh = surfaceElement->GetWaterHeight();
}
if (zLow > zHigh)
{
int32_t temp = zHigh;
zHigh = zLow;
zLow = temp;
}
if (auto res2 = MapCanConstructAt({ _coords, zLow, zHigh }, { 0b1111, 0b1111 }); res2->Error != GameActions::Status::Ok)
{
return MakeResult(
GameActions::Status::NoClearance, STR_NONE, res2->ErrorMessage.GetStringId(), res2->ErrorMessageArgs.data());
}
if (surfaceElement->HasTrackThatNeedsWater())
{
return MakeResult(GameActions::Status::Disallowed, STR_NONE);
}
res->Cost = 250;
return res;
}
GameActions::Result::Ptr WaterSetHeightAction::Execute() const
{
auto res = MakeResult();
res->Expenditure = ExpenditureType::Landscaping;
res->Position = { _coords, _height * COORDS_Z_STEP };
int32_t surfaceHeight = tile_element_height(_coords);
footpath_remove_litter({ _coords, surfaceHeight });
if (!gCheatsDisableClearanceChecks)
wall_remove_at_z({ _coords, surfaceHeight });
SurfaceElement* surfaceElement = map_get_surface_element_at(_coords);
if (surfaceElement == nullptr)
{
log_error("Could not find surface element at: x %u, y %u", _coords.x, _coords.y);
return std::make_unique<GameActions::Result>(GameActions::Status::Unknown, STR_NONE);
}
if (_height > surfaceElement->base_height)
{
surfaceElement->SetWaterHeight(_height * COORDS_Z_STEP);
}
else
{
surfaceElement->SetWaterHeight(0);
}
map_invalidate_tile_full(_coords);
res->Cost = 250;
return res;
}
rct_string_id WaterSetHeightAction::CheckParameters() const
{
if (_coords.x > gMapSizeMaxXY || _coords.y > gMapSizeMaxXY)
{
return STR_OFF_EDGE_OF_MAP;
}
if (_height < MINIMUM_WATER_HEIGHT)
{
return STR_TOO_LOW;
}
if (_height > MAXIMUM_WATER_HEIGHT)
{
return STR_TOO_HIGH;
}
return STR_NONE;
}