10 #include "../stdafx.h"
16 #include "../vehicle_func.h"
18 #include "../roadveh.h"
20 #include "../aircraft.h"
21 #include "../timetable.h"
22 #include "../station_base.h"
23 #include "../effectvehicle_base.h"
24 #include "../company_base.h"
25 #include "../company_func.h"
26 #include "../disaster_vehicle.h"
27 #include "../economy_base.h"
29 #include "../safeguards.h"
38 v->other_multiheaded_part =
nullptr;
42 if (v->IsFrontEngine() || v->IsFreeWagon()) {
56 bool sequential_matching = v->IsFrontEngine();
59 if (u->other_multiheaded_part !=
nullptr)
continue;
61 if (u->IsMultiheaded()) {
71 if (sequential_matching) {
90 if (stack_pos == 0)
break;
97 w->other_multiheaded_part = u;
98 u->other_multiheaded_part = w;
118 if (
HasBit(t->subtype, 7) && ((t->subtype & ~0x80) == 0 || (t->subtype & ~0x80) == 4)) {
119 for (
Train *u = t; u !=
nullptr; u = u->
Next()) {
123 switch (u->subtype) {
132 u->SetArticulatedPart();
142 if (rvi->railveh_type ==
RAILVEH_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
169 st->airport.flags = 0;
175 if (a->IsNormalAircraft()) {
177 if ((a->vehstatus &
VS_STOPPED) && a->state == 0) {
185 a->cur_speed = a->vcache.cached_max_speed;
186 if (!a->current_order.IsType(OT_GOTO_STATION) && !a->current_order.IsType(OT_GOTO_DEPOT)) {
188 a->current_order.MakeDummy();
196 if (a->subtype ==
AIR_HELICOPTER) a->Next()->Next()->cur_speed = 32;
206 for (
auto iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ) {
209 iter = st->loading_vehicles.erase(iter);
242 if (v->engine_type >= total_engines || v->type != v->GetEngine()->type) {
243 v->engine_type = first_engine[v->type];
260 if (v->Next() !=
nullptr) v->Next()->previous = v;
261 if (v->NextShared() !=
nullptr) v->NextShared()->previous_shared = v;
263 if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID;
265 if (v->IsGroundVehicle()) v->GetGroundVehicleCache()->first_engine =
INVALID_ENGINE;
277 std::map<Order*, OrderList*> mapping;
280 if (v->old_orders !=
nullptr) {
282 if (mapping[v->old_orders] ==
nullptr) {
289 v->orders = mapping[v->old_orders] =
new OrderList(v->old_orders, v);
291 v->orders = mapping[v->old_orders];
294 v->AddToShared(v->orders->GetFirstSharedVehicle());
298 if (v->PreviousShared() ==
nullptr) {
299 v->orders->Initialize(v->orders->first, v);
308 if (v->Previous() ==
nullptr) {
309 for (
Vehicle *u = v; u !=
nullptr; u = u->
Next()) {
319 if (v->First() != v || v->orders !=
nullptr || v->previous_shared !=
nullptr || v->next_shared ==
nullptr)
continue;
325 u->orders = v->orders;
333 if (rv->subtype == 0) {
335 rv->SetFrontEngine();
336 }
else if (rv->subtype == 1) {
339 rv->SetArticulatedPart();
349 if (!v->IsPrimaryVehicle() && v->type !=
VEH_DISASTER) {
350 v->current_order.Free();
366 if (!v->IsPrimaryVehicle())
continue;
371 v->SetServiceIntervalIsCustom(v->GetServiceInterval() != interval);
379 s->rotation = s->direction;
383 if (s->rotation == s->direction)
continue;
388 s->rotation_x_pos = s->x_pos;
389 s->rotation_y_pos = s->y_pos;
397 if (v->timetable_start == 0)
continue;
406 v->economy_age = v->age.base();
418 assert(v->First() !=
nullptr);
439 RoadTramType rtt = GetRoadTramType(rv->
roadtype);
487 v->GetImage(v->direction,
EIT_ON_MAP, &v->sprite_cache.sprite_seq);
492 v->GetImage(v->direction,
EIT_ON_MAP, &v->sprite_cache.sprite_seq);
496 if (shadow ==
nullptr)
SlErrorCorrupt(
"Missing shadow for aircraft");
503 if (rotor ==
nullptr)
SlErrorCorrupt(
"Missing rotor for helicopter");
532 if (part_of_load && v->unitnumber != 0) {
533 Company::Get(v->owner)->freeunits[v->type].UseID(v->unitnumber);
540 v->UpdateViewport(
false);
554 if (v->type ==
VEH_TRAIN && v->IsPrimaryVehicle()) {
566 for (done = 0; done < diff; done++) {
570 if (next !=
nullptr && done < diff && u->IsFrontEngine()) {
580 int r = CountVehiclesInChain(u) - 1;
592 for (moved = 0; moved < diff + 1; moved++) {
597 r = CountVehiclesInChain(u) - 1;
601 u->force_proceed = old_tfp;
605 if (moved < diff + 1)
break;
633 static uint8_t _cargo_periods;
634 static uint16_t _cargo_source;
635 static uint32_t _cargo_source_xy;
636 static uint16_t _cargo_count;
637 static uint16_t _cargo_paid_for;
638 static Money _cargo_feeder_share;
642 inline static const SaveLoad description[] = {
774 void Save(
Vehicle *v)
const override
779 void Load(
Vehicle *v)
const override
784 void FixPointers(
Vehicle *v)
const override
792 inline static const SaveLoad description[] = {
806 void Save(
Vehicle *v)
const override
812 void Load(
Vehicle *v)
const override
818 void FixPointers(
Vehicle *v)
const override
827 inline static const SaveLoad description[] = {
839 static inline std::vector<Trackdir> rv_path_td;
840 static inline std::vector<TileIndex> rv_path_tile;
842 inline static const SaveLoad description[] = {
861 if (rv_path_td.size() != rv_path_tile.size()) {
862 Debug(sl, 1,
"Found RoadVehicle {} with invalid path cache, ignoring.", rv.
index);
865 size_t n = std::min(rv_path_td.size(), rv_path_tile.size());
869 for (
size_t c = 0; c < n; ++c) {
870 rv.
path.emplace_back(rv_path_td[c], rv_path_tile[c]);
874 std::reverse(std::begin(rv.
path), std::end(rv.
path));
877 void Save(
Vehicle *v)
const override
883 void Load(
Vehicle *v)
const override
892 void FixPointers(
Vehicle *v)
const override
901 inline static const SaveLoad description[] = {
911 static inline std::vector<Trackdir> ship_path_td;
913 inline static const SaveLoad description[] = {
922 void Save(
Vehicle *v)
const override
928 void Load(
Vehicle *v)
const override
936 std::transform(std::rbegin(ship_path_td), std::rend(ship_path_td), std::back_inserter(s->
path), [](
Trackdir trackdir) { return trackdir; });
940 void FixPointers(
Vehicle *v)
const override
949 inline static const SaveLoad description[] = {
968 void Save(
Vehicle *v)
const override
974 void Load(
Vehicle *v)
const override
980 void FixPointers(
Vehicle *v)
const override
989 inline static const SaveLoad description[] = {
1002 SLE_VAR(
Vehicle, sprite_cache.sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32),
1013 void Save(
Vehicle *v)
const override
1019 void Load(
Vehicle *v)
const override
1025 void FixPointers(
Vehicle *v)
const override
1034 inline static const SaveLoad description[] = {
1057 SLE_VAR(
Vehicle, sprite_cache.sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32),
1071 void Save(
Vehicle *v)
const override
1077 void Load(
Vehicle *v)
const override
1083 void FixPointers(
Vehicle *v)
const override
1090 const static SaveLoad _vehicle_desc[] = {
1109 SlSetArrayIndex(v->index);
1141 CargoPacket *cp =
new CargoPacket(_cargo_count, _cargo_periods, _cargo_source, _cargo_source_xy, _cargo_feeder_share);
void GetAircraftFlightLevelBounds(const Vehicle *v, int *min, int *max)
Get the 'flight level' bounds, in pixels from 'z_pos' 0 for a particular vehicle for normal flight si...
void AircraftNextAirportPos_and_Order(Aircraft *v)
set the right pos when heading to other airports after takeoff
void AircraftLeaveHangar(Aircraft *v, Direction exit_dir)
Aircraft is about to leave the hangar.
void SetAircraftPosition(Aircraft *v, int x, int y, int z)
Set aircraft position.
@ AIR_HELICOPTER
an helicopter
void UpdateAircraftCache(Aircraft *v, bool update_range=false)
Update cached values of an aircraft.
@ HANGAR
Heading for hangar.
@ FLYING
Vehicle is flying in the air.
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr static debug_inline uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
Default handler for saving/loading an object to/from disk.
SaveLoadTable GetDescription() const override
RoadTypes powered_roadtypes
bitmask to the OTHER roadtypes on which a vehicle of THIS roadtype generates power
SaveLoadTable GetLoadDescription() const
Get the description for how to load the chunk.
std::vector< RoadVehPathElement > & GetVector(RoadVehicle *rv) const override
Get instance of vector to load/save.
std::vector< ShipPathElement > & GetVector(Ship *s) const override
Get instance of vector to load/save.
Default handler for saving/loading a vector to/from disk.
void Append(CargoPacket *cp, MoveToAction action=MTA_KEEP)
Appends the given cargo packet.
int CompanyServiceInterval(const Company *c, VehicleType type)
Get the service interval for the given company and vehicle type.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
@ ST_SMALL_UFO
Small UFO, tries to find a road vehicle to destroy.
@ RAILVEH_WAGON
simple wagon, not motorized
@ RAILVEH_MULTIHEAD
indicates a combination of two locomotives
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
uint16_t EngineID
Unique identification number of an engine.
static const GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
int TicksToLeaveDepot(const Train *v)
Compute number of ticks when next wagon will leave a depot.
Track GetRailDepotTrack(Tile t)
Returns the track of a depot, ignoring direction.
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
@ INVALID_ROADTYPE
flag for invalid roadtype
void RoadVehUpdateCache(RoadVehicle *v, bool same_length=false)
Update the cache of a road vehicle.
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
uint8_t SlReadByte()
Wrapper for reading a byte from the buffer.
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
Functions/types related to saving and loading games.
@ SLF_ALLOW_CONTROL
Allow control codes in the strings.
#define SLEG_CONDVAR(name, variable, type, from, to)
Storage of a global variable in some savegame versions.
#define SLEG_CONDVECTOR(name, variable, type, from, to)
Storage of a global vector of SL_VAR elements in some savegame versions.
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
#define SLE_SAVEBYTE(base, variable)
Only write byte during saving; never read it during loading.
#define SLE_REF(base, variable, type)
Storage of a reference in every version of a savegame.
#define SLE_CONDREFLIST(base, variable, type, from, to)
Storage of a list of SL_REF elements in some savegame versions.
#define SLE_CONDARR(base, variable, type, length, from, to)
Storage of a fixed-size array of SL_VAR elements in some savegame versions.
std::span< const struct SaveLoadCompat > SaveLoadCompatTable
A table of SaveLoadCompat entries.
#define SLEG_STRUCT(name, handler)
Storage of a structs in every savegame version.
#define SLE_CONDSSTR(base, variable, type, from, to)
Storage of a std::string in some savegame versions.
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
@ SLV_182
182 25115 FS#5492, r25259, r25296 Goal status
@ SLV_VEHICLE_ECONOMY_AGE
334 PR#12141 v14.0 Add vehicle age in economy year, for profit stats minimum age
@ SLV_ROADVEH_PATH_CACHE
211 PR#7261 Add path cache for road vehicles.
@ SLV_DISASTER_VEH_STATE
312 PR#10798 Explicit storage of disaster vehicle state.
@ SLV_TIMETABLE_START_TICKS
321 PR#11468 Convert timetable start from a date to ticks.
@ SLV_SHIP_ROTATION
204 PR#7065 Add extra rotation stages for ships.
@ SLV_191
191 26636 FS#6026 Fix disaster vehicle storage (No bump) 191 26646 FS#6041 Linkgraph - store location...
@ SLV_SHIP_PATH_CACHE
203 PR#7072 Add path cache for ships
@ SLV_PATH_CACHE_FORMAT
346 PR#12345 Vehicle path cache format changed.
@ SL_MAX_VERSION
Highest possible saveload version.
@ SL_MIN_VERSION
First savegame version.
@ SLV_VEH_MOTION_COUNTER
288 PR#8591 Desync safe motion counter
@ SLV_EXTEND_VEHICLE_RANDOM
310 PR#10701 Extend vehicle random bits.
@ SLV_2
2.0 0.3.0 2.1 0.3.1, 0.3.2
@ SLV_LAST_LOADING_TICK
301 PR#9693 Store tick of last loading for vehicles.
@ SLV_DEPOT_UNBUNCHING
331 PR#11945 Allow unbunching shared order vehicles at a depot.
@ SLV_TIMETABLE_TICKS_TYPE
323 PR#11435 Convert timetable current order time to ticks.
@ SLV_5
5.0 1429 5.1 1440 5.2 1525 0.3.6
@ SLV_NEWGRF_LAST_SERVICE
317 PR#11124 Added stable date_of_last_service to avoid NewGRF trouble.
#define SLE_CONDREF(base, variable, type, from, to)
Storage of a reference in some savegame versions.
@ REF_VEHICLE_OLD
Load/save an old-style reference to a vehicle (for pre-4.4 savegames).
@ REF_CARGO_PACKET
Load/save a reference to a cargo packet.
@ REF_ORDER
Load/save a reference to an order.
@ REF_ORDERLIST
Load/save a reference to an orderlist.
@ REF_VEHICLE
Load/save a reference to a vehicle.
#define SLEG_CONDSTRUCTLIST(name, handler, from, to)
Storage of a list of structs in some savegame versions.
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
#define SLE_CONDVARNAME(base, variable, name, type, from, to)
Storage of a variable in some savegame versions.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Aircraft, helicopters, rotors and their shadows belong to this class.
VehicleType type
Type of vehicle.
Container for cargo from the same location and time.
Handlers and description of chunk.
CompanySettings settings
settings specific for each company
VehicleDefaultSettings vehicle
default settings for vehicles
Disasters, like submarines, skyrangers and their shadows, belong to this class.
A special vehicle is one of the following:
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
VehicleSettings vehicle
options for vehicles
Position information of a vehicle after it moved.
int y
x and y position of the vehicle after moving
uint16_t last_speed
The last speed we did display, so we only have to redraw when this changes.
GroundVehicleCache gcache
Cache of often calculated values.
void CargoChanged()
Recalculates the cached weight of a vehicle and its parts.
bool IsEngine() const
Check if a vehicle is an engine (can be first in a consist).
bool IsMultiheaded() const
Check if the vehicle is a multiheaded engine.
bool IsFreeWagon() const
Check if the vehicle is a free wagon (got no engine in front of it).
void ClearEngine()
Clear engine status.
void ClearMultiheaded()
Clear multiheaded engine property.
VehicleSpriteSeq sprite_seq
Vehicle appearance.
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
bool IsType(OrderType type) const
Check whether this order is of the given type.
uint8_t type
The type of order + non-stop flags.
uint8_t flags
Load/unload types, depot order/action types.
static size_t GetPoolSize()
Returns first unused index.
Tindex index
Index of this pool item.
static Titem * Get(size_t index)
Returns Titem with given index.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Information about a rail vehicle.
Element of the RoadVehPathCache.
Buses, trucks and trams belong to this class.
RoadTypes compatible_roadtypes
NOSAVE: Roadtypes this consist is powered on.
RoadVehPathCache path
Cached path.
RoadType roadtype
NOSAVE: Roadtype of this vehicle.
VehicleID disaster_vehicle
NOSAVE: Disaster vehicle targetting this vehicle.
Element of the ShipPathCache.
All ships have this type.
ShipPathCache path
Cached path.
void UpdateCache()
Update the caches of this ship.
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
static T * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
T * GetNextVehicle() const
Get the next real (non-articulated part) vehicle in the consist.
T * Next() const
Get next vehicle in the chain.
static Pool::IterateWrapper< T > Iterate(size_t from=0)
Returns an iterable ensemble of all valid vehicles of type T.
static T * GetIfValid(size_t index)
Returns vehicle if the index is a valid index for this vehicle type.
'Train' is either a loco or a wagon.
void ConsistChanged(ConsistChangeFlags allowed_changes)
Recalculates the cached stuff of a train.
void FixPointers() const override
Fix the pointers.
void Load() const override
Load the chunk.
void Save() const override
Save the chunk.
bool servint_ispercent
service intervals are in percents
uint8_t roadveh_acceleration_model
realistic acceleration for road vehicles
void CopyWithoutPalette(const VehicleSpriteSeq &src)
Copy data from another sprite sequence, while dropping all recolouring information.
CargoPayment * cargo_payment
The cargo payment we're currently in.
EngineID engine_type
The type of engine used for this vehicle.
VehicleCargoList cargo
The cargo this vehicle is carrying.
StationID last_loading_station
Last station the vehicle has stopped at and could possibly leave from with any cargo loaded.
GroupID group_id
Index of group Pool array.
Vehicle * Next() const
Get the next vehicle of this vehicle.
debug_inline bool IsFrontEngine() const
Check if the vehicle is a front engine.
Order current_order
The current order (+ status, like: loading)
uint8_t spritenum
currently displayed sprite index 0xfd == custom sprite, 0xfe == custom second head sprite 0xff == res...
uint16_t cur_speed
current speed
MutableSpriteCache sprite_cache
Cache of sprites and values related to recalculating them, see MutableSpriteCache.
TileIndex tile
Current tile index.
StationID last_station_visited
The last station we stopped at.
Vehicle * next_shared
pointer to the next vehicle that shares the order
TrackBits TrackToTrackBits(Track track)
Maps a Track to the corresponding TrackBits value.
@ TRACK_BIT_DEPOT
Bitflag for a depot.
Trackdir
Enumeration for tracks and directions.
@ CCF_TRACK
Valid changes while vehicle is driving, and possibly changing tracks.
@ CCF_SAVELOAD
Valid changes when loading a savegame. (Everything that is not stored in the save....
TrainForceProceeding
Modes for ignoring signals.
@ TFP_SIGNAL
Ignore next signal, after the signal ignore being stuck.
GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v)
Get position information of a vehicle when moving one pixel in the direction it is facing.
uint8_t CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
Calculates how full a vehicle is.
@ VS_STOPPED
Vehicle is stopped by the player.
@ VS_HIDDEN
Vehicle is not visible.
@ VS_CRASHED
Vehicle is crashed.
static const int32_t INVALID_COORD
Sentinel for an invalid coordinate.
bool IsCompanyBuildableVehicleType(VehicleType type)
Is the given vehicle type buildable by a company?
void AfterLoadVehiclesPhase1(bool part_of_load)
Called after load for phase 1 of vehicle initialisation.
void FixupTrainLengths()
Fixup old train spacing.
void UpdateOldAircraft()
need to be called to load aircraft from old version
void ReverseTrainDirection(Train *v)
Turn a train around.
void ConvertOldMultiheadToNew()
Converts all trains to the new subtype format introduced in savegame 16.2 It also links multiheaded e...
bool TrainController(Train *v, Vehicle *nomove, bool reverse=true)
Move a vehicle chain one movement stop forwards.
void ConnectMultiheadedTrains()
Link front and rear multiheaded engines to each other This is done when loading a savegame.
uint8_t _age_cargo_skip_counter
Skip aging of cargo? Used before savegame version 162.
void AfterLoadVehiclesPhase2(bool part_of_load)
Called after load for phase 2 of vehicle initialisation.
void ReverseTrainSwapVeh(Train *v, int l, int r)
Swap vehicles l and r in consist v, and reverse their direction.
static void CheckValidVehicles()
Check all vehicles to ensure their engine type is valid for the currently loaded NewGRFs (that includ...
Loading of vehicle chunks before table headers were added.
const SaveLoadCompat _vehicle_train_sl_compat[]
Original field order for SlVehicleTrain.
const SaveLoadCompat _vehicle_disaster_sl_compat[]
Original field order for SlVehicleDisaster.
const SaveLoadCompat _vehicle_effect_sl_compat[]
Original field order for SlVehicleEffect.
const SaveLoadCompat _vehicle_ship_sl_compat[]
Original field order for SlVehicleShip.
const SaveLoadCompat _vehicle_sl_compat[]
Original field order for vehicle_desc.
const SaveLoadCompat _vehicle_roadveh_sl_compat[]
Original field order for SlVehicleRoadVeh.
const SaveLoadCompat _vehicle_common_sl_compat[]
Original field order for SlVehicleCommon.
const SaveLoadCompat _vehicle_aircraft_sl_compat[]
Original field order for SlVehicleAircraft.
@ EIT_ON_MAP
Vehicle drawn in viewport.
VehicleType
Available vehicle types.
@ VEH_INVALID
Non-existing type of vehicle.
@ VEH_ROAD
Road vehicle type.
@ VEH_DISASTER
Disaster vehicle type.
@ VEH_AIRCRAFT
Aircraft vehicle type.
@ VEH_SHIP
Ship vehicle type.
@ VEH_EFFECT
Effect vehicle type (smoke, explosions, sparks, bubbles)
@ VEH_TRAIN
Train vehicle type.
static const VehicleID INVALID_VEHICLE
Constant representing a non-existing vehicle.
static const uint VEHICLE_LENGTH
The length of a vehicle in tile units.