1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
8 /** @file script_group.hpp Everything to put vehicles into groups. */
9 
10 #ifndef SCRIPT_GROUP_HPP
11 #define SCRIPT_GROUP_HPP
12 
13 #include "script_vehicle.hpp"
14 #include "../../group_type.h"
15 
16 /**
17  * Class that handles all group related functions.
18  * @api ai
19  */
20 class ScriptGroup : public ScriptObject {
21 public:
22 	/**
23 	 * The group IDs of some special groups.
24 	 */
25 	enum GroupID {
26 		/* Note: these values represent part of the in-game static values */
27 		GROUP_ALL     = ::ALL_GROUP,     ///< All vehicles are in this group.
28 		GROUP_DEFAULT = ::DEFAULT_GROUP, ///< Vehicles not put in any other group are in this one.
29 		GROUP_INVALID = ::INVALID_GROUP, ///< An invalid group id.
30 	};
31 
32 	/**
33 	 * Checks whether the given group is valid.
34 	 * @param group_id The group to check.
35 	 * @pre group_id != GROUP_DEFAULT && group_id != GROUP_ALL.
36 	 * @return True if and only if the group is valid.
37 	 */
38 	static bool IsValidGroup(GroupID group_id);
39 
40 	/**
41 	 * Create a new group.
42 	 * @param vehicle_type The type of vehicle to create a group for.
43 	 * @param parent_group_id The parent group id to create this group under, INVALID_GROUP for top-level.
44 	 * @return The GroupID of the new group, or an invalid GroupID when
45 	 *  it failed. Check the return value using IsValidGroup(). In test-mode
46 	 *  0 is returned if it was successful; any other value indicates failure.
47 	 */
48 	static GroupID CreateGroup(ScriptVehicle::VehicleType vehicle_type, GroupID parent_group_id);
49 
50 	/**
51 	 * Delete the given group. When the deletion succeeds all vehicles in the
52 	 *  given group will move to the GROUP_DEFAULT.
53 	 * @param group_id The group to delete.
54 	 * @pre IsValidGroup(group_id).
55 	 * @return True if and only if the group was successfully deleted.
56 	 */
57 	static bool DeleteGroup(GroupID group_id);
58 
59 	/**
60 	 * Get the vehicle type of a group.
61 	 * @param group_id The group to get the type from.
62 	 * @pre IsValidGroup(group_id).
63 	 * @return The vehicletype of the given group.
64 	 */
65 	static ScriptVehicle::VehicleType GetVehicleType(GroupID group_id);
66 
67 	/**
68 	 * Set the name of a group.
69 	 * @param group_id The group to set the name for.
70 	 * @param name The name for the group (can be either a raw string, or a ScriptText object).
71 	 * @pre IsValidGroup(group_id).
72 	 * @pre name != nullptr && len(name) != 0
73 	 * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE
74 	 * @return True if and only if the name was changed.
75 	 */
76 	static bool SetName(GroupID group_id, Text *name);
77 
78 	/**
79 	 * Get the name of a group.
80 	 * @param group_id The group to get the name of.
81 	 * @pre IsValidGroup(group_id).
82 	 * @return The name the group has.
83 	 */
84 	static char *GetName(GroupID group_id);
85 
86 	/**
87 	 * Set parent group of a group.
88 	 * @param group_id The group to set the parent for.
89 	 * @param parent_group_id The parent group to set.
90 	 * @pre IsValidGroup(group_id).
91 	 * @pre IsValidGroup(parent_group_id).
92 	 * @return True if and only if the parent group was changed.
93 	 */
94 	static bool SetParent(GroupID group_id, GroupID parent_group_id);
95 
96 	/**
97 	 * Get parent group of a group.
98 	 * @param group_id The group to get the parent of.
99 	 * @pre IsValidGroup(group_id).
100 	 * @return The group id of the parent group.
101 	 */
102 	static GroupID GetParent(GroupID group_id);
103 
104 	/**
105 	 * Enable or disable autoreplace protected. If the protection is
106 	 *  enabled, global autoreplace won't affect vehicles in this group.
107 	 * @param group_id The group to change the protection for.
108 	 * @param enable True if protection should be enabled.
109 	 * @pre IsValidGroup(group_id).
110 	 * @return True if and only if the protection was successfully changed.
111 	 */
112 	static bool EnableAutoReplaceProtection(GroupID group_id, bool enable);
113 
114 	/**
115 	 * Get the autoreplace protection status.
116 	 * @param group_id The group to get the protection status for.
117 	 * @pre IsValidGroup(group_id).
118 	 * @return The autoreplace protection status for the given group.
119 	 */
120 	static bool GetAutoReplaceProtection(GroupID group_id);
121 
122 	/**
123 	 * Get the number of engines in a given group.
124 	 * @param group_id The group to get the number of engines in.
125 	 * @param engine_id The engine id to count.
126 	 * @pre IsValidGroup(group_id) || group_id == GROUP_ALL || group_id == GROUP_DEFAULT.
127 	 * @return The number of engines with id engine_id in the group with id group_id.
128 	 */
129 	static int32 GetNumEngines(GroupID group_id, EngineID engine_id);
130 
131 	/**
132 	 * Get the total number of vehicles in a given group and its sub-groups.
133 	 * @param group_id The group to get the number of vehicles in.
134 	 * @param vehicle_type The type of vehicle of the group.
135 	 * @pre IsValidGroup(group_id) || group_id == GROUP_ALL || group_id == GROUP_DEFAULT.
136 	 * @pre IsValidGroup(group_id) || vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL ||
137 	 *   vehicle_type == ScriptVehicle::VT_WATER || vehicle_type == ScriptVehicle::VT_AIR
138 	 * @return The total number of vehicles in the group with id group_id and it's sub-groups.
139 	 * @note If the group is valid (neither GROUP_ALL nor GROUP_DEFAULT), the value of
140 	 *  vehicle_type is retrieved from the group itself and not from the input value.
141 	 *  But if the group is GROUP_ALL or GROUP_DEFAULT, then vehicle_type must be valid.
142 	 */
143 	static int32 GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type);
144 
145 	/**
146 	 * Move a vehicle to a group.
147 	 * @param group_id The group to move the vehicle to.
148 	 * @param vehicle_id The vehicle to move to the group.
149 	 * @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT.
150 	 * @pre ScriptVehicle::IsValidVehicle(vehicle_id).
151 	 * @return True if and only if the vehicle was successfully moved to the group.
152 	 * @note A vehicle can be in only one group at the same time. To remove it from
153 	 *  a group, move it to another or to GROUP_DEFAULT. Moving the vehicle to the
154 	 *  given group means removing it from another group.
155 	 */
156 	static bool MoveVehicle(GroupID group_id, VehicleID vehicle_id);
157 
158 	/**
159 	 * Enable or disable the removal of wagons when a (part of a) vehicle is
160 	 *  (auto)replaced with a longer variant (longer wagons or longer engines)
161 	 *  If enabled, wagons are removed from the end of the vehicle until it
162 	 *  fits in the same number of tiles as it did before.
163 	 * @param keep_length If true, wagons will be removed if the new engine is longer.
164 	 * @return True if and only if the value was successfully changed.
165 	 */
166 	static bool EnableWagonRemoval(bool keep_length);
167 
168 	/**
169 	 * Get the current status of wagon removal.
170 	 * @return Whether or not wagon removal is enabled.
171 	 */
172 	static bool HasWagonRemoval();
173 
174 	/**
175 	 * Start replacing all vehicles with a specified engine with another engine.
176 	 * @param group_id The group to replace vehicles from. Use ALL_GROUP to replace
177 	 *  vehicles from all groups that haven't set autoreplace protection.
178 	 * @param engine_id_old The engine id to start replacing.
179 	 * @param engine_id_new The engine id to replace with.
180 	 * @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL.
181 	 * @pre ScriptEngine.IsBuildable(engine_id_new).
182 	 * @return True if and if the replacing was successfully started.
183 	 * @note To stop autoreplacing engine_id_old, call StopAutoReplace(group_id, engine_id_old).
184 	 */
185 	static bool SetAutoReplace(GroupID group_id, EngineID engine_id_old, EngineID engine_id_new);
186 
187 	/**
188 	 * Get the EngineID the given EngineID is replaced with.
189 	 * @param group_id The group to get the replacement from.
190 	 * @param engine_id The engine that is being replaced.
191 	 * @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL.
192 	 * @return The EngineID that is replacing engine_id or an invalid EngineID
193 	 *   in case engine_id is not begin replaced.
194 	 */
195 	static EngineID GetEngineReplacement(GroupID group_id, EngineID engine_id);
196 
197 	/**
198 	 * Stop replacing a certain engine in the specified group.
199 	 * @param group_id The group to stop replacing the engine in.
200 	 * @param engine_id The engine id to stop replacing with another engine.
201 	 * @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL.
202 	 * @return True if and if the replacing was successfully stopped.
203 	 */
204 	static bool StopAutoReplace(GroupID group_id, EngineID engine_id);
205 
206 	/**
207 	 * Get the current profit of a group.
208 	 * @param group_id The group to get the profit of.
209 	 * @pre IsValidGroup(group_id).
210 	 * @return The current profit the group has.
211 	 */
212 	static Money GetProfitThisYear(GroupID group_id);
213 
214 	/**
215 	 * Get the profit of last year of a group.
216 	 * @param group_id The group to get the profit of.
217 	 * @pre IsValidGroup(group_id).
218 	 * @return The current profit the group had last year.
219 	 */
220 	static Money GetProfitLastYear(GroupID group_id);
221 
222 	/**
223 	 * Get the current vehicle usage of a group.
224 	 * @param group_id The group to get the current usage of.
225 	 * @pre IsValidGroup(group_id).
226 	 * @return The current usage of the group.
227 	 */
228 	static uint32 GetCurrentUsage(GroupID group_id);
229 
230 	/**
231 	 * Set primary colour for a group.
232 	 * @param group_id The group id to set the colour of.
233 	 * @param colour Colour to set.
234 	 * @pre IsValidGroup(group_id).
235 	 */
236 	static bool SetPrimaryColour(GroupID group_id, ScriptCompany::Colours colour);
237 
238 	/**
239 	 * Set secondary colour for a group.
240 	 * @param group_id The group id to set the colour of.
241 	 * @param colour Colour to set.
242 	 * @pre IsValidGroup(group_id).
243 	 */
244 	static bool SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour);
245 
246 	/**
247 	 * Get primary colour of a group.
248 	 * @param group_id The group id to get the colour of.
249 	 * @pre IsValidGroup(group_id).
250 	 */
251 	static ScriptCompany::Colours GetPrimaryColour(GroupID group_id);
252 
253 	/**
254 	 * Get secondary colour for a group.
255 	 * @param group_id The group id to get the colour of.
256 	 * @pre IsValidGroup(group_id).
257 	 */
258 	static ScriptCompany::Colours GetSecondaryColour(GroupID group_id);
259 };
260 
261 #endif /* SCRIPT_GROUP_HPP */
262