mirror of https://github.com/OpenTTD/OpenTTD
Codechange: replace magic numbers with enumeration
parent
4a4c77ff04
commit
ea6aa4653a
|
@ -136,6 +136,32 @@
|
||||||
|
|
||||||
/* Helper functions for ScriptRoad::CanBuildConnectedRoadParts(). */
|
/* Helper functions for ScriptRoad::CanBuildConnectedRoadParts(). */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration or the orientations of road parts.
|
||||||
|
*
|
||||||
|
* Technically DiagDirection could be used, but that allows simple conversions to/from integer. In this case that is not wanted.
|
||||||
|
*/
|
||||||
|
enum class RoadPartOrientation {
|
||||||
|
NW, NE, SW, SE
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the two given orientations combined are a straight road.
|
||||||
|
* @param start The part that should be build first.
|
||||||
|
* @param end The part that will be build second.
|
||||||
|
* @return True iff start and end combined describe a straight road (ROAD_X or ROAD_Y).
|
||||||
|
*/
|
||||||
|
static bool IsStraight(RoadPartOrientation start, RoadPartOrientation end)
|
||||||
|
{
|
||||||
|
switch (start) {
|
||||||
|
case RoadPartOrientation::NW: return end == RoadPartOrientation::SE;
|
||||||
|
case RoadPartOrientation::NE: return end == RoadPartOrientation::SW;
|
||||||
|
case RoadPartOrientation::SW: return end == RoadPartOrientation::NE;
|
||||||
|
case RoadPartOrientation::SE: return end == RoadPartOrientation::NW;
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the given existing bits the start and end part can be build.
|
* Check whether the given existing bits the start and end part can be build.
|
||||||
* As the function assumes the bits being build on a slope that does not
|
* As the function assumes the bits being build on a slope that does not
|
||||||
|
@ -150,9 +176,9 @@
|
||||||
* @param end The part that will be build second.
|
* @param end The part that will be build second.
|
||||||
* @return True if and only if the road bits can be build.
|
* @return True if and only if the road bits can be build.
|
||||||
*/
|
*/
|
||||||
static bool CheckAutoExpandedRoadBits(const Array<> &existing, int32_t start, int32_t end)
|
static bool CheckAutoExpandedRoadBits(const Array<RoadPartOrientation> &existing, RoadPartOrientation start, RoadPartOrientation end)
|
||||||
{
|
{
|
||||||
return (start + end == 0) && (existing.empty() || existing[0] == start || existing[0] == end);
|
return IsStraight(start, end) && (existing.empty() || existing[0] == start || existing[0] == end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -165,7 +191,7 @@ static bool CheckAutoExpandedRoadBits(const Array<> &existing, int32_t start, in
|
||||||
* they are build or 2 when building the first part automatically
|
* they are build or 2 when building the first part automatically
|
||||||
* builds the second part.
|
* builds the second part.
|
||||||
*/
|
*/
|
||||||
static int32_t LookupWithoutBuildOnSlopes(::Slope slope, const Array<> &existing, int32_t start, int32_t end)
|
static int32_t LookupWithoutBuildOnSlopes(::Slope slope, const Array<RoadPartOrientation> &existing, RoadPartOrientation start, RoadPartOrientation end)
|
||||||
{
|
{
|
||||||
switch (slope) {
|
switch (slope) {
|
||||||
/* Flat slopes can always be build. */
|
/* Flat slopes can always be build. */
|
||||||
|
@ -177,9 +203,9 @@ static int32_t LookupWithoutBuildOnSlopes(::Slope slope, const Array<> &existing
|
||||||
* in the game have been changed.
|
* in the game have been changed.
|
||||||
*/
|
*/
|
||||||
case SLOPE_NE: case SLOPE_SW:
|
case SLOPE_NE: case SLOPE_SW:
|
||||||
return (CheckAutoExpandedRoadBits(existing, start, end) && (start == 1 || end == 1)) ? (existing.empty() ? 2 : 1) : 0;
|
return (CheckAutoExpandedRoadBits(existing, start, end) && (start == RoadPartOrientation::SW || end == RoadPartOrientation::SW)) ? (existing.empty() ? 2 : 1) : 0;
|
||||||
case SLOPE_SE: case SLOPE_NW:
|
case SLOPE_SE: case SLOPE_NW:
|
||||||
return (CheckAutoExpandedRoadBits(existing, start, end) && (start != 1 && end != 1)) ? (existing.empty() ? 2 : 1) : 0;
|
return (CheckAutoExpandedRoadBits(existing, start, end) && (start != RoadPartOrientation::SW && end != RoadPartOrientation::SW)) ? (existing.empty() ? 2 : 1) : 0;
|
||||||
|
|
||||||
/* Any other tile cannot be built on. */
|
/* Any other tile cannot be built on. */
|
||||||
default:
|
default:
|
||||||
|
@ -192,13 +218,13 @@ static int32_t LookupWithoutBuildOnSlopes(::Slope slope, const Array<> &existing
|
||||||
* @param neighbour The neighbour.
|
* @param neighbour The neighbour.
|
||||||
* @return The rotate neighbour data.
|
* @return The rotate neighbour data.
|
||||||
*/
|
*/
|
||||||
static int32_t RotateNeighbour(int32_t neighbour)
|
static RoadPartOrientation RotateNeighbour(RoadPartOrientation neighbour)
|
||||||
{
|
{
|
||||||
switch (neighbour) {
|
switch (neighbour) {
|
||||||
case -2: return -1;
|
case RoadPartOrientation::NW: return RoadPartOrientation::NE;
|
||||||
case -1: return 2;
|
case RoadPartOrientation::NE: return RoadPartOrientation::SE;
|
||||||
case 1: return -2;
|
case RoadPartOrientation::SE: return RoadPartOrientation::SW;
|
||||||
case 2: return 1;
|
case RoadPartOrientation::SW: return RoadPartOrientation::NW;
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,13 +234,13 @@ static int32_t RotateNeighbour(int32_t neighbour)
|
||||||
* @param neighbour The neighbour.
|
* @param neighbour The neighbour.
|
||||||
* @return The bits representing the direction.
|
* @return The bits representing the direction.
|
||||||
*/
|
*/
|
||||||
static RoadBits NeighbourToRoadBits(int32_t neighbour)
|
static RoadBits NeighbourToRoadBits(RoadPartOrientation neighbour)
|
||||||
{
|
{
|
||||||
switch (neighbour) {
|
switch (neighbour) {
|
||||||
case -2: return ROAD_NW;
|
case RoadPartOrientation::NW: return ROAD_NW;
|
||||||
case -1: return ROAD_NE;
|
case RoadPartOrientation::NE: return ROAD_NE;
|
||||||
case 2: return ROAD_SE;
|
case RoadPartOrientation::SE: return ROAD_SE;
|
||||||
case 1: return ROAD_SW;
|
case RoadPartOrientation::SW: return ROAD_SW;
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +255,7 @@ static RoadBits NeighbourToRoadBits(int32_t neighbour)
|
||||||
* they are build or 2 when building the first part automatically
|
* they are build or 2 when building the first part automatically
|
||||||
* builds the second part.
|
* builds the second part.
|
||||||
*/
|
*/
|
||||||
static int32_t LookupWithBuildOnSlopes(::Slope slope, const Array<> &existing, int32_t start, int32_t end)
|
static int32_t LookupWithBuildOnSlopes(::Slope slope, const Array<RoadPartOrientation> &existing, RoadPartOrientation start, RoadPartOrientation end)
|
||||||
{
|
{
|
||||||
/* Steep slopes behave the same as slopes with one corner raised. */
|
/* Steep slopes behave the same as slopes with one corner raised. */
|
||||||
if (IsSteepSlope(slope)) {
|
if (IsSteepSlope(slope)) {
|
||||||
|
@ -287,7 +313,7 @@ static int32_t LookupWithBuildOnSlopes(::Slope slope, const Array<> &existing, i
|
||||||
RoadBits start_roadbits = NeighbourToRoadBits(start);
|
RoadBits start_roadbits = NeighbourToRoadBits(start);
|
||||||
RoadBits new_roadbits = start_roadbits | NeighbourToRoadBits(end);
|
RoadBits new_roadbits = start_roadbits | NeighbourToRoadBits(end);
|
||||||
RoadBits existing_roadbits = ROAD_NONE;
|
RoadBits existing_roadbits = ROAD_NONE;
|
||||||
for (int32_t neighbour : existing) {
|
for (RoadPartOrientation neighbour : existing) {
|
||||||
for (int j = 0; j < base_rotate; j++) {
|
for (int j = 0; j < base_rotate; j++) {
|
||||||
neighbour = RotateNeighbour(neighbour);
|
neighbour = RotateNeighbour(neighbour);
|
||||||
}
|
}
|
||||||
|
@ -356,55 +382,44 @@ static int32_t LookupWithBuildOnSlopes(::Slope slope, const Array<> &existing, i
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalise all input data so we can easily handle it without needing
|
* Normalise all input data (tile indices) so we can easily handle it without needing
|
||||||
* to call the API lots of times or create large if-elseif-elseif-else
|
* to call the API lots of times or create large if-elseif-elseif-else constructs.
|
||||||
* constructs.
|
* @param tile The tile to get the orientation from.
|
||||||
* In this case it means that a TileXY(0, -1) becomes -2 and TileXY(0, 1)
|
* @return The orientation or an empty optional when the input is invalid..
|
||||||
* becomes 2. TileXY(-1, 0) and TileXY(1, 0) stay respectively -1 and 1.
|
|
||||||
* Any other value means that it is an invalid tile offset.
|
|
||||||
* @param tile The tile to normalise.
|
|
||||||
* @return True if and only if the tile offset is valid.
|
|
||||||
*/
|
*/
|
||||||
static bool NormaliseTileOffset(int32_t *tile)
|
static std::optional<RoadPartOrientation> ToRoadPartOrientation(const TileIndex &tile)
|
||||||
{
|
{
|
||||||
if (*tile == ScriptMap::GetTileIndex(-1, 0)) {
|
if (tile == ScriptMap::GetTileIndex(0, -1)) return RoadPartOrientation::NW;
|
||||||
*tile = -1;
|
if (tile == ScriptMap::GetTileIndex(1, 0)) return RoadPartOrientation::SW;
|
||||||
return true;
|
if (tile == ScriptMap::GetTileIndex(0, 1)) return RoadPartOrientation::SE;
|
||||||
}
|
if (tile == ScriptMap::GetTileIndex(-1, 0)) return RoadPartOrientation::NE;
|
||||||
if (*tile == ScriptMap::GetTileIndex(1, 0)) {
|
return std::nullopt;
|
||||||
*tile = 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (*tile == ScriptMap::GetTileIndex(0, -1)) {
|
|
||||||
*tile = -2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (*tile == ScriptMap::GetTileIndex(0, 1)) {
|
|
||||||
*tile = 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ SQInteger ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::Slope slope_, Array<> &&existing, TileIndex start_, TileIndex end_)
|
/* static */ SQInteger ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::Slope slope_, Array<TileIndex> &&existing, TileIndex start, TileIndex end)
|
||||||
{
|
{
|
||||||
::Slope slope = (::Slope)slope_;
|
::Slope slope = (::Slope)slope_;
|
||||||
int32_t start = start_.base();
|
|
||||||
int32_t end = end_.base();
|
|
||||||
|
|
||||||
/* The start tile and end tile cannot be the same tile either. */
|
/* The start tile and end tile cannot be the same tile either. */
|
||||||
if (start == end) return -1;
|
if (start == end) return -1;
|
||||||
|
|
||||||
for (size_t i = 0; i < existing.size(); i++) {
|
std::vector<RoadPartOrientation> existing_orientations;
|
||||||
if (!NormaliseTileOffset(&existing[i])) return -1;
|
existing_orientations.reserve(existing.size());
|
||||||
|
for (const auto &t : existing) {
|
||||||
|
auto orientation = ToRoadPartOrientation(t);
|
||||||
|
if (!orientation) return -1;
|
||||||
|
existing_orientations.push_back(*orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NormaliseTileOffset(&start)) return -1;
|
auto start_orientation = ToRoadPartOrientation(start);
|
||||||
if (!NormaliseTileOffset(&end)) return -1;
|
auto end_orientation = ToRoadPartOrientation(end);
|
||||||
|
if (!start_orientation || !end_orientation) return -1;
|
||||||
|
|
||||||
/* Without build on slopes the characteristics are vastly different, so use
|
/* Without build on slopes the characteristics are vastly different, so use
|
||||||
* a different helper function (one that is much simpler). */
|
* a different helper function (one that is much simpler). */
|
||||||
return _settings_game.construction.build_on_slopes ? LookupWithBuildOnSlopes(slope, existing, start, end) : LookupWithoutBuildOnSlopes(slope, existing, start, end);
|
return _settings_game.construction.build_on_slopes ?
|
||||||
|
LookupWithBuildOnSlopes(slope, existing_orientations, *start_orientation, *end_orientation) :
|
||||||
|
LookupWithoutBuildOnSlopes(slope, existing_orientations, *start_orientation, *end_orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ SQInteger ScriptRoad::CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end)
|
/* static */ SQInteger ScriptRoad::CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end)
|
||||||
|
@ -426,9 +441,9 @@ static bool NormaliseTileOffset(int32_t *tile)
|
||||||
rb = ::GetAnyRoadBits(tile, RTT_ROAD) | ::GetAnyRoadBits(tile, RTT_TRAM);
|
rb = ::GetAnyRoadBits(tile, RTT_ROAD) | ::GetAnyRoadBits(tile, RTT_TRAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
Array<> existing;
|
Array<TileIndex> existing;
|
||||||
for (uint i = 0; i < lengthof(neighbours); i++) {
|
for (uint i = 0; i < lengthof(neighbours); i++) {
|
||||||
if (HasBit(rb, i)) existing.emplace_back(neighbours[i].base());
|
if (HasBit(rb, i)) existing.emplace_back(neighbours[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::GetSlope(tile), std::move(existing), start - tile, end - tile);
|
return ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::GetSlope(tile), std::move(existing), start - tile, end - tile);
|
||||||
|
|
|
@ -248,7 +248,7 @@ public:
|
||||||
* they are build or 2 when building the first part automatically
|
* they are build or 2 when building the first part automatically
|
||||||
* builds the second part. -1 means the preconditions are not met.
|
* builds the second part. -1 means the preconditions are not met.
|
||||||
*/
|
*/
|
||||||
static SQInteger CanBuildConnectedRoadParts(ScriptTile::Slope slope, Array<> &&existing, TileIndex start, TileIndex end);
|
static SQInteger CanBuildConnectedRoadParts(ScriptTile::Slope slope, Array<TileIndex> &&existing, TileIndex start, TileIndex end);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup function for building road parts independent of whether the
|
* Lookup function for building road parts independent of whether the
|
||||||
|
|
Loading…
Reference in New Issue