mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #8914 from duncanspumpkin/buy_land_rights
Add landset/buyrights action
This commit is contained in:
commit
62e188586c
|
@ -119,6 +119,7 @@
|
|||
9346F9DC208A191900C77D91 /* GuestPathfinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9346F9D7208A191900C77D91 /* GuestPathfinding.cpp */; };
|
||||
9346F9DD208A191900C77D91 /* GuestPathfinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9346F9D7208A191900C77D91 /* GuestPathfinding.cpp */; };
|
||||
937A92152242CDAA00B09278 /* LandSmoothAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 937A92142242CDAA00B09278 /* LandSmoothAction.hpp */; };
|
||||
937A92132242CCB300B09278 /* LandBuyRightsAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 937A92122242CCB300B09278 /* LandBuyRightsAction.hpp */; };
|
||||
939A359A20C12FC800630B3F /* Paint.Litter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 939A359720C12FC700630B3F /* Paint.Litter.cpp */; };
|
||||
939A359B20C12FC800630B3F /* Paint.Misc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 939A359820C12FC700630B3F /* Paint.Misc.cpp */; };
|
||||
939A359C20C12FC800630B3F /* Paint.Sprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 939A359920C12FC700630B3F /* Paint.Sprite.h */; };
|
||||
|
@ -1243,6 +1244,7 @@
|
|||
9350B52820B46E0900897BC5 /* ftrender.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ftrender.h; sourceTree = "<group>"; };
|
||||
9350B52920B46E0900897BC5 /* ft2build.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ft2build.h; sourceTree = "<group>"; };
|
||||
937A92142242CDAA00B09278 /* LandSmoothAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LandSmoothAction.hpp; sourceTree = "<group>"; };
|
||||
937A92122242CCB300B09278 /* LandBuyRightsAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LandBuyRightsAction.hpp; sourceTree = "<group>"; };
|
||||
939A359720C12FC700630B3F /* Paint.Litter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Paint.Litter.cpp; sourceTree = "<group>"; };
|
||||
939A359820C12FC700630B3F /* Paint.Misc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Paint.Misc.cpp; sourceTree = "<group>"; };
|
||||
939A359920C12FC700630B3F /* Paint.Sprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Paint.Sprite.h; sourceTree = "<group>"; };
|
||||
|
@ -2155,6 +2157,7 @@
|
|||
C9C630BD2235A9C6009AD16E /* FootpathPlaceFromTrackAction.hpp */,
|
||||
C9C630BB2235A7F9009AD16E /* WaterLowerAction.hpp */,
|
||||
C9C630BC2235A7F9009AD16E /* WaterRaiseAction.hpp */,
|
||||
937A92122242CCB300B09278 /* LandBuyRightsAction.hpp */,
|
||||
C9C630BA2235A7E7009AD16E /* LandLowerAction.hpp */,
|
||||
C9C630B92235A7E7009AD16E /* LandRaiseAction.hpp */,
|
||||
937A92142242CDAA00B09278 /* LandSmoothAction.hpp */,
|
||||
|
@ -3535,6 +3538,7 @@
|
|||
2A43D2C02225B91A00E8F73B /* RideSetVehiclesAction.hpp in Headers */,
|
||||
2ADE2F1C2244187B002598AF /* ParkSetNameAction.hpp in Headers */,
|
||||
2AA050322209A8E300D3A922 /* StaffSetCostumeAction.hpp in Headers */,
|
||||
937A92132242CCB300B09278 /* LandBuyRightsAction.hpp in Headers */,
|
||||
2A61CAF72229E5720095AD67 /* FootpathPlaceAction.hpp in Headers */,
|
||||
2A43D2C22225B91A00E8F73B /* LoadOrQuitAction.hpp in Headers */,
|
||||
C62D838B1FD36D6F008C04F1 /* EditorObjectSelectionSession.h in Headers */,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <openrct2/Context.h>
|
||||
#include <openrct2/Game.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/actions/LandBuyRightsAction.hpp>
|
||||
#include <openrct2/drawing/Drawing.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include <openrct2/world/Park.h>
|
||||
|
@ -364,11 +365,13 @@ static void window_land_rights_tool_update_land_rights(int16_t x, int16_t y)
|
|||
if (!state_changed)
|
||||
return;
|
||||
|
||||
_landRightsCost = game_do_command(
|
||||
gMapSelectPositionA.x, GAME_COMMAND_FLAG_NO_SPEND, gMapSelectPositionA.y,
|
||||
(_landRightsMode == LAND_RIGHTS_MODE_BUY_LAND) ? BUY_LAND_RIGHTS_FLAG_BUY_LAND
|
||||
: BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS,
|
||||
GAME_COMMAND_BUY_LAND_RIGHTS, gMapSelectPositionB.x, gMapSelectPositionB.y);
|
||||
auto landBuyRightsAction = LandBuyRightsAction(
|
||||
{ gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y },
|
||||
(_landRightsMode == LAND_RIGHTS_MODE_BUY_LAND) ? LandBuyRightSetting::BuyLand
|
||||
: LandBuyRightSetting::BuyConstructionRights);
|
||||
auto res = GameActions::Query(&landBuyRightsAction);
|
||||
|
||||
_landRightsCost = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -407,21 +410,20 @@ static void window_land_rights_tooldown(rct_window* w, rct_widgetindex widgetInd
|
|||
{
|
||||
if (x != LOCATION_NULL)
|
||||
{
|
||||
gGameCommandErrorTitle = STR_CANT_BUY_LAND;
|
||||
game_do_command(
|
||||
gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y, BUY_LAND_RIGHTS_FLAG_BUY_LAND,
|
||||
GAME_COMMAND_BUY_LAND_RIGHTS, gMapSelectPositionB.x, gMapSelectPositionB.y);
|
||||
auto landBuyRightsAction = LandBuyRightsAction(
|
||||
{ gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y },
|
||||
LandBuyRightSetting::BuyLand);
|
||||
GameActions::Execute(&landBuyRightsAction);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x != LOCATION_NULL)
|
||||
{
|
||||
gGameCommandErrorTitle = STR_CANT_BUY_CONSTRUCTION_RIGHTS_HERE;
|
||||
game_do_command(
|
||||
gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y,
|
||||
BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS, GAME_COMMAND_BUY_LAND_RIGHTS, gMapSelectPositionB.x,
|
||||
gMapSelectPositionB.y);
|
||||
auto landBuyRightsAction = LandBuyRightsAction(
|
||||
{ gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y },
|
||||
LandBuyRightSetting::BuyConstructionRights);
|
||||
GameActions::Execute(&landBuyRightsAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -436,21 +438,20 @@ static void window_land_rights_tooldrag(rct_window* w, rct_widgetindex widgetInd
|
|||
{
|
||||
if (x != LOCATION_NULL)
|
||||
{
|
||||
gGameCommandErrorTitle = STR_CANT_BUY_LAND;
|
||||
game_do_command(
|
||||
gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y, BUY_LAND_RIGHTS_FLAG_BUY_LAND,
|
||||
GAME_COMMAND_BUY_LAND_RIGHTS, gMapSelectPositionB.x, gMapSelectPositionB.y);
|
||||
auto landBuyRightsAction = LandBuyRightsAction(
|
||||
{ gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y },
|
||||
LandBuyRightSetting::BuyLand);
|
||||
GameActions::Execute(&landBuyRightsAction);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x != LOCATION_NULL)
|
||||
{
|
||||
gGameCommandErrorTitle = STR_CANT_BUY_CONSTRUCTION_RIGHTS_HERE;
|
||||
game_do_command(
|
||||
gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y,
|
||||
BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS, GAME_COMMAND_BUY_LAND_RIGHTS, gMapSelectPositionB.x,
|
||||
gMapSelectPositionB.y);
|
||||
auto landBuyRightsAction = LandBuyRightsAction(
|
||||
{ gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y },
|
||||
LandBuyRightSetting::BuyConstructionRights);
|
||||
GameActions::Execute(&landBuyRightsAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <openrct2/Game.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
#include <openrct2/actions/LandSetRightsAction.hpp>
|
||||
#include <openrct2/actions/SurfaceSetStyleAction.hpp>
|
||||
#include <openrct2/audio/audio.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
|
@ -505,10 +506,10 @@ static void window_map_tooldrag(rct_window* w, rct_widgetindex widgetIndex, int3
|
|||
case WIDX_SET_LAND_RIGHTS:
|
||||
if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE)
|
||||
{
|
||||
gGameCommandErrorTitle = 0;
|
||||
game_do_command(
|
||||
gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y, _activeTool,
|
||||
GAME_COMMAND_SET_LAND_OWNERSHIP, gMapSelectPositionB.x, gMapSelectPositionB.y);
|
||||
auto landSetRightsAction = LandSetRightsAction(
|
||||
{ gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y },
|
||||
LandSetRightSetting::SetOwnershipWithChecks, _activeTool << 4);
|
||||
GameActions::Execute(&landSetRightsAction);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -614,10 +615,10 @@ static void window_map_scrollmousedown(rct_window* w, int32_t scrollIndex, int32
|
|||
gMapSelectPositionB.y = mapY + size;
|
||||
map_invalidate_selection_rect();
|
||||
|
||||
gGameCommandErrorTitle = 0;
|
||||
game_do_command(
|
||||
gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y, _activeTool, GAME_COMMAND_SET_LAND_OWNERSHIP,
|
||||
gMapSelectPositionB.x, gMapSelectPositionB.y);
|
||||
auto landSetRightsAction = LandSetRightsAction(
|
||||
{ gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y },
|
||||
LandSetRightSetting::SetOwnershipWithChecks, _activeTool << 4);
|
||||
GameActions::Execute(&landSetRightsAction);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include "GameState.h"
|
||||
#include "OpenRCT2.h"
|
||||
#include "ParkImporter.h"
|
||||
#include "actions/LandBuyRightsAction.hpp"
|
||||
#include "actions/LandSetRightsAction.hpp"
|
||||
#include "audio/audio.h"
|
||||
#include "interface/Viewport.h"
|
||||
#include "localisation/Localisation.h"
|
||||
|
@ -193,7 +195,14 @@ namespace Editor
|
|||
{
|
||||
int32_t mapSize = gMapSize;
|
||||
|
||||
game_do_command(64, 1, 64, 2, GAME_COMMAND_SET_LAND_OWNERSHIP, (mapSize - 3) * 32, (mapSize - 3) * 32);
|
||||
MapRange range = { 64, 64, (mapSize - 3) * 32, (mapSize - 3) * 32 };
|
||||
auto landSetRightsAction = LandSetRightsAction(range, LandSetRightSetting::SetForSale);
|
||||
landSetRightsAction.SetFlags(GAME_COMMAND_FLAG_NO_SPEND);
|
||||
GameActions::Execute(&landSetRightsAction);
|
||||
|
||||
auto landBuyRightsAction = LandBuyRightsAction(range, LandBuyRightSetting::BuyLand);
|
||||
landBuyRightsAction.SetFlags(GAME_COMMAND_FLAG_NO_SPEND);
|
||||
GameActions::Execute(&landBuyRightsAction);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1191,7 +1191,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = {
|
|||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
game_command_buy_land_rights,
|
||||
nullptr,
|
||||
game_command_place_park_entrance,
|
||||
nullptr,
|
||||
game_command_set_maze_track,
|
||||
|
@ -1212,7 +1212,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = {
|
|||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
game_command_set_land_ownership,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
|
|
|
@ -54,7 +54,7 @@ enum GAME_COMMAND
|
|||
GAME_COMMAND_SET_STAFF_ORDERS, // GA
|
||||
GAME_COMMAND_SET_PARK_NAME, // GA
|
||||
GAME_COMMAND_SET_PARK_OPEN, // GA
|
||||
GAME_COMMAND_BUY_LAND_RIGHTS,
|
||||
GAME_COMMAND_BUY_LAND_RIGHTS, // GA
|
||||
GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA
|
||||
GAME_COMMAND_REMOVE_PARK_ENTRANCE, // GA
|
||||
GAME_COMMAND_SET_MAZE_TRACK, // GA
|
||||
|
@ -75,7 +75,7 @@ enum GAME_COMMAND
|
|||
GAME_COMMAND_SET_WALL_COLOUR, // GA
|
||||
GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, // GA
|
||||
GAME_COMMAND_SET_BANNER_COLOUR, // GA
|
||||
GAME_COMMAND_SET_LAND_OWNERSHIP,
|
||||
GAME_COMMAND_SET_LAND_OWNERSHIP, // GA
|
||||
GAME_COMMAND_CLEAR_SCENERY, // GA
|
||||
GAME_COMMAND_SET_BANNER_NAME, // GA
|
||||
GAME_COMMAND_SET_SIGN_NAME, // GA
|
||||
|
|
|
@ -22,9 +22,11 @@
|
|||
#include "GameAction.h"
|
||||
#include "GuestSetFlagsAction.hpp"
|
||||
#include "GuestSetNameAction.hpp"
|
||||
#include "LandBuyRightsAction.hpp"
|
||||
#include "LandLowerAction.hpp"
|
||||
#include "LandRaiseAction.hpp"
|
||||
#include "LandSetHeightAction.hpp"
|
||||
#include "LandSetRightsAction.hpp"
|
||||
#include "LandSmoothAction.hpp"
|
||||
#include "LargeSceneryPlaceAction.hpp"
|
||||
#include "LargeSceneryRemoveAction.hpp"
|
||||
|
@ -135,9 +137,11 @@ namespace GameActions
|
|||
Register<LargeSceneryPlaceAction>();
|
||||
Register<LargeSceneryRemoveAction>();
|
||||
Register<LargeScenerySetColourAction>();
|
||||
Register<LandBuyRightsAction>();
|
||||
Register<LandLowerAction>();
|
||||
Register<LandRaiseAction>();
|
||||
Register<LandSetHeightAction>();
|
||||
Register<LandSetRightsAction>();
|
||||
Register<LandSmoothAction>();
|
||||
Register<TrackPlaceAction>();
|
||||
Register<TrackRemoveAction>();
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2019 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 "../Context.h"
|
||||
#include "../OpenRCT2.h"
|
||||
#include "../actions/LandSetHeightAction.hpp"
|
||||
#include "../audio/audio.h"
|
||||
#include "../interface/Window.h"
|
||||
#include "../localisation/Localisation.h"
|
||||
#include "../localisation/StringIds.h"
|
||||
#include "../management/Finance.h"
|
||||
#include "../ride/RideData.h"
|
||||
#include "../windows/Intent.h"
|
||||
#include "../world/Park.h"
|
||||
#include "../world/Scenery.h"
|
||||
#include "../world/Sprite.h"
|
||||
#include "../world/Surface.h"
|
||||
#include "GameAction.h"
|
||||
|
||||
enum class LandBuyRightSetting : uint8_t
|
||||
{
|
||||
BuyLand,
|
||||
BuyConstructionRights,
|
||||
Count
|
||||
};
|
||||
|
||||
DEFINE_GAME_ACTION(LandBuyRightsAction, GAME_COMMAND_BUY_LAND_RIGHTS, GameActionResult)
|
||||
{
|
||||
private:
|
||||
MapRange _range;
|
||||
uint8_t _setting = static_cast<uint8_t>(LandBuyRightSetting::Count);
|
||||
|
||||
constexpr static rct_string_id _ErrorTitles[] = { STR_CANT_BUY_LAND, STR_CANT_BUY_CONSTRUCTION_RIGHTS_HERE };
|
||||
|
||||
public:
|
||||
LandBuyRightsAction() = default;
|
||||
|
||||
LandBuyRightsAction(MapRange range, LandBuyRightSetting setting)
|
||||
: _range(range)
|
||||
, _setting(static_cast<uint8_t>(setting))
|
||||
{
|
||||
}
|
||||
|
||||
LandBuyRightsAction(CoordsXY coord, LandBuyRightSetting setting)
|
||||
: _range(coord.x, coord.y, coord.x, coord.y)
|
||||
, _setting(static_cast<uint8_t>(setting))
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t GetActionFlags() const override
|
||||
{
|
||||
return GameAction::GetActionFlags();
|
||||
}
|
||||
|
||||
void Serialise(DataSerialiser & stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << DS_TAG(_range) << DS_TAG(_setting);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
{
|
||||
return QueryExecute(false);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Execute() const override
|
||||
{
|
||||
return QueryExecute(true);
|
||||
}
|
||||
|
||||
private:
|
||||
GameActionResult::Ptr QueryExecute(bool isExecuting) const
|
||||
{
|
||||
auto res = MakeResult();
|
||||
|
||||
MapRange normRange = _range.Normalise();
|
||||
// Keep big coordinates within map boundaries
|
||||
auto aX = std::max<decltype(normRange.GetLeft())>(32, normRange.GetLeft());
|
||||
auto bX = std::min<decltype(normRange.GetRight())>(gMapSizeMaxXY, normRange.GetRight());
|
||||
auto aY = std::max<decltype(normRange.GetTop())>(32, normRange.GetTop());
|
||||
auto bY = std::min<decltype(normRange.GetBottom())>(gMapSizeMaxXY, normRange.GetBottom());
|
||||
|
||||
MapRange validRange = MapRange{ aX, aY, bX, bY };
|
||||
|
||||
CoordsXYZ centre{ (validRange.GetLeft() + validRange.GetRight()) / 2 + 16,
|
||||
(validRange.GetTop() + validRange.GetBottom()) / 2 + 16, 0 };
|
||||
centre.z = tile_element_height(centre.x, centre.y);
|
||||
|
||||
res->Position = centre;
|
||||
res->ExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE;
|
||||
|
||||
// Game command modified to accept selection size
|
||||
for (auto y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32)
|
||||
{
|
||||
for (auto x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32)
|
||||
{
|
||||
auto result = map_buy_land_rights_for_tile({ x, y }, isExecuting);
|
||||
if (result->Error == GA_ERROR::OK)
|
||||
{
|
||||
res->Cost += result->Cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isExecuting)
|
||||
{
|
||||
map_count_remaining_land_rights();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
GameActionResult::Ptr map_buy_land_rights_for_tile(const CoordsXY loc, bool isExecuting) const
|
||||
{
|
||||
if (_setting >= static_cast<uint8_t>(LandBuyRightSetting::Count))
|
||||
{
|
||||
log_warning("Tried calling buy land rights with an incorrect setting. setting = %u", _setting);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, _ErrorTitles[0], STR_NONE);
|
||||
}
|
||||
|
||||
SurfaceElement* surfaceElement = map_get_surface_element_at(loc)->AsSurface();
|
||||
if (surfaceElement == nullptr)
|
||||
{
|
||||
log_error("Could not find surface. x = %d, y = %d", loc.x, loc.y);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, _ErrorTitles[_setting], STR_NONE);
|
||||
}
|
||||
|
||||
auto res = MakeResult();
|
||||
switch (static_cast<LandBuyRightSetting>(_setting))
|
||||
{
|
||||
case LandBuyRightSetting::BuyLand: // 0
|
||||
if ((surfaceElement->GetOwnership() & OWNERSHIP_OWNED) != 0)
|
||||
{ // If the land is already owned
|
||||
return res;
|
||||
}
|
||||
|
||||
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0
|
||||
|| (surfaceElement->GetOwnership() & OWNERSHIP_AVAILABLE) == 0)
|
||||
{
|
||||
return MakeResult(GA_ERROR::NOT_OWNED, _ErrorTitles[_setting], STR_LAND_NOT_FOR_SALE);
|
||||
}
|
||||
if (isExecuting)
|
||||
{
|
||||
surfaceElement->SetOwnership(OWNERSHIP_OWNED);
|
||||
update_park_fences_around_tile(loc);
|
||||
}
|
||||
res->Cost = gLandPrice;
|
||||
return res;
|
||||
|
||||
case LandBuyRightSetting::BuyConstructionRights: // 2
|
||||
if ((surfaceElement->GetOwnership() & (OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)) != 0)
|
||||
{ // If the land or construction rights are already owned
|
||||
return res;
|
||||
}
|
||||
|
||||
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0
|
||||
|| (surfaceElement->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) == 0)
|
||||
{
|
||||
return MakeResult(GA_ERROR::NOT_OWNED, _ErrorTitles[_setting], STR_CONSTRUCTION_RIGHTS_NOT_FOR_SALE);
|
||||
}
|
||||
|
||||
if (isExecuting)
|
||||
{
|
||||
surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED);
|
||||
uint16_t baseHeight = surfaceElement->base_height * 8;
|
||||
map_invalidate_tile(loc.x, loc.y, baseHeight, baseHeight + 16);
|
||||
}
|
||||
res->Cost = gConstructionRightsPrice;
|
||||
return res;
|
||||
|
||||
default:
|
||||
log_warning("Tried calling buy land rights with an incorrect setting. setting = %u", _setting);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, _ErrorTitles[0], STR_NONE);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,233 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2019 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 "../Context.h"
|
||||
#include "../OpenRCT2.h"
|
||||
#include "../actions/LandSetHeightAction.hpp"
|
||||
#include "../audio/audio.h"
|
||||
#include "../interface/Window.h"
|
||||
#include "../localisation/Localisation.h"
|
||||
#include "../localisation/StringIds.h"
|
||||
#include "../management/Finance.h"
|
||||
#include "../ride/RideData.h"
|
||||
#include "../windows/Intent.h"
|
||||
#include "../world/Park.h"
|
||||
#include "../world/Scenery.h"
|
||||
#include "../world/Sprite.h"
|
||||
#include "../world/Surface.h"
|
||||
#include "GameAction.h"
|
||||
|
||||
enum class LandSetRightSetting : uint8_t
|
||||
{
|
||||
UnownLand,
|
||||
UnownConstructionRights,
|
||||
SetForSale,
|
||||
SetConstructionRightsForSale,
|
||||
SetOwnershipWithChecks,
|
||||
Count
|
||||
};
|
||||
|
||||
DEFINE_GAME_ACTION(LandSetRightsAction, GAME_COMMAND_SET_LAND_OWNERSHIP, GameActionResult)
|
||||
{
|
||||
private:
|
||||
MapRange _range;
|
||||
uint8_t _setting = static_cast<uint8_t>(LandSetRightSetting::Count);
|
||||
uint8_t _ownership = 0;
|
||||
|
||||
public:
|
||||
LandSetRightsAction() = default;
|
||||
|
||||
LandSetRightsAction(MapRange range, LandSetRightSetting setting, uint8_t ownership = 0)
|
||||
: _range(range)
|
||||
, _setting(static_cast<uint8_t>(setting))
|
||||
, _ownership(ownership)
|
||||
{
|
||||
}
|
||||
|
||||
LandSetRightsAction(CoordsXY coord, LandSetRightSetting setting, uint8_t ownership = 0)
|
||||
: _range(coord.x, coord.y, coord.x, coord.y)
|
||||
, _setting(static_cast<uint8_t>(setting))
|
||||
, _ownership(ownership)
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t GetActionFlags() const override
|
||||
{
|
||||
return GameAction::GetActionFlags() | GA_FLAGS::EDITOR_ONLY;
|
||||
}
|
||||
|
||||
void Serialise(DataSerialiser & stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << DS_TAG(_range) << DS_TAG(_setting) << DS_TAG(_ownership);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
{
|
||||
return QueryExecute(false);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Execute() const override
|
||||
{
|
||||
return QueryExecute(true);
|
||||
}
|
||||
|
||||
private:
|
||||
GameActionResult::Ptr QueryExecute(bool isExecuting) const
|
||||
{
|
||||
auto res = MakeResult();
|
||||
|
||||
MapRange normRange = _range.Normalise();
|
||||
// Keep big coordinates within map boundaries
|
||||
auto aX = std::max<decltype(normRange.GetLeft())>(32, normRange.GetLeft());
|
||||
auto bX = std::min<decltype(normRange.GetRight())>(gMapSizeMaxXY, normRange.GetRight());
|
||||
auto aY = std::max<decltype(normRange.GetTop())>(32, normRange.GetTop());
|
||||
auto bY = std::min<decltype(normRange.GetBottom())>(gMapSizeMaxXY, normRange.GetBottom());
|
||||
|
||||
MapRange validRange = MapRange{ aX, aY, bX, bY };
|
||||
|
||||
CoordsXYZ centre{ (validRange.GetLeft() + validRange.GetRight()) / 2 + 16,
|
||||
(validRange.GetTop() + validRange.GetBottom()) / 2 + 16, 0 };
|
||||
centre.z = tile_element_height(centre.x, centre.y);
|
||||
|
||||
res->Position = centre;
|
||||
res->ExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE;
|
||||
|
||||
if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !gCheatsSandboxMode)
|
||||
{
|
||||
return MakeResult(GA_ERROR::NOT_IN_EDITOR_MODE, STR_NONE, STR_LAND_NOT_FOR_SALE);
|
||||
}
|
||||
|
||||
// Game command modified to accept selection size
|
||||
for (auto y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32)
|
||||
{
|
||||
for (auto x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32)
|
||||
{
|
||||
auto result = map_buy_land_rights_for_tile({ x, y }, isExecuting);
|
||||
if (result->Error == GA_ERROR::OK)
|
||||
{
|
||||
res->Cost += result->Cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isExecuting)
|
||||
{
|
||||
map_count_remaining_land_rights();
|
||||
audio_play_sound_at_location(SOUND_PLACE_ITEM, centre.x, centre.y, centre.z);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
GameActionResult::Ptr map_buy_land_rights_for_tile(const CoordsXY loc, bool isExecuting) const
|
||||
{
|
||||
SurfaceElement* surfaceElement = map_get_surface_element_at(loc)->AsSurface();
|
||||
if (surfaceElement == nullptr)
|
||||
{
|
||||
log_error("Could not find surface. x = %d, y = %d", loc.x, loc.y);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE, STR_NONE);
|
||||
}
|
||||
|
||||
auto res = MakeResult();
|
||||
switch (static_cast<LandSetRightSetting>(_setting))
|
||||
{
|
||||
case LandSetRightSetting::UnownLand:
|
||||
if (isExecuting)
|
||||
{
|
||||
surfaceElement->SetOwnership(
|
||||
surfaceElement->GetOwnership() & ~(OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED));
|
||||
update_park_fences_around_tile(loc);
|
||||
}
|
||||
return res;
|
||||
case LandSetRightSetting::UnownConstructionRights:
|
||||
if (isExecuting)
|
||||
{
|
||||
surfaceElement->SetOwnership(surfaceElement->GetOwnership() & ~OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED);
|
||||
uint16_t baseHeight = surfaceElement->base_height * 8;
|
||||
map_invalidate_tile(loc.x, loc.y, baseHeight, baseHeight + 16);
|
||||
}
|
||||
return res;
|
||||
case LandSetRightSetting::SetForSale:
|
||||
if (isExecuting)
|
||||
{
|
||||
surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_AVAILABLE);
|
||||
uint16_t baseHeight = surfaceElement->base_height * 8;
|
||||
map_invalidate_tile(loc.x, loc.y, baseHeight, baseHeight + 16);
|
||||
}
|
||||
return res;
|
||||
case LandSetRightSetting::SetConstructionRightsForSale:
|
||||
if (isExecuting)
|
||||
{
|
||||
surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE);
|
||||
uint16_t baseHeight = surfaceElement->base_height * 8;
|
||||
map_invalidate_tile(loc.x, loc.y, baseHeight, baseHeight + 16);
|
||||
}
|
||||
return res;
|
||||
case LandSetRightSetting::SetOwnershipWithChecks:
|
||||
{
|
||||
if (_ownership == surfaceElement->GetOwnership())
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
TileElement* tileElement = map_get_first_element_at(loc.x / 32, loc.y / 32);
|
||||
do
|
||||
{
|
||||
if (tileElement == nullptr)
|
||||
break;
|
||||
|
||||
if (tileElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE)
|
||||
continue;
|
||||
|
||||
if (tileElement->AsEntrance()->GetEntranceType() != ENTRANCE_TYPE_PARK_ENTRANCE)
|
||||
continue;
|
||||
|
||||
// Do not allow ownership of park entrance.
|
||||
if (_ownership == OWNERSHIP_OWNED || _ownership == OWNERSHIP_AVAILABLE)
|
||||
return res;
|
||||
|
||||
// Allow construction rights available / for sale on park entrances on surface.
|
||||
// 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)
|
||||
return res;
|
||||
}
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
|
||||
res->Cost = gLandPrice;
|
||||
if (isExecuting)
|
||||
{
|
||||
if (_ownership != OWNERSHIP_UNOWNED)
|
||||
{
|
||||
gPeepSpawns.erase(
|
||||
std::remove_if(
|
||||
gPeepSpawns.begin(), gPeepSpawns.end(),
|
||||
[x = loc.x, y = loc.y](const auto& spawn) {
|
||||
return floor2(spawn.x, 32) == x && floor2(spawn.y, 32) == y;
|
||||
}),
|
||||
gPeepSpawns.end());
|
||||
}
|
||||
surfaceElement->SetOwnership(_ownership);
|
||||
update_park_fences_around_tile(loc);
|
||||
gMapLandRightsUpdateSuccess = true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
default:
|
||||
log_warning("Tried calling set land rights with an incorrect setting. setting = %u", _setting);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE, STR_NONE);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -32,7 +32,7 @@
|
|||
// This string specifies which version of network stream current build uses.
|
||||
// It is used for making sure only compatible builds get connected, even within
|
||||
// single OpenRCT2 version.
|
||||
#define NETWORK_STREAM_VERSION "27"
|
||||
#define NETWORK_STREAM_VERSION "28"
|
||||
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
|
||||
|
||||
static Peep* _pickup_peep = nullptr;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "../OpenRCT2.h"
|
||||
#include "../actions/FootpathPlaceAction.hpp"
|
||||
#include "../actions/FootpathRemoveAction.hpp"
|
||||
#include "../actions/LandSetRightsAction.hpp"
|
||||
#include "../core/Guard.hpp"
|
||||
#include "../localisation/Localisation.h"
|
||||
#include "../management/Finance.h"
|
||||
|
@ -1238,7 +1239,9 @@ static void footpath_fix_ownership(int32_t x, int32_t y)
|
|||
ownership = OWNERSHIP_UNOWNED;
|
||||
}
|
||||
|
||||
map_buy_land_rights(x, y, x, y, BUY_LAND_RIGHTS_FLAG_SET_OWNERSHIP_WITH_CHECKS, (ownership << 4) | GAME_COMMAND_FLAG_APPLY);
|
||||
auto landSetRightsAction = LandSetRightsAction({ x, y }, LandSetRightSetting::SetOwnershipWithChecks, ownership);
|
||||
landSetRightsAction.SetFlags(GAME_COMMAND_FLAG_NO_SPEND);
|
||||
GameActions::Execute(&landSetRightsAction);
|
||||
}
|
||||
|
||||
static bool get_next_direction(int32_t edges, int32_t* direction)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "../actions/LandLowerAction.hpp"
|
||||
#include "../actions/LandRaiseAction.hpp"
|
||||
#include "../actions/LandSetHeightAction.hpp"
|
||||
#include "../actions/LandSetRightsAction.hpp"
|
||||
#include "../actions/LargeSceneryRemoveAction.hpp"
|
||||
#include "../actions/ParkEntranceRemoveAction.hpp"
|
||||
#include "../actions/SmallSceneryRemoveAction.hpp"
|
||||
|
@ -924,52 +925,6 @@ int32_t tile_element_get_corner_height(const TileElement* tileElement, int32_t d
|
|||
return map_get_corner_height(z, slope, direction);
|
||||
}
|
||||
|
||||
static money32 map_set_land_ownership(uint8_t flags, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t newOwnership)
|
||||
{
|
||||
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE;
|
||||
|
||||
if (!(flags & GAME_COMMAND_FLAG_APPLY))
|
||||
return 0;
|
||||
|
||||
// Clamp to maximum addressable element to prevent long loop spamming the log
|
||||
x1 = std::clamp<int16_t>(x1, 32, gMapSizeUnits - 32);
|
||||
y1 = std::clamp<int16_t>(y1, 32, gMapSizeUnits - 32);
|
||||
x2 = std::clamp<int16_t>(x2, 32, gMapSizeUnits - 32);
|
||||
y2 = std::clamp<int16_t>(y2, 32, gMapSizeUnits - 32);
|
||||
gMapLandRightsUpdateSuccess = false;
|
||||
map_buy_land_rights(x1, y1, x2, y2, BUY_LAND_RIGHTS_FLAG_SET_OWNERSHIP_WITH_CHECKS, flags | (newOwnership << 8));
|
||||
|
||||
if (!gMapLandRightsUpdateSuccess)
|
||||
return 0;
|
||||
|
||||
int16_t x = std::clamp<int16_t>(x1, 32, gMapSizeUnits - 32);
|
||||
int16_t y = std::clamp<int16_t>(y1, 32, gMapSizeUnits - 32);
|
||||
|
||||
x += 16;
|
||||
y += 16;
|
||||
|
||||
int16_t z = tile_element_height(x, y);
|
||||
audio_play_sound_at_location(SOUND_PLACE_ITEM, x, y, z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006648E3
|
||||
*/
|
||||
void game_command_set_land_ownership(
|
||||
int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp)
|
||||
{
|
||||
int32_t flags = *ebx & 0xFF;
|
||||
|
||||
*ebx = map_set_land_ownership(flags, *eax & 0xFFFF, *ecx & 0xFFFF, *edi & 0xFFFF, *ebp & 0xFFFF, *edx & 0xFF);
|
||||
|
||||
if (flags & GAME_COMMAND_FLAG_APPLY)
|
||||
{
|
||||
map_count_remaining_land_rights();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t map_get_lowest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax)
|
||||
{
|
||||
xMin = std::max(xMin, 32);
|
||||
|
@ -1648,7 +1603,13 @@ void map_remove_out_of_range_elements()
|
|||
{
|
||||
if (x == 0 || y == 0 || x >= mapMaxXY || y >= mapMaxXY)
|
||||
{
|
||||
map_buy_land_rights(x, y, x, y, BUY_LAND_RIGHTS_FLAG_UNOWN_TILE, GAME_COMMAND_FLAG_APPLY);
|
||||
// Note this purposely does not use LandSetRightsAction as X Y coordinates are outside of normal range.
|
||||
auto surfaceElement = map_get_surface_element_at({ x, y });
|
||||
if (surfaceElement != nullptr)
|
||||
{
|
||||
surfaceElement->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED);
|
||||
update_park_fences_around_tile({ x, y });
|
||||
}
|
||||
clear_elements_at(x, y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -188,8 +188,6 @@ void rotate_map_coordinates(int16_t* x, int16_t* y, int32_t rotation);
|
|||
LocationXY16 coordinate_3d_to_2d(const LocationXYZ16* coordinate_3d, int32_t rotation);
|
||||
money32 map_clear_scenery(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t clear, int32_t flags);
|
||||
|
||||
void game_command_set_land_ownership(
|
||||
int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp);
|
||||
void game_command_place_park_entrance(
|
||||
int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp);
|
||||
void game_command_set_banner_name(
|
||||
|
|
|
@ -203,213 +203,6 @@ void park_set_name(const char* name)
|
|||
}
|
||||
}
|
||||
|
||||
static money32 map_buy_land_rights_for_tile(int32_t x, int32_t y, int32_t setting, int32_t flags)
|
||||
{
|
||||
SurfaceElement* surfaceElement = map_get_surface_element_at({ x, y })->AsSurface();
|
||||
if (surfaceElement == nullptr)
|
||||
return MONEY32_UNDEFINED;
|
||||
|
||||
switch (setting)
|
||||
{
|
||||
case BUY_LAND_RIGHTS_FLAG_BUY_LAND: // 0
|
||||
if ((surfaceElement->GetOwnership() & OWNERSHIP_OWNED) != 0)
|
||||
{ // If the land is already owned
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0
|
||||
|| (surfaceElement->GetOwnership() & OWNERSHIP_AVAILABLE) == 0)
|
||||
{
|
||||
gGameCommandErrorText = STR_LAND_NOT_FOR_SALE;
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
if (flags & GAME_COMMAND_FLAG_APPLY)
|
||||
{
|
||||
surfaceElement->SetOwnership(OWNERSHIP_OWNED);
|
||||
update_park_fences_around_tile({ x, y });
|
||||
}
|
||||
return gLandPrice;
|
||||
case BUY_LAND_RIGHTS_FLAG_UNOWN_TILE: // 1
|
||||
if (flags & GAME_COMMAND_FLAG_APPLY)
|
||||
{
|
||||
surfaceElement->SetOwnership(
|
||||
surfaceElement->GetOwnership() & ~(OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED));
|
||||
update_park_fences_around_tile({ x, y });
|
||||
}
|
||||
return 0;
|
||||
case BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS: // 2
|
||||
if ((surfaceElement->GetOwnership() & (OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)) != 0)
|
||||
{ // If the land or construction rights are already owned
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0
|
||||
|| (surfaceElement->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) == 0)
|
||||
{
|
||||
gGameCommandErrorText = STR_CONSTRUCTION_RIGHTS_NOT_FOR_SALE;
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
if (flags & GAME_COMMAND_FLAG_APPLY)
|
||||
{
|
||||
surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED);
|
||||
uint16_t baseHeight = surfaceElement->base_height * 8;
|
||||
map_invalidate_tile(x, y, baseHeight, baseHeight + 16);
|
||||
}
|
||||
return gConstructionRightsPrice;
|
||||
case BUY_LAND_RIGHTS_FLAG_UNOWN_CONSTRUCTION_RIGHTS: // 3
|
||||
if (flags & GAME_COMMAND_FLAG_APPLY)
|
||||
{
|
||||
surfaceElement->SetOwnership(surfaceElement->GetOwnership() & ~OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED);
|
||||
uint16_t baseHeight = surfaceElement->base_height * 8;
|
||||
map_invalidate_tile(x, y, baseHeight, baseHeight + 16);
|
||||
}
|
||||
return 0;
|
||||
case BUY_LAND_RIGHTS_FLAG_SET_FOR_SALE: // 4
|
||||
if (flags & GAME_COMMAND_FLAG_APPLY)
|
||||
{
|
||||
surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_AVAILABLE);
|
||||
uint16_t baseHeight = surfaceElement->base_height * 8;
|
||||
map_invalidate_tile(x, y, baseHeight, baseHeight + 16);
|
||||
}
|
||||
return 0;
|
||||
case BUY_LAND_RIGHTS_FLAG_SET_CONSTRUCTION_RIGHTS_FOR_SALE: // 5
|
||||
if (flags & GAME_COMMAND_FLAG_APPLY)
|
||||
{
|
||||
surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE);
|
||||
uint16_t baseHeight = surfaceElement->base_height * 8;
|
||||
map_invalidate_tile(x, y, baseHeight, baseHeight + 16);
|
||||
}
|
||||
return 0;
|
||||
case BUY_LAND_RIGHTS_FLAG_SET_OWNERSHIP_WITH_CHECKS:
|
||||
{
|
||||
if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !gCheatsSandboxMode)
|
||||
{
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
if (x <= 0 || y <= 0)
|
||||
{
|
||||
gGameCommandErrorText = STR_TOO_CLOSE_TO_EDGE_OF_MAP;
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
if (x >= gMapSizeUnits || y >= gMapSizeUnits)
|
||||
{
|
||||
gGameCommandErrorText = STR_TOO_CLOSE_TO_EDGE_OF_MAP;
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
uint8_t newOwnership = (flags & 0xFF00) >> 4;
|
||||
if (newOwnership == surfaceElement->GetOwnership())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
TileElement* tileElement = map_get_first_element_at(x / 32, y / 32);
|
||||
do
|
||||
{
|
||||
if (tileElement->GetType() == TILE_ELEMENT_TYPE_ENTRANCE
|
||||
&& tileElement->AsEntrance()->GetEntranceType() == ENTRANCE_TYPE_PARK_ENTRANCE)
|
||||
{
|
||||
// Do not allow ownership of park entrance.
|
||||
if (newOwnership == OWNERSHIP_OWNED || newOwnership == OWNERSHIP_AVAILABLE)
|
||||
return 0;
|
||||
// Allow construction rights available / for sale on park entrances on surface.
|
||||
// There is no need to check the height if newOwnership is 0 (unowned and no rights available).
|
||||
if ((newOwnership == OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED
|
||||
|| newOwnership == OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE)
|
||||
&& (tileElement->base_height - 3 > surfaceElement->base_height
|
||||
|| tileElement->base_height < surfaceElement->base_height))
|
||||
return 0;
|
||||
}
|
||||
} while (!(tileElement++)->IsLastForTile());
|
||||
|
||||
if (!(flags & GAME_COMMAND_FLAG_APPLY))
|
||||
{
|
||||
return gLandPrice;
|
||||
}
|
||||
|
||||
if ((newOwnership & 0xF0) != 0)
|
||||
{
|
||||
gPeepSpawns.erase(
|
||||
std::remove_if(
|
||||
gPeepSpawns.begin(), gPeepSpawns.end(),
|
||||
[x, y](const auto& spawn) { return floor2(spawn.x, 32) == x && floor2(spawn.y, 32) == y; }),
|
||||
gPeepSpawns.end());
|
||||
}
|
||||
surfaceElement->SetOwnership(newOwnership);
|
||||
update_park_fences_around_tile({ x, y });
|
||||
gMapLandRightsUpdateSuccess = true;
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
log_warning("Tried calling map_buy_land_rights_for_tile() with an incorrect setting!");
|
||||
assert(false);
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t map_buy_land_rights(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t setting, int32_t flags)
|
||||
{
|
||||
int32_t x, y, z;
|
||||
money32 totalCost, cost;
|
||||
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE;
|
||||
|
||||
if (x1 == 0 && y1 == 0)
|
||||
{
|
||||
x1 = x0;
|
||||
y1 = y0;
|
||||
}
|
||||
|
||||
x = (x0 + x1) / 2 + 16;
|
||||
y = (y0 + y1) / 2 + 16;
|
||||
z = tile_element_height(x, y);
|
||||
gCommandPosition.x = x;
|
||||
gCommandPosition.y = y;
|
||||
gCommandPosition.z = z;
|
||||
|
||||
// Game command modified to accept selection size
|
||||
totalCost = 0;
|
||||
gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED;
|
||||
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 || game_is_not_paused() || gCheatsBuildInPauseMode)
|
||||
{
|
||||
for (y = y0; y <= y1; y += 32)
|
||||
{
|
||||
for (x = x0; x <= x1; x += 32)
|
||||
{
|
||||
cost = map_buy_land_rights_for_tile(x, y, setting, flags);
|
||||
if (cost != MONEY32_UNDEFINED)
|
||||
{
|
||||
totalCost += cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return totalCost;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006649BD
|
||||
*/
|
||||
void game_command_buy_land_rights(
|
||||
int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp)
|
||||
{
|
||||
int32_t flags = *ebx & 0xFFFF;
|
||||
|
||||
*ebx = map_buy_land_rights((*eax & 0xFFFF), (*ecx & 0xFFFF), (*edi & 0xFFFF), (*ebp & 0xFFFF), (*edx & 0x00FF), flags);
|
||||
|
||||
// Too expensive to always call in map_buy_land_rights.
|
||||
// It's already counted when the park is loaded, after
|
||||
// that it should only be called for user actions.
|
||||
if (flags & GAME_COMMAND_FLAG_APPLY)
|
||||
{
|
||||
map_count_remaining_land_rights();
|
||||
}
|
||||
}
|
||||
|
||||
void set_forced_park_rating(int32_t rating)
|
||||
{
|
||||
_forcedParkRating = rating;
|
||||
|
|
|
@ -87,17 +87,6 @@ namespace OpenRCT2
|
|||
};
|
||||
} // namespace OpenRCT2
|
||||
|
||||
enum
|
||||
{
|
||||
BUY_LAND_RIGHTS_FLAG_BUY_LAND,
|
||||
BUY_LAND_RIGHTS_FLAG_UNOWN_TILE,
|
||||
BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS,
|
||||
BUY_LAND_RIGHTS_FLAG_UNOWN_CONSTRUCTION_RIGHTS,
|
||||
BUY_LAND_RIGHTS_FLAG_SET_FOR_SALE,
|
||||
BUY_LAND_RIGHTS_FLAG_SET_CONSTRUCTION_RIGHTS_FOR_SALE,
|
||||
BUY_LAND_RIGHTS_FLAG_SET_OWNERSHIP_WITH_CHECKS, // Used in scenario editor
|
||||
};
|
||||
|
||||
extern rct_string_id gParkName;
|
||||
extern uint32_t gParkNameArgs;
|
||||
extern uint32_t gParkFlags;
|
||||
|
@ -137,12 +126,8 @@ int32_t park_entrance_get_index(int32_t x, int32_t y, int32_t z);
|
|||
void park_set_name(const char* name);
|
||||
void park_set_entrance_fee(money32 value);
|
||||
|
||||
int32_t map_buy_land_rights(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t setting, int32_t flags);
|
||||
|
||||
void game_command_set_park_entrance_fee(
|
||||
int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp);
|
||||
void game_command_buy_land_rights(
|
||||
int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp);
|
||||
|
||||
money16 park_get_entrance_fee();
|
||||
|
||||
|
|
Loading…
Reference in New Issue