1 /*****************************************************************************
2 * Copyright (c) 2014-2020 OpenRCT2 developers
3 *
4 * For a complete list of all authors, please refer to contributors.md
5 * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
6 *
7 * OpenRCT2 is licensed under the GNU General Public License version 3.
8 *****************************************************************************/
9
10 #include "BannerSetStyleAction.h"
11
12 #include "../Context.h"
13 #include "../management/Finance.h"
14 #include "../util/Util.h"
15 #include "../windows/Intent.h"
16 #include "../world/Banner.h"
17 #include "GameAction.h"
18
BannerSetStyleAction(BannerSetStyleType type,uint8_t bannerIndex,uint8_t parameter)19 BannerSetStyleAction::BannerSetStyleAction(BannerSetStyleType type, uint8_t bannerIndex, uint8_t parameter)
20 : _type(type)
21 , _bannerIndex(bannerIndex)
22 , _parameter(parameter)
23 {
24 }
25
AcceptParameters(GameActionParameterVisitor & visitor)26 void BannerSetStyleAction::AcceptParameters(GameActionParameterVisitor& visitor)
27 {
28 visitor.Visit("id", _bannerIndex);
29 visitor.Visit("type", _type);
30 visitor.Visit("parameter", _parameter);
31 }
32
GetActionFlags() const33 uint16_t BannerSetStyleAction::GetActionFlags() const
34 {
35 return GameAction::GetActionFlags() | GameActions::Flags::AllowWhilePaused;
36 }
37
Serialise(DataSerialiser & stream)38 void BannerSetStyleAction::Serialise(DataSerialiser& stream)
39 {
40 GameAction::Serialise(stream);
41
42 stream << DS_TAG(_type) << DS_TAG(_bannerIndex) << DS_TAG(_parameter);
43 }
44
Query() const45 GameActions::Result::Ptr BannerSetStyleAction::Query() const
46 {
47 auto res = MakeResult();
48
49 auto banner = GetBanner(_bannerIndex);
50 if (banner == nullptr)
51 {
52 log_error("Invalid banner index: index = %u", _bannerIndex);
53 return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
54 }
55
56 res->Expenditure = ExpenditureType::Landscaping;
57 auto location = banner->position.ToCoordsXY().ToTileCentre();
58 res->Position = { location, tile_element_height(location) };
59
60 TileElement* tileElement = banner_get_tile_element(_bannerIndex);
61
62 if (tileElement == nullptr)
63 {
64 log_error("Could not find banner index = %u", _bannerIndex);
65 return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
66 }
67
68 switch (_type)
69 {
70 case BannerSetStyleType::PrimaryColour:
71 if (_parameter > 31)
72 {
73 log_error("Invalid primary colour: colour = %u", _parameter);
74 return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
75 }
76 break;
77
78 case BannerSetStyleType::TextColour:
79 if (_parameter > 13)
80 {
81 log_error("Invalid text colour: colour = %u", _parameter);
82 return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
83 }
84 break;
85 case BannerSetStyleType::NoEntry:
86 if (tileElement->AsBanner() == nullptr)
87 {
88 log_error("Tile element was not a banner.");
89 return MakeResult(GameActions::Status::Unknown, STR_CANT_REPAINT_THIS, STR_NONE);
90 }
91 break;
92 default:
93 log_error("Invalid type: %u", _type);
94 return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
95 }
96 return res;
97 }
98
Execute() const99 GameActions::Result::Ptr BannerSetStyleAction::Execute() const
100 {
101 auto res = MakeResult();
102
103 auto banner = GetBanner(_bannerIndex);
104 if (banner == nullptr)
105 {
106 log_error("Invalid banner index: index = %u", _bannerIndex);
107 return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
108 }
109
110 res->Expenditure = ExpenditureType::Landscaping;
111 auto location = banner->position.ToCoordsXY().ToTileCentre();
112 res->Position = { location, tile_element_height(location) };
113
114 TileElement* tileElement = banner_get_tile_element(_bannerIndex);
115
116 if (tileElement == nullptr)
117 {
118 log_error("Could not find banner index = %u", _bannerIndex);
119 return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
120 }
121
122 switch (_type)
123 {
124 case BannerSetStyleType::PrimaryColour:
125 banner->colour = _parameter;
126 break;
127 case BannerSetStyleType::TextColour:
128 banner->text_colour = _parameter;
129 break;
130 case BannerSetStyleType::NoEntry:
131 {
132 BannerElement* bannerElement = tileElement->AsBanner();
133 if (bannerElement == nullptr)
134 {
135 log_error("Tile element was not a banner.");
136 return MakeResult(GameActions::Status::Unknown, STR_CANT_REPAINT_THIS, STR_NONE);
137 }
138
139 banner->flags &= ~BANNER_FLAG_NO_ENTRY;
140 banner->flags |= (_parameter != 0) ? BANNER_FLAG_NO_ENTRY : 0;
141 uint8_t allowedEdges = 0xF;
142 if (banner->flags & BANNER_FLAG_NO_ENTRY)
143 {
144 allowedEdges &= ~(1 << bannerElement->GetPosition());
145 }
146 bannerElement->SetAllowedEdges(allowedEdges);
147 break;
148 }
149 default:
150 log_error("Invalid type: %u", _type);
151 return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
152 }
153
154 auto intent = Intent(INTENT_ACTION_UPDATE_BANNER);
155 intent.putExtra(INTENT_EXTRA_BANNER_INDEX, _bannerIndex);
156 context_broadcast_intent(&intent);
157
158 return res;
159 }
160