Merge remote-tracking branch 'upstream/master'

This commit is contained in:
dP
2025-09-28 02:33:49 +05:00
926 changed files with 37902 additions and 27369 deletions

View File

@@ -83,7 +83,7 @@ static void GetShipIcon(EngineID engine, EngineImageType image_type, VehicleSpri
const Engine *e = Engine::Get(engine);
uint8_t spritenum = e->u.ship.image_index;
if (is_custom_sprite(spritenum)) {
if (IsCustomVehicleSpriteNum(spritenum)) {
GetCustomVehicleIcon(engine, DIR_W, image_type, result);
if (result->IsValid()) return;
@@ -137,7 +137,7 @@ void Ship::GetImage(Direction direction, EngineImageType image_type, VehicleSpri
if (image_type == EIT_ON_MAP) direction = this->rotation;
if (is_custom_sprite(spritenum)) {
if (IsCustomVehicleSpriteNum(spritenum)) {
GetCustomVehicleSprite(this, direction, image_type, result);
if (result->IsValid()) return;
@@ -168,7 +168,7 @@ static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance)
patches_to_search.pop_front();
/* Add neighbours of the current patch to the search queue. */
TVisitWaterRegionPatchCallBack visit_func = [&](const WaterRegionPatchDesc &water_region_patch) {
VisitWaterRegionPatchCallback visit_func = [&](const WaterRegionPatchDesc &water_region_patch) {
/* Note that we check the max distance per axis, not the total distance. */
if (std::abs(water_region_patch.x - start_patch.x) > max_region_distance ||
std::abs(water_region_patch.y - start_patch.y) > max_region_distance) return;
@@ -330,43 +330,29 @@ TileIndex Ship::GetOrderStationLocation(StationID station)
void Ship::UpdateDeltaXY()
{
static const int8_t _delta_xy_table[8][4] = {
/* y_extent, x_extent, y_offs, x_offs */
{ 6, 6, -3, -3}, // N
{ 6, 32, -3, -16}, // NE
{ 6, 6, -3, -3}, // E
{32, 6, -16, -3}, // SE
{ 6, 6, -3, -3}, // S
{ 6, 32, -3, -16}, // SW
{ 6, 6, -3, -3}, // W
{32, 6, -16, -3}, // NW
static constexpr SpriteBounds ship_bounds[DIR_END] = {
{{ -3, -3, 0}, { 6, 6, 6}, {}}, // N
{{-16, -3, 0}, {32, 6, 6}, {}}, // NE
{{ -3, -3, 0}, { 6, 6, 6}, {}}, // E
{{ -3, -16, 0}, { 6, 32, 6}, {}}, // SE
{{ -3, -3, 0}, { 6, 6, 6}, {}}, // S
{{-16, -3, 0}, {32, 6, 6}, {}}, // SW
{{ -3, -3, 0}, { 6, 6, 6}, {}}, // W
{{ -3, -16, 0}, { 6, 32, 6}, {}}, // NW
};
const int8_t *bb = _delta_xy_table[this->rotation];
this->x_offs = bb[3];
this->y_offs = bb[2];
this->x_extent = bb[1];
this->y_extent = bb[0];
this->z_extent = 6;
this->bounds = ship_bounds[this->rotation];
if (this->direction != this->rotation) {
/* If we are rotating, then it is possible the ship was moved to its next position. In that
* case, because we are still showing the old direction, the ship will appear to glitch sideways
* slightly. We can work around this by applying an additional offset to make the ship appear
* where it was before it moved. */
this->x_offs -= this->x_pos - this->rotation_x_pos;
this->y_offs -= this->y_pos - this->rotation_y_pos;
this->bounds.origin.x -= this->x_pos - this->rotation_x_pos;
this->bounds.origin.y -= this->y_pos - this->rotation_y_pos;
}
}
/**
* Test-procedure for HasVehicleOnPos to check for any ships which are moving.
*/
static Vehicle *EnsureNoMovingShipProc(Vehicle *v, void *)
{
return v->type == VEH_SHIP && v->cur_speed != 0 ? v : nullptr;
}
static bool CheckReverseShip(const Ship *v, Trackdir *trackdir = nullptr)
{
/* Ask pathfinder for best direction */
@@ -392,7 +378,9 @@ static bool CheckShipLeaveDepot(Ship *v)
/* Don't leave depot if another vehicle is already entering/leaving */
/* This helps avoid CPU load if many ships are set to start at the same time */
if (HasVehicleOnPos(v->tile, nullptr, &EnsureNoMovingShipProc)) return true;
if (HasVehicleOnTile(v->tile, [](const Vehicle *u) {
return u->type == VEH_SHIP && u->cur_speed != 0;
})) return true;
TileIndex tile = v->tile;
Axis axis = GetShipDepotAxis(tile);
@@ -549,7 +537,7 @@ struct ShipSubcoordData {
* so each Diagdir sub-array will have three valid and three invalid structures per Track.
*/
static const ShipSubcoordData _ship_subcoord[DIAGDIR_END][TRACK_END] = {
// DIAGDIR_NE
/* DIAGDIR_NE */
{
{15, 8, DIR_NE}, // TRACK_X
{ 0, 0, INVALID_DIR}, // TRACK_Y
@@ -558,7 +546,7 @@ static const ShipSubcoordData _ship_subcoord[DIAGDIR_END][TRACK_END] = {
{15, 7, DIR_N}, // TRACK_LEFT
{ 0, 0, INVALID_DIR}, // TRACK_RIGHT
},
// DIAGDIR_SE
/* DIAGDIR_SE */
{
{ 0, 0, INVALID_DIR}, // TRACK_X
{ 8, 0, DIR_SE}, // TRACK_Y
@@ -567,7 +555,7 @@ static const ShipSubcoordData _ship_subcoord[DIAGDIR_END][TRACK_END] = {
{ 8, 0, DIR_S}, // TRACK_LEFT
{ 0, 0, INVALID_DIR}, // TRACK_RIGHT
},
// DIAGDIR_SW
/* DIAGDIR_SW */
{
{ 0, 8, DIR_SW}, // TRACK_X
{ 0, 0, INVALID_DIR}, // TRACK_Y
@@ -576,7 +564,7 @@ static const ShipSubcoordData _ship_subcoord[DIAGDIR_END][TRACK_END] = {
{ 0, 0, INVALID_DIR}, // TRACK_LEFT
{ 0, 8, DIR_S}, // TRACK_RIGHT
},
// DIAGDIR_NW
/* DIAGDIR_NW */
{
{ 0, 0, INVALID_DIR}, // TRACK_X
{ 8, 15, DIR_NW}, // TRACK_Y
@@ -742,8 +730,8 @@ static void ShipController(Ship *v)
gp.y = v->y_pos;
} else {
/* Not inside depot */
const VehicleEnterTileStatus r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
if (HasBit(r, VETS_CANNOT_ENTER)) return ReverseShip(v);
auto vets = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
if (vets.Test(VehicleEnterTileState::CannotEnter)) return ReverseShip(v);
/* A leave station order only needs one tick to get processed, so we can
* always skip ahead. */
@@ -810,10 +798,10 @@ static void ShipController(Ship *v)
gp.y = (gp.y & ~0xF) | b.y_subcoord;
/* Call the landscape function and tell it that the vehicle entered the tile */
const VehicleEnterTileStatus r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
if (HasBit(r, VETS_CANNOT_ENTER)) return ReverseShip(v);
auto vets = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
if (vets.Test(VehicleEnterTileState::CannotEnter)) return ReverseShip(v);
if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
if (!vets.Test(VehicleEnterTileState::EnteredWormhole)) {
v->tile = gp.new_tile;
v->state = TrackToTrackBits(track);
@@ -843,7 +831,7 @@ static void ShipController(Ship *v)
}
} else {
/* On a bridge */
if (!IsTileType(gp.new_tile, MP_TUNNELBRIDGE) || !HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
if (!IsTileType(gp.new_tile, MP_TUNNELBRIDGE) || !VehicleEnterTile(v, gp.new_tile, gp.x, gp.y).Test(VehicleEnterTileState::EnteredWormhole)) {
v->x_pos = gp.x;
v->y_pos = gp.y;
v->UpdatePosition();