Create game actions and UI for restricted scenery

This commit is contained in:
Michael Steenbeek 2024-02-28 20:38:43 +01:00 committed by GitHub
parent 626e922591
commit 25ec1e4211
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 252 additions and 83 deletions

View File

@ -3687,6 +3687,11 @@ STR_6614 :Cant change park entrance fee
STR_6615 :Track on this tile needs water
STR_6616 :Action invalid for that staff type
STR_6617 :Cant swap tile element with itself
STR_6618 :Cant restrict or derestrict object…
STR_6619 :Object type cannot be restricted!
STR_6620 :Object not found!
STR_6621 :Restrict
STR_6622 :Restrict object to the Scenario Editor and Sandbox mode.
#############
# Scenarios #

View File

@ -3,6 +3,7 @@
- Feature: [#20376] Add Ukrainian language.
- Feature: [#20709] [Plugin] Plugins can now check metadata from all registered plugins.
- Feature: [#21376] Add option to reload an object (for object developers).
- Feature: [#21455] Add option to control hidden scenery.
- Improved: [#21356] Resize the title bar when moving between displays with different scaling factors on Windows systems.
- Improved: [#21388] Tooltips will now show even when an error message is present.
- Improved: [#21423] Add mechanism to allow building partly underground.

View File

@ -16,6 +16,8 @@
#include <openrct2/Context.h>
#include <openrct2/GameState.h>
#include <openrct2/Input.h>
#include <openrct2/OpenRCT2.h>
#include <openrct2/actions/ScenerySetRestrictedAction.h>
#include <openrct2/audio/audio.h>
#include <openrct2/core/Guard.hpp>
#include <openrct2/localisation/Formatter.h>
@ -69,6 +71,7 @@ enum WindowSceneryListWidgetIdx
WIDX_SCENERY_BUILD_CLUSTER_BUTTON,
WIDX_FILTER_TEXT_BOX,
WIDX_FILTER_CLEAR_BUTTON,
WIDX_RESTRICT_SCENERY,
WIDX_SCENERY_TAB_1,
};
@ -90,6 +93,7 @@ static Widget WindowSceneryBaseWidgets[] = {
MakeWidget ({609, 169}, { 24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, ImageId(SPR_SCENERY_CLUSTER), STR_SCENERY_CLUSTER_TIP ), // 40000000 0x009DE478
MakeWidget ({ 4, 46}, {211, 14}, WindowWidgetType::TextBox, WindowColour::Secondary ),
MakeWidget ({218, 46}, { 70, 14}, WindowWidgetType::Button, WindowColour::Secondary, STR_OBJECT_SEARCH_CLEAR ),
MakeWidget ({539, 46}, { 70, 14}, WindowWidgetType::Button, WindowColour::Secondary, STR_RESTRICT_SCENERY, STR_RESTRICT_SCENERY_TIP ),
WIDGETS_END,
};
// clang-format on
@ -280,6 +284,19 @@ public:
scrolls->v_top = 0;
Invalidate();
break;
case WIDX_RESTRICT_SCENERY:
{
const auto tabIndex = _activeTabIndex;
const auto tabSelectedScenery = GetSelectedScenery(tabIndex);
if (!tabSelectedScenery.IsUndefined())
{
const auto newStatus = !IsSceneryItemRestricted(tabSelectedScenery);
const auto objectType = GetObjectTypeFromSceneryType(tabSelectedScenery.SceneryType);
auto action = ScenerySetRestrictedAction(objectType, tabSelectedScenery.EntryIndex, newStatus);
GameActions::Execute(&action);
}
break;
}
}
}
@ -616,6 +633,7 @@ public:
widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WindowWidgetType::Empty;
widgets[WIDX_SCENERY_EYEDROPPER_BUTTON].type = WindowWidgetType::Empty;
widgets[WIDX_SCENERY_BUILD_CLUSTER_BUTTON].type = WindowWidgetType::Empty;
widgets[WIDX_RESTRICT_SCENERY].type = WindowWidgetType::Empty;
if (!(gWindowSceneryPaintEnabled & 1))
{
@ -642,6 +660,15 @@ public:
{
widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WindowWidgetType::FlatBtn;
}
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode)
{
widgets[WIDX_RESTRICT_SCENERY].type = WindowWidgetType::Button;
if (IsSceneryItemRestricted(tabSelectedScenery))
pressed_widgets |= (1uLL << WIDX_RESTRICT_SCENERY);
else
pressed_widgets &= ~(1uLL << WIDX_RESTRICT_SCENERY);
}
}
widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].image = GetColourButtonImage(gWindowSceneryPrimaryColour);

View File

@ -20,90 +20,91 @@ struct ParkLoadResult;
enum class GameCommand : int32_t
{
SetRideAppearance, // GA
SetLandHeight, // GA
TogglePause, // GA
PlaceTrack, // GA
RemoveTrack, // GA
LoadOrQuit, // GA
CreateRide, // GA
DemolishRide, // GA
SetRideStatus, // GA
SetRideVehicles, // GA
SetRideName, // GA
SetRideSetting, // GA
PlaceRideEntranceOrExit, // GA
RemoveRideEntranceOrExit, // GA
RemoveScenery, // GA
PlaceScenery, // GA
SetWaterHeight, // GA
PlacePath, // GA
PlacePathLayout, // GA
RemovePath, // GA
ChangeSurfaceStyle, // GA
SetRidePrice, // GA
SetGuestName, // GA
SetStaffName, // GA
RaiseLand, // GA
LowerLand, // GA
EditLandSmooth, // GA
RaiseWater, // GA
LowerWater, // GA
SetBrakesSpeed, // GA
HireNewStaffMember, // GA
SetStaffPatrol, // GA
FireStaffMember, // GA
SetStaffOrders, // GA
SetParkName, // GA
SetParkOpen, // GA
BuyLandRights, // GA
PlaceParkEntrance, // GA
RemoveParkEntrance, // GA
SetMazeTrack, // GA
SetParkEntranceFee, // GA
SetStaffColour, // GA
PlaceWall, // GA
RemoveWall, // GA
PlaceLargeScenery, // GA
RemoveLargeScenery, // GA
SetCurrentLoan, // GA
SetResearchFunding, // GA
PlaceTrackDesign, // GA
StartMarketingCampaign, // GA
PlaceMazeDesign, // GA
PlaceBanner, // GA
RemoveBanner, // GA
SetSceneryColour, // GA
SetWallColour, // GA
SetLargeSceneryColour, // GA
SetBannerColour, // GA
SetLandOwnership, // GA
ClearScenery, // GA
SetBannerName, // GA
SetSignName, // GA
SetBannerStyle, // GA
SetSignStyle, // GA
SetPlayerGroup, // GA
ModifyGroups, // GA
KickPlayer, // GA
Cheat, // GA
PickupGuest, // GA
PickupStaff, // GA
BalloonPress, // GA
ModifyTile, // GA
EditScenarioOptions, // GA
PlacePeepSpawn, // GA
SetClimate, // GA
SetColourScheme, // GA
SetStaffCostume, // GA
PlaceFootpathAddition, // GA
RemoveFootpathAddition, // GA
GuestSetFlags, // GA
SetDate, // GA
Custom, // GA
SetRideAppearance,
SetLandHeight,
TogglePause,
PlaceTrack,
RemoveTrack,
LoadOrQuit,
CreateRide,
DemolishRide,
SetRideStatus,
SetRideVehicles,
SetRideName,
SetRideSetting,
PlaceRideEntranceOrExit,
RemoveRideEntranceOrExit,
RemoveScenery,
PlaceScenery,
SetWaterHeight,
PlacePath,
PlacePathLayout,
RemovePath,
ChangeSurfaceStyle,
SetRidePrice,
SetGuestName,
SetStaffName,
RaiseLand,
LowerLand,
EditLandSmooth,
RaiseWater,
LowerWater,
SetBrakesSpeed,
HireNewStaffMember,
SetStaffPatrol,
FireStaffMember,
SetStaffOrders,
SetParkName,
SetParkOpen,
BuyLandRights,
PlaceParkEntrance,
RemoveParkEntrance,
SetMazeTrack,
SetParkEntranceFee,
SetStaffColour,
PlaceWall,
RemoveWall,
PlaceLargeScenery,
RemoveLargeScenery,
SetCurrentLoan,
SetResearchFunding,
PlaceTrackDesign,
StartMarketingCampaign,
PlaceMazeDesign,
PlaceBanner,
RemoveBanner,
SetSceneryColour,
SetWallColour,
SetLargeSceneryColour,
SetBannerColour,
SetLandOwnership,
ClearScenery,
SetBannerName,
SetSignName,
SetBannerStyle,
SetSignStyle,
SetPlayerGroup,
ModifyGroups,
KickPlayer,
Cheat,
PickupGuest,
PickupStaff,
BalloonPress,
ModifyTile,
EditScenarioOptions,
PlacePeepSpawn,
SetClimate,
SetColourScheme,
SetStaffCostume,
PlaceFootpathAddition,
RemoveFootpathAddition,
GuestSetFlags,
SetDate,
Custom,
ChangeMapSize,
FreezeRideRating,
SetGameSpeed,
SetRestrictedScenery,
Count,
};

View File

@ -67,6 +67,7 @@
#include "RideSetStatusAction.h"
#include "RideSetVehicleAction.h"
#include "ScenarioSetSettingAction.h"
#include "ScenerySetRestrictedAction.h"
#include "SignSetNameAction.h"
#include "SignSetStyleAction.h"
#include "SmallSceneryPlaceAction.h"
@ -208,6 +209,7 @@ namespace GameActions
REGISTER_ACTION(CheatSetAction);
REGISTER_ACTION(MapChangeSizeAction);
REGISTER_ACTION(GameSetSpeedAction);
REGISTER_ACTION(ScenerySetRestrictedAction);
#ifdef ENABLE_SCRIPTING
REGISTER_ACTION(CustomAction);
#endif

View File

@ -0,0 +1,56 @@
/*****************************************************************************
* Copyright (c) 2014-2024 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 "ScenerySetRestrictedAction.h"
#include "../object/SceneryGroupObject.h"
#include "../world/Scenery.h"
ScenerySetRestrictedAction::ScenerySetRestrictedAction(ObjectType objectType, ObjectEntryIndex entryIndex, bool isRestricted)
: _objectType(objectType)
, _objectIndex(entryIndex)
, _isRestricted(isRestricted)
{
}
void ScenerySetRestrictedAction::Serialise(DataSerialiser& stream)
{
GameAction::Serialise(stream);
stream << DS_TAG(_objectType) << DS_TAG(_objectIndex) << DS_TAG(_isRestricted);
}
uint16_t ScenerySetRestrictedAction::GetActionFlags() const
{
return GameAction::GetActionFlags() | GameActions::Flags::AllowWhilePaused;
}
GameActions::Result ScenerySetRestrictedAction::Query() const
{
if (!ObjectTypeCanBeRestricted(_objectType))
{
return GameActions::Result(
GameActions::Status::InvalidParameters, STR_CANT_RESTRICT_OBJECT, STR_OBJECT_TYPE_CANNOT_BE_RESTRICTED);
}
const auto* loadedObject = ObjectEntryGetObject(_objectType, _objectIndex);
if (loadedObject == nullptr)
{
return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_RESTRICT_OBJECT, STR_OBJECT_NOT_FOUND);
}
return GameActions::Result();
}
GameActions::Result ScenerySetRestrictedAction::Execute() const
{
auto sceneryType = GetSceneryTypeFromObjectType(_objectType);
SetSceneryItemRestricted({ sceneryType, _objectIndex }, _isRestricted);
return GameActions::Result();
}

View File

@ -0,0 +1,30 @@
/*****************************************************************************
* Copyright (c) 2014-2024 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 "GameAction.h"
class ScenerySetRestrictedAction final : public GameActionBase<GameCommand::SetRestrictedScenery>
{
private:
ObjectType _objectType;
ObjectEntryIndex _objectIndex;
bool _isRestricted;
public:
ScenerySetRestrictedAction() = default;
ScenerySetRestrictedAction(ObjectType objectType, ObjectEntryIndex entryIndex, bool isRestricted);
uint16_t GetActionFlags() const override;
void Serialise(DataSerialiser& stream) override;
GameActions::Result Query() const override;
GameActions::Result Execute() const override;
};

View File

@ -352,7 +352,7 @@ constexpr int32_t WC_RIDE_CONSTRUCTION__WIDX_ROTATE = 32;
constexpr int32_t WC_MAZE_CONSTRUCTION__WIDX_MAZE_DIRECTION_GROUPBOX = WC_RIDE_CONSTRUCTION__WIDX_CONSTRUCT;
constexpr int32_t WC_MAZE_CONSTRUCTION__WIDX_MAZE_ENTRANCE = WC_RIDE_CONSTRUCTION__WIDX_ENTRANCE;
constexpr int32_t WC_MAZE_CONSTRUCTION__WIDX_MAZE_EXIT = WC_RIDE_CONSTRUCTION__WIDX_EXIT;
constexpr int32_t WC_SCENERY__WIDX_SCENERY_TAB_1 = 14;
constexpr int32_t WC_SCENERY__WIDX_SCENERY_TAB_1 = 15;
constexpr int32_t WC_SCENERY__WIDX_SCENERY_ROTATE_OBJECTS_BUTTON = 5;
constexpr int32_t WC_SCENERY__WIDX_SCENERY_EYEDROPPER_BUTTON = 10;
constexpr int32_t WC_PEEP__WIDX_PATROL = 10;

View File

@ -138,6 +138,7 @@
<ClInclude Include="actions\RideSetStatusAction.h" />
<ClInclude Include="actions\RideSetVehicleAction.h" />
<ClInclude Include="actions\ScenarioSetSettingAction.h" />
<ClInclude Include="actions\ScenerySetRestrictedAction.h" />
<ClInclude Include="actions\SignSetNameAction.h" />
<ClInclude Include="actions\SignSetStyleAction.h" />
<ClInclude Include="actions\SmallSceneryPlaceAction.h" />
@ -663,6 +664,7 @@
<ClCompile Include="actions\RideSetStatusAction.cpp" />
<ClCompile Include="actions\RideSetVehicleAction.cpp" />
<ClCompile Include="actions\ScenarioSetSettingAction.cpp" />
<ClCompile Include="actions\ScenerySetRestrictedAction.cpp" />
<ClCompile Include="actions\SignSetNameAction.cpp" />
<ClCompile Include="actions\SignSetStyleAction.cpp" />
<ClCompile Include="actions\SmallSceneryPlaceAction.cpp" />

View File

@ -4029,6 +4029,12 @@ enum : uint16_t
STR_ERR_ACTION_INVALID_FOR_THAT_STAFF_TYPE = 6616,
STR_ERR_CANT_SWAP_TILE_ELEMENT_WITH_ITSELF = 6617,
STR_CANT_RESTRICT_OBJECT = 6618,
STR_OBJECT_TYPE_CANNOT_BE_RESTRICTED = 6619,
STR_OBJECT_NOT_FOUND = 6620,
STR_RESTRICT_SCENERY = 6621,
STR_RESTRICT_SCENERY_TIP = 6622,
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
/* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings
};

View File

@ -46,7 +46,7 @@ using namespace OpenRCT2;
// It is used for making sure only compatible builds get connected, even within
// single OpenRCT2 version.
#define NETWORK_STREAM_VERSION "1"
#define NETWORK_STREAM_VERSION "2"
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION

View File

@ -31,6 +31,7 @@
#include "../object/ObjectManager.h"
#include "../object/PathAdditionEntry.h"
#include "../object/SceneryGroupEntry.h"
#include "../object/SceneryGroupObject.h"
#include "../object/SmallSceneryEntry.h"
#include "../object/WallSceneryEntry.h"
#include "../scenario/Scenario.h"
@ -388,6 +389,42 @@ std::vector<ScenerySelection>& GetRestrictedScenery()
return GetGameState().RestrictedScenery;
}
void SetSceneryItemRestricted(const ScenerySelection& item, bool on)
{
auto& gameState = GetGameState();
auto existingItem = std::find(std::begin(gameState.RestrictedScenery), std::end(gameState.RestrictedScenery), item);
const bool existingItemIsPresent = existingItem != std::end(gameState.RestrictedScenery);
if (on)
{
if (!existingItemIsPresent)
{
gameState.RestrictedScenery.push_back(item);
}
}
else
{
if (existingItemIsPresent)
{
gameState.RestrictedScenery.erase(existingItem);
}
}
}
bool ObjectTypeCanBeRestricted(ObjectType objectType)
{
switch (objectType)
{
case ObjectType::SmallScenery:
case ObjectType::LargeScenery:
case ObjectType::Walls:
case ObjectType::Banners:
case ObjectType::PathAdditions:
return true;
default:
return false;
}
}
static std::vector<ScenerySelection> GetAllMiscScenery()
{
std::vector<ScenerySelection> miscScenery;

View File

@ -84,6 +84,8 @@ void ClearRestrictedScenery();
void RestrictAllMiscScenery();
void MarkAllUnrestrictedSceneryAsInvented();
std::vector<ScenerySelection>& GetRestrictedScenery();
void SetSceneryItemRestricted(const ScenerySelection& item, bool on);
bool ObjectTypeCanBeRestricted(ObjectType objectType);
ObjectType GetObjectTypeFromSceneryType(uint8_t type);
uint8_t GetSceneryTypeFromObjectType(ObjectType type);