Codechange: rework definition of ship and train tile entrance coordinates (#15650)

This commit is contained in:
Peter Nelson
2026-05-31 08:16:26 +01:00
committed by GitHub
parent ebc61380f6
commit ee0d9f662e
4 changed files with 64 additions and 74 deletions
+3 -55
View File
@@ -509,56 +509,6 @@ static inline TrackBits GetAvailShipTracks(TileIndex tile, DiagDirection dir)
return tracks;
}
/** Structure for ship sub-coordinate data for moving into a new tile via a Diagdir onto a Track. */
struct ShipSubcoordData {
uint8_t x_subcoord; ///< New X sub-coordinate on the new tile
uint8_t y_subcoord; ///< New Y sub-coordinate on the new tile
Direction dir; ///< New Direction to move in on the new track
};
/** Ship sub-coordinate data for moving into a new tile via a Diagdir onto a Track.
* Array indexes are Diagdir, Track.
* There will always be three possible tracks going into an adjacent tile via a Diagdir,
* so each Diagdir sub-array will have three valid and three invalid structures per Track.
*/
static constexpr DiagDirectionIndexArray<TrackIndexArray<ShipSubcoordData>> _ship_subcoord{{{
/* DIAGDIR_NE */
{{{
{15, 8, DIR_NE}, // TRACK_X
{ 0, 0, INVALID_DIR}, // TRACK_Y
{ 0, 0, INVALID_DIR}, // TRACK_UPPER
{15, 8, DIR_E}, // TRACK_LOWER
{15, 7, DIR_N}, // TRACK_LEFT
{ 0, 0, INVALID_DIR}, // TRACK_RIGHT
}}},
/* DIAGDIR_SE */
{{{
{ 0, 0, INVALID_DIR}, // TRACK_X
{ 8, 0, DIR_SE}, // TRACK_Y
{ 7, 0, DIR_E}, // TRACK_UPPER
{ 0, 0, INVALID_DIR}, // TRACK_LOWER
{ 8, 0, DIR_S}, // TRACK_LEFT
{ 0, 0, INVALID_DIR}, // TRACK_RIGHT
}}},
/* DIAGDIR_SW */
{{{
{ 0, 8, DIR_SW}, // TRACK_X
{ 0, 0, INVALID_DIR}, // TRACK_Y
{ 0, 7, DIR_W}, // TRACK_UPPER
{ 0, 0, INVALID_DIR}, // TRACK_LOWER
{ 0, 0, INVALID_DIR}, // TRACK_LEFT
{ 0, 8, DIR_S}, // TRACK_RIGHT
}}},
/* DIAGDIR_NW */
{{{
{ 0, 0, INVALID_DIR}, // TRACK_X
{ 8, 15, DIR_NW}, // TRACK_Y
{ 0, 0, INVALID_DIR}, // TRACK_UPPER
{ 8, 15, DIR_W}, // TRACK_LOWER
{ 0, 0, INVALID_DIR}, // TRACK_LEFT
{ 7, 15, DIR_N}, // TRACK_RIGHT
}}},
}}};
/**
* Test if a ship is in the centre of a lock and should move up or down.
* @param v Ship being tested.
@@ -776,10 +726,8 @@ static void ShipController(Ship *v)
const Track track = ChooseShipTrack(v, gp.new_tile, tracks);
if (track == INVALID_TRACK) return ReverseShip(v);
const ShipSubcoordData &b = _ship_subcoord[diagdir][track];
gp.x = (gp.x & ~0xF) | b.x_subcoord;
gp.y = (gp.y & ~0xF) | b.y_subcoord;
/* Update XY to reflect the entrance to the new tile, and select the direction to use */
Direction chosen_dir = VehicleEnterTileCoordinates(gp, diagdir, track);
/* Call the landscape function and tell it that the vehicle entered the tile */
auto vets = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
@@ -793,7 +741,7 @@ static void ShipController(Ship *v)
if (GetEffectiveWaterClass(gp.old_tile) != GetEffectiveWaterClass(gp.new_tile)) v->UpdateCache();
}
const Direction new_direction = b.dir;
const Direction new_direction = chosen_dir;
const DirDiff diff = DirDifference(new_direction, v->direction);
switch (diff) {
case DirDiff::Same:
+1 -19
View File
@@ -2524,15 +2524,6 @@ void FreeTrainTrackReservation(const Train *consist)
UpdateSignalsInBuffer();
}
static const uint8_t _initial_tile_subcoord[6][4][3] = {
{{ 15, 8, 1 }, { 0, 0, 0 }, { 0, 8, 5 }, { 0, 0, 0 }},
{{ 0, 0, 0 }, { 8, 0, 3 }, { 0, 0, 0 }, { 8, 15, 7 }},
{{ 0, 0, 0 }, { 7, 0, 2 }, { 0, 7, 6 }, { 0, 0, 0 }},
{{ 15, 8, 2 }, { 0, 0, 0 }, { 0, 0, 0 }, { 8, 15, 6 }},
{{ 15, 7, 0 }, { 8, 0, 4 }, { 0, 0, 0 }, { 0, 0, 0 }},
{{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 8, 4 }, { 7, 15, 0 }},
};
/**
* Perform pathfinding for a train.
*
@@ -3524,17 +3515,8 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
chosen_track &= bits;
}
/* Make sure chosen track is a valid track */
assert(
chosen_track == TRACK_BIT_X || chosen_track == TRACK_BIT_Y ||
chosen_track == TRACK_BIT_UPPER || chosen_track == TRACK_BIT_LOWER ||
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 uint8_t *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];
Direction chosen_dir = VehicleEnterTileCoordinates(gp, enterdir, TrackBitsToTrack(chosen_track));
/* Call the landscape function and tell it that the vehicle entered the tile */
auto vets = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
+59
View File
@@ -3339,3 +3339,62 @@ bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2)
{
return std::ranges::equal(v1->Orders(), v2->Orders(), [](const Order &o1, const Order &o2) { return o1.Equals(o2); });
}
/** Vehicle sub-coordinate data for moving into a new tile. */
struct VehicleSubcoordData : Coord2D<uint8_t> {
Direction dir = INVALID_DIR; ///< new direction.
};
/**
* Table of subtile coordinates and direction for each combination of chosen track and tile enter direction.
* Combinations that are not possible result in INVALID_DIR.
*/
static constexpr DiagDirectionIndexArray<TrackIndexArray<VehicleSubcoordData>> _vehicle_subcoord{{{
{{{ // NE
{{15, 8}, DIR_NE}, // TRACK_X
{}, // TRACK_Y
{}, // TRACK_UPPER
{{15, 8}, DIR_E}, // TRACK_LOWER
{{15, 7}, DIR_N}, // TRACK_LEFT
{}, // TRACK_RIGHT
}}},
{{{ // SE
{}, // TRACK_X
{{8, 0}, DIR_SE}, // TRACK_Y
{{7, 0}, DIR_E}, // TRACK_UPPER
{}, // TRACK_LOWER
{{8, 0}, DIR_S}, // TRACK_LEFT
{}, // TRACK_RIGHT
}}},
{{{ // SW
{{0, 8}, DIR_SW}, // TRACK_X
{}, // TRACK_Y
{{0, 7}, DIR_W}, // TRACK_UPPER
{}, // TRACK_LOWER
{}, // TRACK_LEFT
{{0, 8}, DIR_S}, // TRACK_RIGHT
}}},
{{{ // NW
{}, // TRACK_X
{{8, 15}, DIR_NW}, // TRACK_Y
{}, // TRACK_UPPER
{{8, 15}, DIR_W}, // TRACK_LOWER
{}, // TRACK_LEFT
{{7, 15}, DIR_N}, // TRACK_RIGHT
}}},
}}};
/**
* Lookup new subposition coordinates and direction to use when entering a new tile, applying the subcoordinates to the vehicle position result.
* @param gp new vehicle position result to apply subcoordinates to.
* @param enterdir the enter direction for the tile.
* @param track The chosen track for the tile.
* @return the new vehicle direction.
*/
Direction VehicleEnterTileCoordinates(GetNewVehiclePosResult &gp, DiagDirection enterdir, Track track)
{
const VehicleSubcoordData &b = _vehicle_subcoord[enterdir][track];
gp.x = (gp.x & ~TILE_UNIT_MASK) | b.x;
gp.y = (gp.y & ~TILE_UNIT_MASK) | b.y;
return b.dir;
}
+1
View File
@@ -330,5 +330,6 @@ bool VehiclesHaveSameEngineList(const Vehicle *v1, const Vehicle *v2);
bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2);
bool IsUniqueVehicleName(const std::string &name);
Direction VehicleEnterTileCoordinates(GetNewVehiclePosResult &gp, DiagDirection enterdir, Track track);
#endif /* VEHICLE_FUNC_H */