Merge branch 'template_train_replacement-sx' into jgrpp
Remove a duplicated declaration. # Conflicts: # projects/openttd_vs100.vcxproj # projects/openttd_vs100.vcxproj.filters # projects/openttd_vs140.vcxproj # projects/openttd_vs140.vcxproj.filters # projects/openttd_vs80.vcproj # projects/openttd_vs90.vcproj # source.list # src/group_gui.cpp # src/lang/english.txt # src/network/network_command.cpp # src/saveload/extended_ver_sl.cpp # src/saveload/extended_ver_sl.h # src/saveload/saveload.cpp # src/train_cmd.cpp # src/vehicle.cpp # src/vehicle_gui.cpp # src/vehicle_gui_base.h # src/window_type.h
This commit is contained in:
@@ -37,6 +37,9 @@
|
||||
#include "zoom_func.h"
|
||||
#include "newgrf_debug.h"
|
||||
#include "tracerestrict.h"
|
||||
#include "tbtr_template_vehicle_func.h"
|
||||
#include "autoreplace_func.h"
|
||||
#include "engine_func.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
#include "table/train_cmd.h"
|
||||
@@ -308,7 +311,7 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes)
|
||||
|
||||
if (this->IsFrontEngine()) {
|
||||
this->UpdateAcceleration();
|
||||
SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
|
||||
if (!HasBit(this->subtype, GVSF_VIRTUAL)) SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
|
||||
InvalidateWindowData(WC_VEHICLE_REFIT, this->index, VIWD_CONSIST_CHANGED);
|
||||
InvalidateWindowData(WC_VEHICLE_ORDERS, this->index, VIWD_CONSIST_CHANGED);
|
||||
InvalidateNewGRFInspectWindow(GSF_TRAINS, this->index);
|
||||
@@ -1225,6 +1228,7 @@ static void NormaliseTrainHead(Train *head)
|
||||
* @param p1 various bitstuffed elements
|
||||
* - p1 (bit 0 - 19) source vehicle index
|
||||
* - p1 (bit 20) move all vehicles following the source vehicle
|
||||
* - p1 (bit 21) this is a virtual vehicle (for creating TemplateVehicles)
|
||||
* @param p2 what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
@@ -1289,10 +1293,16 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
||||
if (!move_chain && dst != NULL && dst->IsRearDualheaded() && src == dst->other_multiheaded_part) return CommandCost();
|
||||
|
||||
/* Check if all vehicles in the source train are stopped inside a depot. */
|
||||
if (!src_head->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
|
||||
/* Do this check only if the vehicle to be moved is non-virtual */
|
||||
if (!HasBit(p1, 21)) {
|
||||
if (!src_head->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
|
||||
}
|
||||
|
||||
/* Check if all vehicles in the destination train are stopped inside a depot. */
|
||||
if (dst_head != NULL && !dst_head->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
|
||||
/* Do this check only if the destination vehicle is non-virtual */
|
||||
if (!HasBit(p1, 21)) {
|
||||
if (dst_head != NULL && !dst_head->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
|
||||
}
|
||||
|
||||
/* First make a backup of the order of the trains. That way we can do
|
||||
* whatever we want with the order and later on easily revert. */
|
||||
@@ -1401,8 +1411,11 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
||||
if (dst_head != NULL) dst_head->First()->MarkDirty();
|
||||
|
||||
/* We are undoubtedly changing something in the depot and train list. */
|
||||
InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
|
||||
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
||||
/* But only if the moved vehicle is not virtual */
|
||||
if (!HasBit(src->subtype, GVSF_VIRTUAL)) {
|
||||
InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
|
||||
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
||||
}
|
||||
} else {
|
||||
/* We don't want to execute what we're just tried. */
|
||||
RestoreTrainBackup(original_src);
|
||||
@@ -1485,8 +1498,11 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, uint16 data, uint3
|
||||
NormaliseTrainHead(new_head);
|
||||
|
||||
/* We are undoubtedly changing something in the depot and train list. */
|
||||
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
|
||||
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
||||
/* Unless its a virtual train */
|
||||
if (!HasBit(v->subtype, GVSF_VIRTUAL)) {
|
||||
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
|
||||
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
||||
}
|
||||
|
||||
/* Actually delete the sold 'goods' */
|
||||
delete sell_head;
|
||||
@@ -4199,6 +4215,16 @@ static bool TrainCheckIfLineEnds(Train *v, bool reverse)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Calculate the summed up value of all parts of a train */
|
||||
Money Train::CalculateCurrentOverallValue() const
|
||||
{
|
||||
Money ovr_value = 0;
|
||||
const Train *v = this;
|
||||
do {
|
||||
ovr_value += v->value;
|
||||
} while ((v = v->GetNextVehicle()) != NULL);
|
||||
return ovr_value;
|
||||
}
|
||||
|
||||
static bool TrainLocoHandler(Train *v, bool mode)
|
||||
{
|
||||
@@ -4543,3 +4569,389 @@ void DeleteVisibleTrain(Train *v)
|
||||
|
||||
UpdateSignalsInBuffer();
|
||||
}
|
||||
|
||||
/* Get the pixel-width of the image that is used for the train vehicle
|
||||
* @return: the image width number in pixel
|
||||
*/
|
||||
int GetDisplayImageWidth(Train *t, Point *offset)
|
||||
{
|
||||
int reference_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
|
||||
int vehicle_pitch = 0;
|
||||
|
||||
const Engine *e = Engine::Get(t->engine_type);
|
||||
if (e->grf_prop.grffile != NULL && is_custom_sprite(e->u.rail.image_index)) {
|
||||
reference_width = e->grf_prop.grffile->traininfo_vehicle_width;
|
||||
vehicle_pitch = e->grf_prop.grffile->traininfo_vehicle_pitch;
|
||||
}
|
||||
|
||||
if (offset != NULL) {
|
||||
offset->x = reference_width / 2;
|
||||
offset->y = vehicle_pitch;
|
||||
}
|
||||
return t->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH;
|
||||
}
|
||||
|
||||
Train* CmdBuildVirtualRailWagon(const Engine *e)
|
||||
{
|
||||
const RailVehicleInfo *rvi = &e->u.rail;
|
||||
|
||||
Train *v = new Train();
|
||||
|
||||
v->x_pos = 0;
|
||||
v->y_pos = 0;
|
||||
|
||||
v->spritenum = rvi->image_index;
|
||||
|
||||
v->engine_type = e->index;
|
||||
v->gcache.first_engine = INVALID_ENGINE; // needs to be set before first callback
|
||||
|
||||
v->direction = DIR_W;
|
||||
v->tile = 0; // INVALID_TILE;
|
||||
|
||||
v->owner = _current_company;
|
||||
v->track = TRACK_BIT_DEPOT;
|
||||
v->vehstatus = VS_HIDDEN | VS_DEFPAL;
|
||||
|
||||
v->SetWagon();
|
||||
v->SetFreeWagon();
|
||||
|
||||
v->cargo_type = e->GetDefaultCargoType();
|
||||
v->cargo_cap = rvi->capacity;
|
||||
|
||||
v->railtype = rvi->railtype;
|
||||
|
||||
v->build_year = _cur_year;
|
||||
v->cur_image = SPR_IMG_QUERY;
|
||||
v->random_bits = VehicleRandomBits();
|
||||
|
||||
v->group_id = DEFAULT_GROUP;
|
||||
|
||||
AddArticulatedParts(v);
|
||||
|
||||
// Make sure we set EVERYTHING to virtual, even articulated parts.
|
||||
for (Train* train_part = v; train_part != NULL; train_part = train_part->Next()) {
|
||||
train_part->SetVirtual();
|
||||
}
|
||||
|
||||
_new_vehicle_id = v->index;
|
||||
|
||||
v->UpdateViewport(true, false);
|
||||
|
||||
v->First()->ConsistChanged(CCF_ARRANGE);
|
||||
|
||||
CheckConsistencyOfArticulatedVehicle(v);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a railroad vehicle.
|
||||
* @param tile tile of the depot where rail-vehicle is built.
|
||||
* @param flags type of operation.
|
||||
* @param e the engine to build.
|
||||
* @param data bit 0 prevents any free cars from being added to the train.
|
||||
* @param ret[out] the vehicle that has been built.
|
||||
* @return the cost of this operation or an error.
|
||||
*/
|
||||
Train* CmdBuildVirtualRailVehicle(EngineID eid)
|
||||
{
|
||||
if (!IsEngineBuildable(eid, VEH_TRAIN, _current_company)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const Engine* e = Engine::Get(eid);
|
||||
const RailVehicleInfo *rvi = &e->u.rail;
|
||||
|
||||
int num_vehicles = (e->u.rail.railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) + CountArticulatedParts(eid, false);
|
||||
if (!Train::CanAllocateItem(num_vehicles)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (rvi->railveh_type == RAILVEH_WAGON) {
|
||||
return CmdBuildVirtualRailWagon(e);
|
||||
}
|
||||
|
||||
Train *v = new Train();
|
||||
|
||||
v->x_pos = 0;
|
||||
v->y_pos = 0;
|
||||
|
||||
v->direction = DIR_W;
|
||||
v->tile = 0; // INVALID_TILE;
|
||||
v->owner = _current_company;
|
||||
v->track = TRACK_BIT_DEPOT;
|
||||
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
|
||||
v->spritenum = rvi->image_index;
|
||||
v->cargo_type = e->GetDefaultCargoType();
|
||||
v->cargo_cap = rvi->capacity;
|
||||
v->last_station_visited = INVALID_STATION;
|
||||
|
||||
v->engine_type = e->index;
|
||||
v->gcache.first_engine = INVALID_ENGINE; // needs to be set before first callback
|
||||
|
||||
v->reliability = e->reliability;
|
||||
v->reliability_spd_dec = e->reliability_spd_dec;
|
||||
v->max_age = e->GetLifeLengthInDays();
|
||||
|
||||
v->railtype = rvi->railtype;
|
||||
_new_vehicle_id = v->index;
|
||||
|
||||
v->cur_image = SPR_IMG_QUERY;
|
||||
v->random_bits = VehicleRandomBits();
|
||||
|
||||
v->group_id = DEFAULT_GROUP;
|
||||
|
||||
v->SetFrontEngine();
|
||||
v->SetEngine();
|
||||
|
||||
v->UpdateViewport(true, false);
|
||||
|
||||
if (rvi->railveh_type == RAILVEH_MULTIHEAD) {
|
||||
AddRearEngineToMultiheadedTrain(v);
|
||||
} else {
|
||||
AddArticulatedParts(v);
|
||||
}
|
||||
|
||||
// Make sure we set EVERYTHING to virtual, even articulated parts.
|
||||
for (Train* train_part = v; train_part != NULL; train_part = train_part->Next()) {
|
||||
train_part->SetVirtual();
|
||||
}
|
||||
|
||||
v->ConsistChanged(CCF_ARRANGE);
|
||||
|
||||
CheckConsistencyOfArticulatedVehicle(v);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a virtual train vehicle.
|
||||
* @param tile unused
|
||||
* @param flags type of operation
|
||||
* @param p1 the engine ID to build
|
||||
* @param p2 unused
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdBuildVirtualRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
EngineID eid = p1;
|
||||
|
||||
bool should_execute = (flags & DC_EXEC) != 0;
|
||||
|
||||
if (should_execute) {
|
||||
Train* train = CmdBuildVirtualRailVehicle(eid);
|
||||
|
||||
if (train == NULL) {
|
||||
return CMD_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace a vehicle based on a template replacement order.
|
||||
* @param tile unused
|
||||
* @param flags type of operation
|
||||
* @param p1 the ID of the vehicle to replace.
|
||||
* @param p2 whether the vehicle should stay in the depot.
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
VehicleID vehicle_id = p1;
|
||||
|
||||
Vehicle* vehicle = Vehicle::GetIfValid(vehicle_id);
|
||||
|
||||
if (vehicle == NULL || vehicle->type != VEH_TRAIN) {
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
bool should_execute = (flags & DC_EXEC) != 0;
|
||||
|
||||
if (!should_execute) {
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
Train* incoming = Train::From(vehicle);
|
||||
bool stayInDepot = p2 != 0;
|
||||
|
||||
Train *new_chain = NULL;
|
||||
Train *remainder_chain = NULL;
|
||||
Train *tmp_chain = NULL;
|
||||
TemplateVehicle *tv = GetTemplateVehicleByGroupID(incoming->group_id);
|
||||
EngineID eid = tv->engine_type;
|
||||
|
||||
CommandCost buy(EXPENSES_NEW_VEHICLES);
|
||||
CommandCost move_cost(EXPENSES_NEW_VEHICLES);
|
||||
CommandCost tmp_result(EXPENSES_NEW_VEHICLES);
|
||||
|
||||
|
||||
/* first some tests on necessity and sanity */
|
||||
if (tv == NULL) return buy;
|
||||
bool need_replacement = !TrainMatchesTemplate(incoming, tv);
|
||||
bool need_refit = !TrainMatchesTemplateRefit(incoming, tv);
|
||||
bool use_refit = tv->refit_as_template;
|
||||
CargoID store_refit_ct = CT_INVALID;
|
||||
short store_refit_csubt = 0;
|
||||
// if a train shall keep its old refit, store the refit setting of its first vehicle
|
||||
if (!use_refit) {
|
||||
for (Train *getc = incoming; getc != NULL; getc = getc->GetNextUnit()) {
|
||||
if (getc->cargo_type != CT_INVALID) {
|
||||
store_refit_ct = getc->cargo_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: set result status to success/no success before returning
|
||||
if (!need_replacement) {
|
||||
if (!need_refit || !use_refit) {
|
||||
/* before returning, release incoming train first if 2nd param says so */
|
||||
if (!stayInDepot) incoming->vehstatus &= ~VS_STOPPED;
|
||||
return buy;
|
||||
}
|
||||
} else {
|
||||
CommandCost buyCost = TestBuyAllTemplateVehiclesInChain(tv, tile);
|
||||
if (!buyCost.Succeeded() || !CheckCompanyHasMoney(buyCost)) {
|
||||
if (!stayInDepot) incoming->vehstatus &= ~VS_STOPPED;
|
||||
return_cmd_error(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY);
|
||||
}
|
||||
}
|
||||
|
||||
/* define replacement behavior */
|
||||
bool reuseDepot = tv->IsSetReuseDepotVehicles();
|
||||
bool keepRemainders = tv->IsSetKeepRemainingVehicles();
|
||||
|
||||
if (need_replacement) {
|
||||
// step 1: generate primary for newchain and generate remainder_chain
|
||||
// 1. primary of incoming might already fit the template
|
||||
// leave incoming's primary as is and move the rest to a free chain = remainder_chain
|
||||
// 2. needed primary might be one of incoming's member vehicles
|
||||
// 3. primary might be available as orphan vehicle in the depot
|
||||
// 4. we need to buy a new engine for the primary
|
||||
// all options other than 1. need to make sure to copy incoming's primary's status
|
||||
if (eid == incoming->engine_type) { // 1
|
||||
new_chain = incoming;
|
||||
remainder_chain = incoming->GetNextUnit();
|
||||
if (remainder_chain) {
|
||||
move_cost.AddCost(CmdMoveRailVehicle(tile, flags, remainder_chain->index | (1 << 20), INVALID_VEHICLE, 0));
|
||||
}
|
||||
} else if ((tmp_chain = ChainContainsEngine(eid, incoming)) && tmp_chain != NULL) { // 2
|
||||
// new_chain is the needed engine, move it to an empty spot in the depot
|
||||
new_chain = tmp_chain;
|
||||
move_cost.AddCost(DoCommand(tile, new_chain->index, INVALID_VEHICLE, flags, CMD_MOVE_RAIL_VEHICLE));
|
||||
remainder_chain = incoming;
|
||||
} else if (reuseDepot && (tmp_chain = DepotContainsEngine(tile, eid, incoming)) && tmp_chain != NULL) { // 3
|
||||
new_chain = tmp_chain;
|
||||
move_cost.AddCost(DoCommand(tile, new_chain->index, INVALID_VEHICLE, flags, CMD_MOVE_RAIL_VEHICLE));
|
||||
remainder_chain = incoming;
|
||||
} else { // 4
|
||||
tmp_result = DoCommand(tile, eid, 0, flags, CMD_BUILD_VEHICLE);
|
||||
/* break up in case buying the vehicle didn't succeed */
|
||||
if (!tmp_result.Succeeded()) {
|
||||
return tmp_result;
|
||||
}
|
||||
buy.AddCost(tmp_result);
|
||||
new_chain = Train::Get(_new_vehicle_id);
|
||||
/* make sure the newly built engine is not attached to any free wagons inside the depot */
|
||||
move_cost.AddCost(DoCommand(tile, new_chain->index, INVALID_VEHICLE, flags, CMD_MOVE_RAIL_VEHICLE));
|
||||
/* prepare the remainder chain */
|
||||
remainder_chain = incoming;
|
||||
}
|
||||
// If we bought a new engine or reused one from the depot, copy some parameters from the incoming primary engine
|
||||
if (incoming != new_chain && flags == DC_EXEC) {
|
||||
CopyHeadSpecificThings(incoming, new_chain, flags);
|
||||
NeutralizeStatus(incoming);
|
||||
|
||||
// additionally, if we don't want to use the template refit, refit as incoming
|
||||
// the template refit will be set further down, if we use it at all
|
||||
if (!use_refit) {
|
||||
uint32 cb = GetCmdRefitVeh(new_chain);
|
||||
DoCommand(new_chain->tile, new_chain->index, store_refit_ct | store_refit_csubt << 8 | 1 << 16 | (1 << 5), flags, cb);
|
||||
}
|
||||
}
|
||||
|
||||
// step 2: fill up newchain according to the template
|
||||
// foreach member of template (after primary):
|
||||
// 1. needed engine might be within remainder_chain already
|
||||
// 2. needed engine might be orphaned within the depot (copy status)
|
||||
// 3. we need to buy (again) (copy status)
|
||||
TemplateVehicle *cur_tmpl = tv->GetNextUnit();
|
||||
Train *last_veh = new_chain;
|
||||
while (cur_tmpl) {
|
||||
// 1. engine contained in remainder chain
|
||||
if ((tmp_chain = ChainContainsEngine(cur_tmpl->engine_type, remainder_chain)) && tmp_chain != NULL) {
|
||||
// advance remainder_chain (if necessary) to not lose track of it
|
||||
if (tmp_chain == remainder_chain) {
|
||||
remainder_chain = remainder_chain->GetNextUnit();
|
||||
}
|
||||
move_cost.AddCost(CmdMoveRailVehicle(tile, flags, tmp_chain->index, last_veh->index, 0));
|
||||
}
|
||||
// 2. engine contained somewhere else in the depot
|
||||
else if (reuseDepot && (tmp_chain = DepotContainsEngine(tile, cur_tmpl->engine_type, new_chain)) && tmp_chain != NULL) {
|
||||
move_cost.AddCost(CmdMoveRailVehicle(tile, flags, tmp_chain->index, last_veh->index, 0));
|
||||
}
|
||||
// 3. must buy new engine
|
||||
else {
|
||||
tmp_result = DoCommand(tile, cur_tmpl->engine_type, 0, flags, CMD_BUILD_VEHICLE);
|
||||
if (!tmp_result.Succeeded()) {
|
||||
return tmp_result;
|
||||
}
|
||||
buy.AddCost(tmp_result);
|
||||
tmp_chain = Train::Get(_new_vehicle_id);
|
||||
move_cost.AddCost(CmdMoveRailVehicle(tile, flags, tmp_chain->index, last_veh->index, 0));
|
||||
}
|
||||
// TODO: is this enough ? might it be that we bought a new wagon here and it now has std refit ?
|
||||
if (need_refit && flags == DC_EXEC) {
|
||||
if (use_refit) {
|
||||
uint32 cb = GetCmdRefitVeh(tmp_chain);
|
||||
DoCommand(tmp_chain->tile, tmp_chain->index, cur_tmpl->cargo_type | (cur_tmpl->cargo_subtype << 8) | (1 << 16) | (1 << 5), flags, cb);
|
||||
} else {
|
||||
uint32 cb = GetCmdRefitVeh(tmp_chain);
|
||||
DoCommand(tmp_chain->tile, tmp_chain->index, store_refit_ct | (store_refit_csubt << 8) | (1 << 16) | (1 << 5), flags, cb);
|
||||
}
|
||||
}
|
||||
cur_tmpl = cur_tmpl->GetNextUnit();
|
||||
last_veh = tmp_chain;
|
||||
}
|
||||
}
|
||||
/* no replacement done */
|
||||
else {
|
||||
new_chain = incoming;
|
||||
}
|
||||
/// step 3: reorder and neutralize the remaining vehicles from incoming
|
||||
// wagons remaining from remainder_chain should be filled up in as few freewagonchains as possible
|
||||
// each locos might be left as singular in the depot
|
||||
// neutralize each remaining engine's status
|
||||
|
||||
// refit, only if the template option is set so
|
||||
if (use_refit && (need_refit || need_replacement)) {
|
||||
CmdRefitTrainFromTemplate(new_chain, tv, flags);
|
||||
}
|
||||
|
||||
if (new_chain && remainder_chain) {
|
||||
for (Train *ct = remainder_chain; ct; ct = ct->GetNextUnit()) {
|
||||
TransferCargoForTrain(ct, new_chain);
|
||||
}
|
||||
}
|
||||
|
||||
// point incoming to the newly created train so that starting/stopping from the calling function can be done
|
||||
incoming = new_chain;
|
||||
if (!stayInDepot && flags == DC_EXEC) {
|
||||
new_chain->vehstatus &= ~VS_STOPPED;
|
||||
}
|
||||
|
||||
if (remainder_chain && keepRemainders && flags == DC_EXEC) {
|
||||
BreakUpRemainders(remainder_chain);
|
||||
} else if (remainder_chain) {
|
||||
buy.AddCost(DoCommand(tile, remainder_chain->index | (1 << 20), 0, flags, CMD_SELL_VEHICLE));
|
||||
}
|
||||
|
||||
/* Redraw main gui for changed statistics */
|
||||
SetWindowClassesDirty(WC_TEMPLATEGUI_MAIN);
|
||||
|
||||
return buy;
|
||||
}
|
||||
|
Reference in New Issue
Block a user