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/>.
8 /** @file articulated_vehicles.cpp Implementation of articulated vehicles. */
13 #include "vehicle_func.h"
14 #include "engine_func.h"
15 #include "company_func.h"
18 #include "table/strings.h"
20 #include "safeguards.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
= nullptr, bool *mirrored
= nullptr)
34 assert(front
== nullptr || 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
!= nullptr) *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
!= nullptr) *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
!= nullptr) *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 CargoTypes
GetAvailableVehicleCargoTypes(EngineID engine
, bool include_initial_cargo_type
)
122 const Engine
*e
= Engine::Get(engine
);
123 if (!e
->CanCarryCargo()) return 0;
125 CargoTypes 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 * Get the default cargoes and refits of an articulated vehicle.
165 * The refits are linked to a cargo rather than an articulated part to prevent a long list of parts.
166 * @param engine Model to investigate.
167 * @param[out] cargoes Total amount of units that can be transported, summed by cargo.
168 * @param[out] refits Whether a (possibly partial) refit for each cargo is possible.
169 * @param cargo_type Selected refitted cargo type
170 * @param cargo_capacity Capacity of selected refitted cargo type
172 void GetArticulatedVehicleCargoesAndRefits(EngineID engine
, CargoArray
*cargoes
, CargoTypes
*refits
, CargoID cargo_type
, uint cargo_capacity
)
177 const Engine
*e
= Engine::Get(engine
);
179 if (cargo_type
< NUM_CARGO
&& cargo_capacity
> 0) {
180 (*cargoes
)[cargo_type
] += cargo_capacity
;
181 if (IsEngineRefittable(engine
)) SetBit(*refits
, cargo_type
);
184 if (!e
->IsGroundVehicle() || !HasBit(e
->info
.callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return;
186 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
187 EngineID artic_engine
= GetNextArticulatedPart(i
, engine
);
188 if (artic_engine
== INVALID_ENGINE
) break;
190 cargo_capacity
= GetVehicleDefaultCapacity(artic_engine
, &cargo_type
);
191 if (cargo_type
< NUM_CARGO
&& cargo_capacity
> 0) {
192 (*cargoes
)[cargo_type
] += cargo_capacity
;
193 if (IsEngineRefittable(artic_engine
)) SetBit(*refits
, cargo_type
);
199 * Checks whether any of the articulated parts is refittable
200 * @param engine the first part
201 * @return true if refittable
203 bool IsArticulatedVehicleRefittable(EngineID engine
)
205 if (IsEngineRefittable(engine
)) return true;
207 const Engine
*e
= Engine::Get(engine
);
208 if (!e
->IsGroundVehicle()) return false;
210 if (!HasBit(e
->info
.callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return false;
212 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
213 EngineID artic_engine
= GetNextArticulatedPart(i
, engine
);
214 if (artic_engine
== INVALID_ENGINE
) break;
216 if (IsEngineRefittable(artic_engine
)) return true;
223 * Merges the refit_masks of all articulated parts.
224 * @param engine the first part
225 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
226 * @param union_mask returns bit mask of CargoIDs which are a refit option for at least one articulated part
227 * @param intersection_mask returns bit mask of CargoIDs which are a refit option for every articulated part (with default capacity > 0)
229 void GetArticulatedRefitMasks(EngineID engine
, bool include_initial_cargo_type
, CargoTypes
*union_mask
, CargoTypes
*intersection_mask
)
231 const Engine
*e
= Engine::Get(engine
);
232 CargoTypes veh_cargoes
= GetAvailableVehicleCargoTypes(engine
, include_initial_cargo_type
);
233 *union_mask
= veh_cargoes
;
234 *intersection_mask
= (veh_cargoes
!= 0) ? veh_cargoes
: ALL_CARGOTYPES
;
236 if (!e
->IsGroundVehicle()) return;
237 if (!HasBit(e
->info
.callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return;
239 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
240 EngineID artic_engine
= GetNextArticulatedPart(i
, engine
);
241 if (artic_engine
== INVALID_ENGINE
) break;
243 veh_cargoes
= GetAvailableVehicleCargoTypes(artic_engine
, include_initial_cargo_type
);
244 *union_mask
|= veh_cargoes
;
245 if (veh_cargoes
!= 0) *intersection_mask
&= veh_cargoes
;
250 * Ors the refit_masks of all articulated parts.
251 * @param engine the first part
252 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
253 * @return bit mask of CargoIDs which are a refit option for at least one articulated part
255 CargoTypes
GetUnionOfArticulatedRefitMasks(EngineID engine
, bool include_initial_cargo_type
)
257 CargoTypes union_mask
, intersection_mask
;
258 GetArticulatedRefitMasks(engine
, include_initial_cargo_type
, &union_mask
, &intersection_mask
);
263 * Ands the refit_masks of all articulated parts.
264 * @param engine the first part
265 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
266 * @return bit mask of CargoIDs which are a refit option for every articulated part (with default capacity > 0)
268 CargoTypes
GetIntersectionOfArticulatedRefitMasks(EngineID engine
, bool include_initial_cargo_type
)
270 CargoTypes union_mask
, intersection_mask
;
271 GetArticulatedRefitMasks(engine
, include_initial_cargo_type
, &union_mask
, &intersection_mask
);
272 return intersection_mask
;
277 * Tests if all parts of an articulated vehicle are refitted to the same cargo.
278 * Note: Vehicles not carrying anything are ignored
279 * @param v the first vehicle in the chain
280 * @param cargo_type returns the common CargoID if needed. (CT_INVALID if no part is carrying something or they are carrying different things)
281 * @return true if some parts are carrying different cargoes, false if all parts are carrying the same (nothing is also the same)
283 bool IsArticulatedVehicleCarryingDifferentCargoes(const Vehicle
*v
, CargoID
*cargo_type
)
285 CargoID first_cargo
= CT_INVALID
;
288 if (v
->cargo_type
!= CT_INVALID
&& v
->GetEngine()->CanCarryCargo()) {
289 if (first_cargo
== CT_INVALID
) first_cargo
= v
->cargo_type
;
290 if (first_cargo
!= v
->cargo_type
) {
291 if (cargo_type
!= nullptr) *cargo_type
= CT_INVALID
;
296 v
= v
->HasArticulatedPart() ? v
->GetNextArticulatedPart() : nullptr;
297 } while (v
!= nullptr);
299 if (cargo_type
!= nullptr) *cargo_type
= first_cargo
;
304 * Checks whether the specs of freshly build articulated vehicles are consistent with the information specified in the purchase list.
305 * Only essential information is checked to leave room for magic tricks/workarounds to grfcoders.
307 * For autoreplace/-renew:
308 * - Default cargo type (without capacity)
309 * - intersection and union of refit masks.
311 void CheckConsistencyOfArticulatedVehicle(const Vehicle
*v
)
313 const Engine
*engine
= v
->GetEngine();
315 CargoTypes purchase_refit_union
, purchase_refit_intersection
;
316 GetArticulatedRefitMasks(v
->engine_type
, true, &purchase_refit_union
, &purchase_refit_intersection
);
317 CargoArray purchase_default_capacity
= GetCapacityOfArticulatedParts(v
->engine_type
);
319 CargoTypes real_refit_union
= 0;
320 CargoTypes real_refit_intersection
= ALL_CARGOTYPES
;
321 CargoArray real_default_capacity
;
324 CargoTypes refit_mask
= GetAvailableVehicleCargoTypes(v
->engine_type
, true);
325 real_refit_union
|= refit_mask
;
326 if (refit_mask
!= 0) real_refit_intersection
&= refit_mask
;
328 assert(v
->cargo_type
< NUM_CARGO
);
329 real_default_capacity
[v
->cargo_type
] += v
->cargo_cap
;
331 v
= v
->HasArticulatedPart() ? v
->GetNextArticulatedPart() : nullptr;
332 } while (v
!= nullptr);
334 /* Check whether the vehicle carries more cargoes than expected */
335 bool carries_more
= false;
336 for (CargoID cid
= 0; cid
< NUM_CARGO
; cid
++) {
337 if (real_default_capacity
[cid
] != 0 && purchase_default_capacity
[cid
] == 0) {
343 /* show a warning once for each GRF after each game load */
344 if (real_refit_union
!= purchase_refit_union
|| real_refit_intersection
!= purchase_refit_intersection
|| carries_more
) {
345 ShowNewGrfVehicleError(engine
->index
, STR_NEWGRF_BUGGY
, STR_NEWGRF_BUGGY_ARTICULATED_CARGO
, GBUG_VEH_REFIT
, false);
350 * Add the remaining articulated parts to the given vehicle.
351 * @param first The head of the articulated bit.
353 void AddArticulatedParts(Vehicle
*first
)
355 VehicleType type
= first
->type
;
356 if (!HasBit(EngInfo(first
->engine_type
)->callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return;
359 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
361 EngineID engine_type
= GetNextArticulatedPart(i
, first
->engine_type
, first
, &flip_image
);
362 if (engine_type
== INVALID_ENGINE
) return;
364 /* In the (very rare) case the GRF reported wrong number of articulated parts
365 * and we run out of available vehicles, bail out. */
366 if (!Vehicle::CanAllocateItem()) return;
368 GroundVehicleCache
*gcache
= v
->GetGroundVehicleCache();
369 gcache
->first_engine
= v
->engine_type
; // Needs to be set before first callback
371 const Engine
*e_artic
= Engine::Get(engine_type
);
373 default: NOT_REACHED();
376 Train
*front
= Train::From(first
);
377 Train
*t
= new Train();
382 t
->track
= front
->track
;
383 t
->railtype
= front
->railtype
;
385 t
->spritenum
= e_artic
->u
.rail
.image_index
;
386 if (e_artic
->CanCarryCargo()) {
387 t
->cargo_type
= e_artic
->GetDefaultCargoType();
388 t
->cargo_cap
= e_artic
->u
.rail
.capacity
; // Callback 36 is called when the consist is finished
390 t
->cargo_type
= front
->cargo_type
; // Needed for livery selection
395 t
->SetArticulatedPart();
400 RoadVehicle
*front
= RoadVehicle::From(first
);
401 RoadVehicle
*rv
= new RoadVehicle();
406 gcache
->cached_veh_length
= VEHICLE_LENGTH
; // Callback is called when the consist is finished
407 rv
->state
= RVSB_IN_DEPOT
;
409 rv
->roadtype
= front
->roadtype
;
410 rv
->compatible_roadtypes
= front
->compatible_roadtypes
;
412 rv
->spritenum
= e_artic
->u
.road
.image_index
;
413 if (e_artic
->CanCarryCargo()) {
414 rv
->cargo_type
= e_artic
->GetDefaultCargoType();
415 rv
->cargo_cap
= e_artic
->u
.road
.capacity
; // Callback 36 is called when the consist is finished
417 rv
->cargo_type
= front
->cargo_type
; // Needed for livery selection
422 rv
->SetArticulatedPart();
427 /* get common values from first engine */
428 v
->direction
= first
->direction
;
429 v
->owner
= first
->owner
;
430 v
->tile
= first
->tile
;
431 v
->x_pos
= first
->x_pos
;
432 v
->y_pos
= first
->y_pos
;
433 v
->z_pos
= first
->z_pos
;
434 v
->date_of_last_service
= first
->date_of_last_service
;
435 v
->build_year
= first
->build_year
;
436 v
->vehstatus
= first
->vehstatus
& ~VS_STOPPED
;
438 v
->cargo_subtype
= 0;
440 v
->engine_type
= engine_type
;
442 v
->sprite_seq
.Set(SPR_IMG_QUERY
);
443 v
->random_bits
= VehicleRandomBits();
445 if (flip_image
) v
->spritenum
++;