OpenTTD
articulated_vehicles.cpp
Go to the documentation of this file.
1 /* $Id: articulated_vehicles.cpp 27666 2016-10-16 14:57:56Z frosch $ */
2 
3 /*
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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "train.h"
14 #include "roadveh.h"
15 #include "vehicle_func.h"
16 #include "engine_func.h"
17 #include "company_func.h"
18 #include "newgrf.h"
19 
20 #include "table/strings.h"
21 
22 #include "safeguards.h"
23 
24 static const uint MAX_ARTICULATED_PARTS = 100;
25 
34 static EngineID GetNextArticulatedPart(uint index, EngineID front_type, Vehicle *front = NULL, bool *mirrored = NULL)
35 {
36  assert(front == NULL || front->engine_type == front_type);
37 
38  const Engine *front_engine = Engine::Get(front_type);
39 
40  uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, index, 0, front_type, front);
41  if (callback == CALLBACK_FAILED) return INVALID_ENGINE;
42 
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);
49  } else {
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);
54  }
55 
56  return GetNewEngineID(front_engine->GetGRF(), front_engine->type, callback);
57 }
58 
64 bool IsArticulatedEngine(EngineID engine_type)
65 {
66  return HasBit(EngInfo(engine_type)->callback_mask, CBM_VEHICLE_ARTIC_ENGINE);
67 }
68 
75 uint CountArticulatedParts(EngineID engine_type, bool purchase_window)
76 {
77  if (!HasBit(EngInfo(engine_type)->callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return 0;
78 
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;
82 
83  Vehicle *v = NULL;
84  if (!purchase_window) {
85  v = new Vehicle();
86  v->engine_type = engine_type;
88  }
89 
90  uint i;
91  for (i = 1; i < MAX_ARTICULATED_PARTS; i++) {
92  if (GetNextArticulatedPart(i, engine_type, v) == INVALID_ENGINE) break;
93  }
94 
95  delete v;
96 
97  return i - 1;
98 }
99 
100 
107 static inline uint16 GetVehicleDefaultCapacity(EngineID engine, CargoID *cargo_type)
108 {
109  const Engine *e = Engine::Get(engine);
111  if (cargo_type != NULL) *cargo_type = cargo;
112  if (cargo == CT_INVALID) return 0;
113  return e->GetDisplayDefaultCapacity();
114 }
115 
122 static inline uint32 GetAvailableVehicleCargoTypes(EngineID engine, bool include_initial_cargo_type)
123 {
124  const Engine *e = Engine::Get(engine);
125  if (!e->CanCarryCargo()) return 0;
126 
127  uint32 cargoes = e->info.refit_mask;
128 
129  if (include_initial_cargo_type) {
130  SetBit(cargoes, e->GetDefaultCargoType());
131  }
132 
133  return cargoes;
134 }
135 
142 {
143  CargoArray capacity;
144  const Engine *e = Engine::Get(engine);
145 
146  CargoID cargo_type;
147  uint16 cargo_capacity = GetVehicleDefaultCapacity(engine, &cargo_type);
148  if (cargo_type < NUM_CARGO) capacity[cargo_type] = cargo_capacity;
149 
150  if (!e->IsGroundVehicle()) return capacity;
151 
152  if (!HasBit(e->info.callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return capacity;
153 
154  for (uint i = 1; i < MAX_ARTICULATED_PARTS; i++) {
155  EngineID artic_engine = GetNextArticulatedPart(i, engine);
156  if (artic_engine == INVALID_ENGINE) break;
157 
158  cargo_capacity = GetVehicleDefaultCapacity(artic_engine, &cargo_type);
159  if (cargo_type < NUM_CARGO) capacity[cargo_type] += cargo_capacity;
160  }
161 
162  return capacity;
163 }
164 
172 void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, uint32 *refits)
173 {
174  cargoes->Clear();
175  *refits = 0;
176 
177  const Engine *e = Engine::Get(engine);
178 
179  CargoID cargo_type;
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);
184  }
185 
186  if (!e->IsGroundVehicle() || !HasBit(e->info.callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return;
187 
188  for (uint i = 1; i < MAX_ARTICULATED_PARTS; i++) {
189  EngineID artic_engine = GetNextArticulatedPart(i, engine);
190  if (artic_engine == INVALID_ENGINE) break;
191 
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);
196  }
197  }
198 }
199 
206 {
207  if (IsEngineRefittable(engine)) return true;
208 
209  const Engine *e = Engine::Get(engine);
210  if (!e->IsGroundVehicle()) return false;
211 
212  if (!HasBit(e->info.callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return false;
213 
214  for (uint i = 1; i < MAX_ARTICULATED_PARTS; i++) {
215  EngineID artic_engine = GetNextArticulatedPart(i, engine);
216  if (artic_engine == INVALID_ENGINE) break;
217 
218  if (IsEngineRefittable(artic_engine)) return true;
219  }
220 
221  return false;
222 }
223 
231 void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, uint32 *union_mask, uint32 *intersection_mask)
232 {
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;
237 
238  if (!e->IsGroundVehicle()) return;
239  if (!HasBit(e->info.callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return;
240 
241  for (uint i = 1; i < MAX_ARTICULATED_PARTS; i++) {
242  EngineID artic_engine = GetNextArticulatedPart(i, engine);
243  if (artic_engine == INVALID_ENGINE) break;
244 
245  veh_cargoes = GetAvailableVehicleCargoTypes(artic_engine, include_initial_cargo_type);
246  *union_mask |= veh_cargoes;
247  if (veh_cargoes != 0) *intersection_mask &= veh_cargoes;
248  }
249 }
250 
257 uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type)
258 {
259  uint32 union_mask, intersection_mask;
260  GetArticulatedRefitMasks(engine, include_initial_cargo_type, &union_mask, &intersection_mask);
261  return union_mask;
262 }
263 
270 uint32 GetIntersectionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type)
271 {
272  uint32 union_mask, intersection_mask;
273  GetArticulatedRefitMasks(engine, include_initial_cargo_type, &union_mask, &intersection_mask);
274  return intersection_mask;
275 }
276 
277 
286 {
287  CargoID first_cargo = CT_INVALID;
288 
289  do {
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;
294  return true;
295  }
296  }
297 
298  v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL;
299  } while (v != NULL);
300 
301  if (cargo_type != NULL) *cargo_type = first_cargo;
302  return false;
303 }
304 
314 {
315  const Engine *engine = v->GetEngine();
316 
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);
320 
321  uint32 real_refit_union = 0;
322  uint32 real_refit_intersection = UINT_MAX;
323  CargoArray real_default_capacity;
324 
325  do {
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;
329 
330  assert(v->cargo_type < NUM_CARGO);
331  real_default_capacity[v->cargo_type] += v->cargo_cap;
332 
333  v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL;
334  } while (v != NULL);
335 
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) {
340  carries_more = true;
341  break;
342  }
343  }
344 
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);
348  }
349 }
350 
356 {
357  VehicleType type = first->type;
358  if (!HasBit(EngInfo(first->engine_type)->callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return;
359 
360  Vehicle *v = first;
361  for (uint i = 1; i < MAX_ARTICULATED_PARTS; i++) {
362  bool flip_image;
363  EngineID engine_type = GetNextArticulatedPart(i, first->engine_type, first, &flip_image);
364  if (engine_type == INVALID_ENGINE) return;
365 
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;
369 
371  gcache->first_engine = v->engine_type; // Needs to be set before first callback
372 
373  const Engine *e_artic = Engine::Get(engine_type);
374  switch (type) {
375  default: NOT_REACHED();
376 
377  case VEH_TRAIN: {
378  Train *front = Train::From(first);
379  Train *t = new Train();
380  v->SetNext(t);
381  v = t;
382 
383  t->subtype = 0;
384  t->track = front->track;
385  t->railtype = front->railtype;
386 
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
391  } else {
392  t->cargo_type = front->cargo_type; // Needed for livery selection
393  t->cargo_cap = 0;
394  }
395  t->refit_cap = 0;
396 
397  t->SetArticulatedPart();
398  break;
399  }
400 
401  case VEH_ROAD: {
402  RoadVehicle *front = RoadVehicle::From(first);
403  RoadVehicle *rv = new RoadVehicle();
404  v->SetNext(rv);
405  v = rv;
406 
407  rv->subtype = 0;
408  gcache->cached_veh_length = VEHICLE_LENGTH; // Callback is called when the consist is finished
409  rv->state = RVSB_IN_DEPOT;
410 
411  rv->roadtype = front->roadtype;
412  rv->compatible_roadtypes = front->compatible_roadtypes;
413 
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
418  } else {
419  rv->cargo_type = front->cargo_type; // Needed for livery selection
420  rv->cargo_cap = 0;
421  }
422  rv->refit_cap = 0;
423 
424  rv->SetArticulatedPart();
425  break;
426  }
427  }
428 
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;
437  v->build_year = first->build_year;
438  v->vehstatus = first->vehstatus & ~VS_STOPPED;
439 
440  v->cargo_subtype = 0;
441  v->max_age = 0;
442  v->engine_type = engine_type;
443  v->value = 0;
444  v->sprite_seq.Set(SPR_IMG_QUERY);
446 
447  if (flip_image) v->spritenum++;
448 
449  v->UpdatePosition();
450  }
451 }
Road vehicle states.
Date max_age
Maximum age.
Definition: vehicle_base.h:259
Vehicle is stopped by the player.
Definition: vehicle_base.h:33
byte state
Definition: roadveh.h:89
Money value
Value of the vehicle.
Definition: vehicle_base.h:241
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
uint GetDisplayDefaultCapacity(uint16 *mail_capacity=NULL) const
Determines the default cargo capacity of an engine for display purposes.
Definition: engine_base.h:101
DirectionByte direction
facing
Definition: vehicle_base.h:271
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
bool CanCarryCargo() const
Determines whether an engine can carry something.
Definition: engine.cpp:173
Base for the train class.
void AddArticulatedParts(Vehicle *first)
Add the remaining articulated parts to the given vehicle.
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
CargoArray GetCapacityOfArticulatedParts(EngineID engine)
Get the capacity of the parts of a given engine.
Builds articulated engines for trains and RVs.
byte spritenum
currently displayed sprite index 0xfd == custom sprite, 0xfe == custom second head sprite 0xff == res...
Definition: vehicle_base.h:279
static uint16 GetVehicleDefaultCapacity(EngineID engine, CargoID *cargo_type)
Returns the default (non-refitted) capacity of a specific EngineID.
Functions related to vehicles.
bool IsArticulatedEngine(EngineID engine_type)
Does a NewGRF report that this should be an articulated vehicle?
void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, uint32 *union_mask, uint32 *intersection_mask)
Merges the refit_masks of all articulated parts.
Vehicle data structure.
Definition: vehicle_base.h:212
void Set(SpriteID sprite)
Assign a single sprite to the sequence.
Definition: vehicle_base.h:163
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
void SetNext(Vehicle *next)
Set the next vehicle of this vehicle.
Definition: vehicle.cpp:2631
bool IsArticulatedVehicleCarryingDifferentCargoes(const Vehicle *v, CargoID *cargo_type)
Tests if all parts of an articulated vehicle are refitted to the same cargo.
byte vehstatus
Status.
Definition: vehicle_base.h:317
Cached, frequently calculated values.
static Train * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition: vehicle.cpp:743
CargoID GetDefaultCargoType() const
Determines the default cargo type of an engine.
Definition: engine_base.h:81
static const uint MAX_ARTICULATED_PARTS
Maximum of articulated parts per vehicle, i.e. when to abort calling the articulated vehicle callback...
byte VehicleRandomBits()
Get a value for a vehicle&#39;s random_bits.
Definition: vehicle.cpp:362
VehicleSpriteSeq sprite_seq
Vehicle appearance.
Definition: vehicle_base.h:280
EngineID first_engine
Cached EngineID of the front vehicle. INVALID_ENGINE for the front vehicle itself.
bool IsEngineRefittable(EngineID engine)
Check if an engine is refittable.
Definition: engine.cpp:1102
byte subtype
subtype (Filled with values from #EffectVehicles/#TrainSubTypes/#AircraftSubTypes) ...
Definition: vehicle_base.h:327
Buses, trucks and trams belong to this class.
Definition: roadveh.h:88
uint16 cargo_cap
total capacity
Definition: vehicle_base.h:307
void Clear()
Reset all entries.
Definition: cargo_type.h:86
byte cargo_subtype
Used for livery refits (NewGRF variations)
Definition: vehicle_base.h:306
Functions related to engines.
GroundVehicleCache * GetGroundVehicleCache()
Access the ground vehicle cache of the vehicle.
Definition: vehicle.cpp:2797
VehicleType
Available vehicle types.
Definition: vehicle_type.h:21
byte callback_mask
Bitmask of vehicle callbacks that have to be called.
Definition: engine_type.h:143
Definition of base types and functions in a cross-platform compatible way.
static const uint VEHICLE_LENGTH
The length of a vehicle in tile units.
Definition: vehicle_type.h:78
A number of safeguards to prevent using unsafe methods.
VehicleType type
Vehicle type, ie VEH_ROAD, VEH_TRAIN, etc.
Definition: engine_base.h:42
The vehicle is in a depot.
Definition: roadveh.h:39
CargoID cargo_type
type of cargo this vehicle is carrying
Definition: vehicle_base.h:305
byte capacity
Cargo capacity of vehicle; For multiheaded engines the capacity of each single engine.
Definition: engine_type.h:54
TileIndex tile
Current tile index.
Definition: vehicle_base.h:230
bool HasArticulatedPart() const
Check if an engine has an articulated part.
Definition: vehicle_base.h:900
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
Return the ID of a new engine.
Definition: newgrf.cpp:695
Road vehicle type.
Definition: vehicle_type.h:25
Invalid cargo type.
Definition: cargo_type.h:70
uint32 GetIntersectionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type)
Ands the refit_masks of all articulated parts.
uint16 refit_cap
Capacity left over from before last refit.
Definition: vehicle_base.h:308
byte random_bits
Bits used for determining which randomized variational spritegroups to use when drawing.
Definition: vehicle_base.h:299
Add articulated engines (trains and road vehicles)
Year build_year
Year the vehicle has been built.
Definition: vehicle_base.h:257
Articulated vehicles carry different cargoes resp. are differently refittable than specified in purch...
Definition: newgrf_config.h:46
&#39;Train&#39; is either a loco or a wagon.
Definition: train.h:88
Maximal number of cargo types in a game.
Definition: cargo_type.h:66
uint CountArticulatedParts(EngineID engine_type, bool purchase_window)
Count the number of articulated parts of an engine.
static EngineID GetNextArticulatedPart(uint index, EngineID front_type, Vehicle *front=NULL, bool *mirrored=NULL)
Determines the next articulated part to attach.
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
Definition: engine_type.h:174
Functions related to companies.
void UpdatePosition()
Update the position of the vehicle.
Definition: vehicle.cpp:1547
void CheckConsistencyOfArticulatedVehicle(const Vehicle *v)
Checks whether the specs of freshly build articulated vehicles are consistent with the information sp...
Class for storing amounts of cargo.
Definition: cargo_type.h:74
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
Definition: engine_base.h:140
uint16 EngineID
Unique identification number of an engine.
Definition: engine_type.h:22
CompanyByte _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
Date date_of_last_service
Last date the vehicle had a service at a depot.
Definition: vehicle_base.h:260
void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRFBugs bug_type, bool critical)
Displays a "NewGrf Bug" error message for a engine, and pauses the game if not networking.
Definition: vehicle.cpp:297
OwnerByte owner
Which company owns the vehicle?
Definition: vehicle_base.h:273
Vehicle * GetNextArticulatedPart() const
Get the next part of an articulated engine.
Definition: vehicle_base.h:910
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:216
int32 z_pos
z coordinate.
Definition: vehicle_base.h:270
void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, uint32 *refits)
Get the default cargoes and refits of an articulated vehicle.
uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v)
Evaluate a newgrf callback for vehicles.
uint8 cached_veh_length
Length of this vehicle in units of 1/VEHICLE_LENGTH of normal length. It is cached because this can b...
bool IsGroundVehicle() const
Check if the engine is a ground vehicle.
Definition: engine_base.h:130
EngineID engine_type
The type of engine used for this vehicle.
Definition: vehicle_base.h:288
void SetArticulatedPart()
Set a vehicle to be an articulated part.
int32 x_pos
x coordinate.
Definition: vehicle_base.h:268
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
int32 y_pos
y coordinate.
Definition: vehicle_base.h:269
static uint32 GetAvailableVehicleCargoTypes(EngineID engine, bool include_initial_cargo_type)
Returns all cargoes a vehicle can carry.
uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type)
Ors the refit_masks of all articulated parts.
VehicleTypeByte type
Type of vehicle.
Definition: vehicle_type.h:54
bool IsArticulatedVehicleRefittable(EngineID engine)
Checks whether any of the articulated parts is refittable.
Train vehicle type.
Definition: vehicle_type.h:24
Base for the NewGRF implementation.