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 "ScenarioSetSettingAction.h"
11 
12 #include "../OpenRCT2.h"
13 #include "../interface/Window.h"
14 #include "../management/Finance.h"
15 #include "../peep/Peep.h"
16 #include "../scenario/Scenario.h"
17 #include "../util/Util.h"
18 #include "../world/Park.h"
19 
20 #include <algorithm>
21 
Serialise(DataSerialiser & stream)22 void ScenarioSetSettingAction::Serialise(DataSerialiser& stream)
23 {
24     GameAction::Serialise(stream);
25 
26     stream << DS_TAG(_setting) << DS_TAG(_value);
27 }
28 
Query() const29 GameActions::Result::Ptr ScenarioSetSettingAction::Query() const
30 {
31     if (_setting >= ScenarioSetSetting::Count)
32     {
33         log_error("Invalid setting: %u", _setting);
34         return MakeResult(GameActions::Status::InvalidParameters, STR_NONE, STR_NONE);
35     }
36 
37     return MakeResult();
38 }
39 
Execute() const40 GameActions::Result::Ptr ScenarioSetSettingAction::Execute() const
41 {
42     switch (_setting)
43     {
44         case ScenarioSetSetting::NoMoney:
45             if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR)
46             {
47                 if (_value != 0)
48                 {
49                     gParkFlags |= PARK_FLAGS_NO_MONEY_SCENARIO;
50                 }
51                 else
52                 {
53                     gParkFlags &= ~PARK_FLAGS_NO_MONEY_SCENARIO;
54                 }
55             }
56             else
57             {
58                 if (_value != 0)
59                 {
60                     gParkFlags |= PARK_FLAGS_NO_MONEY;
61                 }
62                 else
63                 {
64                     gParkFlags &= ~PARK_FLAGS_NO_MONEY;
65                 }
66                 // Invalidate all windows that have anything to do with finance
67                 window_invalidate_by_class(WC_RIDE);
68                 window_invalidate_by_class(WC_PEEP);
69                 window_invalidate_by_class(WC_PARK_INFORMATION);
70                 window_invalidate_by_class(WC_FINANCES);
71                 window_invalidate_by_class(WC_BOTTOM_TOOLBAR);
72                 window_invalidate_by_class(WC_TOP_TOOLBAR);
73             }
74             break;
75         case ScenarioSetSetting::InitialCash:
76             gInitialCash = std::clamp<money64>(_value, MONEY(0, 00), MONEY(1000000, 00));
77             gCash = gInitialCash;
78             window_invalidate_by_class(WC_FINANCES);
79             window_invalidate_by_class(WC_BOTTOM_TOOLBAR);
80             break;
81         case ScenarioSetSetting::InitialLoan:
82             gBankLoan = std::clamp<money64>(_value, MONEY(0, 00), MONEY(5000000, 00));
83             gMaxBankLoan = std::max(gBankLoan, gMaxBankLoan);
84             window_invalidate_by_class(WC_FINANCES);
85             break;
86         case ScenarioSetSetting::MaximumLoanSize:
87             gMaxBankLoan = std::clamp<money64>(_value, MONEY(0, 00), MONEY(5000000, 00));
88             gBankLoan = std::min(gBankLoan, gMaxBankLoan);
89             window_invalidate_by_class(WC_FINANCES);
90             break;
91         case ScenarioSetSetting::AnnualInterestRate:
92             gBankLoanInterestRate = std::clamp<uint8_t>(_value, 0, 80);
93             window_invalidate_by_class(WC_FINANCES);
94             break;
95         case ScenarioSetSetting::ForbidMarketingCampaigns:
96             if (_value != 0)
97             {
98                 gParkFlags |= PARK_FLAGS_FORBID_MARKETING_CAMPAIGN;
99             }
100             else
101             {
102                 gParkFlags &= ~PARK_FLAGS_FORBID_MARKETING_CAMPAIGN;
103             }
104             break;
105         case ScenarioSetSetting::AverageCashPerGuest:
106             gGuestInitialCash = std::clamp<money64>(_value, MONEY(0, 00), MONEY(1000, 00));
107             break;
108         case ScenarioSetSetting::GuestInitialHappiness:
109             gGuestInitialHappiness = std::clamp<uint8_t>(_value, 40, 250);
110             break;
111         case ScenarioSetSetting::GuestInitialHunger:
112             gGuestInitialHunger = std::clamp<uint8_t>(_value, 40, 250);
113             break;
114         case ScenarioSetSetting::GuestInitialThirst:
115             gGuestInitialThirst = std::clamp<uint8_t>(_value, 40, 250);
116             break;
117         case ScenarioSetSetting::GuestsPreferLessIntenseRides:
118             if (_value != 0)
119             {
120                 gParkFlags |= PARK_FLAGS_PREF_LESS_INTENSE_RIDES;
121             }
122             else
123             {
124                 gParkFlags &= ~PARK_FLAGS_PREF_LESS_INTENSE_RIDES;
125             }
126             break;
127         case ScenarioSetSetting::GuestsPreferMoreIntenseRides:
128             if (_value != 0)
129             {
130                 gParkFlags |= PARK_FLAGS_PREF_MORE_INTENSE_RIDES;
131             }
132             else
133             {
134                 gParkFlags &= ~PARK_FLAGS_PREF_MORE_INTENSE_RIDES;
135             }
136             break;
137         case ScenarioSetSetting::CostToBuyLand:
138             gLandPrice = std::clamp<money32>(_value, MONEY(5, 00), MONEY(200, 00));
139             break;
140         case ScenarioSetSetting::CostToBuyConstructionRights:
141             gConstructionRightsPrice = std::clamp<money32>(_value, MONEY(5, 00), MONEY(200, 00));
142             break;
143         case ScenarioSetSetting::ParkChargeMethod:
144             if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR)
145             {
146                 if (_value == 0)
147                 {
148                     gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY;
149                     gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES;
150                     gParkEntranceFee = MONEY(0, 00);
151                 }
152                 else if (_value == 1)
153                 {
154                     gParkFlags &= ~PARK_FLAGS_PARK_FREE_ENTRY;
155                     gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES;
156                     gParkEntranceFee = MONEY(10, 00);
157                 }
158                 else
159                 {
160                     gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY;
161                     gParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES;
162                     gParkEntranceFee = MONEY(10, 00);
163                 }
164             }
165             else
166             {
167                 if (_value == 0)
168                 {
169                     gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY;
170                     gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES;
171                 }
172                 else if (_value == 1)
173                 {
174                     gParkFlags &= ~PARK_FLAGS_PARK_FREE_ENTRY;
175                     gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES;
176                 }
177                 else
178                 {
179                     gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY;
180                     gParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES;
181                 }
182                 window_invalidate_by_class(WC_PARK_INFORMATION);
183                 window_invalidate_by_class(WC_RIDE);
184             }
185             break;
186         case ScenarioSetSetting::ParkChargeEntryFee:
187             gParkEntranceFee = std::clamp<money32>(_value, MONEY(0, 00), MAX_ENTRANCE_FEE);
188             window_invalidate_by_class(WC_PARK_INFORMATION);
189             break;
190         case ScenarioSetSetting::ForbidTreeRemoval:
191             if (_value != 0)
192             {
193                 gParkFlags |= PARK_FLAGS_FORBID_TREE_REMOVAL;
194             }
195             else
196             {
197                 gParkFlags &= ~PARK_FLAGS_FORBID_TREE_REMOVAL;
198             }
199             break;
200         case ScenarioSetSetting::ForbidLandscapeChanges:
201             if (_value != 0)
202             {
203                 gParkFlags |= PARK_FLAGS_FORBID_LANDSCAPE_CHANGES;
204             }
205             else
206             {
207                 gParkFlags &= ~PARK_FLAGS_FORBID_LANDSCAPE_CHANGES;
208             }
209             break;
210         case ScenarioSetSetting::ForbidHighConstruction:
211             if (_value != 0)
212             {
213                 gParkFlags |= PARK_FLAGS_FORBID_HIGH_CONSTRUCTION;
214             }
215             else
216             {
217                 gParkFlags &= ~PARK_FLAGS_FORBID_HIGH_CONSTRUCTION;
218             }
219             break;
220         case ScenarioSetSetting::ParkRatingHigherDifficultyLevel:
221             if (_value != 0)
222             {
223                 gParkFlags |= PARK_FLAGS_DIFFICULT_PARK_RATING;
224             }
225             else
226             {
227                 gParkFlags &= ~PARK_FLAGS_DIFFICULT_PARK_RATING;
228             }
229             break;
230         case ScenarioSetSetting::GuestGenerationHigherDifficultyLevel:
231             if (_value != 0)
232             {
233                 gParkFlags |= PARK_FLAGS_DIFFICULT_GUEST_GENERATION;
234             }
235             else
236             {
237                 gParkFlags &= ~PARK_FLAGS_DIFFICULT_GUEST_GENERATION;
238             }
239             break;
240         case ScenarioSetSetting::AllowEarlyCompletion:
241             gAllowEarlyCompletionInNetworkPlay = _value;
242             break;
243         default:
244             log_error("Invalid setting: %u", _setting);
245             return MakeResult(GameActions::Status::InvalidParameters, STR_NONE, STR_NONE);
246     }
247     window_invalidate_by_class(WC_EDITOR_SCENARIO_OPTIONS);
248     return MakeResult();
249 }
250