4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
10 /** @file articulated_vehicles.cpp Implementation of articulated vehicles. */
15 #include "vehicle_func.h"
16 #include "engine_func.h"
17 #include "company_func.h"
20 #include "table/strings.h"
22 static const uint MAX_ARTICULATED_PARTS
= 100; ///< Maximum of articulated parts per vehicle, i.e. when to abort calling the articulated vehicle callback.
25 * Determines the next articulated part to attach
26 * @param index Position in chain
27 * @param front_type Front engine type
28 * @param front Front engine
29 * @param mirrored Returns whether the part shall be flipped.
30 * @return engine to add or INVALID_ENGINE
32 static EngineID
GetNextArticulatedPart(uint index
, EngineID front_type
, Vehicle
*front
= NULL
, bool *mirrored
= NULL
)
34 assert(front
== NULL
|| front
->engine_type
== front_type
);
36 const Engine
*front_engine
= Engine::Get(front_type
);
38 uint16 callback
= GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE
, index
, 0, front_type
, front
);
39 if (callback
== CALLBACK_FAILED
) return INVALID_ENGINE
;
41 if (front_engine
->GetGRF()->grf_version
< 8) {
42 /* 8 bits, bit 7 for mirroring */
43 callback
= GB(callback
, 0, 8);
44 if (callback
== 0xFF) return INVALID_ENGINE
;
45 if (mirrored
!= NULL
) *mirrored
= HasBit(callback
, 7);
46 callback
= GB(callback
, 0, 7);
48 /* 15 bits, bit 14 for mirroring */
49 if (callback
== 0x7FFF) return INVALID_ENGINE
;
50 if (mirrored
!= NULL
) *mirrored
= HasBit(callback
, 14);
51 callback
= GB(callback
, 0, 14);
54 return GetNewEngineID(front_engine
->GetGRF(), front_engine
->type
, callback
);
58 * Does a NewGRF report that this should be an articulated vehicle?
59 * @param engine_type The engine to check.
60 * @return True iff the articulated engine callback flag is set.
62 bool IsArticulatedEngine(EngineID engine_type
)
64 return HasBit(EngInfo(engine_type
)->callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
);
68 * Count the number of articulated parts of an engine.
69 * @param engine_type The engine to get the number of parts of.
70 * @param purchase_window Whether we are in the scope of the purchase window or not, i.e. whether we cannot allocate vehicles.
71 * @return The number of parts.
73 uint
CountArticulatedParts(EngineID engine_type
, bool purchase_window
)
75 if (!HasBit(EngInfo(engine_type
)->callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return 0;
77 /* If we can't allocate a vehicle now, we can't allocate it in the command
78 * either, so it doesn't matter how many articulated parts there are. */
79 if (!Vehicle::CanAllocateItem()) return 0;
82 if (!purchase_window
) {
84 v
->engine_type
= engine_type
;
85 v
->owner
= _current_company
;
89 for (i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
90 if (GetNextArticulatedPart(i
, engine_type
, v
) == INVALID_ENGINE
) break;
100 * Returns the default (non-refitted) capacity of a specific EngineID.
101 * @param engine the EngineID of interest
102 * @param cargo_type returns the default cargo type, if needed
105 static inline uint16
GetVehicleDefaultCapacity(EngineID engine
, CargoID
*cargo_type
)
107 const Engine
*e
= Engine::Get(engine
);
108 CargoID cargo
= (e
->CanCarryCargo() ? e
->GetDefaultCargoType() : (CargoID
)CT_INVALID
);
109 if (cargo_type
!= NULL
) *cargo_type
= cargo
;
110 if (cargo
== CT_INVALID
) return 0;
111 return e
->GetDisplayDefaultCapacity();
115 * Returns all cargoes a vehicle can carry.
116 * @param engine the EngineID of interest
117 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
118 * @return bit set of CargoIDs
120 static inline uint32
GetAvailableVehicleCargoTypes(EngineID engine
, bool include_initial_cargo_type
)
122 const Engine
*e
= Engine::Get(engine
);
123 if (!e
->CanCarryCargo()) return 0;
125 uint32 cargoes
= e
->info
.refit_mask
;
127 if (include_initial_cargo_type
) {
128 SetBit(cargoes
, e
->GetDefaultCargoType());
135 * Get the capacity of the parts of a given engine.
136 * @param engine The engine to get the capacities from.
137 * @return The cargo capacities.
139 CargoArray
GetCapacityOfArticulatedParts(EngineID engine
)
142 const Engine
*e
= Engine::Get(engine
);
145 uint16 cargo_capacity
= GetVehicleDefaultCapacity(engine
, &cargo_type
);
146 if (cargo_type
< NUM_CARGO
) capacity
[cargo_type
] = cargo_capacity
;
148 if (!e
->IsGroundVehicle()) return capacity
;
150 if (!HasBit(e
->info
.callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return capacity
;
152 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
153 EngineID artic_engine
= GetNextArticulatedPart(i
, engine
);
154 if (artic_engine
== INVALID_ENGINE
) break;
156 cargo_capacity
= GetVehicleDefaultCapacity(artic_engine
, &cargo_type
);
157 if (cargo_type
< NUM_CARGO
) capacity
[cargo_type
] += cargo_capacity
;
164 * Checks whether any of the articulated parts is refittable
165 * @param engine the first part
166 * @return true if refittable
168 bool IsArticulatedVehicleRefittable(EngineID engine
)
170 if (IsEngineRefittable(engine
)) return true;
172 const Engine
*e
= Engine::Get(engine
);
173 if (!e
->IsGroundVehicle()) return false;
175 if (!HasBit(e
->info
.callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return false;
177 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
178 EngineID artic_engine
= GetNextArticulatedPart(i
, engine
);
179 if (artic_engine
== INVALID_ENGINE
) break;
181 if (IsEngineRefittable(artic_engine
)) return true;
188 * Merges the refit_masks of all articulated parts.
189 * @param engine the first part
190 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
191 * @param union_mask returns bit mask of CargoIDs which are a refit option for at least one articulated part
192 * @param intersection_mask returns bit mask of CargoIDs which are a refit option for every articulated part (with default capacity > 0)
194 void GetArticulatedRefitMasks(EngineID engine
, bool include_initial_cargo_type
, uint32
*union_mask
, uint32
*intersection_mask
)
196 const Engine
*e
= Engine::Get(engine
);
197 uint32 veh_cargoes
= GetAvailableVehicleCargoTypes(engine
, include_initial_cargo_type
);
198 *union_mask
= veh_cargoes
;
199 *intersection_mask
= (veh_cargoes
!= 0) ? veh_cargoes
: UINT32_MAX
;
201 if (!e
->IsGroundVehicle()) return;
202 if (!HasBit(e
->info
.callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return;
204 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
205 EngineID artic_engine
= GetNextArticulatedPart(i
, engine
);
206 if (artic_engine
== INVALID_ENGINE
) break;
208 veh_cargoes
= GetAvailableVehicleCargoTypes(artic_engine
, include_initial_cargo_type
);
209 *union_mask
|= veh_cargoes
;
210 if (veh_cargoes
!= 0) *intersection_mask
&= veh_cargoes
;
215 * Ors the refit_masks of all articulated parts.
216 * @param engine the first part
217 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
218 * @return bit mask of CargoIDs which are a refit option for at least one articulated part
220 uint32
GetUnionOfArticulatedRefitMasks(EngineID engine
, bool include_initial_cargo_type
)
222 uint32 union_mask
, intersection_mask
;
223 GetArticulatedRefitMasks(engine
, include_initial_cargo_type
, &union_mask
, &intersection_mask
);
228 * Ands the refit_masks of all articulated parts.
229 * @param engine the first part
230 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
231 * @return bit mask of CargoIDs which are a refit option for every articulated part (with default capacity > 0)
233 uint32
GetIntersectionOfArticulatedRefitMasks(EngineID engine
, bool include_initial_cargo_type
)
235 uint32 union_mask
, intersection_mask
;
236 GetArticulatedRefitMasks(engine
, include_initial_cargo_type
, &union_mask
, &intersection_mask
);
237 return intersection_mask
;
242 * Tests if all parts of an articulated vehicle are refitted to the same cargo.
243 * Note: Vehicles not carrying anything are ignored
244 * @param v the first vehicle in the chain
245 * @param cargo_type returns the common CargoID if needed. (CT_INVALID if no part is carrying something or they are carrying different things)
246 * @return true if some parts are carrying different cargoes, false if all parts are carrying the same (nothing is also the same)
248 bool IsArticulatedVehicleCarryingDifferentCargoes(const Vehicle
*v
, CargoID
*cargo_type
)
250 CargoID first_cargo
= CT_INVALID
;
253 if (v
->cargo_type
!= CT_INVALID
&& v
->GetEngine()->CanCarryCargo()) {
254 if (first_cargo
== CT_INVALID
) first_cargo
= v
->cargo_type
;
255 if (first_cargo
!= v
->cargo_type
) {
256 if (cargo_type
!= NULL
) *cargo_type
= CT_INVALID
;
261 v
= v
->HasArticulatedPart() ? v
->GetNextArticulatedPart() : NULL
;
264 if (cargo_type
!= NULL
) *cargo_type
= first_cargo
;
269 * Checks whether the specs of freshly build articulated vehicles are consistent with the information specified in the purchase list.
270 * Only essential information is checked to leave room for magic tricks/workarounds to grfcoders.
272 * For autoreplace/-renew:
273 * - Default cargo type (without capacity)
274 * - intersection and union of refit masks.
276 void CheckConsistencyOfArticulatedVehicle(const Vehicle
*v
)
278 const Engine
*engine
= v
->GetEngine();
280 uint32 purchase_refit_union
, purchase_refit_intersection
;
281 GetArticulatedRefitMasks(v
->engine_type
, true, &purchase_refit_union
, &purchase_refit_intersection
);
282 CargoArray purchase_default_capacity
= GetCapacityOfArticulatedParts(v
->engine_type
);
284 uint32 real_refit_union
= 0;
285 uint32 real_refit_intersection
= UINT_MAX
;
286 CargoArray real_default_capacity
;
289 uint32 refit_mask
= GetAvailableVehicleCargoTypes(v
->engine_type
, true);
290 real_refit_union
|= refit_mask
;
291 if (refit_mask
!= 0) real_refit_intersection
&= refit_mask
;
293 assert(v
->cargo_type
< NUM_CARGO
);
294 real_default_capacity
[v
->cargo_type
] += v
->cargo_cap
;
296 v
= v
->HasArticulatedPart() ? v
->GetNextArticulatedPart() : NULL
;
299 /* Check whether the vehicle carries more cargoes than expected */
300 bool carries_more
= false;
301 for (CargoID cid
= 0; cid
< NUM_CARGO
; cid
++) {
302 if (real_default_capacity
[cid
] != 0 && purchase_default_capacity
[cid
] == 0) {
308 /* show a warning once for each GRF after each game load */
309 if (real_refit_union
!= purchase_refit_union
|| real_refit_intersection
!= purchase_refit_intersection
|| carries_more
) {
310 ShowNewGrfVehicleError(engine
->index
, STR_NEWGRF_BUGGY
, STR_NEWGRF_BUGGY_ARTICULATED_CARGO
, GBUG_VEH_REFIT
, false);
315 * Add the remaining articulated parts to the given vehicle.
316 * @param first The head of the articulated bit.
318 void AddArticulatedParts(Vehicle
*first
)
320 VehicleType type
= first
->type
;
321 if (!HasBit(EngInfo(first
->engine_type
)->callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return;
324 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
326 EngineID engine_type
= GetNextArticulatedPart(i
, first
->engine_type
, first
, &flip_image
);
327 if (engine_type
== INVALID_ENGINE
) return;
329 /* In the (very rare) case the GRF reported wrong number of articulated parts
330 * and we run out of available vehicles, bail out. */
331 if (!Vehicle::CanAllocateItem()) return;
333 GroundVehicleCache
*gcache
= v
->GetGroundVehicleCache();
334 gcache
->first_engine
= v
->engine_type
; // Needs to be set before first callback
336 const Engine
*e_artic
= Engine::Get(engine_type
);
338 default: NOT_REACHED();
341 Train
*front
= Train::From(first
);
342 Train
*t
= new Train();
347 t
->trackdir
= front
->trackdir
;
348 t
->railtype
= front
->railtype
;
350 t
->spritenum
= e_artic
->u
.rail
.image_index
;
351 if (e_artic
->CanCarryCargo()) {
352 t
->cargo_type
= e_artic
->GetDefaultCargoType();
353 t
->cargo_cap
= e_artic
->u
.rail
.capacity
; // Callback 36 is called when the consist is finished
355 t
->cargo_type
= front
->cargo_type
; // Needed for livery selection
360 t
->SetArticulatedPart();
365 RoadVehicle
*front
= RoadVehicle::From(first
);
366 RoadVehicle
*rv
= new RoadVehicle();
371 gcache
->cached_veh_length
= VEHICLE_LENGTH
; // Callback is called when the consist is finished
372 rv
->state
= RVSB_IN_DEPOT
;
374 rv
->roadtype
= front
->roadtype
;
375 rv
->compatible_roadtypes
= front
->compatible_roadtypes
;
377 rv
->spritenum
= e_artic
->u
.road
.image_index
;
378 if (e_artic
->CanCarryCargo()) {
379 rv
->cargo_type
= e_artic
->GetDefaultCargoType();
380 rv
->cargo_cap
= e_artic
->u
.road
.capacity
; // Callback 36 is called when the consist is finished
382 rv
->cargo_type
= front
->cargo_type
; // Needed for livery selection
387 rv
->SetArticulatedPart();
392 /* get common values from first engine */
393 v
->direction
= first
->direction
;
394 v
->owner
= first
->owner
;
395 v
->tile
= first
->tile
;
396 v
->x_pos
= first
->x_pos
;
397 v
->y_pos
= first
->y_pos
;
398 v
->z_pos
= first
->z_pos
;
399 v
->build_year
= first
->build_year
;
400 v
->vehstatus
= first
->vehstatus
& ~VS_STOPPED
;
402 v
->cargo_subtype
= 0;
404 v
->engine_type
= engine_type
;
406 v
->cur_image
= SPR_IMG_QUERY
;
407 v
->random_bits
= VehicleRandomBits();
409 if (flip_image
) v
->spritenum
++;
411 VehicleUpdatePosition(v
);