OpenTTD Source 20260208-master-g43af8e94d0
autoreplace_cmd.cpp File Reference

Deals with autoreplace execution but not the setup. More...

#include "stdafx.h"
#include "company_func.h"
#include "train.h"
#include "command_func.h"
#include "engine_func.h"
#include "vehicle_func.h"
#include "autoreplace_func.h"
#include "autoreplace_gui.h"
#include "articulated_vehicles.h"
#include "core/bitmath_func.hpp"
#include "core/random_func.hpp"
#include "vehiclelist.h"
#include "road.h"
#include "ai/ai.hpp"
#include "news_func.h"
#include "strings_func.h"
#include "autoreplace_cmd.h"
#include "group_cmd.h"
#include "order_cmd.h"
#include "train_cmd.h"
#include "vehicle_cmd.h"
#include "table/strings.h"
#include "safeguards.h"

Go to the source code of this file.

Data Structures

struct  ReplaceChainItem
 Struct for recording vehicle chain replacement information. More...

Functions

void ChangeVehicleViewports (VehicleID from_index, VehicleID to_index)
 Switches viewports following vehicles, which get autoreplaced.
void ChangeVehicleNews (VehicleID from_index, VehicleID to_index)
 Report a change in vehicle IDs (due to autoreplace) to affected vehicle news.
void ChangeVehicleViewWindow (VehicleID from_index, VehicleID to_index)
 Report a change in vehicle IDs (due to autoreplace) to affected vehicle windows.
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).
bool CheckAutoreplaceValidity (EngineID from, EngineID to, CompanyID company)
 Checks some basic properties whether autoreplace is allowed.
void CheckCargoCapacity (Vehicle *v)
 Check the capacity of all vehicles in a chain and spread cargo if needed.
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.
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.
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 CargoType GetNewCargoTypeForReplace (Vehicle *v, EngineID engine_type, bool part_of_chain)
 Function to find what type of cargo to refit to when autoreplacing.
static CommandCost GetNewEngineType (const Vehicle *v, const Company *c, bool always_replace, EngineID &e)
 Get the EngineID of the replacement for a vehicle.
static CommandCost BuildReplacementVehicle (Vehicle *old_veh, Vehicle **new_vehicle, bool part_of_chain, DoCommandFlags flags)
 Builds and refits a replacement vehicle Important: The old vehicle is still in the original vehicle chain (used for determining the cargo when the old vehicle did not carry anything, but the new one does).
static CommandCost DoCmdStartStopVehicle (const Vehicle *v, bool evaluate_callback)
 Issue a start/stop command.
static CommandCost CmdMoveVehicle (const Vehicle *v, const Vehicle *after, DoCommandFlags flags, bool whole_chain)
 Issue a train vehicle move command.
static CommandCost CopyHeadSpecificThings (Vehicle *old_head, Vehicle *new_head, DoCommandFlags flags)
 Copy head specific things to the new vehicle chain after it was successfully constructed.
static CommandCost ReplaceFreeUnit (Vehicle **single_unit, DoCommandFlags flags, bool *nothing_to_do)
 Replace a single unit in a free wagon chain.
static CommandCost ReplaceChain (Vehicle **chain, DoCommandFlags flags, bool wagon_removal, bool *nothing_to_do)
 Replace a whole vehicle chain.
CommandCost CmdAutoreplaceVehicle (DoCommandFlags flags, VehicleID veh_id)
 Autoreplaces a vehicle Trains are replaced as a whole chain, free wagons in depot are replaced on their own.
CommandCost CmdSetAutoReplace (DoCommandFlags flags, GroupID id_g, EngineID old_engine_type, EngineID new_engine_type, bool when_old)
 Change engine renewal parameters.

Detailed Description

Deals with autoreplace execution but not the setup.

Definition in file autoreplace_cmd.cpp.

Function Documentation

◆ BuildReplacementVehicle()

CommandCost BuildReplacementVehicle ( Vehicle * old_veh,
Vehicle ** new_vehicle,
bool part_of_chain,
DoCommandFlags flags )
static

Builds and refits a replacement vehicle Important: The old vehicle is still in the original vehicle chain (used for determining the cargo when the old vehicle did not carry anything, but the new one does).

Parameters
old_vehA single (articulated/multiheaded) vehicle that shall be replaced.
new_vehicleReturns the newly build and refitted vehicle
part_of_chainThe vehicle is part of a train
flagsThe calling command flags.
Returns
cost or error

Definition at line 320 of file autoreplace_cmd.cpp.

References _current_company, CommandCost::AddCost(), AddVehicleAdviceNewsItem(), AutorenewFailed, AutoReplace, CARGO_NO_REFIT, Vehicle::cargo_type, Execute, CommandCost::Failed(), Flipped, SpecializedVehicle< Train, Type >::From(), CargoSpec::Get(), GetBestFittingSubType(), GetEncodedString(), GetIncompatibleRefitOrderIdForAutoreplace(), GetNewCargoTypeForReplace(), GetNewEngineType(), INVALID_CLIENT_ID, IsLocalCompany(), IsValidCargoType(), Reversed, CommandCost::Succeeded(), BaseBitSet< Timpl, Tvalue_type, Tstorage, Tmask >::Test(), TestVehicleBuildProbability(), Vehicle::tile, BaseVehicle::type, and VEH_TRAIN.

Referenced by ReplaceChain(), and ReplaceFreeUnit().

◆ ChangeVehicleNews()

void ChangeVehicleNews ( VehicleID from_index,
VehicleID to_index )
extern

Report a change in vehicle IDs (due to autoreplace) to affected vehicle news.

Note
Viewports of currently displayed news is changed via ChangeVehicleViewports
Parameters
from_indexthe old vehicle ID
to_indexthe new vehicle ID

Definition at line 1084 of file news_gui.cpp.

References _news, NewsItem::flags, NewsItem::headline, NewsItem::ref1, NewsItem::ref2, EncodedString::ReplaceParam(), BaseBitSet< Timpl, Tvalue_type, Tstorage, Tmask >::Test(), and VehicleParam0.

Referenced by CopyHeadSpecificThings().

◆ ChangeVehicleViewports()

void ChangeVehicleViewports ( VehicleID from_index,
VehicleID to_index )
extern

Switches viewports following vehicles, which get autoreplaced.

Parameters
from_indexthe old vehicle ID
to_indexthe new vehicle ID

Definition at line 3527 of file window.cpp.

References Window::SetDirty(), and Window::viewport.

Referenced by CopyHeadSpecificThings().

◆ ChangeVehicleViewWindow()

void ChangeVehicleViewWindow ( VehicleID from_index,
VehicleID to_index )
extern

Report a change in vehicle IDs (due to autoreplace) to affected vehicle windows.

Parameters
from_indexthe old vehicle ID
to_indexthe new vehicle ID

Definition at line 1589 of file vehicle_gui.cpp.

References ChangeVehicleWindow(), WC_VEHICLE_DETAILS, WC_VEHICLE_ORDERS, WC_VEHICLE_REFIT, WC_VEHICLE_TIMETABLE, and WC_VEHICLE_VIEW.

Referenced by CopyHeadSpecificThings().

◆ CheckAutoreplaceValidity()

◆ CheckCargoCapacity()

void CheckCargoCapacity ( Vehicle * v)

Check the capacity of all vehicles in a chain and spread cargo if needed.

Parameters
vThe vehicle to check.
Precondition
You can only do this if the consist is not loading or unloading. It must not carry reserved cargo, nor cargo to be unloaded or transferred.

Definition at line 107 of file autoreplace_cmd.cpp.

References Vehicle::First(), CargoList< VehicleCargoList, CargoPacketList >::MTA_KEEP, and Vehicle::Next().

Referenced by CmdMoveRailVehicle(), and ReplaceChain().

◆ CmdAutoreplaceVehicle()

◆ CmdMoveVehicle()

CommandCost CmdMoveVehicle ( const Vehicle * v,
const Vehicle * after,
DoCommandFlags flags,
bool whole_chain )
inlinestatic

Issue a train vehicle move command.

Parameters
vThe vehicle to move
afterThe vehicle to insert 'v' after, or nullptr to start new chain
flagsthe command flags to use
whole_chainmove all vehicles following 'v' (true), or only 'v' (false)
Returns
success or error

Definition at line 405 of file autoreplace_cmd.cpp.

References NoCargoCapacityCheck, and BaseBitSet< Timpl, Tvalue_type, Tstorage, Tmask >::Set().

Referenced by ReplaceChain(), and ReplaceFreeUnit().

◆ CmdSetAutoReplace()

CommandCost CmdSetAutoReplace ( DoCommandFlags flags,
GroupID id_g,
EngineID old_engine_type,
EngineID new_engine_type,
bool when_old )

Change engine renewal parameters.

Parameters
flagsoperation to perform
id_gengine group
old_engine_typeold engine type
new_engine_typenew engine type
when_oldreplace when engine gets old?
Returns
the cost of this operation or an error

Definition at line 827 of file autoreplace_cmd.cpp.

References _current_company, AddEngineReplacementForCompany(), CheckAutoreplaceValidity(), CMD_ERROR, Execute, GetWindowClassForVehicleType(), InvalidateAutoreplaceWindow(), IsAllGroupID(), IsLocalCompany(), RemoveEngineReplacementForCompany(), SetWindowDirty(), BaseBitSet< Timpl, Tvalue_type, Tstorage, Tmask >::Test(), GroupStatistics::UpdateAutoreplace(), VL_GROUP_LIST, and WC_REPLACE_VEHICLE.

◆ CopyHeadSpecificThings()

CommandCost CopyHeadSpecificThings ( Vehicle * old_head,
Vehicle * new_head,
DoCommandFlags flags )
static

Copy head specific things to the new vehicle chain after it was successfully constructed.

Parameters
old_headThe old front vehicle (no wagons attached anymore)
new_headThe new head of the completely replaced vehicle chain
flagsthe command flags to use

Definition at line 416 of file autoreplace_cmd.cpp.

References CommandCost::AddCost(), GroupStatistics::AddProfitLastYear(), ChangeVehicleNews(), ChangeVehicleViewports(), ChangeVehicleViewWindow(), Vehicle::CopyVehicleConfigAndStatistics(), DoCmdStartStopVehicle(), Execute, Vehicle::group_id, Stopped, CommandCost::Succeeded(), BaseBitSet< Timpl, Tvalue_type, Tstorage, Tmask >::Test(), and Vehicle::vehstatus.

Referenced by ReplaceChain().

◆ DoCmdStartStopVehicle()

CommandCost DoCmdStartStopVehicle ( const Vehicle * v,
bool evaluate_callback )
inlinestatic

Issue a start/stop command.

Parameters
va vehicle
evaluate_callbackshall the start/stop callback be evaluated?
Returns
success or error

Definition at line 392 of file autoreplace_cmd.cpp.

References AutoReplace, and Execute.

Referenced by CmdAutoreplaceVehicle(), and CopyHeadSpecificThings().

◆ EnginesHaveCargoInCommon()

bool EnginesHaveCargoInCommon ( EngineID engine_a,
EngineID engine_b )
static

Figure out if two engines got at least one type of cargo in common (refitting if needed).

Parameters
engine_aone of the EngineIDs
engine_bthe other EngineID
Returns
true if they can both carry the same type of cargo (or at least one of them got no capacity at all)

Definition at line 46 of file autoreplace_cmd.cpp.

References GetUnionOfArticulatedRefitMasks().

Referenced by CheckAutoreplaceValidity().

◆ GetIncompatibleRefitOrderIdForAutoreplace()

int GetIncompatibleRefitOrderIdForAutoreplace ( const Vehicle * v,
EngineID engine_type )
static

Gets the index of the first refit order that is incompatible with the requested engine type.

Parameters
vThe vehicle to be replaced
engine_typeThe type we want to replace with
Returns
index of the incompatible order or -1 if none were found

Definition at line 205 of file autoreplace_cmd.cpp.

References Vehicle::First(), OrderList::GetNumOrders(), OrderList::GetOrderAt(), Order::GetRefitCargo(), GetUnionOfArticulatedRefitMasks(), HasBit(), Order::IsRefit(), Vehicle::orders, BaseVehicle::type, and VEH_TRAIN.

Referenced by BuildReplacementVehicle().

◆ GetNewCargoTypeForReplace()

CargoType GetNewCargoTypeForReplace ( Vehicle * v,
EngineID engine_type,
bool part_of_chain )
static

Function to find what type of cargo to refit to when autoreplacing.

Parameters
*vOriginal vehicle that is being replaced.
engine_typeThe EngineID of the vehicle that is being replaced to
part_of_chainThe vehicle is part of a train
Returns
The cargo type to replace to CARGO_NO_REFIT is returned if no refit is needed INVALID_CARGO is returned when both old and new vehicle got cargo capacity and refitting the new one to the old one's cargo type isn't possible

Definition at line 231 of file autoreplace_cmd.cpp.

References Engine::CanCarryCargo(), CARGO_NO_REFIT, Vehicle::cargo_type, Vehicle::First(), GetArticulatedRefitMasks(), GetCargoTypesOfArticulatedParts(), GetCargoTypesOfArticulatedVehicle(), Vehicle::GetEngine(), HasAtMostOneBit(), HasBit(), IsValidCargoType(), Vehicle::Next(), BaseVehicle::type, VEH_TRAIN, and VerifyAutoreplaceRefitForOrders().

Referenced by BuildReplacementVehicle().

◆ GetNewEngineType()

CommandCost GetNewEngineType ( const Vehicle * v,
const Company * c,
bool always_replace,
EngineID & e )
static

Get the EngineID of the replacement for a vehicle.

Parameters
vThe vehicle to find a replacement for
cThe vehicle's owner (it's faster to forward the pointer than refinding it)
always_replaceAlways replace, even if not old.
[out]ethe EngineID of the replacement. EngineID::Invalid() if no replacement is found
Returns
Error if the engine to build is not available

Definition at line 281 of file autoreplace_cmd.cpp.

References _current_company, Vehicle::engine_type, EngineReplacementForCompany(), SpecializedVehicle< Train, Type >::From(), Vehicle::group_id, Vehicle::IsArticulatedPart(), IsEngineBuildable(), Vehicle::NeedsAutorenewing(), BaseVehicle::type, and VEH_TRAIN.

Referenced by BuildReplacementVehicle(), and CmdAutoreplaceVehicle().

◆ ReplaceChain()

CommandCost ReplaceChain ( Vehicle ** chain,
DoCommandFlags flags,
bool wagon_removal,
bool * nothing_to_do )
static

Replace a whole vehicle chain.

Parameters
chainvehicle chain to let autoreplace/renew operator on
flagscommand flags
wagon_removalremove wagons when the resulting chain occupies more tiles than the old did
nothing_to_dois set to 'false' when something was done (only valid when not failed)
Returns
cost or error

< Shall store the last engine unit after this step

Definition at line 525 of file autoreplace_cmd.cpp.

References _settings_game, CommandCost::AddCost(), AutoReplace, BuildReplacementVehicle(), CeilDiv(), CheckCargoCapacity(), CmdMoveVehicle(), CopyHeadSpecificThings(), Vehicle::engine_type, Execute, EXPENSES_NEW_VEHICLES, CommandCost::Failed(), Vehicle::First(), SpecializedVehicle< Train, Type >::From(), CommandCost::GetCost(), CommandCost::GetErrorMessage(), Train::GetNextUnit(), Train::GetPrevUnit(), INVALID_CLIENT_ID, Vehicle::IsPrimaryVehicle(), ReplaceChainItem::new_veh, AI::NewEvent(), ReplaceChainItem::old_veh, Vehicle::owner, RAILVEH_WAGON, CommandCost::Succeeded(), BaseBitSet< Timpl, Tvalue_type, Tstorage, Tmask >::Test(), TILE_SIZE, TransferCargo(), BaseVehicle::type, and VEH_TRAIN.

Referenced by CmdAutoreplaceVehicle().

◆ ReplaceFreeUnit()

CommandCost ReplaceFreeUnit ( Vehicle ** single_unit,
DoCommandFlags flags,
bool * nothing_to_do )
static

Replace a single unit in a free wagon chain.

Parameters
single_unitvehicle to let autoreplace/renew operator on
flagscommand flags
nothing_to_dois set to 'false' when something was done (only valid when not failed)
Returns
cost or error

Definition at line 458 of file autoreplace_cmd.cpp.

References CommandCost::AddCost(), BuildReplacementVehicle(), CmdMoveVehicle(), Execute, EXPENSES_NEW_VEHICLES, SpecializedVehicle< Train, Type >::From(), INVALID_CLIENT_ID, Vehicle::IsArticulatedPart(), GroundVehicle< T, Type >::IsRearDualheaded(), AI::NewEvent(), Vehicle::owner, CommandCost::Succeeded(), BaseBitSet< Timpl, Tvalue_type, Tstorage, Tmask >::Test(), and TransferCargo().

Referenced by CmdAutoreplaceVehicle().

◆ TransferCargo()

void TransferCargo ( Vehicle * old_veh,
Vehicle * new_head,
bool part_of_chain )
static

Transfer cargo from a single (articulated )old vehicle to the new vehicle chain.

Parameters
old_vehOld vehicle that will be sold
new_headHead of the completely constructed new vehicle chain
part_of_chainThe vehicle is part of a train
Precondition
You can only do this if both consists are not loading or unloading. They must not carry reserved cargo, nor cargo to be unloaded or transferred.

Definition at line 142 of file autoreplace_cmd.cpp.

References Vehicle::cargo, CCF_LOADUNLOAD, Train::ConsistChanged(), SpecializedVehicle< Train, Type >::From(), Vehicle::IsPrimaryVehicle(), CargoList< VehicleCargoList, CargoPacketList >::MTA_KEEP, Vehicle::Next(), NUM_CARGO, VehicleCargoList::TotalCount(), BaseVehicle::type, and VEH_TRAIN.

Referenced by ReplaceChain(), and ReplaceFreeUnit().

◆ VerifyAutoreplaceRefitForOrders()

bool VerifyAutoreplaceRefitForOrders ( const Vehicle * v,
EngineID engine_type )
static

Tests whether refit orders that applied to v will also apply to the new vehicle type.

Parameters
vThe vehicle to be replaced
engine_typeThe type we want to replace with
Returns
true iff all refit orders stay valid

Definition at line 182 of file autoreplace_cmd.cpp.

References Vehicle::engine_type, Vehicle::First(), GetUnionOfArticulatedRefitMasks(), HasBit(), BaseVehicle::type, and VEH_TRAIN.

Referenced by GetNewCargoTypeForReplace().