OpenTTD Source 20260512-master-g20b387b91f
cargopacket.h
Go to the documentation of this file.
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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#ifndef CARGOPACKET_H
11#define CARGOPACKET_H
12
13#include "core/pool_type.hpp"
14#include "economy_type.h"
15#include "station_type.h"
16#include "order_type.h"
17#include "cargo_type.h"
18#include "source_type.h"
19#include "vehicle_type.h"
20#include "core/multimap.hpp"
21#include "saveload/saveload.h"
22
25struct CargoPacket;
26
30extern CargoPacketPool _cargopacket_pool;
31
32struct GoodsEntry; // forward-declare for Stage() and RerouteStalePackets()
33
34template <class Tinst, class Tcont> class CargoList;
35class StationCargoList; // forward-declare, so we can use it in VehicleCargoList.
37
41struct CargoPacket : CargoPacketPool::PoolItem<&_cargopacket_pool> {
42private:
43 uint16_t count = 0;
44 uint16_t periods_in_transit = 0;
45
46 Money feeder_share = 0;
47
50
52
53#ifdef WITH_ASSERT
54 bool in_vehicle = false;
55#endif /* WITH_ASSERT */
56
57 StationID first_station = StationID::Invalid();
58 StationID next_hop = StationID::Invalid();
59
61 template <class Tinst, class Tcont> friend class CargoList;
62 friend class VehicleCargoList;
63 friend class StationCargoList;
66public:
68 static const uint16_t MAX_COUNT = UINT16_MAX;
69
73 CargoPacket(CargoPacketID index, uint16_t count, Money feeder_share, CargoPacket &original);
74
77
78 CargoPacket *Split(uint new_size);
79 void Merge(CargoPacket *cp);
80 void Reduce(uint count);
81
86 void SetNextHop(StationID next_hop)
87 {
88 this->next_hop = next_hop;
89 }
90
106 {
107 if (this->source_xy == INVALID_TILE) {
108 this->source_xy = tile;
109 }
110
111#ifdef WITH_ASSERT
112 assert(!this->in_vehicle);
113 this->in_vehicle = true;
114#endif /* WITH_ASSERT */
115
116 /* We want to calculate the vector from tile-unload to tile-load. As
117 * we currently only know the latter, add it. When we know where we unload,
118 * we subtract is, giving us our vector (unload - load). */
119 this->travelled.x += TileX(tile);
120 this->travelled.y += TileY(tile);
121 }
122
129 {
130#ifdef WITH_ASSERT
131 assert(this->in_vehicle);
132 this->in_vehicle = false;
133#endif /* WITH_ASSERT */
134
135 this->travelled.x -= TileX(tile);
136 this->travelled.y -= TileY(tile);
137 }
138
143 void AddFeederShare(Money new_share)
144 {
145 this->feeder_share += new_share;
146 }
147
152 inline uint16_t Count() const
153 {
154 return this->count;
155 }
156
162 inline Money GetFeederShare() const
163 {
164 return this->feeder_share;
165 }
166
173 inline Money GetFeederShare(uint part) const
174 {
175 return this->feeder_share * part / static_cast<uint>(this->count);
176 }
177
185 inline uint16_t GetPeriodsInTransit() const
186 {
187 return this->periods_in_transit;
188 }
189
194 inline Source GetSource() const
195 {
196 return this->source;
197 }
198
203 inline StationID GetFirstStation() const
204 {
205 return this->first_station;
206 }
207
214 inline uint GetDistance(TileIndex current_tile) const
215 {
216 assert(this->source_xy != INVALID_TILE);
217#ifdef WITH_ASSERT
218 assert(this->in_vehicle);
219#endif /* WITH_ASSERT */
220
221 /* Distance is always requested when the cargo is still inside the
222 * vehicle. So first finish the calculation for travelled to
223 * become a vector. */
224 auto local_travelled = travelled;
225 local_travelled.x -= TileX(current_tile);
226 local_travelled.y -= TileY(current_tile);
227
228 /* Cargo-movement is a vector that indicates how much the cargo has
229 * actually traveled in a vehicle. This is the distance you get paid
230 * for. However, one could construct a route where this vector would
231 * be really long. To not overpay the player, cap out at the distance
232 * between source and destination.
233 *
234 * This way of calculating is to counter people moving cargo for free
235 * and instantly in stations, where you deliver it in one part of the
236 * station and pick it up in another. By using the actual distance
237 * traveled in a vehicle, using this trick doesn't give you more money.
238 *
239 * However, especially in large networks with large transfer station,
240 * etc, one could actually make the route a lot longer. In that case,
241 * use the actual distance between source and destination.
242 */
243
244 uint distance_travelled = abs(local_travelled.x) + abs(local_travelled.y);
245 uint distance_source_dest = DistanceManhattan(this->source_xy, current_tile);
246 return std::min(distance_travelled, distance_source_dest);
247 }
248
253 inline StationID GetNextHop() const
254 {
255 return this->next_hop;
256 }
257
258 static void InvalidateAllFrom(Source src);
259 static void InvalidateAllFrom(StationID sid);
260 static void AfterLoad();
261};
262
267template <class Tinst, class Tcont>
269public:
271 typedef typename Tcont::iterator Iterator;
273 typedef typename Tcont::reverse_iterator ReverseIterator;
275 typedef typename Tcont::const_iterator ConstIterator;
277 typedef typename Tcont::const_reverse_iterator ConstReverseIterator;
278
280 enum MoveToAction : uint8_t {
281 MTA_BEGIN = 0,
286 MTA_END,
287 NUM_MOVE_TO_ACTION = MTA_END
288 };
289
290protected:
291 uint count = 0;
293
294 Tcont packets{};
295
296 void AddToCache(const CargoPacket *cp);
297
298 void RemoveFromCache(const CargoPacket *cp, uint count);
299
300 static bool TryMerge(CargoPacket *cp, CargoPacket *icp);
301
302public:
305
307
309
314 inline const Tcont *Packets() const
315 {
316 return &this->packets;
317 }
318
323 inline uint PeriodsInTransit() const
324 {
325 return this->count == 0 ? 0 : this->cargo_periods_in_transit / this->count;
326 }
327
329};
330
331typedef std::list<CargoPacket *> CargoPacketList;
332
336class VehicleCargoList : public CargoList<VehicleCargoList, CargoPacketList> {
337protected:
340
342 uint action_counts[NUM_MOVE_TO_ACTION];
343
344 template <class Taction>
345 void ShiftCargo(Taction action);
346
347 template <class Taction>
348 void PopCargo(Taction action);
349
353 inline void AssertCountConsistency() const
354 {
355 assert(this->action_counts[MTA_KEEP] +
356 this->action_counts[MTA_DELIVER] +
357 this->action_counts[MTA_TRANSFER] +
358 this->action_counts[MTA_LOAD] == this->count);
359 }
360
361 void AddToCache(const CargoPacket *cp);
362 void RemoveFromCache(const CargoPacket *cp, uint count);
363
364 void AddToMeta(const CargoPacket *cp, MoveToAction action);
365 void RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count);
366
367 static MoveToAction ChooseAction(const CargoPacket *cp, StationID cargo_next,
368 StationID current_station, bool accepted, std::span<const StationID> next_station);
369
370public:
372 friend class StationCargoList;
374 friend class CargoList<VehicleCargoList, CargoPacketList>;
375 /* So we can use private/protected variables in the saveload code */
376 friend class SlVehicleCommon;
377
378 friend class CargoShift;
379 friend class CargoTransfer;
380 friend class CargoDelivery;
381 template <class Tsource>
382 friend class CargoRemoval;
383 friend class CargoReturn;
384 friend class VehicleCargoReroute;
385
390 inline StationID GetFirstStation() const
391 {
392 return this->count == 0 ? StationID::Invalid() : this->packets.front()->first_station;
393 }
394
399 inline Money GetFeederShare() const
400 {
401 return this->feeder_share;
402 }
403
409 inline uint ActionCount(MoveToAction action) const
410 {
411 return this->action_counts[action];
412 }
413
419 inline uint StoredCount() const
420 {
421 return this->count - this->action_counts[MTA_LOAD];
422 }
423
428 inline uint TotalCount() const
429 {
430 return this->count;
431 }
432
437 inline uint ReservedCount() const
438 {
439 return this->action_counts[MTA_LOAD];
440 }
441
446 inline uint UnloadCount() const
447 {
448 return this->action_counts[MTA_TRANSFER] + this->action_counts[MTA_DELIVER];
449 }
450
455 inline uint RemainingCount() const
456 {
457 return this->action_counts[MTA_KEEP] + this->action_counts[MTA_LOAD];
458 }
459
460 void Append(CargoPacket *cp, MoveToAction action = MTA_KEEP);
461
462 void AgeCargo();
463
464 void InvalidateCache();
465
466 bool Stage(bool accepted, StationID current_station, std::span<const StationID> next_station, OrderUnloadType unload_type, const GoodsEntry *ge, CargoType cargo, CargoPayment *payment, TileIndex current_tile);
467
473 inline void KeepAll()
474 {
475 this->action_counts[MTA_DELIVER] = this->action_counts[MTA_TRANSFER] = this->action_counts[MTA_LOAD] = 0;
476 this->action_counts[MTA_KEEP] = this->count;
477 }
478
479 /* Methods for moving cargo around. First parameter is always maximum
480 * amount of cargo to be moved. Second parameter is destination (if
481 * applicable), return value is amount of cargo actually moved. */
482
483 template <MoveToAction Tfrom, MoveToAction Tto>
484 uint Reassign(uint max_move);
485 uint Return(uint max_move, StationCargoList *dest, StationID next_station, TileIndex current_tile);
486 uint Unload(uint max_move, StationCargoList *dest, CargoType cargo, CargoPayment *payment, TileIndex current_tile);
487 uint Shift(uint max_move, VehicleCargoList *dest);
488 uint Truncate(uint max_move = UINT_MAX);
489 uint Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge);
490
498 static bool AreMergable(const CargoPacket *cp1, const CargoPacket *cp2)
499 {
500 return cp1->source_xy == cp2->source_xy &&
502 cp1->first_station == cp2->first_station &&
503 cp1->source == cp2->source;
504 }
505};
506
507typedef MultiMap<StationID, CargoPacket *> StationCargoPacketMap;
508typedef std::map<StationID, uint> StationCargoAmountMap;
509
513class StationCargoList : public CargoList<StationCargoList, StationCargoPacketMap> {
514protected:
517
519
520public:
522 friend class CargoList<StationCargoList, StationCargoPacketMap>;
523 /* So we can use private/protected variables in the saveload code */
524 friend class SlStationGoods;
525
526 friend class CargoLoad;
527 friend class CargoTransfer;
528 template <class Tsource>
529 friend class CargoRemoval;
530 friend class CargoReservation;
531 friend class CargoReturn;
532 friend class StationCargoReroute;
533
534 static void InvalidateAllFrom(Source src);
535
536 template <class Taction>
537 bool ShiftCargo(Taction &action, StationID next);
538
539 template <class Taction>
540 uint ShiftCargo(Taction action, std::span<const StationID> next, bool include_invalid);
541
542 void Append(CargoPacket *cp, StationID next);
543
549 inline bool HasCargoFor(std::span<const StationID> next) const
550 {
551 for (const StationID &station : next) {
552 if (this->packets.find(station) != this->packets.end()) return true;
553 }
554 /* Packets for StationID::Invalid() can go anywhere. */
555 return this->packets.find(StationID::Invalid()) != this->packets.end();
556 }
557
562 inline StationID GetFirstStation() const
563 {
564 return this->count == 0 ? StationID::Invalid() : this->packets.begin()->second.front()->first_station;
565 }
566
572 inline uint AvailableCount() const
573 {
574 return this->count;
575 }
576
581 inline uint ReservedCount() const
582 {
583 return this->reserved_count;
584 }
585
591 inline uint TotalCount() const
592 {
593 return this->count + this->reserved_count;
594 }
595
596 /* Methods for moving cargo around. First parameter is always maximum
597 * amount of cargo to be moved. Second parameter is destination (if
598 * applicable), return value is amount of cargo actually moved. */
599
600 uint Reserve(uint max_move, VehicleCargoList *dest, std::span<const StationID> next, TileIndex current_tile);
601 uint Load(uint max_move, VehicleCargoList *dest, std::span<const StationID> next, TileIndex current_tile);
602 uint Truncate(uint max_move = UINT_MAX, StationCargoAmountMap *cargo_per_source = nullptr);
603 uint Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge);
604
612 static bool AreMergable(const CargoPacket *cp1, const CargoPacket *cp2)
613 {
614 return cp1->source_xy == cp2->source_xy &&
616 cp1->first_station == cp2->first_station &&
617 cp1->source == cp2->source;
618 }
619};
620
621#endif /* CARGOPACKET_H */
Types related to cargoes...
CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
PoolID< uint32_t, struct CargoPacketIDTag, 0xFFF000, 0xFFFFFF > CargoPacketID
Unique identifier for a single cargo packet.
Definition cargopacket.h:24
SaveLoadTable GetCargoPacketDesc()
Wrapper function to get the CargoPacket's internal structure while some of the variables itself are p...
Pool< CargoPacket, CargoPacketID, 1024, PoolType::Normal, true > CargoPacketPool
Type of the pool for cargo packets for a little over 16 million packets.
Definition cargopacket.h:28
Simple collection class for a list of cargo packets.
Tcont::reverse_iterator ReverseIterator
The reverse iterator for our container.
void OnCleanPool()
Empty the cargo list, but don't free the cargo packets; the cargo packets are cleaned by CargoPacket'...
~CargoList()
Destroy the cargolist ("frees" all cargo packets).
const Tcont * Packets() const
Returns a pointer to the cargo packet list (so you can iterate over it etc).
Tcont::const_iterator ConstIterator
The const iterator for our container.
CargoList()
Create the cargo list.
static bool TryMerge(CargoPacket *cp, CargoPacket *icp)
Tries to merge the second packet into the first and return if that was successful.
Tcont::iterator Iterator
The iterator for our container.
MoveToAction
Kind of actions that could be done with packets on move.
Tcont::const_reverse_iterator ConstReverseIterator
The const reverse iterator for our container.
uint PeriodsInTransit() const
Returns average number of cargo aging periods in transit for a cargo entity.
void AddToCache(const CargoPacket *cp)
Update the cache to reflect adding of this packet.
void InvalidateCache()
Invalidates the cached data and rebuilds it.
void RemoveFromCache(const CargoPacket *cp, uint count)
Update the cached values to reflect the removal of this packet or part of it.
Hand-rolled multimap as map of lists.
Definition multimap.hpp:223
CargoList that is used for stations.
bool HasCargoFor(std::span< const StationID > next) const
Check for cargo headed for a specific station.
CargoList< StationCargoList, StationCargoPacketMap > Parent
The (direct) parent of this class.
uint TotalCount() const
Returns total count of cargo at the station, including cargo which is already reserved for loading.
uint Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
Routes packets with station "avoid" as next hop to a different place.
uint ReservedCount() const
Returns sum of cargo reserved for loading onto vehicles.
uint Load(uint max_move, VehicleCargoList *dest, std::span< const StationID > next, TileIndex current_tile)
Loads cargo onto a vehicle.
uint AvailableCount() const
Returns sum of cargo still available for loading at the station.
void Append(CargoPacket *cp, StationID next)
Appends the given cargo packet to the range of packets with the same next station.
uint Truncate(uint max_move=UINT_MAX, StationCargoAmountMap *cargo_per_source=nullptr)
Truncates where each destination loses roughly the same percentage of its cargo.
bool ShiftCargo(Taction &action, StationID next)
Shifts cargo from the front of the packet list for a specific station and applies some action to it.
uint reserved_count
Amount of cargo being reserved for loading.
static bool AreMergable(const CargoPacket *cp1, const CargoPacket *cp2)
Are the two CargoPackets mergeable in the context of a list of CargoPackets for a Station?
uint Reserve(uint max_move, VehicleCargoList *dest, std::span< const StationID > next, TileIndex current_tile)
Reserves cargo for loading onto the vehicle.
StationID GetFirstStation() const
Returns first station of the first cargo packet in this list.
CargoList that is used for vehicles.
uint Shift(uint max_move, VehicleCargoList *dest)
Shifts cargo between two vehicles.
void AddToMeta(const CargoPacket *cp, MoveToAction action)
Adds a packet to the metadata.
uint UnloadCount() const
Returns sum of cargo to be moved out of the vehicle at the current station.
void PopCargo(Taction action)
Pops cargo from the back of the packet list and applies some action to it.
friend class StationCargoList
The station cargo list needs to control the unloading.
Money GetFeederShare() const
Returns total sum of the feeder share for all packets.
uint Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
Routes packets with station "avoid" as next hop to a different place.
uint ActionCount(MoveToAction action) const
Returns the amount of cargo designated for a given purpose.
static MoveToAction ChooseAction(const CargoPacket *cp, StationID cargo_next, StationID current_station, bool accepted, std::span< const StationID > next_station)
Choose action to be performed with the given cargo packet.
uint Truncate(uint max_move=UINT_MAX)
Truncates the cargo in this list to the given amount.
void AssertCountConsistency() const
Assert that the designation counts add up.
void RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count)
Removes a packet or part of it from the metadata.
uint Return(uint max_move, StationCargoList *dest, StationID next_station, TileIndex current_tile)
Returns reserved cargo to the station and removes it from the cache.
static bool AreMergable(const CargoPacket *cp1, const CargoPacket *cp2)
Are the two CargoPackets mergeable in the context of a list of CargoPackets for a Vehicle?
uint TotalCount() const
Returns sum of cargo, including reserved cargo.
uint action_counts[NUM_MOVE_TO_ACTION]
Counts of cargo to be transferred, delivered, kept and loaded.
uint ReservedCount() const
Returns sum of reserved cargo.
uint RemainingCount() const
Returns the sum of cargo to be kept in the vehicle at the current station.
CargoList< VehicleCargoList, CargoPacketList > Parent
The (direct) parent of this class.
Money feeder_share
Cache for the feeder share.
void Append(CargoPacket *cp, MoveToAction action=MTA_KEEP)
Appends the given cargo packet.
void RemoveFromCache(const CargoPacket *cp, uint count)
Update the cached values to reflect the removal of this packet or part of it.
uint Reassign(uint max_move)
Moves some cargo from one designation to another.
void InvalidateCache()
Invalidates the cached data and rebuild it.
void AddToCache(const CargoPacket *cp)
Update the cache to reflect adding of this packet.
void KeepAll()
Marks all cargo in the vehicle as to be kept.
StationID GetFirstStation() const
Returns the first station of the first cargo packet in this list.
void AgeCargo()
Ages the all cargo in this list.
uint StoredCount() const
Returns sum of cargo on board the vehicle (ie not only reserved).
uint Unload(uint max_move, StationCargoList *dest, CargoType cargo, CargoPayment *payment, TileIndex current_tile)
Unloads cargo at the given station.
bool Stage(bool accepted, StationID current_station, std::span< const StationID > next_station, OrderUnloadType unload_type, const GoodsEntry *ge, CargoType cargo, CargoPayment *payment, TileIndex current_tile)
Stages cargo for unloading.
void ShiftCargo(Taction action)
Shifts cargo from the front of the packet list and applies some action to it.
Types related to the economy.
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:169
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:429
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:419
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition math_func.hpp:23
Multimap with deterministic ordering of items with equal keys.
Types related to orders.
OrderUnloadType
Unloading order types.
Definition order_type.h:67
Definition of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle,...
Functions/types related to saving and loading games.
std::span< const struct SaveLoad > SaveLoadTable
A table of SaveLoad entries.
Definition saveload.h:535
Type for the source of cargo.
@ Industry
Source/destination is an industry.
Definition source_type.h:21
Types related to stations.
Container for cargo from the same location and time.
Definition cargopacket.h:41
void Reduce(uint count)
Reduce the packet by the given amount and remove the feeder share.
uint16_t Count() const
Gets the number of 'items' in this packet.
Money GetFeederShare(uint part) const
Gets part of the amount of money already paid to earlier vehicles in the feeder chain.
~CargoPacket()
Destroy the packet.
Definition cargopacket.h:76
friend class CargoList
The CargoList caches, thus needs to know about it.
Definition cargopacket.h:61
void Merge(CargoPacket *cp)
Merge another packet into this one.
Money feeder_share
Value of feeder pickup to be paid for on delivery of cargo.
Definition cargopacket.h:46
static const uint16_t MAX_COUNT
Maximum number of items in a single cargo packet.
Definition cargopacket.h:68
TileIndex source_xy
The origin of the cargo.
Definition cargopacket.h:48
void SetNextHop(StationID next_hop)
Sets the station where the packet is supposed to go next.
Definition cargopacket.h:86
CargoPacket * Split(uint new_size)
Split this packet in two and return the split off part.
StationID next_hop
Station where the cargo wants to go next.
Definition cargopacket.h:58
Source source
Source of the cargo.
Definition cargopacket.h:51
Coord2D< int16_t > travelled
If cargo is in station: the vector from the unload tile to the source tile. If in vehicle: an interme...
Definition cargopacket.h:49
void UpdateLoadingTile(TileIndex tile)
Update for the cargo being loaded on this tile.
friend SaveLoadTable GetCargoPacketDesc()
We want this to be saved, right?
void AddFeederShare(Money new_share)
Adds some feeder share to the packet.
CargoPacket(CargoPacketID index)
Create a new packet for savegame loading.
static void AfterLoad()
Savegame conversion for cargopackets.
StationID GetNextHop() const
Gets the ID of station the cargo wants to go next.
uint16_t count
The amount of cargo in this packet.
Definition cargopacket.h:43
Money GetFeederShare() const
Gets the amount of money already paid to earlier vehicles in the feeder chain.
StationID GetFirstStation() const
Gets the ID of the station where the cargo was loaded for the first time.
uint GetDistance(TileIndex current_tile) const
Get the current distance the cargo has traveled.
StationID first_station
The station where the cargo came from first.
Definition cargopacket.h:57
uint16_t GetPeriodsInTransit() const
Gets the number of cargo aging periods this cargo has been in transit.
Source GetSource() const
Gets the source of the packet for subsidy purposes.
static void InvalidateAllFrom(Source src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
void UpdateUnloadingTile(TileIndex tile)
Update for the cargo being unloaded on this tile.
uint16_t periods_in_transit
Amount of cargo aging periods this packet has been in transit.
Definition cargopacket.h:44
Helper class to perform the cargo payment.
A coordinate with two dimensions.
T y
Y coordinate.
T x
X coordinate.
Stores station stats for a single cargo.
Templated helper to make a PoolID a single POD value.
Definition pool_type.hpp:47
Base class for all pools.
A location from where cargo can come from (or go to).
Definition source_type.h:32
static constexpr SourceID Invalid
Invalid/unknown index of source.
Definition source_type.h:34
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:100
Types related to vehicles.