Update to 14.0-beta1

This commit is contained in:
dP
2024-02-04 02:18:17 +05:30
parent 79037e2c65
commit 33ef333b57
1325 changed files with 138465 additions and 70987 deletions

View File

@@ -11,6 +11,7 @@
#include "error.h"
#include "articulated_vehicles.h"
#include "command_func.h"
#include "error_func.h"
#include "pathfinder/npf/npf_func.h"
#include "pathfinder/yapf/yapf.hpp"
#include "news_func.h"
@@ -36,6 +37,8 @@
#include "framerate_type.h"
#include "train_cmd.h"
#include "misc_cmd.h"
#include "timer/timer_game_calendar.h"
#include "timer/timer_game_economy.h"
#include "table/strings.h"
#include "table/train_sprites.h"
@@ -53,7 +56,7 @@ static const byte _vehicle_initial_x_fract[4] = {10, 8, 4, 8};
static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
template <>
bool IsValidImageIndex<VEH_TRAIN>(uint8 image_index)
bool IsValidImageIndex<VEH_TRAIN>(uint8_t image_index)
{
return image_index < lengthof(_engine_sprite_base);
}
@@ -107,7 +110,7 @@ void CheckTrainsLengths()
*/
void Train::ConsistChanged(ConsistChangeFlags allowed_changes)
{
uint16 max_speed = UINT16_MAX;
uint16_t max_speed = UINT16_MAX;
assert(this->IsFrontEngine() || this->IsFreeWagon());
@@ -184,12 +187,12 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes)
/* max speed is the minimum of the speed limits of all vehicles in the consist */
if ((rvi_u->railveh_type != RAILVEH_WAGON || _settings_game.vehicle.wagon_speed_limits) && !UsesWagonOverride(u)) {
uint16 speed = GetVehicleProperty(u, PROP_TRAIN_SPEED, rvi_u->max_speed);
uint16_t speed = GetVehicleProperty(u, PROP_TRAIN_SPEED, rvi_u->max_speed);
if (speed != 0) max_speed = std::min(speed, max_speed);
}
}
uint16 new_cap = e_u->DetermineCapacity(u);
uint16_t new_cap = e_u->DetermineCapacity(u);
if (allowed_changes & CCF_CAPACITY) {
/* Update vehicle capacity. */
if (u->cargo_cap > new_cap) u->cargo.Truncate(new_cap);
@@ -202,7 +205,7 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes)
u->vcache.cached_cargo_age_period = GetVehicleProperty(u, PROP_TRAIN_CARGO_AGE_PERIOD, e_u->info.cargo_age_period);
/* check the vehicle length (callback) */
uint16 veh_len = CALLBACK_FAILED;
uint16_t veh_len = CALLBACK_FAILED;
if (e_u->GetGRF() != nullptr && e_u->GetGRF()->grf_version >= 8) {
/* Use callback 36 */
veh_len = GetVehicleProperty(u, PROP_TRAIN_SHORTEN_FACTOR, CALLBACK_FAILED);
@@ -355,7 +358,7 @@ int Train::GetCurveSpeedLimit() const
if (max_speed != absolute_max_speed) {
/* Apply the current railtype's curve speed advantage */
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(this->tile));
const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(this->tile));
max_speed += (max_speed / 2) * rti->curve_speed;
if (this->tcache.cached_tilt) {
@@ -467,7 +470,7 @@ int Train::GetDisplayImageWidth(Point *offset) const
if (offset != nullptr) {
if (HasBit(this->flags, VRF_REVERSE_DIRECTION) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_RAIL_FLIPS)) {
offset->x = ScaleSpriteTrad((this->gcache.cached_veh_length - VEHICLE_LENGTH / 2) * reference_width / VEHICLE_LENGTH);
offset->x = ScaleSpriteTrad(((int)this->gcache.cached_veh_length - (int)VEHICLE_LENGTH / 2) * reference_width / (int)VEHICLE_LENGTH);
} else {
offset->x = ScaleSpriteTrad(reference_width) / 2;
}
@@ -476,7 +479,7 @@ int Train::GetDisplayImageWidth(Point *offset) const
return ScaleSpriteTrad(this->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH);
}
static SpriteID GetDefaultTrainSprite(uint8 spritenum, Direction direction)
static SpriteID GetDefaultTrainSprite(uint8_t spritenum, Direction direction)
{
assert(IsValidImageIndex<VEH_TRAIN>(spritenum));
return ((direction + _engine_sprite_add[spritenum]) & _engine_sprite_and[spritenum]) + _engine_sprite_base[spritenum];
@@ -490,7 +493,7 @@ static SpriteID GetDefaultTrainSprite(uint8 spritenum, Direction direction)
*/
void Train::GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const
{
uint8 spritenum = this->spritenum;
uint8_t spritenum = this->spritenum;
if (HasBit(this->flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction);
@@ -513,7 +516,7 @@ static void GetRailIcon(EngineID engine, bool rear_head, int &y, EngineImageType
{
const Engine *e = Engine::Get(engine);
Direction dir = rear_head ? DIR_E : DIR_W;
uint8 spritenum = e->u.rail.image_index;
uint8_t spritenum = e->u.rail.image_index;
if (is_custom_sprite(spritenum)) {
GetCustomVehicleIcon(engine, dir, image_type, result);
@@ -635,7 +638,7 @@ static CommandCost CmdBuildRailWagon(DoCommandFlag flags, TileIndex tile, const
v->x_pos = x;
v->y_pos = y;
v->z_pos = GetSlopePixelZ(x, y);
v->z_pos = GetSlopePixelZ(x, y, true);
v->owner = _current_company;
v->track = TRACK_BIT_DEPOT;
v->vehstatus = VS_HIDDEN | VS_DEFPAL;
@@ -651,13 +654,15 @@ static CommandCost CmdBuildRailWagon(DoCommandFlag flags, TileIndex tile, const
v->railtype = rvi->railtype;
v->date_of_last_service = _date;
v->build_year = _cur_year;
v->date_of_last_service = TimerGameEconomy::date;
v->date_of_last_service_newgrf = TimerGameCalendar::date;
v->build_year = TimerGameCalendar::year;
v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = VehicleRandomBits();
v->random_bits = Random();
v->group_id = DEFAULT_GROUP;
if (TestVehicleBuildProbability(v, v->engine_type, BuildProbabilityType::Reversed)) SetBit(v->flags, VRF_REVERSE_DIRECTION);
AddArticulatedParts(v);
v->UpdatePosition();
@@ -686,6 +691,7 @@ static CommandCost CmdBuildRailWagon(DoCommandFlag flags, TileIndex tile, const
/** Move all free vehicles in the depot to the train */
void NormalizeTrainVehInDepot(const Train *u)
{
assert(u->IsEngine());
for (const Train *v : Train::Iterate()) {
if (v->IsFreeWagon() && v->tile == u->tile &&
v->track == TRACK_BIT_DEPOT) {
@@ -717,12 +723,14 @@ static void AddRearEngineToMultiheadedTrain(Train *v)
u->railtype = v->railtype;
u->engine_type = v->engine_type;
u->date_of_last_service = v->date_of_last_service;
u->date_of_last_service_newgrf = v->date_of_last_service_newgrf;
u->build_year = v->build_year;
u->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
u->random_bits = VehicleRandomBits();
u->random_bits = Random();
v->SetMultiheaded();
u->SetMultiheaded();
v->SetNext(u);
if (TestVehicleBuildProbability(u, u->engine_type, BuildProbabilityType::Reversed)) SetBit(u->flags, VRF_REVERSE_DIRECTION);
u->UpdatePosition();
/* Now we need to link the front and rear engines together */
@@ -760,7 +768,7 @@ CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engin
v->owner = _current_company;
v->x_pos = x;
v->y_pos = y;
v->z_pos = GetSlopePixelZ(x, y);
v->z_pos = GetSlopePixelZ(x, y, true);
v->track = TRACK_BIT_DEPOT;
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
v->spritenum = rvi->image_index;
@@ -780,10 +788,11 @@ CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engin
v->railtype = rvi->railtype;
v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_trains);
v->date_of_last_service = _date;
v->build_year = _cur_year;
v->date_of_last_service = TimerGameEconomy::date;
v->date_of_last_service_newgrf = TimerGameCalendar::date;
v->build_year = TimerGameCalendar::year;
v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = VehicleRandomBits();
v->random_bits = Random();
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent);
@@ -793,6 +802,7 @@ CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engin
v->SetFrontEngine();
v->SetEngine();
if (TestVehicleBuildProbability(v, v->engine_type, BuildProbabilityType::Reversed)) SetBit(v->flags, VRF_REVERSE_DIRECTION);
v->UpdatePosition();
if (rvi->railveh_type == RAILVEH_MULTIHEAD) {
@@ -849,7 +859,7 @@ static void MakeTrainBackup(TrainList &list, Train *t)
static void RestoreTrainBackup(TrainList &list)
{
/* No train, nothing to do. */
if (list.size() == 0) return;
if (list.empty()) return;
Train *prev = nullptr;
/* Iterate over the list and rebuild it. */
@@ -1029,7 +1039,7 @@ static CommandCost CheckTrainAttachment(Train *t)
* the loop and after each callback does not need to be cleared here. */
t->InvalidateNewGRFCache();
uint16 callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, head->engine_type, t, head);
uint16_t callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, head->engine_type, t, head);
/* Restore original first_engine data */
t->gcache.first_engine = first_engine;
@@ -1197,7 +1207,7 @@ CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID
dst = Train::GetIfValid(dest_veh);
if (dst == nullptr) return CMD_ERROR;
CommandCost ret = CheckOwnership(dst->owner);
ret = CheckOwnership(dst->owner);
if (ret.Failed()) return ret;
/* Do not allow appending to crashed vehicles, too */
@@ -1266,7 +1276,7 @@ CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID
/* If the autoreplace flag is set we do not need to test for the validity
* because we are going to revert the train to its original state. As we
* assume the original state was correct autoreplace can skip this. */
CommandCost ret = ValidateTrains(original_dst_head, dst_head, original_src_head, src_head, true);
ret = ValidateTrains(original_dst_head, dst_head, original_src_head, src_head, true);
if (ret.Failed()) {
/* Restore the train we had. */
RestoreTrainBackup(original_src);
@@ -1315,10 +1325,15 @@ CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID
DeleteNewGRFInspectWindow(GSF_TRAINS, src->index);
SetWindowDirty(WC_COMPANY, _current_company);
/* Delete orders, group stuff and the unit number as we're not the
* front of any vehicle anymore. */
if (src_head != nullptr && src_head->IsFrontEngine()) {
/* Cases #?b: Transfer order, unit number and other stuff
* to the new front engine. */
src_head->orders = src->orders;
if (src_head->orders != nullptr) src_head->AddToShared(src);
src_head->CopyVehicleConfigAndStatistics(src);
}
/* Remove stuff not valid anymore for non-front engines. */
DeleteVehicleOrders(src);
RemoveVehicleFromGroup(src);
src->unitnumber = 0;
src->name.clear();
}
@@ -1411,16 +1426,18 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, bool sell_chain, b
/* First normalise the sub types of the chain. */
NormaliseSubtypes(new_head);
if (v == first && v->IsEngine() && !sell_chain && new_head != nullptr && new_head->IsFrontEngine()) {
/* We are selling the front engine. In this case we want to
* 'give' the order, unit number and such to the new head. */
new_head->orders = first->orders;
new_head->AddToShared(first);
DeleteVehicleOrders(first);
if (v == first && !sell_chain && new_head != nullptr && new_head->IsFrontEngine()) {
if (v->IsEngine()) {
/* We are selling the front engine. In this case we want to
* 'give' the order, unit number and such to the new head. */
new_head->orders = first->orders;
new_head->AddToShared(first);
DeleteVehicleOrders(first);
/* Copy other important data from the front engine */
new_head->CopyVehicleConfigAndStatistics(first);
GroupStatistics::CountVehicle(new_head, 1); // after copying over the profit
/* Copy other important data from the front engine */
new_head->CopyVehicleConfigAndStatistics(first);
}
GroupStatistics::CountVehicle(new_head, 1); // after copying over the profit, if required
} else if (v->IsPrimaryVehicle() && backup_order) {
OrderBackup::Backup(v, user);
}
@@ -1542,10 +1559,10 @@ static void MarkTrainAsStuck(Train *v)
* @param[in,out] swap_flag1 First train flag.
* @param[in,out] swap_flag2 Second train flag.
*/
static void SwapTrainFlags(uint16 *swap_flag1, uint16 *swap_flag2)
static void SwapTrainFlags(uint16_t *swap_flag1, uint16_t *swap_flag2)
{
uint16 flag1 = *swap_flag1;
uint16 flag2 = *swap_flag2;
uint16_t flag1 = *swap_flag1;
uint16_t flag2 = *swap_flag2;
/* Clear the flags */
ClrBit(*swap_flag1, GVF_GOINGUP_BIT);
@@ -1618,7 +1635,7 @@ void ReverseTrainSwapVeh(Train *v, int l, int r)
if (a != b) {
/* swap the hidden bits */
{
uint16 tmp = (a->vehstatus & ~VS_HIDDEN) | (b->vehstatus & VS_HIDDEN);
uint16_t tmp = (a->vehstatus & ~VS_HIDDEN) | (b->vehstatus & VS_HIDDEN);
b->vehstatus = (b->vehstatus & ~VS_HIDDEN) | (a->vehstatus & VS_HIDDEN);
a->vehstatus = tmp;
}
@@ -1762,7 +1779,7 @@ void UpdateLevelCrossing(TileIndex tile, bool sound, bool force_bar)
/* Check if an adjacent crossing is barred. */
for (DiagDirection dir : { dir1, dir2 }) {
for (TileIndex t = tile; !forced_state && t < MapSize() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == axis; t = TileAddByDiagDir(t, dir)) {
for (TileIndex t = tile; !forced_state && t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == axis; t = TileAddByDiagDir(t, dir)) {
forced_state |= CheckLevelCrossing(t);
}
}
@@ -1771,7 +1788,7 @@ void UpdateLevelCrossing(TileIndex tile, bool sound, bool force_bar)
* we need to update those tiles. We start with the tile itself, then look along the road axis. */
UpdateLevelCrossingTile(tile, sound, forced_state);
for (DiagDirection dir : { dir1, dir2 }) {
for (TileIndex t = TileAddByDiagDir(tile, dir); t < MapSize() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == axis; t = TileAddByDiagDir(t, dir)) {
for (TileIndex t = TileAddByDiagDir(tile, dir); t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == axis; t = TileAddByDiagDir(t, dir)) {
UpdateLevelCrossingTile(t, sound, forced_state);
}
}
@@ -1788,7 +1805,7 @@ void MarkDirtyAdjacentLevelCrossingTiles(TileIndex tile, Axis road_axis)
const DiagDirection dir2 = ReverseDiagDir(dir1);
for (DiagDirection dir : { dir1, dir2 }) {
const TileIndex t = TileAddByDiagDir(tile, dir);
if (t < MapSize() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis) {
if (t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis) {
MarkTileDirtyByTile(t);
}
}
@@ -1806,18 +1823,18 @@ void UpdateAdjacentLevelCrossingTilesOnLevelCrossingRemoval(TileIndex tile, Axis
for (DiagDirection dir : { dir1, dir2 }) {
const TileIndexDiff diff = TileOffsByDiagDir(dir);
bool occupied = false;
for (TileIndex t = tile + diff; t < MapSize() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis; t += diff) {
for (TileIndex t = tile + diff; t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis; t += diff) {
occupied |= CheckLevelCrossing(t);
}
if (occupied) {
/* Mark the immediately adjacent tile dirty */
const TileIndex t = tile + diff;
if (t < MapSize() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis) {
if (t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis) {
MarkTileDirtyByTile(t);
}
} else {
/* Unbar the crossing tiles in this direction as necessary */
for (TileIndex t = tile + diff; t < MapSize() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis; t += diff) {
for (TileIndex t = tile + diff; t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis; t += diff) {
if (IsCrossingBarred(t)) {
/* The crossing tile is barred, unbar it and continue to check the next tile */
SetCrossingBarred(t, false);
@@ -2095,6 +2112,9 @@ CommandCost CmdReverseTrainDirection(DoCommandFlag flags, VehicleID veh_id, bool
HideFillingPercent(&v->fill_percent_te_id);
ReverseTrainDirection(v);
}
/* Unbunching data is no longer valid. */
v->ResetDepotUnbunching();
}
}
return CommandCost();
@@ -2125,6 +2145,9 @@ CommandCost CmdForceTrainProceed(DoCommandFlag flags, VehicleID veh_id)
* next signal we encounter. */
t->force_proceed = t->force_proceed == TFP_SIGNAL ? TFP_NONE : HasBit(t->flags, VRF_TRAIN_STUCK) || t->IsChainInDepot() ? TFP_STUCK : TFP_SIGNAL;
SetWindowDirty(WC_VEHICLE_VIEW, t->index);
/* Unbunching data is no longer valid. */
t->ResetDepotUnbunching();
}
return CommandCost();
@@ -2154,23 +2177,12 @@ static FindDepotData FindClosestTrainDepot(Train *v, int max_distance)
}
}
/**
* Locate the closest depot for this consist, and return the information to the caller.
* @param[out] location If not \c nullptr and a depot is found, store its location in the given address.
* @param[out] destination If not \c nullptr and a depot is found, store its index in the given address.
* @param[out] reverse If not \c nullptr and a depot is found, store reversal information in the given address.
* @return A depot has been found.
*/
bool Train::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
ClosestDepot Train::FindClosestDepot()
{
FindDepotData tfdd = FindClosestTrainDepot(this, 0);
if (tfdd.best_length == UINT_MAX) return false;
if (tfdd.best_length == UINT_MAX) return ClosestDepot();
if (location != nullptr) *location = tfdd.tile;
if (destination != nullptr) *destination = GetDepotIndex(tfdd.tile);
if (reverse != nullptr) *reverse = tfdd.reverse;
return true;
return ClosestDepot(tfdd.tile, GetDepotIndex(tfdd.tile), tfdd.reverse);
}
/** Play a sound for a train leaving the station. */
@@ -2269,6 +2281,9 @@ static bool CheckTrainStayInDepot(Train *v)
return true;
}
/* Check if we should wait here for unbunching. */
if (v->IsWaitingForUnbunching()) return true;
SigSegState seg_state;
if (v->force_proceed == TFP_NONE) {
@@ -2309,8 +2324,9 @@ static bool CheckTrainStayInDepot(Train *v)
if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(v->tile);
VehicleServiceInDepot(v);
SetWindowClassesDirty(WC_TRAINS_LIST);
v->LeaveUnbunchingDepot();
v->PlayLeaveStationSound();
SetWindowClassesDirty(WC_TRAINS_LIST);
v->track = TRACK_BIT_X;
if (v->direction & 2) v->track = TRACK_BIT_Y;
@@ -2638,7 +2654,7 @@ public:
case OT_GOTO_DEPOT:
/* Skip service in depot orders when the train doesn't need service. */
if ((order->GetDepotOrderType() & ODTFB_SERVICE) && !this->v->NeedsServicing()) break;
FALLTHROUGH;
[[fallthrough]];
case OT_GOTO_STATION:
case OT_GOTO_WAYPOINT:
this->v->current_order = *order;
@@ -3046,7 +3062,7 @@ static inline void AffectSpeedByZChange(Train *v, int old_z)
if (old_z < v->z_pos) {
v->cur_speed -= (v->cur_speed * asp->z_up >> 8);
} else {
uint16 spd = v->cur_speed + asp->z_down;
uint16_t spd = v->cur_speed + asp->z_down;
if (spd <= v->gcache.cached_max_track_speed) v->cur_speed = spd;
}
}
@@ -3282,7 +3298,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
/* Reverse when we are at the end of the track already, do not move to the new position */
if (v->IsFrontEngine() && !TrainCheckIfLineEnds(v, reverse)) return false;
uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
uint32_t r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
if (HasBit(r, VETS_CANNOT_ENTER)) {
goto invalid_rail;
}
@@ -3354,12 +3370,12 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
v->cur_speed = 0;
v->subspeed = 0;
v->progress = 255; // make sure that every bit of acceleration will hit the signal again, so speed stays 0.
if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_oneway_signal * DAY_TICKS * 2) return false;
if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_oneway_signal * Ticks::DAY_TICKS * 2) return false;
} else if (HasSignalOnTrackdir(gp.new_tile, i)) {
v->cur_speed = 0;
v->subspeed = 0;
v->progress = 255; // make sure that every bit of acceleration will hit the signal again, so speed stays 0.
if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_twoway_signal * DAY_TICKS * 2) {
if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_twoway_signal * Ticks::DAY_TICKS * 2) {
DiagDirection exitdir = TrackdirToExitdir(i);
TileIndex o_tile = TileAddByDiagDir(gp.new_tile, exitdir);
@@ -3423,13 +3439,13 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
chosen_track == TRACK_BIT_LEFT || chosen_track == TRACK_BIT_RIGHT);
/* Update XY to reflect the entrance to the new tile, and select the direction to use */
const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir];
const byte *b = _initial_tile_subcoord[FindFirstBit(chosen_track)][enterdir];
gp.x = (gp.x & ~0xF) | b[0];
gp.y = (gp.y & ~0xF) | b[1];
Direction chosen_dir = (Direction)b[2];
/* Call the landscape function and tell it that the vehicle entered the tile */
uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
uint32_t r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
if (HasBit(r, VETS_CANNOT_ENTER)) {
goto invalid_rail;
}
@@ -3558,7 +3574,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
invalid_rail:
/* We've reached end of line?? */
if (prev != nullptr) error("Disconnecting train");
if (prev != nullptr) FatalError("Disconnecting train");
reverse_train_direction:
if (reverse) {
@@ -3721,7 +3737,7 @@ static bool HandleCrashedTrain(Train *v)
CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
}
uint32 r;
uint32_t r;
if (state <= 200 && Chance16R(1, 7, r)) {
int index = (r * 10 >> 16);
@@ -3752,7 +3768,7 @@ static bool HandleCrashedTrain(Train *v)
}
/** Maximum speeds for train that is broken down or approaching line end */
static const uint16 _breakdown_speeds[16] = {
static const uint16_t _breakdown_speeds[16] = {
225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
};
@@ -3775,7 +3791,7 @@ static bool TrainApproachingLineEnd(Train *v, bool signal, bool reverse)
* for other directions, it will be 1, 3, 5, ..., 15 */
switch (v->direction) {
case DIR_N : x = ~x + ~y + 25; break;
case DIR_NW: x = y; FALLTHROUGH;
case DIR_NW: x = y; [[fallthrough]];
case DIR_NE: x = ~x + 16; break;
case DIR_E : x = ~x + y + 9; break;
case DIR_SE: x = y; break;
@@ -3798,7 +3814,7 @@ static bool TrainApproachingLineEnd(Train *v, bool signal, bool reverse)
/* slow down */
v->vehstatus |= VS_TRAIN_SLOWING;
uint16 break_speed = _breakdown_speeds[x & 0xF];
uint16_t break_speed = _breakdown_speeds[x & 0xF];
if (break_speed < v->cur_speed) v->cur_speed = break_speed;
return true;
@@ -3875,7 +3891,7 @@ static bool TrainCheckIfLineEnds(Train *v, bool reverse)
if (t > 1) {
v->vehstatus |= VS_TRAIN_SLOWING;
uint16 break_speed = _breakdown_speeds[GB(~t, 4, 4)];
uint16_t break_speed = _breakdown_speeds[GB(~t, 4, 4)];
if (break_speed < v->cur_speed) v->cur_speed = break_speed;
} else {
v->vehstatus &= ~VS_TRAIN_SLOWING;
@@ -3979,14 +3995,14 @@ static bool TrainLocoHandler(Train *v, bool mode)
++v->wait_counter;
/* Should we try reversing this tick if still stuck? */
bool turn_around = v->wait_counter % (_settings_game.pf.wait_for_pbs_path * DAY_TICKS) == 0 && _settings_game.pf.reverse_at_signals;
bool turn_around = v->wait_counter % (_settings_game.pf.wait_for_pbs_path * Ticks::DAY_TICKS) == 0 && _settings_game.pf.reverse_at_signals;
if (!turn_around && v->wait_counter % _settings_game.pf.path_backoff_interval != 0 && v->force_proceed == TFP_NONE) return true;
if (!TryPathReserve(v)) {
/* Still stuck. */
if (turn_around) ReverseTrainDirection(v);
if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->wait_counter > 2 * _settings_game.pf.wait_for_pbs_path * DAY_TICKS) {
if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->wait_counter > 2 * _settings_game.pf.wait_for_pbs_path * Ticks::DAY_TICKS) {
/* Show message to player. */
if (_settings_client.gui.lost_vehicle_warn && v->owner == _local_company) {
SetDParam(0, v->index);
@@ -4158,11 +4174,15 @@ static void CheckIfTrainNeedsService(Train *v)
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
}
/** Update day counters of the train vehicle. */
void Train::OnNewDay()
/** Calendar day handler. */
void Train::OnNewCalendarDay()
{
AgeVehicle(this);
}
/** Economy day handler. */
void Train::OnNewEconomyDay()
{
if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
if (this->IsFrontEngine()) {
@@ -4180,7 +4200,7 @@ void Train::OnNewDay()
if (this->running_ticks != 0) {
/* running costs */
CommandCost cost(EXPENSES_TRAIN_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS));
CommandCost cost(EXPENSES_TRAIN_RUN, this->GetRunningCost() * this->running_ticks / (CalendarTime::DAYS_IN_YEAR * Ticks::DAY_TICKS));
this->profit_this_year -= cost.GetCost();
this->running_ticks = 0;
@@ -4214,9 +4234,9 @@ Trackdir Train::GetVehicleTrackdir() const
return TrackDirectionToTrackdir(FindFirstTrack(this->track), this->direction);
}
uint16 Train::GetMaxWeight() const
uint16_t Train::GetMaxWeight() const
{
uint16 weight = CargoSpec::Get(this->cargo_type)->WeightOfNUnitsInTrain(this->GetEngine()->DetermineCapacity(this));
uint16_t weight = CargoSpec::Get(this->cargo_type)->WeightOfNUnitsInTrain(this->GetEngine()->DetermineCapacity(this));
/* Vehicle weight is not added for articulated parts. */
if (!this->IsArticulatedPart()) {