Add WaterSetHeightAction

This commit is contained in:
duncanspumpkin 2019-02-28 17:08:58 +00:00
parent ec60781a2b
commit 61cb84e0ca
4 changed files with 187 additions and 8 deletions

View File

@ -47,6 +47,7 @@
#include "TrackPlaceAction.hpp"
#include "TrackRemoveAction.hpp"
#include "WallRemoveAction.hpp"
#include "WaterSetHeightAction.hpp"
namespace GameActions
{
@ -91,5 +92,6 @@ namespace GameActions
Register<ClearAction>();
Register<PauseToggleAction>();
Register<LoadOrQuitAction>();
Register<WaterSetHeightAction>();
}
} // namespace GameActions

View File

@ -0,0 +1,161 @@
/*****************************************************************************
* Copyright (c) 2014-2018 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.
*****************************************************************************/
#pragma once
#include "../world/Surface.h"
#include "GameAction.h"
DEFINE_GAME_ACTION(WaterSetHeightAction, GAME_COMMAND_SET_WATER_HEIGHT, GameActionResult)
{
private:
CoordsXY _coords;
uint8_t _height;
public:
WaterSetHeightAction()
{
}
WaterSetHeightAction(CoordsXY coords, uint8_t height)
: _coords(coords)
, _height(height)
{
}
uint16_t GetActionFlags() const override
{
return GameAction::GetActionFlags();
}
void Serialise(DataSerialiser & stream) override
{
GameAction::Serialise(stream);
stream << DS_TAG(_coords) << DS_TAG(_height);
}
GameActionResult::Ptr Query() const override
{
auto res = MakeResult();
res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING;
res->Position.x = _coords.x + 16;
res->Position.y = _coords.y + 16;
res->Position.z = _height * 8;
if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode
&& gParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES)
{
return MakeResult(GA_ERROR::DISALLOWED, STR_NONE, STR_FORBIDDEN_BY_THE_LOCAL_AUTHORITY);
}
rct_string_id errorMsg = CheckParameters();
if (errorMsg != STR_NONE)
{
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE, errorMsg);
}
if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode)
{
if (!map_is_location_in_park(_coords))
{
return MakeResult(GA_ERROR::DISALLOWED, STR_NONE, STR_LAND_NOT_OWNED_BY_PARK);
}
}
SurfaceElement* surfaceElement = map_get_surface_element_at(_coords)->AsSurface();
if (surfaceElement == nullptr)
{
log_error("Could not find surface element at: x %u, y %u", _coords.x, _coords.y);
return MakeResult(GA_ERROR::UNKNOWN, STR_NONE);
}
int32_t zHigh = surfaceElement->base_height;
int32_t zLow = _height;
if (surfaceElement->GetWaterHeight() > 0)
{
zHigh = surfaceElement->GetWaterHeight() * 2;
}
if (zLow > zHigh)
{
int32_t temp = zHigh;
zHigh = zLow;
zLow = temp;
}
if (!map_can_construct_at(_coords.x, _coords.y, zLow, zHigh, { 0b1111, 0b1111 }))
{
return MakeResult(GA_ERROR::NO_CLEARANCE, STR_NONE, gGameCommandErrorText, gCommonFormatArgs);
}
if (surfaceElement->HasTrackThatNeedsWater())
{
return MakeResult(GA_ERROR::DISALLOWED, STR_NONE);
}
res->Cost = 250;
return res;
}
GameActionResult::Ptr Execute() const override
{
auto res = MakeResult();
res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING;
res->Position.x = _coords.x + 16;
res->Position.y = _coords.y + 16;
res->Position.z = _height * 8;
int32_t surfaceHeight = tile_element_height(_coords.x, _coords.y) & 0xFFFF;
footpath_remove_litter(_coords.x, _coords.y, surfaceHeight);
if (!gCheatsDisableClearanceChecks)
wall_remove_at_z(_coords.x, _coords.y, surfaceHeight);
SurfaceElement* surfaceElement = map_get_surface_element_at(_coords)->AsSurface();
if (surfaceElement == nullptr)
{
log_error("Could not find surface element at: x %u, y %u", _coords.x, _coords.y);
return std::make_unique<GameActionResult>(GA_ERROR::UNKNOWN, STR_NONE);
}
if (_height > surfaceElement->base_height)
{
surfaceElement->SetWaterHeight(_height / 2);
}
else
{
surfaceElement->SetWaterHeight(0);
}
map_invalidate_tile_full(_coords.x, _coords.y);
res->Cost = 250;
return res;
}
private:
rct_string_id 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;
}
};

View File

@ -19,6 +19,7 @@
#include "../actions/LargeSceneryRemoveAction.hpp"
#include "../actions/SmallSceneryRemoveAction.hpp"
#include "../actions/WallRemoveAction.hpp"
#include "../actions/WaterSetHeightAction.hpp"
#include "../audio/audio.h"
#include "../config/Config.h"
#include "../core/Guard.hpp"
@ -1402,12 +1403,18 @@ money32 raise_water(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t flag
height = tile_element->base_height + 2;
}
money32 tileCost = game_do_command(
xi, flags, yi, (max_height << 8) + height, GAME_COMMAND_SET_WATER_HEIGHT, 0, 0);
if (tileCost == MONEY32_UNDEFINED)
auto waterSetHeightAction = WaterSetHeightAction({ xi, yi }, height);
waterSetHeightAction.SetFlags(flags);
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&waterSetHeightAction)
: GameActions::QueryNested(&waterSetHeightAction);
if (res->Error != GA_ERROR::OK)
{
gGameCommandErrorText = res->ErrorMessage;
// set gCommonFormatArguments to res->ErrorArgs
return MONEY32_UNDEFINED;
}
cost += tileCost;
cost += res->Cost;
waterHeightChanged = true;
}
}
@ -1490,11 +1497,18 @@ money32 lower_water(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t flag
if (height < min_height)
continue;
height -= 2;
int32_t tileCost = game_do_command(
xi, flags, yi, (min_height << 8) + height, GAME_COMMAND_SET_WATER_HEIGHT, 0, 0);
if (tileCost == MONEY32_UNDEFINED)
auto waterSetHeightAction = WaterSetHeightAction({ xi, yi }, height);
waterSetHeightAction.SetFlags(flags);
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&waterSetHeightAction)
: GameActions::QueryNested(&waterSetHeightAction);
if (res->Error != GA_ERROR::OK)
{
gGameCommandErrorText = res->ErrorMessage;
// set gCommonFormatArguments to res->ErrorArgs
return MONEY32_UNDEFINED;
cost += tileCost;
}
cost += res->Cost;
waterHeightChanged = true;
}
}

View File

@ -19,6 +19,8 @@
#define MINIMUM_LAND_HEIGHT 2
#define MAXIMUM_LAND_HEIGHT 142
#define MINIMUM_WATER_HEIGHT 2
#define MAXIMUM_WATER_HEIGHT 58
#define MINIMUM_MAP_SIZE_TECHNICAL 15
#define MAXIMUM_MAP_SIZE_TECHNICAL 256