|
@@ -127,14 +127,14 @@ void TrainPowerChanged(Train *v)
|
|
|
if (v->tcache.cached_power != total_power || v->tcache.cached_max_te != max_te) {
|
|
|
/* If it has no power (no catenary), stop the train */
|
|
|
if (total_power == 0) v->vehstatus |= VS_STOPPED;
|
|
|
|
|
|
v->tcache.cached_power = total_power;
|
|
|
v->tcache.cached_max_te = max_te;
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* Recalculates the cached weight of a train and its vehicles. Should be called each time the cargo on
|
|
@@ -352,13 +352,13 @@ void TrainConsistChanged(Train *v, bool
|
|
|
|
|
|
/* recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) */
|
|
|
TrainCargoChanged(v);
|
|
|
|
|
|
if (v->IsFrontEngine()) {
|
|
|
UpdateTrainAcceleration(v);
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
|
|
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
enum AccelType {
|
|
|
AM_ACCEL,
|
|
|
AM_BRAKE
|
|
@@ -765,13 +765,13 @@ static CommandCost CmdBuildRailWagon(Eng
|
|
|
_new_vehicle_id = v->index;
|
|
|
|
|
|
VehicleMove(v, false);
|
|
|
TrainConsistChanged(v->First(), false);
|
|
|
UpdateTrainGroupID(v->First());
|
|
|
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
|
|
|
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
|
|
|
if (IsLocalCompany()) {
|
|
|
InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Train window
|
|
|
}
|
|
|
Company::Get(_current_company)->num_engines[engine]++;
|
|
|
|
|
|
CheckConsistencyOfArticulatedVehicle(v);
|
|
@@ -936,13 +936,13 @@ CommandCost CmdBuildRailVehicle(TileInde
|
|
|
if (!HasBit(p2, 1) && !(flags & DC_AUTOREPLACE)) { // check if the cars should be added to the new vehicle
|
|
|
NormalizeTrainVehInDepot(v);
|
|
|
}
|
|
|
|
|
|
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
|
|
|
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
|
|
InvalidateWindow(WC_COMPANY, v->owner);
|
|
|
SetWindowDirty(WC_COMPANY, v->owner);
|
|
|
if (IsLocalCompany()) {
|
|
|
InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Train window
|
|
|
}
|
|
|
|
|
|
Company::Get(_current_company)->num_engines[p1]++;
|
|
|
|
|
@@ -1403,30 +1403,30 @@ CommandCost CmdMoveRailVehicle(TileIndex
|
|
|
if (src_head != NULL) {
|
|
|
NormaliseTrainConsist(src_head);
|
|
|
TrainConsistChanged(src_head, false);
|
|
|
UpdateTrainGroupID(src_head);
|
|
|
if (src_head->IsFrontEngine()) {
|
|
|
/* Update the refit button and window */
|
|
|
InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, VVW_WIDGET_REFIT_VEH);
|
|
|
SetWindowDirty(WC_VEHICLE_REFIT, src_head->index);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, src_head->index, VVW_WIDGET_REFIT_VEH);
|
|
|
}
|
|
|
/* Update the depot window */
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
|
|
|
SetWindowDirty(WC_VEHICLE_DEPOT, src_head->tile);
|
|
|
}
|
|
|
|
|
|
if (dst_head != NULL) {
|
|
|
NormaliseTrainConsist(dst_head);
|
|
|
TrainConsistChanged(dst_head, false);
|
|
|
UpdateTrainGroupID(dst_head);
|
|
|
if (dst_head->IsFrontEngine()) {
|
|
|
/* Update the refit button and window */
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, VVW_WIDGET_REFIT_VEH);
|
|
|
InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, dst_head->index, VVW_WIDGET_REFIT_VEH);
|
|
|
SetWindowDirty(WC_VEHICLE_REFIT, dst_head->index);
|
|
|
}
|
|
|
/* Update the depot window */
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, dst_head->tile);
|
|
|
SetWindowDirty(WC_VEHICLE_DEPOT, dst_head->tile);
|
|
|
}
|
|
|
|
|
|
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
|
|
}
|
|
|
|
|
|
return CommandCost();
|
|
@@ -1467,13 +1467,13 @@ CommandCost CmdSellRailWagon(TileIndex t
|
|
|
DeleteWindowById(WC_VEHICLE_VIEW, first->index);
|
|
|
DeleteWindowById(WC_VEHICLE_ORDERS, first->index);
|
|
|
DeleteWindowById(WC_VEHICLE_REFIT, first->index);
|
|
|
DeleteWindowById(WC_VEHICLE_DETAILS, first->index);
|
|
|
DeleteWindowById(WC_VEHICLE_TIMETABLE, first->index);
|
|
|
}
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
|
|
|
SetWindowDirty(WC_VEHICLE_DEPOT, first->tile);
|
|
|
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
|
|
}
|
|
|
|
|
|
CommandCost cost(EXPENSES_NEW_VEHICLES);
|
|
|
switch (p2) {
|
|
|
case 0: { // Delete given wagon
|
|
@@ -1543,13 +1543,13 @@ CommandCost CmdSellRailWagon(TileIndex t
|
|
|
|
|
|
/* 5. If the train still exists, update its acceleration, window, etc. */
|
|
|
if (first != NULL) {
|
|
|
NormaliseTrainConsist(first);
|
|
|
TrainConsistChanged(first, false);
|
|
|
UpdateTrainGroupID(first);
|
|
|
if (first->IsFrontEngine()) InvalidateWindow(WC_VEHICLE_REFIT, first->index);
|
|
|
if (first->IsFrontEngine()) SetWindowDirty(WC_VEHICLE_REFIT, first->index);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
} break;
|
|
|
case 1: { // Delete wagon and all wagons after it given certain criteria
|
|
|
/* Start deleting every vehicle after the selected one
|
|
@@ -1594,13 +1594,13 @@ CommandCost CmdSellRailWagon(TileIndex t
|
|
|
|
|
|
/* 3. If it is still a valid train after selling, update its acceleration and cached values */
|
|
|
if ((flags & DC_EXEC) && first != NULL) {
|
|
|
NormaliseTrainConsist(first);
|
|
|
TrainConsistChanged(first, false);
|
|
|
UpdateTrainGroupID(first);
|
|
|
InvalidateWindow(WC_VEHICLE_REFIT, first->index);
|
|
|
SetWindowDirty(WC_VEHICLE_REFIT, first->index);
|
|
|
}
|
|
|
} break;
|
|
|
}
|
|
|
return cost;
|
|
|
}
|
|
|
|
|
@@ -1630,13 +1630,13 @@ void Train::UpdateDeltaXY(Direction dire
|
|
|
static inline void SetLastSpeed(Train *v, int spd)
|
|
|
{
|
|
|
int old = v->tcache.last_speed;
|
|
|
if (spd != old) {
|
|
|
v->tcache.last_speed = spd;
|
|
|
if (_settings_client.gui.vehicle_speed || (old == 0) != (spd == 0)) {
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/** Mark a train as stuck and stop it if it isn't stopped right now. */
|
|
|
static void MarkTrainAsStuck(Train *v)
|
|
@@ -1652,13 +1652,13 @@ static void MarkTrainAsStuck(Train *v)
|
|
|
|
|
|
/* Stop train */
|
|
|
v->cur_speed = 0;
|
|
|
v->subspeed = 0;
|
|
|
SetLastSpeed(v, 0);
|
|
|
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void SwapTrainFlags(uint16 *swap_flag1, uint16 *swap_flag2)
|
|
|
{
|
|
|
uint16 flag1 = *swap_flag1;
|
|
@@ -1957,13 +1957,13 @@ static void ReverseTrainDirection(Train
|
|
|
crossing = TrainApproachingCrossingTile(v);
|
|
|
if (crossing != INVALID_TILE) MaybeBarCrossingWithSound(crossing);
|
|
|
|
|
|
/* If we are inside a depot after reversing, don't bother with path reserving. */
|
|
|
if (v->track == TRACK_BIT_DEPOT) {
|
|
|
/* Can't be stuck here as inside a depot is always a safe tile. */
|
|
|
if (HasBit(v->flags, VRF_TRAIN_STUCK)) InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
if (HasBit(v->flags, VRF_TRAIN_STUCK)) SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* TrainExitDir does not always produce the desired dir for depots and
|
|
|
* tunnels/bridges that is needed for UpdateSignalsOnSegment. */
|
|
@@ -2015,14 +2015,14 @@ CommandCost CmdReverseTrainDirection(Til
|
|
|
if (CheckTrainStoppedInDepot(front) < 0) {
|
|
|
return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
|
|
|
}
|
|
|
|
|
|
if (flags & DC_EXEC) {
|
|
|
ToggleBit(v->flags, VRF_REVERSE_DIRECTION);
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
|
|
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
|
|
|
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
|
|
|
}
|
|
|
} else {
|
|
|
/* turn the whole train around */
|
|
|
if ((v->vehstatus & VS_CRASHED) || v->breakdown_ctr != 0) return CMD_ERROR;
|
|
|
|
|
|
if (flags & DC_EXEC) {
|
|
@@ -2145,14 +2145,14 @@ CommandCost CmdRefitRailVehicle(TileInde
|
|
|
num += amount;
|
|
|
if (flags & DC_EXEC) {
|
|
|
v->cargo.Truncate((v->cargo_type == new_cid) ? amount : 0);
|
|
|
v->cargo_type = new_cid;
|
|
|
v->cargo_cap = amount;
|
|
|
v->cargo_subtype = new_subtype;
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
|
|
|
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
|
|
|
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
|
|
|
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
|
|
}
|
|
|
}
|
|
|
} while ((v = v->Next()) != NULL && !only_this);
|
|
|
|
|
|
_returned_refit_capacity = num;
|
|
@@ -2434,31 +2434,31 @@ static bool CheckTrainStayInDepot(Train
|
|
|
if (u->track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
|
|
|
}
|
|
|
|
|
|
/* if the train got no power, then keep it in the depot */
|
|
|
if (v->tcache.cached_power == 0) {
|
|
|
v->vehstatus |= VS_STOPPED;
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
|
|
|
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
SigSegState seg_state;
|
|
|
|
|
|
if (v->force_proceed == 0) {
|
|
|
/* force proceed was not pressed */
|
|
|
if (++v->load_unload_time_rem < 37) {
|
|
|
InvalidateWindowClasses(WC_TRAINS_LIST);
|
|
|
SetWindowClassesDirty(WC_TRAINS_LIST);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
v->load_unload_time_rem = 0;
|
|
|
|
|
|
seg_state = _settings_game.pf.reserve_paths ? SIGSEG_PBS : UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
|
|
|
if (seg_state == SIGSEG_FULL || HasDepotReservation(v->tile)) {
|
|
|
/* Full and no PBS signal in block or depot reserved, can't exit. */
|
|
|
InvalidateWindowClasses(WC_TRAINS_LIST);
|
|
|
SetWindowClassesDirty(WC_TRAINS_LIST);
|
|
|
return true;
|
|
|
}
|
|
|
} else {
|
|
|
seg_state = _settings_game.pf.reserve_paths ? SIGSEG_PBS : UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
|
|
|
}
|
|
|
|
|
@@ -2471,22 +2471,22 @@ static bool CheckTrainStayInDepot(Train
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* Only leave when we can reserve a path to our destination. */
|
|
|
if (seg_state == SIGSEG_PBS && !TryPathReserve(v) && v->force_proceed == 0) {
|
|
|
/* No path and no force proceed. */
|
|
|
InvalidateWindowClasses(WC_TRAINS_LIST);
|
|
|
SetWindowClassesDirty(WC_TRAINS_LIST);
|
|
|
MarkTrainAsStuck(v);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
SetDepotReservation(v->tile, true);
|
|
|
if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(v->tile);
|
|
|
|
|
|
VehicleServiceInDepot(v);
|
|
|
InvalidateWindowClasses(WC_TRAINS_LIST);
|
|
|
SetWindowClassesDirty(WC_TRAINS_LIST);
|
|
|
v->PlayLeaveStationSound();
|
|
|
|
|
|
v->track = TRACK_BIT_X;
|
|
|
if (v->direction & 2) v->track = TRACK_BIT_Y;
|
|
|
|
|
|
v->vehstatus &= ~VS_HIDDEN;
|
|
@@ -3166,13 +3166,13 @@ bool TryPathReserve(Train *v, bool mark_
|
|
|
if (mark_as_stuck) MarkTrainAsStuck(v);
|
|
|
return false;
|
|
|
}
|
|
|
/* If we have a reserved path and the path ends at a safe tile, we are finished already. */
|
|
|
if (origin.okay && (v->tile != origin.tile || first_tile_okay)) {
|
|
|
/* Can't be stuck then. */
|
|
|
if (HasBit(v->flags, VRF_TRAIN_STUCK)) InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
if (HasBit(v->flags, VRF_TRAIN_STUCK)) SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* If we are in a depot, tentativly reserve the depot. */
|
|
|
if (v->track == TRACK_BIT_DEPOT) {
|
|
@@ -3194,13 +3194,13 @@ bool TryPathReserve(Train *v, bool mark_
|
|
|
if (v->track == TRACK_BIT_DEPOT) SetDepotReservation(v->tile, false);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (HasBit(v->flags, VRF_TRAIN_STUCK)) {
|
|
|
v->load_unload_time_rem = 0;
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -3533,17 +3533,17 @@ static void SetVehicleCrashed(Train *v)
|
|
|
|
|
|
/* we may need to update crossing we were approaching */
|
|
|
TileIndex crossing = TrainApproachingCrossingTile(v);
|
|
|
|
|
|
v->crash_anim_pos++;
|
|
|
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
|
|
|
|
|
|
if (v->track == TRACK_BIT_DEPOT) {
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
|
|
|
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
|
|
|
}
|
|
|
|
|
|
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
|
|
|
|
|
for (; v != NULL; v = v->Next()) {
|
|
|
v->vehstatus |= VS_CRASHED;
|
|
@@ -4021,13 +4021,13 @@ static void DeleteLastWagon(Train *v)
|
|
|
if (first != v) {
|
|
|
/* Recalculate cached train properties */
|
|
|
TrainConsistChanged(first, false);
|
|
|
/* Update the depot window if the first vehicle is in depot -
|
|
|
* if v == first, then it is updated in PreDestructor() */
|
|
|
if (first->track == TRACK_BIT_DEPOT) {
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
|
|
|
SetWindowDirty(WC_VEHICLE_DEPOT, first->tile);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 'v' shouldn't be accessed after it has been deleted */
|
|
|
TrackBits trackbits = v->track;
|
|
|
TileIndex tile = v->tile;
|
|
@@ -4118,13 +4118,13 @@ static bool HandleCrashedTrain(Train *v)
|
|
|
|
|
|
if (state <= 240 && !(v->tick_counter & 3)) ChangeTrainDirRandomly(v);
|
|
|
|
|
|
if (state >= 4440 && !(v->tick_counter & 0x1F)) {
|
|
|
bool ret = v->Next() != NULL;
|
|
|
DeleteLastWagon(v);
|
|
|
InvalidateWindow(WC_REPLACE_VEHICLE, (v->group_id << 16) | VEH_TRAIN);
|
|
|
SetWindowDirty(WC_REPLACE_VEHICLE, (v->group_id << 16) | VEH_TRAIN);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -4134,14 +4134,14 @@ static void HandleBrokenTrain(Train *v)
|
|
|
v->breakdown_ctr = 1;
|
|
|
v->cur_speed = 0;
|
|
|
|
|
|
if (v->breakdowns_since_last_service != 255)
|
|
|
v->breakdowns_since_last_service++;
|
|
|
|
|
|
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
|
|
SetWindowDirty(WC_VEHICLE_VIEW, v->index);
|
|
|
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
|
|
|
|
|
|
if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
|
|
|
SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
|
|
|
SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
|
|
|
}
|
|
|
|
|
@@ -4151,13 +4151,13 @@ static void HandleBrokenTrain(Train *v)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!(v->tick_counter & 3)) {
|
|
|
if (!--v->breakdown_delay) {
|
|
|
v->breakdown_ctr = 0;
|
|
|
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
|
|
SetWindowDirty(WC_VEHICLE_VIEW, v->index);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/** Maximum speeds for train that is broken down or approaching line end */
|
|
|
static const uint16 _breakdown_speeds[16] = {
|
|
@@ -4327,13 +4327,13 @@ static bool TrainLocoHandler(Train *v, b
|
|
|
return mode ? true : HandleCrashedTrain(v); // 'this' can be deleted here
|
|
|
}
|
|
|
|
|
|
if (v->force_proceed != 0) {
|
|
|
v->force_proceed--;
|
|
|
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
|
|
|
/* train is broken down? */
|
|
|
if (v->breakdown_ctr != 0) {
|
|
|
if (v->breakdown_ctr <= 2) {
|
|
|
HandleBrokenTrain(v);
|
|
@@ -4396,27 +4396,27 @@ static bool TrainLocoHandler(Train *v, b
|
|
|
v->load_unload_time_rem = 0;
|
|
|
}
|
|
|
/* Exit if force proceed not pressed, else reset stuck flag anyway. */
|
|
|
if (v->force_proceed == 0) return true;
|
|
|
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
v->load_unload_time_rem = 0;
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (v->current_order.IsType(OT_LEAVESTATION)) {
|
|
|
v->current_order.Free();
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
int j = UpdateTrainSpeed(v);
|
|
|
|
|
|
/* we need to invalidate the widget if we are stopping from 'Stopping 0 km/h' to 'Stopped' */
|
|
|
if (v->cur_speed == 0 && v->tcache.last_speed == 0 && (v->vehstatus & VS_STOPPED)) {
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
|
|
|
int adv_spd = (v->direction & 1) ? 192 : 256;
|
|
|
if (j < adv_spd) {
|
|
|
/* if the vehicle has speed 0, update the last_speed field. */
|
|
|
if (v->cur_speed == 0) SetLastSpeed(v, v->cur_speed);
|
|
@@ -4518,13 +4518,13 @@ static void CheckIfTrainNeedsService(Tra
|
|
|
if (tfdd.best_length == UINT_MAX || tfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) {
|
|
|
if (v->current_order.IsType(OT_GOTO_DEPOT)) {
|
|
|
/* If we were already heading for a depot but it has
|
|
|
* suddenly moved farther away, we continue our normal
|
|
|
* schedule? */
|
|
|
v->current_order.MakeDummy();
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
DepotID depot = GetDepotIndex(tfdd.tile);
|
|
|
|
|
@@ -4533,13 +4533,13 @@ static void CheckIfTrainNeedsService(Tra
|
|
|
!Chance16(3, 16)) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
v->current_order.MakeGoToDepot(depot, ODTFB_SERVICE);
|
|
|
v->dest_tile = tfdd.tile;
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
|
|
|
void Train::OnNewDay()
|
|
|
{
|
|
|
if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
|
|
|
|
|
@@ -4563,14 +4563,14 @@ void Train::OnNewDay()
|
|
|
|
|
|
this->profit_this_year -= cost.GetCost();
|
|
|
this->running_ticks = 0;
|
|
|
|
|
|
SubtractMoneyFromCompanyFract(this->owner, cost);
|
|
|
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
|
|
|
InvalidateWindowClasses(WC_TRAINS_LIST);
|
|
|
SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
|
|
|
SetWindowClassesDirty(WC_TRAINS_LIST);
|
|
|
}
|
|
|
} else if (this->IsEngine()) {
|
|
|
/* Also age engines that aren't front engines */
|
|
|
AgeVehicle(this);
|
|
|
}
|
|
|
}
|