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 "../peep/Staff.h"
11 #include "../ride/Track.h"
12 #include "../world/Entrance.h"
13 #include "../world/Park.h"
14 #include "GameAction.h"
15 #include "GuestSetNameAction.h"
16 #include "MazeSetTrackAction.h"
17 #include "PlaceParkEntranceAction.h"
18 #include "PlacePeepSpawnAction.h"
19 #include "RideCreateAction.h"
20 #include "RideDemolishAction.h"
21 #include "RideSetNameAction.h"
22 #include "RideSetStatusAction.h"
23 #include "SetParkEntranceFeeAction.h"
24 #include "StaffSetNameAction.h"
25 #include "WallRemoveAction.h"
26 
27 #pragma region PlaceParkEntranceAction
28 /**
29  *
30  *  rct2: 0x00666F4E
31  */
park_entrance_place_ghost(const CoordsXYZD & entranceLoc)32 money32 park_entrance_place_ghost(const CoordsXYZD& entranceLoc)
33 {
34     park_entrance_remove_ghost();
35 
36     auto gameAction = PlaceParkEntranceAction(entranceLoc, gFootpathSelectedId);
37     gameAction.SetFlags(GAME_COMMAND_FLAG_GHOST);
38 
39     auto result = GameActions::Execute(&gameAction);
40     if (result->Error == GameActions::Status::Ok)
41     {
42         gParkEntranceGhostPosition = entranceLoc;
43         gParkEntranceGhostExists = true;
44     }
45     return result->Cost;
46 }
47 #pragma endregion
48 
49 #pragma region SetParkEntranceFeeAction
park_set_entrance_fee(money32 fee)50 void park_set_entrance_fee(money32 fee)
51 {
52     auto gameAction = SetParkEntranceFeeAction(static_cast<money16>(fee));
53     GameActions::Execute(&gameAction);
54 }
55 #pragma endregion
56 
57 #pragma region RideCreateAction
58 /**
59  *
60  *  rct2: 0x006B4800
61  */
ride_construct_new(RideSelection listItem)62 void ride_construct_new(RideSelection listItem)
63 {
64     int32_t rideEntryIndex = ride_get_entry_index(listItem.Type, listItem.EntryIndex);
65     int32_t colour1 = ride_get_random_colour_preset_index(listItem.Type);
66     int32_t colour2 = ride_get_unused_preset_vehicle_colour(rideEntryIndex);
67 
68     auto gameAction = RideCreateAction(listItem.Type, listItem.EntryIndex, colour1, colour2);
69 
70     gameAction.SetCallback([](const GameAction* ga, const GameActions::Result* result) {
71         if (result->Error != GameActions::Status::Ok)
72             return;
73         const auto rideIndex = result->GetData<ride_id_t>();
74         auto ride = get_ride(rideIndex);
75         ride_construct(ride);
76     });
77 
78     GameActions::Execute(&gameAction);
79 }
80 
81 #pragma endregion
82 
83 #pragma region RideSetStatusAction
84 
ride_set_status(Ride * ride,RideStatus status)85 void ride_set_status(Ride* ride, RideStatus status)
86 {
87     auto gameAction = RideSetStatusAction(ride->id, status);
88     GameActions::Execute(&gameAction);
89 }
90 
91 #pragma endregion
92 
93 #pragma region RideSetNameAction
ride_set_name(Ride * ride,const char * name,uint32_t flags)94 void ride_set_name(Ride* ride, const char* name, uint32_t flags)
95 {
96     auto gameAction = RideSetNameAction(ride->id, name);
97     gameAction.SetFlags(flags);
98     GameActions::Execute(&gameAction);
99 }
100 #pragma endregion
101 
102 #pragma region RideModifyAction
ride_action_modify(Ride * ride,int32_t modifyType,int32_t flags)103 void ride_action_modify(Ride* ride, int32_t modifyType, int32_t flags)
104 {
105     auto gameAction = RideDemolishAction(ride->id, modifyType);
106     gameAction.SetFlags(flags);
107 
108     GameActions::Execute(&gameAction);
109 }
110 #pragma endregion
111 
112 #pragma region GuestSetName
113 
guest_set_name(uint16_t spriteIndex,const char * name)114 void guest_set_name(uint16_t spriteIndex, const char* name)
115 {
116     auto gameAction = GuestSetNameAction(spriteIndex, name);
117     GameActions::Execute(&gameAction);
118 }
119 #pragma endregion
120 
121 #pragma region StaffSetName
122 
staff_set_name(uint16_t spriteIndex,const char * name)123 void staff_set_name(uint16_t spriteIndex, const char* name)
124 {
125     auto gameAction = StaffSetNameAction(spriteIndex, name);
126     GameActions::Execute(&gameAction);
127 }
128 #pragma endregion
129 
130 #pragma region MazeSetTrack
maze_set_track(uint16_t x,uint16_t y,uint16_t z,uint8_t flags,bool initialPlacement,uint8_t direction,ride_id_t rideIndex,uint8_t mode)131 money32 maze_set_track(
132     uint16_t x, uint16_t y, uint16_t z, uint8_t flags, bool initialPlacement, uint8_t direction, ride_id_t rideIndex,
133     uint8_t mode)
134 {
135     auto gameAction = MazeSetTrackAction({ x, y, z, direction }, initialPlacement, rideIndex, mode);
136     gameAction.SetFlags(flags);
137 
138     GameActions::Result::Ptr res;
139 
140     if (!(flags & GAME_COMMAND_FLAG_APPLY))
141         res = GameActions::Query(&gameAction);
142     else
143         res = GameActions::Execute(&gameAction);
144 
145     // NOTE: ride_construction_tooldown_construct requires them to be set.
146     // Refactor result type once there's no C code referencing this function.
147     if (const auto* title = std::get_if<rct_string_id>(&res->ErrorTitle))
148         gGameCommandErrorTitle = *title;
149     else
150         gGameCommandErrorTitle = STR_NONE;
151 
152     if (const auto* message = std::get_if<rct_string_id>(&res->ErrorMessage))
153         gGameCommandErrorText = *message;
154     else
155         gGameCommandErrorText = STR_NONE;
156 
157     if (res->Error != GameActions::Status::Ok)
158     {
159         return MONEY32_UNDEFINED;
160     }
161 
162     return res->Cost;
163 }
164 #pragma endregion
165