Merge remote-tracking branch 'upstream/master'

This commit is contained in:
dP
2025-06-14 17:01:17 +05:00
1132 changed files with 59429 additions and 52888 deletions
+59 -62
View File
@@ -82,7 +82,7 @@ static const Trackdir _road_reverse_table[DIAGDIR_END] = {
bool RoadVehicle::IsBus() const
{
assert(this->IsFrontEngine());
return IsCargoInClass(this->cargo_type, CC_PASSENGERS);
return IsCargoInClass(this->cargo_type, CargoClass::Passengers);
}
/**
@@ -229,7 +229,7 @@ void RoadVehUpdateCache(RoadVehicle *v, bool same_length)
assert(u->First() == v);
/* Update the 'first engine' */
u->gcache.first_engine = (v == u) ? INVALID_ENGINE : v->engine_type;
u->gcache.first_engine = (v == u) ? EngineID::Invalid() : v->engine_type;
/* Update the length of the vehicle. */
uint veh_len = GetRoadVehLength(u);
@@ -258,14 +258,14 @@ void RoadVehUpdateCache(RoadVehicle *v, bool same_length)
* @param[out] ret the vehicle that has been built.
* @return the cost of this operation or an error.
*/
CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **ret)
CommandCost CmdBuildRoadVehicle(DoCommandFlags flags, TileIndex tile, const Engine *e, Vehicle **ret)
{
/* Check that the vehicle can drive on the road in question */
RoadType rt = e->u.road.roadtype;
const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
if (!HasTileAnyRoadType(tile, rti->powered_roadtypes)) return CommandCost(STR_ERROR_DEPOT_WRONG_DEPOT_TYPE);
if (flags & DC_EXEC) {
if (flags.Test(DoCommandFlag::Execute)) {
const RoadVehicleInfo *rvi = &e->u.road;
RoadVehicle *v = new RoadVehicle();
@@ -281,18 +281,18 @@ CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engin
v->z_pos = GetSlopePixelZ(x, y, true);
v->state = RVSB_IN_DEPOT;
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
v->vehstatus = {VehState::Hidden, VehState::Stopped, VehState::DefaultPalette};
v->spritenum = rvi->image_index;
v->cargo_type = e->GetDefaultCargoType();
assert(IsValidCargoID(v->cargo_type));
assert(IsValidCargoType(v->cargo_type));
v->cargo_cap = rvi->capacity;
v->refit_cap = 0;
v->last_station_visited = INVALID_STATION;
v->last_loading_station = INVALID_STATION;
v->last_station_visited = StationID::Invalid();
v->last_loading_station = StationID::Invalid();
v->engine_type = e->index;
v->gcache.first_engine = INVALID_ENGINE; // needs to be set before first callback
v->gcache.first_engine = EngineID::Invalid(); // needs to be set before first callback
v->reliability = e->reliability;
v->reliability_spd_dec = e->reliability_spd_dec;
@@ -312,7 +312,7 @@ CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engin
v->compatible_roadtypes = rti->powered_roadtypes;
v->gcache.cached_veh_length = VEHICLE_LENGTH;
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
if (e->flags.Test(EngineFlag::ExclusivePreview)) v->vehicle_flags.Set(VehicleFlag::BuiltAsPrototype);
v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent);
AddArticulatedParts(v);
@@ -358,7 +358,7 @@ ClosestDepot RoadVehicle::FindClosestDepot()
* @param veh_id vehicle ID to turn
* @return the cost of this operation or an error
*/
CommandCost CmdTurnRoadVeh(DoCommandFlag flags, VehicleID veh_id)
CommandCost CmdTurnRoadVeh(DoCommandFlags flags, VehicleID veh_id)
{
RoadVehicle *v = RoadVehicle::GetIfValid(veh_id);
if (v == nullptr) return CMD_ERROR;
@@ -368,8 +368,7 @@ CommandCost CmdTurnRoadVeh(DoCommandFlag flags, VehicleID veh_id)
CommandCost ret = CheckOwnership(v->owner);
if (ret.Failed()) return ret;
if ((v->vehstatus & VS_STOPPED) ||
(v->vehstatus & VS_CRASHED) ||
if (v->vehstatus.Any({VehState::Stopped, VehState::Crashed}) ||
v->breakdown_ctr != 0 ||
v->overtaking != 0 ||
v->state == RVSB_WORMHOLE ||
@@ -382,7 +381,7 @@ CommandCost CmdTurnRoadVeh(DoCommandFlag flags, VehicleID veh_id)
if (IsTileType(v->tile, MP_TUNNELBRIDGE) && DirToDiagDir(v->direction) == GetTunnelBridgeDirection(v->tile)) return CMD_ERROR;
if (flags & DC_EXEC) {
if (flags.Test(DoCommandFlag::Execute)) {
v->reverse_ctr = 180;
/* Unbunching data is no longer valid. */
@@ -449,7 +448,7 @@ inline int RoadVehicle::GetCurrentMaxSpeed() const
}
/* Vehicle is on the middle part of a bridge. */
if (u->state == RVSB_WORMHOLE && !(u->vehstatus & VS_HIDDEN)) {
if (u->state == RVSB_WORMHOLE && !u->vehstatus.Test(VehState::Hidden)) {
max_speed = std::min(max_speed, GetBridgeSpec(GetBridgeType(u->tile))->speed * 2);
}
}
@@ -545,18 +544,15 @@ static void RoadVehCrash(RoadVehicle *v)
{
uint victims = v->Crash();
AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING, victims));
Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING, victims));
AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING, victims, v->owner));
Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING, victims, v->owner));
SetDParam(0, victims);
StringID newsitem = (victims == 1) ? STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER : STR_NEWS_ROAD_VEHICLE_CRASH;
NewsType newstype = NT_ACCIDENT;
EncodedString headline = (victims == 1)
? GetEncodedString(STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER)
: GetEncodedString(STR_NEWS_ROAD_VEHICLE_CRASH, victims);
NewsType newstype = v->owner == _local_company ? NewsType::Accident : NewsType::AccidentOther;
if (v->owner != _local_company) {
newstype = NT_ACCIDENT_OTHER;
}
AddTileNewsItem(newsitem, newstype, v->tile);
AddTileNewsItem(std::move(headline), newstype, v->tile);
ModifyStationRatingAround(v->tile, v->owner, -160, 22);
if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
@@ -582,13 +578,13 @@ static bool RoadVehCheckTrainCrash(RoadVehicle *v)
TileIndex RoadVehicle::GetOrderStationLocation(StationID station)
{
if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
if (station == this->last_station_visited) this->last_station_visited = StationID::Invalid();
const Station *st = Station::Get(station);
if (!CanVehicleUseStation(this, st)) {
/* There is no stop left at the station, so don't even TRY to go there */
this->IncrementRealOrderIndex();
return 0;
return TileIndex{};
}
return st->xy;
@@ -621,24 +617,27 @@ static Vehicle *EnumCheckRoadVehClose(Vehicle *v, void *data)
RoadVehFindData *rvf = (RoadVehFindData*)data;
short x_diff = v->x_pos - rvf->x;
short y_diff = v->y_pos - rvf->y;
int x_diff = v->x_pos - rvf->x;
int y_diff = v->y_pos - rvf->y;
if (v->type == VEH_ROAD &&
!v->IsInDepot() &&
abs(v->z_pos - rvf->veh->z_pos) < 6 &&
v->direction == rvf->dir &&
rvf->veh->First() != v->First() &&
(dist_x[v->direction] >= 0 || (x_diff > dist_x[v->direction] && x_diff <= 0)) &&
(dist_x[v->direction] <= 0 || (x_diff < dist_x[v->direction] && x_diff >= 0)) &&
(dist_y[v->direction] >= 0 || (y_diff > dist_y[v->direction] && y_diff <= 0)) &&
(dist_y[v->direction] <= 0 || (y_diff < dist_y[v->direction] && y_diff >= 0))) {
uint diff = abs(x_diff) + abs(y_diff);
/* Not a close Road vehicle when it's not a road vehicle, in the depot, or ourself. */
if (v->type != VEH_ROAD || v->IsInDepot() || rvf->veh->First() == v->First()) return nullptr;
if (diff < rvf->best_diff || (diff == rvf->best_diff && v->index < rvf->best->index)) {
rvf->best = v;
rvf->best_diff = diff;
}
/* Not close when at a different height or when going in a different direction. */
if (abs(v->z_pos - rvf->veh->z_pos) >= 6 || v->direction != rvf->dir) return nullptr;
/* We 'return' the closest vehicle, in distance and then VehicleID as tie-breaker. */
uint diff = abs(x_diff) + abs(y_diff);
if (diff > rvf->best_diff || (diff == rvf->best_diff && v->index > rvf->best->index)) return nullptr;
auto IsCloseOnAxis = [](int dist, int diff) {
if (dist < 0) return diff > dist && diff <= 0;
return diff < dist && diff >= 0;
};
if (IsCloseOnAxis(dist_x[v->direction], x_diff) && IsCloseOnAxis(dist_y[v->direction], y_diff)) {
rvf->best = v;
rvf->best_diff = diff;
}
return nullptr;
@@ -689,10 +688,9 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st)
/* Check if station was ever visited before */
if (!(st->had_vehicle_of_type & HVOT_BUS)) {
st->had_vehicle_of_type |= HVOT_BUS;
SetDParam(0, st->index);
AddVehicleNewsItem(
RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_BUS_ARRIVAL : STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL,
(v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
GetEncodedString(RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_BUS_ARRIVAL : STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL, st->index),
(v->owner == _local_company) ? NewsType::ArrivalCompany : NewsType::ArrivalOther,
v->index,
st->index
);
@@ -703,10 +701,9 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st)
/* Check if station was ever visited before */
if (!(st->had_vehicle_of_type & HVOT_TRUCK)) {
st->had_vehicle_of_type |= HVOT_TRUCK;
SetDParam(0, st->index);
AddVehicleNewsItem(
RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_TRUCK_ARRIVAL : STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL,
(v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
GetEncodedString(RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_TRUCK_ARRIVAL : STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL, st->index),
(v->owner == _local_company) ? NewsType::ArrivalCompany : NewsType::ArrivalOther,
v->index,
st->index
);
@@ -823,7 +820,7 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u)
* Original acceleration always accelerates, so always use the maximum speed. */
int u_speed = (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL || u->GetAcceleration() > 0) ? u->GetCurrentMaxSpeed() : u->cur_speed;
if (u_speed >= v->GetCurrentMaxSpeed() &&
!(u->vehstatus & VS_STOPPED) &&
!u->vehstatus.Test(VehState::Stopped) &&
u->cur_speed != 0) {
return;
}
@@ -844,7 +841,7 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u)
/* When the vehicle in front of us is stopped we may only take
* half the time to pass it than when the vehicle is moving. */
v->overtaking_ctr = (od.u->cur_speed == 0 || (od.u->vehstatus & VS_STOPPED)) ? RV_OVERTAKE_TIMEOUT / 2 : 0;
v->overtaking_ctr = (od.u->cur_speed == 0 || od.u->vehstatus.Test(VehState::Stopped)) ? RV_OVERTAKE_TIMEOUT / 2 : 0;
v->overtaking = RVSB_DRIVE_SIDE;
}
@@ -902,7 +899,7 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection
trackdirs = TRACKDIR_BIT_NONE;
} else {
/* Our station */
RoadStopType rstype = v->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK;
RoadStopType rstype = v->IsBus() ? RoadStopType::Bus : RoadStopType::Truck;
if (GetRoadStopType(tile) != rstype) {
/* Wrong station type */
@@ -1033,7 +1030,7 @@ bool RoadVehLeaveDepot(RoadVehicle *v, bool first)
v->cur_speed = 0;
}
v->vehstatus &= ~VS_HIDDEN;
v->vehstatus.Reset(VehState::Hidden);
v->state = tdir;
v->frame = RVC_DEPOT_START_FRAME;
@@ -1126,7 +1123,7 @@ static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadType rt, RoadB
/* The 'current' company is not necessarily the owner of the vehicle. */
Backup<CompanyID> cur_company(_current_company, c);
CommandCost ret = Command<CMD_BUILD_ROAD>::Do(DC_NO_WATER, t, r, rt, DRD_NONE, 0);
CommandCost ret = Command<CMD_BUILD_ROAD>::Do(DoCommandFlag::NoWater, t, r, rt, DRD_NONE, TownID::Invalid());
cur_company.Restore();
return ret.Succeeded();
@@ -1177,7 +1174,7 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev)
v->x_pos = gp.x;
v->y_pos = gp.y;
v->UpdatePosition();
if ((v->vehstatus & VS_HIDDEN) == 0) v->Vehicle::UpdateViewport(true);
if (!v->vehstatus.Test(VehState::Hidden)) v->Vehicle::UpdateViewport(true);
return true;
}
@@ -1451,7 +1448,7 @@ again:
if (v->cur_speed == 0 && IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) &&
v->owner == GetTileOwner(v->tile) && !v->current_order.IsType(OT_LEAVESTATION) &&
GetRoadStopType(v->tile) == (v->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK)) {
GetRoadStopType(v->tile) == (v->IsBus() ? RoadStopType::Bus : RoadStopType::Truck)) {
Station *st = Station::GetByTile(v->tile);
v->last_station_visited = st->index;
RoadVehArrivesAt(v, st);
@@ -1484,7 +1481,7 @@ again:
(IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) &&
v->owner == GetTileOwner(v->tile) &&
GetRoadStopType(v->tile) == (v->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
GetRoadStopType(v->tile) == (v->IsBus() ? RoadStopType::Bus : RoadStopType::Truck) &&
v->frame == RVC_DRIVE_THROUGH_STOP_FRAME))) {
RoadStop *rs = RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile));
@@ -1565,13 +1562,13 @@ static bool RoadVehController(RoadVehicle *v)
if (v->reverse_ctr != 0) v->reverse_ctr--;
/* handle crashed */
if (v->vehstatus & VS_CRASHED || RoadVehCheckTrainCrash(v)) {
if (v->vehstatus.Test(VehState::Crashed) || RoadVehCheckTrainCrash(v)) {
return RoadVehIsCrashed(v);
}
/* road vehicle has broken down? */
if (v->HandleBreakdown()) return true;
if (v->vehstatus & VS_STOPPED) {
if (v->vehstatus.Test(VehState::Stopped)) {
v->SetLastSpeed();
return true;
}
@@ -1616,7 +1613,7 @@ static bool RoadVehController(RoadVehicle *v)
v->SetLastSpeed();
for (RoadVehicle *u = v; u != nullptr; u = u->Next()) {
if ((u->vehstatus & VS_HIDDEN) != 0) continue;
if (u->vehstatus.Test(VehState::Hidden)) continue;
u->UpdateViewport(false, false);
}
@@ -1647,7 +1644,7 @@ bool RoadVehicle::Tick()
this->tick_counter++;
if (this->IsFrontEngine()) {
if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
if (!this->vehstatus.Test(VehState::Stopped)) this->running_ticks++;
return RoadVehController(this);
}
@@ -1734,7 +1731,7 @@ void RoadVehicle::OnNewEconomyDay()
Trackdir RoadVehicle::GetVehicleTrackdir() const
{
if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
if (this->vehstatus.Test(VehState::Crashed)) return INVALID_TRACKDIR;
if (this->IsInDepot()) {
/* We'll assume the road vehicle is facing outwards */