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 #include "safeguards.h"
24 static const uint MAX_ARTICULATED_PARTS
= 100; ///< Maximum of articulated parts per vehicle, i.e. when to abort calling the articulated vehicle callback.
27 * Determines the next articulated part to attach
28 * @param index Position in chain
29 * @param front_type Front engine type
30 * @param front Front engine
31 * @param mirrored Returns whether the part shall be flipped.
32 * @return engine to add or INVALID_ENGINE
34 static EngineID
GetNextArticulatedPart(uint index
, EngineID front_type
, Vehicle
*front
= NULL
, bool *mirrored
= NULL
)
36 assert(front
== NULL
|| front
->engine_type
== front_type
);
38 const Engine
*front_engine
= Engine::Get(front_type
);
40 uint16 callback
= GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE
, index
, 0, front_type
, front
);
41 if (callback
== CALLBACK_FAILED
) return INVALID_ENGINE
;
43 if (front_engine
->GetGRF()->grf_version
< 8) {
44 /* 8 bits, bit 7 for mirroring */
45 callback
= GB(callback
, 0, 8);
46 if (callback
== 0xFF) return INVALID_ENGINE
;
47 if (mirrored
!= NULL
) *mirrored
= HasBit(callback
, 7);
48 callback
= GB(callback
, 0, 7);
50 /* 15 bits, bit 14 for mirroring */
51 if (callback
== 0x7FFF) return INVALID_ENGINE
;
52 if (mirrored
!= NULL
) *mirrored
= HasBit(callback
, 14);
53 callback
= GB(callback
, 0, 14);
56 return GetNewEngineID(front_engine
->GetGRF(), front_engine
->type
, callback
);
60 * Does a NewGRF report that this should be an articulated vehicle?
61 * @param engine_type The engine to check.
62 * @return True iff the articulated engine callback flag is set.
64 bool IsArticulatedEngine(EngineID engine_type
)
66 return HasBit(EngInfo(engine_type
)->callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
);
70 * Count the number of articulated parts of an engine.
71 * @param engine_type The engine to get the number of parts of.
72 * @param purchase_window Whether we are in the scope of the purchase window or not, i.e. whether we cannot allocate vehicles.
73 * @return The number of parts.
75 uint
CountArticulatedParts(EngineID engine_type
, bool purchase_window
)
77 if (!HasBit(EngInfo(engine_type
)->callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return 0;
79 /* If we can't allocate a vehicle now, we can't allocate it in the command
80 * either, so it doesn't matter how many articulated parts there are. */
81 if (!Vehicle::CanAllocateItem()) return 0;
84 if (!purchase_window
) {
86 v
->engine_type
= engine_type
;
87 v
->owner
= _current_company
;
91 for (i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
92 if (GetNextArticulatedPart(i
, engine_type
, v
) == INVALID_ENGINE
) break;
102 * Returns the default (non-refitted) capacity of a specific EngineID.
103 * @param engine the EngineID of interest
104 * @param cargo_type returns the default cargo type, if needed
107 static inline uint16
GetVehicleDefaultCapacity(EngineID engine
, CargoID
*cargo_type
)
109 const Engine
*e
= Engine::Get(engine
);
110 CargoID cargo
= (e
->CanCarryCargo() ? e
->GetDefaultCargoType() : (CargoID
)CT_INVALID
);
111 if (cargo_type
!= NULL
) *cargo_type
= cargo
;
112 if (cargo
== CT_INVALID
) return 0;
113 return e
->GetDisplayDefaultCapacity();
117 * Returns all cargoes a vehicle can carry.
118 * @param engine the EngineID of interest
119 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
120 * @return bit set of CargoIDs
122 static inline uint32
GetAvailableVehicleCargoTypes(EngineID engine
, bool include_initial_cargo_type
)
124 const Engine
*e
= Engine::Get(engine
);
125 if (!e
->CanCarryCargo()) return 0;
127 uint32 cargoes
= e
->info
.refit_mask
;
129 if (include_initial_cargo_type
) {
130 SetBit(cargoes
, e
->GetDefaultCargoType());
137 * Get the capacity of the parts of a given engine.
138 * @param engine The engine to get the capacities from.
139 * @return The cargo capacities.
141 CargoArray
GetCapacityOfArticulatedParts(EngineID engine
)
144 const Engine
*e
= Engine::Get(engine
);
147 uint16 cargo_capacity
= GetVehicleDefaultCapacity(engine
, &cargo_type
);
148 if (cargo_type
< NUM_CARGO
) capacity
[cargo_type
] = cargo_capacity
;
150 if (!e
->IsGroundVehicle()) return capacity
;
152 if (!HasBit(e
->info
.callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return capacity
;
154 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
155 EngineID artic_engine
= GetNextArticulatedPart(i
, engine
);
156 if (artic_engine
== INVALID_ENGINE
) break;
158 cargo_capacity
= GetVehicleDefaultCapacity(artic_engine
, &cargo_type
);
159 if (cargo_type
< NUM_CARGO
) capacity
[cargo_type
] += cargo_capacity
;
166 * Get the default cargoes and refits of an articulated vehicle.
167 * The refits are linked to a cargo rather than an articulated part to prevent a long list of parts.
168 * @param engine Model to investigate.
169 * @param[out] cargoes Total amount of units that can be transported, summed by cargo.
170 * @param[out] refits Whether a (possibly partial) refit for each cargo is possible.
172 void GetArticulatedVehicleCargoesAndRefits(EngineID engine
, CargoArray
*cargoes
, uint32
*refits
)
177 const Engine
*e
= Engine::Get(engine
);
180 uint16 cargo_capacity
= GetVehicleDefaultCapacity(engine
, &cargo_type
);
181 if (cargo_type
< NUM_CARGO
&& cargo_capacity
> 0) {
182 (*cargoes
)[cargo_type
] += cargo_capacity
;
183 if (IsEngineRefittable(engine
)) SetBit(*refits
, cargo_type
);
186 if (!e
->IsGroundVehicle() || !HasBit(e
->info
.callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return;
188 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
189 EngineID artic_engine
= GetNextArticulatedPart(i
, engine
);
190 if (artic_engine
== INVALID_ENGINE
) break;
192 cargo_capacity
= GetVehicleDefaultCapacity(artic_engine
, &cargo_type
);
193 if (cargo_type
< NUM_CARGO
&& cargo_capacity
> 0) {
194 (*cargoes
)[cargo_type
] += cargo_capacity
;
195 if (IsEngineRefittable(artic_engine
)) SetBit(*refits
, cargo_type
);
201 * Checks whether any of the articulated parts is refittable
202 * @param engine the first part
203 * @return true if refittable
205 bool IsArticulatedVehicleRefittable(EngineID engine
)
207 if (IsEngineRefittable(engine
)) return true;
209 const Engine
*e
= Engine::Get(engine
);
210 if (!e
->IsGroundVehicle()) return false;
212 if (!HasBit(e
->info
.callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return false;
214 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
215 EngineID artic_engine
= GetNextArticulatedPart(i
, engine
);
216 if (artic_engine
== INVALID_ENGINE
) break;
218 if (IsEngineRefittable(artic_engine
)) return true;
225 * Merges the refit_masks of all articulated parts.
226 * @param engine the first part
227 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
228 * @param union_mask returns bit mask of CargoIDs which are a refit option for at least one articulated part
229 * @param intersection_mask returns bit mask of CargoIDs which are a refit option for every articulated part (with default capacity > 0)
231 void GetArticulatedRefitMasks(EngineID engine
, bool include_initial_cargo_type
, uint32
*union_mask
, uint32
*intersection_mask
)
233 const Engine
*e
= Engine::Get(engine
);
234 uint32 veh_cargoes
= GetAvailableVehicleCargoTypes(engine
, include_initial_cargo_type
);
235 *union_mask
= veh_cargoes
;
236 *intersection_mask
= (veh_cargoes
!= 0) ? veh_cargoes
: UINT32_MAX
;
238 if (!e
->IsGroundVehicle()) return;
239 if (!HasBit(e
->info
.callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return;
241 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
242 EngineID artic_engine
= GetNextArticulatedPart(i
, engine
);
243 if (artic_engine
== INVALID_ENGINE
) break;
245 veh_cargoes
= GetAvailableVehicleCargoTypes(artic_engine
, include_initial_cargo_type
);
246 *union_mask
|= veh_cargoes
;
247 if (veh_cargoes
!= 0) *intersection_mask
&= veh_cargoes
;
252 * Ors the refit_masks of all articulated parts.
253 * @param engine the first part
254 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
255 * @return bit mask of CargoIDs which are a refit option for at least one articulated part
257 uint32
GetUnionOfArticulatedRefitMasks(EngineID engine
, bool include_initial_cargo_type
)
259 uint32 union_mask
, intersection_mask
;
260 GetArticulatedRefitMasks(engine
, include_initial_cargo_type
, &union_mask
, &intersection_mask
);
265 * Ands the refit_masks of all articulated parts.
266 * @param engine the first part
267 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
268 * @return bit mask of CargoIDs which are a refit option for every articulated part (with default capacity > 0)
270 uint32
GetIntersectionOfArticulatedRefitMasks(EngineID engine
, bool include_initial_cargo_type
)
272 uint32 union_mask
, intersection_mask
;
273 GetArticulatedRefitMasks(engine
, include_initial_cargo_type
, &union_mask
, &intersection_mask
);
274 return intersection_mask
;
279 * Tests if all parts of an articulated vehicle are refitted to the same cargo.
280 * Note: Vehicles not carrying anything are ignored
281 * @param v the first vehicle in the chain
282 * @param cargo_type returns the common CargoID if needed. (CT_INVALID if no part is carrying something or they are carrying different things)
283 * @return true if some parts are carrying different cargoes, false if all parts are carrying the same (nothing is also the same)
285 bool IsArticulatedVehicleCarryingDifferentCargoes(const Vehicle
*v
, CargoID
*cargo_type
)
287 CargoID first_cargo
= CT_INVALID
;
290 if (v
->cargo_type
!= CT_INVALID
&& v
->GetEngine()->CanCarryCargo()) {
291 if (first_cargo
== CT_INVALID
) first_cargo
= v
->cargo_type
;
292 if (first_cargo
!= v
->cargo_type
) {
293 if (cargo_type
!= NULL
) *cargo_type
= CT_INVALID
;
298 v
= v
->HasArticulatedPart() ? v
->GetNextArticulatedPart() : NULL
;
301 if (cargo_type
!= NULL
) *cargo_type
= first_cargo
;
306 * Checks whether the specs of freshly build articulated vehicles are consistent with the information specified in the purchase list.
307 * Only essential information is checked to leave room for magic tricks/workarounds to grfcoders.
309 * For autoreplace/-renew:
310 * - Default cargo type (without capacity)
311 * - intersection and union of refit masks.
313 void CheckConsistencyOfArticulatedVehicle(const Vehicle
*v
)
315 const Engine
*engine
= v
->GetEngine();
317 uint32 purchase_refit_union
, purchase_refit_intersection
;
318 GetArticulatedRefitMasks(v
->engine_type
, true, &purchase_refit_union
, &purchase_refit_intersection
);
319 CargoArray purchase_default_capacity
= GetCapacityOfArticulatedParts(v
->engine_type
);
321 uint32 real_refit_union
= 0;
322 uint32 real_refit_intersection
= UINT_MAX
;
323 CargoArray real_default_capacity
;
326 uint32 refit_mask
= GetAvailableVehicleCargoTypes(v
->engine_type
, true);
327 real_refit_union
|= refit_mask
;
328 if (refit_mask
!= 0) real_refit_intersection
&= refit_mask
;
330 assert(v
->cargo_type
< NUM_CARGO
);
331 real_default_capacity
[v
->cargo_type
] += v
->cargo_cap
;
333 v
= v
->HasArticulatedPart() ? v
->GetNextArticulatedPart() : NULL
;
336 /* Check whether the vehicle carries more cargoes than expected */
337 bool carries_more
= false;
338 for (CargoID cid
= 0; cid
< NUM_CARGO
; cid
++) {
339 if (real_default_capacity
[cid
] != 0 && purchase_default_capacity
[cid
] == 0) {
345 /* show a warning once for each GRF after each game load */
346 if (real_refit_union
!= purchase_refit_union
|| real_refit_intersection
!= purchase_refit_intersection
|| carries_more
) {
347 ShowNewGrfVehicleError(engine
->index
, STR_NEWGRF_BUGGY
, STR_NEWGRF_BUGGY_ARTICULATED_CARGO
, GBUG_VEH_REFIT
, false);
352 * Add the remaining articulated parts to the given vehicle.
353 * @param first The head of the articulated bit.
355 void AddArticulatedParts(Vehicle
*first
)
357 VehicleType type
= first
->type
;
358 if (!HasBit(EngInfo(first
->engine_type
)->callback_mask
, CBM_VEHICLE_ARTIC_ENGINE
)) return;
361 for (uint i
= 1; i
< MAX_ARTICULATED_PARTS
; i
++) {
363 EngineID engine_type
= GetNextArticulatedPart(i
, first
->engine_type
, first
, &flip_image
);
364 if (engine_type
== INVALID_ENGINE
) return;
366 /* In the (very rare) case the GRF reported wrong number of articulated parts
367 * and we run out of available vehicles, bail out. */
368 if (!Vehicle::CanAllocateItem()) return;
370 GroundVehicleCache
*gcache
= v
->GetGroundVehicleCache();
371 gcache
->first_engine
= v
->engine_type
; // Needs to be set before first callback
373 const Engine
*e_artic
= Engine::Get(engine_type
);
375 default: NOT_REACHED();
378 Train
*front
= Train::From(first
);
379 Train
*t
= new Train();
384 t
->track
= front
->track
;
385 t
->railtype
= front
->railtype
;
387 t
->spritenum
= e_artic
->u
.rail
.image_index
;
388 if (e_artic
->CanCarryCargo()) {
389 t
->cargo_type
= e_artic
->GetDefaultCargoType();
390 t
->cargo_cap
= e_artic
->u
.rail
.capacity
; // Callback 36 is called when the consist is finished
392 t
->cargo_type
= front
->cargo_type
; // Needed for livery selection
397 t
->SetArticulatedPart();
402 RoadVehicle
*front
= RoadVehicle::From(first
);
403 RoadVehicle
*rv
= new RoadVehicle();
408 gcache
->cached_veh_length
= VEHICLE_LENGTH
; // Callback is called when the consist is finished
409 rv
->state
= RVSB_IN_DEPOT
;
411 rv
->roadtype
= front
->roadtype
;
412 rv
->compatible_roadtypes
= front
->compatible_roadtypes
;
414 rv
->spritenum
= e_artic
->u
.road
.image_index
;
415 if (e_artic
->CanCarryCargo()) {
416 rv
->cargo_type
= e_artic
->GetDefaultCargoType();
417 rv
->cargo_cap
= e_artic
->u
.road
.capacity
; // Callback 36 is called when the consist is finished
419 rv
->cargo_type
= front
->cargo_type
; // Needed for livery selection
424 rv
->SetArticulatedPart();
429 /* get common values from first engine */
430 v
->direction
= first
->direction
;
431 v
->owner
= first
->owner
;
432 v
->tile
= first
->tile
;
433 v
->x_pos
= first
->x_pos
;
434 v
->y_pos
= first
->y_pos
;
435 v
->z_pos
= first
->z_pos
;
436 v
->date_of_last_service
= first
->date_of_last_service
;
437 v
->build_year
= first
->build_year
;
438 v
->vehstatus
= first
->vehstatus
& ~VS_STOPPED
;
440 v
->cargo_subtype
= 0;
442 v
->engine_type
= engine_type
;
444 v
->sprite_seq
.Set(SPR_IMG_QUERY
);
445 v
->random_bits
= VehicleRandomBits();
447 if (flip_image
) v
->spritenum
++;