Go to the documentation of this file.
26 #include "table/strings.h"
44 return (available_cargoes_a == 0 || available_cargoes_b == 0 || (available_cargoes_a & available_cargoes_b) != 0);
59 if (from == to)
return false;
106 assert(v ==
nullptr || v->
First() == v);
108 for (
Vehicle *src = v; src !=
nullptr; src = src->
Next()) {
112 if (src->cargo.TotalCount() <= src->cargo_cap)
continue;
115 uint to_spread = src->cargo.TotalCount() - src->cargo_cap;
116 for (
Vehicle *dest = v; dest !=
nullptr && to_spread != 0; dest = dest->
Next()) {
118 if (dest->cargo.TotalCount() >= dest->cargo_cap || dest->cargo_type != src->cargo_type)
continue;
120 uint amount = std::min(to_spread, dest->cargo_cap - dest->cargo.TotalCount());
121 src->cargo.Shift(amount, &dest->cargo);
126 if (src->cargo_cap < src->cargo.TotalCount()) src->cargo.Truncate(src->cargo.TotalCount() - src->cargo_cap);
143 for (
Vehicle *src = old_veh; src !=
nullptr; src = src->
Next()) {
147 src = src->GetLastEnginePart();
150 if (src->cargo_type >=
NUM_CARGO || src->cargo.TotalCount() == 0)
continue;
157 dest = dest->GetLastEnginePart();
160 if (dest->cargo_type != src->cargo_type)
continue;
162 uint amount = std::min(src->cargo.TotalCount(), dest->cargo_cap - dest->cargo.TotalCount());
163 if (amount <= 0)
continue;
165 src->cargo.Shift(amount, &dest->cargo);
186 if (!o->IsRefit() || o->IsAutoRefit())
continue;
187 CargoID cargo_type = o->GetRefitCargo();
189 if (!
HasBit(union_refit_mask_a, cargo_type))
continue;
190 if (!
HasBit(union_refit_mask_b, cargo_type))
return false;
230 CargoTypes available_cargo_types, union_mask;
246 for (v = v->
First(); v !=
nullptr; v = v->
Next()) {
281 bool replace_when_old;
310 *new_vehicle =
nullptr;
316 if (cost.
Failed())
return cost;
327 if (order_id != -1) {
329 SetDParam(1, STR_ERROR_AUTOREPLACE_INCOMPATIBLE_REFIT);
333 SetDParam(1, STR_ERROR_AUTOREPLACE_INCOMPATIBLE_CARGO);
343 if (cost.
Failed())
return cost;
346 *new_vehicle = new_veh;
447 if (cost.
Succeeded() && new_v !=
nullptr) {
448 *nothing_to_do =
false;
462 *single_unit = new_v;
501 Train **old_vehs = CallocT<Train *>(num_units);
502 Train **new_vehs = CallocT<Train *>(num_units);
503 Money *new_costs = MallocT<Money>(num_units);
510 assert(i < num_units);
518 if (new_vehs[i] !=
nullptr) *nothing_to_do =
false;
520 Train *new_head = (new_vehs[0] !=
nullptr ? new_vehs[0] : old_vehs[0]);
528 assert(
Train::From(new_head)->GetNextUnit() ==
nullptr);
534 Train *last_engine =
nullptr;
536 for (
int i = num_units - 1; i > 0; i--) {
537 Train *append = (new_vehs[i] !=
nullptr ? new_vehs[i] : old_vehs[i]);
541 if (new_vehs[i] !=
nullptr) {
548 if (last_engine ==
nullptr) last_engine = append;
552 if (last_engine ==
nullptr) last_engine = new_head;
562 for (
int i = num_units - 1; i > 0; i--) {
563 assert(last_engine !=
nullptr);
564 Vehicle *append = (new_vehs[i] !=
nullptr ? new_vehs[i] : old_vehs[i]);
582 assert(append == last_engine);
591 for (
int i = 1; i < num_units; i++) {
593 if (wagon ==
nullptr)
continue;
594 if (wagon->
First() == new_head)
break;
602 new_vehs[i] =
nullptr;
615 if ((flags &
DC_EXEC) != 0 && new_head != old_head) {
620 for (
int i = 0; i < num_units; i++) {
624 if (w->
First() == new_head)
continue;
633 old_vehs[i] =
nullptr;
652 assert(
Train::From(old_head)->GetNextUnit() ==
nullptr);
654 for (
int i = num_units - 1; i > 0; i--) {
664 for (
int i = num_units - 1; i >= 0; i--) {
665 if (new_vehs[i] !=
nullptr) {
667 new_vehs[i] =
nullptr;
681 if (cost.
Succeeded() && new_head !=
nullptr) {
682 *nothing_to_do =
false;
726 if (ret.
Failed())
return ret;
731 bool free_wagon =
false;
746 bool any_replacements =
false;
747 while (w !=
nullptr) {
750 if (cost.
Failed())
return cost;
756 bool nothing_to_do =
true;
758 if (any_replacements) {
763 if (cost.
Failed())
return cost;
784 ret =
ReplaceChain(&v, flags, wagon_removal, ¬hing_to_do);
@ VEH_AIRCRAFT
Aircraft vehicle type.
uint TotalCount() const
Returns sum of cargo, including reserved cargo.
virtual bool IsChainInDepot() const
Check whether the whole vehicle chain is in the depot.
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
byte VehicleOrderID
The index of an order within its current vehicle (not pool related)
bool IsRefit() const
Is this order a refit order.
uint32 TileIndex
The index/ID of a Tile.
static CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after, DoCommandFlag flags, bool whole_chain)
Issue a train vehicle move command.
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
Shorthand for calling the long DoCommand with a container.
@ CMD_REVERSE_TRAIN_DIRECTION
turn a train around
static Titem * Get(size_t index)
Returns Titem with given index.
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
@ CMD_ADD_VEHICLE_GROUP
add a vehicle to a group
@ CMD_MOVE_RAIL_VEHICLE
move a rail vehicle (in the depot)
byte subtype
Type of aircraft.
static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, DoCommandFlag flags)
Copy head specific things to the new vehicle chain after it was successfully constructed.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, bool always_replace, EngineID &e)
Get the EngineID of the replacement for a vehicle.
The information about a vehicle list.
Vehicle * Next() const
Get the next vehicle of this vehicle.
void ChangeVehicleViewWindow(VehicleID from_index, VehicleID to_index)
Report a change in vehicle IDs (due to autoreplace) to affected vehicle windows.
void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, CargoTypes *union_mask, CargoTypes *intersection_mask)
Merges the refit_masks of all articulated parts.
Stores the state of all random number generators.
Tindex index
Index of this pool item.
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
GroupID group_id
Index of group Pool array.
static EngineID EngineReplacementForCompany(const Company *c, EngineID engine, GroupID group, bool *replace_when_old=nullptr)
Retrieve the engine replacement for the given company and original engine type.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
static void SaveRandomSeeds(SavedRandomSeeds *storage)
Saves the current seeds.
static const uint TILE_SIZE
Tile size in world coordinates.
bool IsRearDualheaded() const
Tell if we are dealing with the rear end of a multiheaded engine.
@ VEH_ROAD
Road vehicle type.
virtual bool IsPrimaryVehicle() const
Whether this is the primary vehicle in the chain.
RoadType roadtype
Road type.
Owner owner
Which company owns the vehicle?
Owner
Enum for all companies/owners.
@ DC_EXEC
execute the given command
StringID GetErrorMessage() const
Returns the error message of a command.
static bool IsLocalCompany()
Is the current company the local company?
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
DoCommandFlag
List of flags for a command.
static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehicle, bool part_of_chain)
Builds and refits a replacement vehicle Important: The old vehicle is still in the original vehicle c...
bool Succeeded() const
Did this command succeed?
static void RestoreRandomSeeds(const SavedRandomSeeds &storage)
Restores previously saved seeds.
bool IsArticulatedPart() const
Check if the vehicle is an articulated part of an engine.
void ChangeVehicleViewports(VehicleID from_index, VehicleID to_index)
Switches viewports following vehicles, which get autoreplaced.
static const RailtypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
bool renew_keep_length
sell some wagons if after autoreplace the train is longer than before
IterateWrapper Orders() const
Returns an iterable ensemble of orders of a vehicle.
uint16 EngineID
Unique identification number of an engine.
static bool EnginesHaveCargoInCommon(EngineID engine_a, EngineID engine_b)
Figure out if two engines got at least one type of cargo in common (refitting if needed)
RoadTypes powered_roadtypes
bitmask to the OTHER roadtypes on which a vehicle of THIS roadtype generates power
CommandCost CheckOwnership(Owner owner, TileIndex tile)
Check whether the current owner owns something.
uint16 cached_total_length
Length of the whole vehicle (valid only for the first engine).
CargoID GetRefitCargo() const
Get the cargo to to refit to.
static int GetIncompatibleRefitOrderIdForAutoreplace(const Vehicle *v, EngineID engine_type)
Gets the index of the first refit order that is incompatible with the requested engine type.
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Common return value for all commands.
CargoTypes GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type)
Ors the refit_masks of all articulated parts.
CommandCost CmdSetAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Change engine renewal parameters.
TileIndex tile
Current tile index.
static const VehicleID INVALID_VEHICLE
Constant representing a non-existing vehicle.
EngineID engine_type
The type of engine used for this vehicle.
@ VS_CRASHED
Vehicle is crashed.
VehicleCargoList cargo
The cargo this vehicle is carrying.
bool Failed() const
Did this command fail?
@ WC_REPLACE_VEHICLE
Replace vehicle window; Window numbers:
GroundVehicleCache gcache
Cache of often calculated values.
static bool VerifyAutoreplaceRefitForOrders(const Vehicle *v, EngineID engine_type)
Tests whether refit orders that applied to v will also apply to the new vehicle type.
bool IsFrontEngine() const
Check if the vehicle is a front engine.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
@ DC_AUTOREPLACE
autoreplace/autorenew is in progress, this shall disable vehicle limits when building,...
@ VS_STOPPED
Vehicle is stopped by the player.
bool IsArticulatedVehicleCarryingDifferentCargoes(const Vehicle *v, CargoID *cargo_type)
Tests if all parts of an articulated vehicle are refitted to the same cargo.
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
void CopyVehicleConfigAndStatistics(const Vehicle *src)
Copy certain configurations and statistics of a vehicle after successful autoreplace/renew The functi...
static void UpdateAutoreplace(CompanyID company)
Update autoreplace_defined and autoreplace_finished of all statistics of a company.
'Train' is either a loco or a wagon.
Money GetCost() const
The costs as made up to this moment.
static CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_callback)
Issue a start/stop command.
@ VRF_REVERSE_DIRECTION
Reverse the visible direction of the vehicle.
void ChangeVehicleNews(VehicleID from_index, VehicleID to_index)
Report a change in vehicle IDs (due to autoreplace) to affected vehicle news.
static bool IsAllGroupID(GroupID id_g)
Checks if a GroupID stands for all vehicles of a company.
void CheckCargoCapacity(Vehicle *v)
Check the capacity of all vehicles in a chain and spread cargo if needed.
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
VehicleType
Available vehicle types.
static CommandCost RemoveEngineReplacementForCompany(Company *c, EngineID engine, GroupID group, DoCommandFlag flags)
Remove an engine replacement for the company.
byte misc_flags
Miscellaneous flags.
Order * GetOrderAt(int index) const
Get a certain order of the order chain.
@ RAILVEH_WAGON
simple wagon, not motorized
OrderList * list
Pointer to the order list for this vehicle.
@ CMD_START_STOP_VEHICLE
start or stop a vehicle
static WindowClass GetWindowClassForVehicleType(VehicleType vt)
Get WindowClass for vehicle list of given vehicle type.
CompanyID _current_company
Company currently doing an action.
Vehicle * First() const
Get the first vehicle of this vehicle chain.
bool CanCarryCargo() const
Determines whether an engine can carry something.
uint16 GroupID
Type for all group identifiers.
@ CCF_LOADUNLOAD
Valid changes while vehicle is loading/unloading.
static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool part_of_chain)
Function to find what type of cargo to refit to when autoreplacing.
static Train * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
void ConsistChanged(ConsistChangeFlags allowed_changes)
Recalculates the cached stuff of a train.
@ DC_NO_CARGO_CAP_CHECK
when autoreplace/autorenew is in progress, this shall prevent truncating the amount of cargo in the v...
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
Train * GetPrevUnit()
Get the previous real (non-articulated part and non rear part of dualheaded engine) vehicle in the co...
union Vehicle::@51 orders
The orders currently assigned to the vehicle.
@ NUM_CARGO
Maximal number of cargo types in a game.
static const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
StringID name
Name of this type of cargo.
CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Autoreplaces a vehicle Trains are replaced as a whole chain, free wagons in depot are replaced on the...
@ EXPENSES_NEW_VEHICLES
New vehicles.
uint32 VehicleID
The type all our vehicle IDs have.
void InvalidateAutoreplaceWindow(EngineID e, GroupID id_g)
Rebuild the left autoreplace list if an engine is removed or added.
static void AddVehicleAdviceNewsItem(StringID string, VehicleID vehicle)
Adds a vehicle-advice news item.
@ AIR_CTOL
Conventional Take Off and Landing, i.e. planes.
bool NeedsAutorenewing(const Company *c, bool use_renew_setting=true) const
Function to tell if a vehicle needs to be autorenewed.
RailTypes compatible_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel
@ MTA_KEEP
Keep the cargo in the vehicle.
static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chain)
Transfer cargo from a single (articulated )old vehicle to the new vehicle chain.
byte CargoID
Cargo slots to indicate a cargo type within a game.
bool IsStoppedInDepot() const
Check whether the vehicle is in the depot and stopped.
static CommandCost AddEngineReplacementForCompany(Company *c, EngineID old_engine, EngineID new_engine, GroupID group, bool replace_when_old, DoCommandFlag flags)
Add an engine replacement for the company.
CargoID cargo_type
type of cargo this vehicle is carrying
uint8 max_train_length
maximum length for trains
Train * GetNextUnit() const
Get the next real (non-articulated part and non rear part of dualheaded engine) vehicle in the consis...
@ EF_ROAD_TRAM
Road vehicle is a tram/light rail vehicle.
static uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company)
Checks some basic properties whether autoreplace is allowed.
static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon_removal, bool *nothing_to_do)
Replace a whole vehicle chain.
VehicleSettings vehicle
options for vehicles
@ VEH_TRAIN
Train vehicle type.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
VehicleType type
Type of vehicle.
T * First() const
Get the first vehicle in the chain.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
@ CT_INVALID
Invalid cargo type.
@ ROADTYPES_NONE
No roadtypes.
@ CT_NO_REFIT
Do not refit cargo of a vehicle (used in vehicle orders and auto-replace/auto-new).
CompanySettings settings
settings specific for each company
bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company)
Check if an engine is buildable.
byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_type)
Get the best fitting subtype when 'cloning'/'replacing' v_from with v_for.
VehicleOrderID GetNumOrders() const
Get number of orders in the order list.
static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, bool *nothing_to_do)
Replace a single unit in a free wagon chain.
VehicleType type
Vehicle type, ie VEH_ROAD, VEH_TRAIN, etc.
@ CMD_CLONE_ORDER
clone (and share) an order