1 /*****************************************************************************
2  * Copyright (c) 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 #ifdef ENABLE_SCRIPTING
11 
12 #    include "ScRide.hpp"
13 
14 #    include "../../../Context.h"
15 #    include "../../../common.h"
16 #    include "../../../ride/Ride.h"
17 #    include "../../Duktape.hpp"
18 #    include "../../ScriptEngine.h"
19 #    include "../object/ScObject.hpp"
20 
21 namespace OpenRCT2::Scripting
22 {
ScRide(ride_id_t rideId)23     ScRide::ScRide(ride_id_t rideId)
24         : _rideId(rideId)
25     {
26     }
27 
id_get() const28     int32_t ScRide::id_get() const
29     {
30         return EnumValue(_rideId);
31     }
32 
object_get()33     std::shared_ptr<ScRideObject> ScRide::object_get()
34     {
35         auto ride = GetRide();
36         if (ride != nullptr)
37         {
38             auto rideObject = GetContext()->GetObjectManager().GetLoadedObject(ObjectType::Ride, ride->subtype);
39             if (rideObject != nullptr)
40             {
41                 return std::make_shared<ScRideObject>(ObjectType::Ride, ride->subtype);
42             }
43         }
44         return nullptr;
45     }
46 
type_get() const47     int32_t ScRide::type_get() const
48     {
49         auto ride = GetRide();
50         return ride != nullptr ? ride->type : 0;
51     }
52 
classification_get() const53     std::string ScRide::classification_get() const
54     {
55         auto ride = GetRide();
56         if (ride != nullptr)
57         {
58             switch (ride->GetClassification())
59             {
60                 case RideClassification::Ride:
61                     return "ride";
62                 case RideClassification::ShopOrStall:
63                     return "stall";
64                 case RideClassification::KioskOrFacility:
65                     return "facility";
66             }
67         }
68         return "";
69     }
70 
name_get() const71     std::string ScRide::name_get() const
72     {
73         auto ride = GetRide();
74         return ride != nullptr ? ride->GetName() : std::string();
75     }
name_set(std::string value)76     void ScRide::name_set(std::string value)
77     {
78         ThrowIfGameStateNotMutable();
79         auto ride = GetRide();
80         if (ride != nullptr)
81         {
82             ride->custom_name = value;
83         }
84     }
85 
status_get() const86     std::string ScRide::status_get() const
87     {
88         auto ride = GetRide();
89         if (ride != nullptr)
90         {
91             switch (ride->status)
92             {
93                 case RideStatus::Closed:
94                     return "closed";
95                 case RideStatus::Open:
96                     return "open";
97                 case RideStatus::Testing:
98                     return "testing";
99                 case RideStatus::Simulating:
100                     return "simulating";
101                 case RideStatus::Count: // Meaningless but necessary to satisfy -Wswitch
102                     return "count";
103             }
104         }
105         return "";
106     }
107 
lifecycleFlags_get() const108     uint32_t ScRide::lifecycleFlags_get() const
109     {
110         auto ride = GetRide();
111         return ride != nullptr ? ride->lifecycle_flags : 0;
112     }
113 
lifecycleFlags_set(uint32_t value)114     void ScRide::lifecycleFlags_set(uint32_t value)
115     {
116         ThrowIfGameStateNotMutable();
117         auto ride = GetRide();
118         if (ride != nullptr)
119         {
120             ride->lifecycle_flags = value;
121         }
122     }
123 
mode_get() const124     uint8_t ScRide::mode_get() const
125     {
126         auto ride = GetRide();
127         return ride != nullptr ? static_cast<uint8_t>(ride->mode) : 0;
128     }
129 
mode_set(uint8_t value)130     void ScRide::mode_set(uint8_t value)
131     {
132         ThrowIfGameStateNotMutable();
133         auto ride = GetRide();
134         if (ride != nullptr)
135         {
136             ride->mode = static_cast<RideMode>(value);
137         }
138     }
139 
departFlags_get() const140     uint8_t ScRide::departFlags_get() const
141     {
142         auto ride = GetRide();
143         return ride != nullptr ? ride->depart_flags : 0;
144     }
145 
departFlags_set(uint8_t value)146     void ScRide::departFlags_set(uint8_t value)
147     {
148         ThrowIfGameStateNotMutable();
149         auto ride = GetRide();
150         if (ride != nullptr)
151         {
152             ride->depart_flags = value;
153         }
154     }
155 
minimumWaitingTime_get() const156     uint8_t ScRide::minimumWaitingTime_get() const
157     {
158         auto ride = GetRide();
159         return ride != nullptr ? ride->min_waiting_time : 0;
160     }
161 
minimumWaitingTime_set(uint8_t value)162     void ScRide::minimumWaitingTime_set(uint8_t value)
163     {
164         ThrowIfGameStateNotMutable();
165         auto ride = GetRide();
166         if (ride != nullptr)
167         {
168             ride->min_waiting_time = value;
169         }
170     }
171 
maximumWaitingTime_get() const172     uint8_t ScRide::maximumWaitingTime_get() const
173     {
174         auto ride = GetRide();
175         return ride != nullptr ? ride->max_waiting_time : 0;
176     }
177 
maximumWaitingTime_set(uint8_t value)178     void ScRide::maximumWaitingTime_set(uint8_t value)
179     {
180         ThrowIfGameStateNotMutable();
181         auto ride = GetRide();
182         if (ride != nullptr)
183         {
184             ride->max_waiting_time = value;
185         }
186     }
187 
vehicles_get() const188     std::vector<uint16_t> ScRide::vehicles_get() const
189     {
190         std::vector<uint16_t> result;
191         auto ride = GetRide();
192         if (ride != nullptr)
193         {
194             result.insert(result.begin(), std::begin(ride->vehicles), std::begin(ride->vehicles) + ride->num_vehicles);
195         }
196         return result;
197     }
198 
vehicleColours_get() const199     std::vector<DukValue> ScRide::vehicleColours_get() const
200     {
201         std::vector<DukValue> result;
202         auto ride = GetRide();
203         if (ride != nullptr)
204         {
205             auto ctx = GetContext()->GetScriptEngine().GetContext();
206             for (const auto& vehicleColour : ride->vehicle_colours)
207             {
208                 result.push_back(ToDuk(ctx, vehicleColour));
209             }
210         }
211         return result;
212     }
213 
vehicleColours_set(const std::vector<DukValue> & value)214     void ScRide::vehicleColours_set(const std::vector<DukValue>& value)
215     {
216         auto ride = GetRide();
217         if (ride != nullptr)
218         {
219             auto count = std::min(value.size(), std::size(ride->vehicle_colours));
220             for (size_t i = 0; i < count; i++)
221             {
222                 ride->vehicle_colours[i] = FromDuk<VehicleColour>(value[i]);
223             }
224         }
225     }
226 
colourSchemes_get() const227     std::vector<DukValue> ScRide::colourSchemes_get() const
228     {
229         std::vector<DukValue> result;
230         auto ride = GetRide();
231         if (ride != nullptr)
232         {
233             auto ctx = GetContext()->GetScriptEngine().GetContext();
234             for (const auto& trackColour : ride->track_colour)
235             {
236                 result.push_back(ToDuk(ctx, trackColour));
237             }
238         }
239         return result;
240     }
241 
colourSchemes_set(const std::vector<DukValue> & value)242     void ScRide::colourSchemes_set(const std::vector<DukValue>& value)
243     {
244         auto ride = GetRide();
245         if (ride != nullptr)
246         {
247             auto count = std::min(value.size(), std::size(ride->track_colour));
248             for (size_t i = 0; i < count; i++)
249             {
250                 ride->track_colour[i] = FromDuk<TrackColour>(value[i]);
251             }
252         }
253     }
254 
stationStyle_get() const255     ObjectEntryIndex ScRide::stationStyle_get() const
256     {
257         auto ride = GetRide();
258         return ride != nullptr ? ride->entrance_style : 0;
259     }
260 
stationStyle_set(ObjectEntryIndex value)261     void ScRide::stationStyle_set(ObjectEntryIndex value)
262     {
263         ThrowIfGameStateNotMutable();
264         auto ride = GetRide();
265         if (ride != nullptr)
266         {
267             ride->entrance_style = value;
268         }
269     }
270 
music_get() const271     ObjectEntryIndex ScRide::music_get() const
272     {
273         auto ride = GetRide();
274         return ride != nullptr ? ride->music : 0;
275     }
276 
music_set(ObjectEntryIndex value)277     void ScRide::music_set(ObjectEntryIndex value)
278     {
279         ThrowIfGameStateNotMutable();
280         auto ride = GetRide();
281         if (ride != nullptr)
282         {
283             ride->music = value;
284         }
285     }
286 
stations_get() const287     std::vector<std::shared_ptr<ScRideStation>> ScRide::stations_get() const
288     {
289         std::vector<std::shared_ptr<ScRideStation>> result;
290         auto ride = GetRide();
291         if (ride != nullptr)
292         {
293             for (size_t i = 0; i < std::size(ride->stations); i++)
294             {
295                 result.push_back(std::make_shared<ScRideStation>(ride->id, static_cast<StationIndex>(i)));
296             }
297         }
298         return result;
299     }
300 
price_get() const301     std::vector<int32_t> ScRide::price_get() const
302     {
303         std::vector<int32_t> result;
304         auto ride = GetRide();
305         if (ride != nullptr)
306         {
307             auto numPrices = ride->GetNumPrices();
308             for (size_t i = 0; i < numPrices; i++)
309             {
310                 result.push_back(ride->price[i]);
311             };
312         }
313         return result;
314     }
315 
price_set(const std::vector<int32_t> & value)316     void ScRide::price_set(const std::vector<int32_t>& value)
317     {
318         ThrowIfGameStateNotMutable();
319         auto ride = GetRide();
320         if (ride != nullptr)
321         {
322             auto numPrices = std::min(value.size(), ride->GetNumPrices());
323             for (size_t i = 0; i < numPrices; i++)
324             {
325                 ride->price[i] = static_cast<money16>(value[i]);
326             }
327         }
328     }
329 
excitement_get() const330     int32_t ScRide::excitement_get() const
331     {
332         auto ride = GetRide();
333         return ride != nullptr ? ride->excitement : 0;
334     }
excitement_set(int32_t value)335     void ScRide::excitement_set(int32_t value)
336     {
337         ThrowIfGameStateNotMutable();
338         auto ride = GetRide();
339         if (ride != nullptr)
340         {
341             ride->excitement = value;
342         }
343     }
344 
intensity_get() const345     int32_t ScRide::intensity_get() const
346     {
347         auto ride = GetRide();
348         return ride != nullptr ? ride->intensity : 0;
349     }
intensity_set(int32_t value)350     void ScRide::intensity_set(int32_t value)
351     {
352         ThrowIfGameStateNotMutable();
353         auto ride = GetRide();
354         if (ride != nullptr)
355         {
356             ride->intensity = value;
357         }
358     }
359 
nausea_get() const360     int32_t ScRide::nausea_get() const
361     {
362         auto ride = GetRide();
363         return ride != nullptr ? ride->nausea : 0;
364     }
nausea_set(int32_t value)365     void ScRide::nausea_set(int32_t value)
366     {
367         ThrowIfGameStateNotMutable();
368         auto ride = GetRide();
369         if (ride != nullptr)
370         {
371             ride->nausea = value;
372         }
373     }
374 
totalCustomers_get() const375     int32_t ScRide::totalCustomers_get() const
376     {
377         auto ride = GetRide();
378         return ride != nullptr ? ride->total_customers : 0;
379     }
totalCustomers_set(int32_t value)380     void ScRide::totalCustomers_set(int32_t value)
381     {
382         ThrowIfGameStateNotMutable();
383         auto ride = GetRide();
384         if (ride != nullptr)
385         {
386             ride->total_customers = value;
387         }
388     }
389 
buildDate_get() const390     int32_t ScRide::buildDate_get() const
391     {
392         auto ride = GetRide();
393         return ride != nullptr ? ride->build_date : 0;
394     }
buildDate_set(int32_t value)395     void ScRide::buildDate_set(int32_t value)
396     {
397         ThrowIfGameStateNotMutable();
398         auto ride = GetRide();
399         if (ride != nullptr)
400         {
401             ride->build_date = value;
402         }
403     }
404 
age_get() const405     int32_t ScRide::age_get() const
406     {
407         auto ride = GetRide();
408         return ride != nullptr ? ride->GetAge() : 0;
409     }
410 
runningCost_get() const411     int16_t ScRide::runningCost_get() const
412     {
413         auto ride = GetRide();
414         return ride != nullptr ? ride->upkeep_cost : 0;
415     }
runningCost_set(int16_t value)416     void ScRide::runningCost_set(int16_t value)
417     {
418         ThrowIfGameStateNotMutable();
419         auto ride = GetRide();
420         if (ride != nullptr)
421         {
422             ride->upkeep_cost = value;
423         }
424     }
425 
totalProfit_get() const426     int32_t ScRide::totalProfit_get() const
427     {
428         auto ride = GetRide();
429         return ride != nullptr ? ride->total_profit : 0;
430     }
totalProfit_set(int32_t value)431     void ScRide::totalProfit_set(int32_t value)
432     {
433         ThrowIfGameStateNotMutable();
434         auto ride = GetRide();
435         if (ride != nullptr)
436         {
437             ride->total_profit = value;
438         }
439     }
440 
inspectionInterval_get() const441     uint8_t ScRide::inspectionInterval_get() const
442     {
443         auto ride = GetRide();
444         return ride != nullptr ? ride->inspection_interval : 0;
445     }
inspectionInterval_set(uint8_t value)446     void ScRide::inspectionInterval_set(uint8_t value)
447     {
448         ThrowIfGameStateNotMutable();
449         auto ride = GetRide();
450         if (ride != nullptr)
451         {
452             ride->inspection_interval = std::clamp<uint8_t>(value, RIDE_INSPECTION_EVERY_10_MINUTES, RIDE_INSPECTION_NEVER);
453         }
454     }
455 
value_get() const456     DukValue ScRide::value_get() const
457     {
458         auto ctx = GetContext()->GetScriptEngine().GetContext();
459         auto ride = GetRide();
460         if (ride != nullptr && ride->value != RIDE_VALUE_UNDEFINED)
461         {
462             return ToDuk<int32_t>(ctx, ride->value);
463         }
464         return ToDuk(ctx, nullptr);
465     }
466 
value_set(const DukValue & value)467     void ScRide::value_set(const DukValue& value)
468     {
469         ThrowIfGameStateNotMutable();
470         auto ride = GetRide();
471         if (ride != nullptr)
472         {
473             if (value.type() == DukValue::Type::NUMBER)
474             {
475                 ride->value = value.as_int();
476             }
477             else
478             {
479                 ride->value = RIDE_VALUE_UNDEFINED;
480             }
481         }
482     }
483 
GetRide() const484     Ride* ScRide::GetRide() const
485     {
486         return get_ride(_rideId);
487     }
488 
downtime_get() const489     uint8_t ScRide::downtime_get() const
490     {
491         auto ride = GetRide();
492         return ride != nullptr ? ride->downtime : 0;
493     }
494 
Register(duk_context * ctx)495     void ScRide::Register(duk_context* ctx)
496     {
497         dukglue_register_property(ctx, &ScRide::id_get, nullptr, "id");
498         dukglue_register_property(ctx, &ScRide::object_get, nullptr, "object");
499         dukglue_register_property(ctx, &ScRide::type_get, nullptr, "type");
500         dukglue_register_property(ctx, &ScRide::classification_get, nullptr, "classification");
501         dukglue_register_property(ctx, &ScRide::name_get, &ScRide::name_set, "name");
502         dukglue_register_property(ctx, &ScRide::status_get, nullptr, "status");
503         dukglue_register_property(ctx, &ScRide::lifecycleFlags_get, &ScRide::lifecycleFlags_set, "lifecycleFlags");
504         dukglue_register_property(ctx, &ScRide::mode_get, &ScRide::mode_set, "mode");
505         dukglue_register_property(ctx, &ScRide::departFlags_get, &ScRide::departFlags_set, "departFlags");
506         dukglue_register_property(ctx, &ScRide::minimumWaitingTime_get, &ScRide::minimumWaitingTime_set, "minimumWaitingTime");
507         dukglue_register_property(ctx, &ScRide::maximumWaitingTime_get, &ScRide::maximumWaitingTime_set, "maximumWaitingTime");
508         dukglue_register_property(ctx, &ScRide::vehicles_get, nullptr, "vehicles");
509         dukglue_register_property(ctx, &ScRide::vehicleColours_get, &ScRide::vehicleColours_set, "vehicleColours");
510         dukglue_register_property(ctx, &ScRide::colourSchemes_get, &ScRide::colourSchemes_set, "colourSchemes");
511         dukglue_register_property(ctx, &ScRide::stationStyle_get, &ScRide::stationStyle_set, "stationStyle");
512         dukglue_register_property(ctx, &ScRide::music_get, &ScRide::music_set, "music");
513         dukglue_register_property(ctx, &ScRide::stations_get, nullptr, "stations");
514         dukglue_register_property(ctx, &ScRide::price_get, &ScRide::price_set, "price");
515         dukglue_register_property(ctx, &ScRide::excitement_get, &ScRide::excitement_set, "excitement");
516         dukglue_register_property(ctx, &ScRide::intensity_get, &ScRide::intensity_set, "intensity");
517         dukglue_register_property(ctx, &ScRide::nausea_get, &ScRide::nausea_set, "nausea");
518         dukglue_register_property(ctx, &ScRide::totalCustomers_get, &ScRide::totalCustomers_set, "totalCustomers");
519         dukglue_register_property(ctx, &ScRide::buildDate_get, &ScRide::buildDate_set, "buildDate");
520         dukglue_register_property(ctx, &ScRide::age_get, nullptr, "age");
521         dukglue_register_property(ctx, &ScRide::runningCost_get, &ScRide::runningCost_set, "runningCost");
522         dukglue_register_property(ctx, &ScRide::totalProfit_get, &ScRide::totalProfit_set, "totalProfit");
523         dukglue_register_property(ctx, &ScRide::inspectionInterval_get, &ScRide::inspectionInterval_set, "inspectionInterval");
524         dukglue_register_property(ctx, &ScRide::value_get, &ScRide::value_set, "value");
525         dukglue_register_property(ctx, &ScRide::downtime_get, nullptr, "downtime");
526     }
527 
528 } // namespace OpenRCT2::Scripting
529 
530 #endif
531