MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / CalcHeightdiff

Function CalcHeightdiff

src/viewport.cpp:2959–3038  ·  view source on GitHub ↗

* Calculates height difference between one tile and another. * Multiplies the result to suit the standard given by #TILE_HEIGHT_STEP. * * To correctly get the height difference we need the direction we are dragging * in, as well as with what kind of tool we are dragging. For example a horizontal * autorail tool that starts in bottom and ends at the top of a tile will need the * maximum of SW

Source from the content-addressed store, hash-verified

2957 * @return Height difference between two tiles. The tile measurement tool utilizes this value in its tooltip.
2958 */
2959static int CalcHeightdiff(HighLightStyle style, uint distance, TileIndex start_tile, TileIndex end_tile)
2960{
2961 bool swap = SwapDirection(style, start_tile, end_tile);
2962 uint h0, h1; // Start height and end height.
2963
2964 if (start_tile == end_tile) return 0;
2965 if (swap) std::swap(start_tile, end_tile);
2966
2967 switch (style & HT_DRAG_MASK) {
2968 case HT_RECT:
2969 /* In the case of an area we can determine whether we were dragging south or
2970 * east by checking the X-coordinates of the tiles */
2971 if (TileX(end_tile) > TileX(start_tile)) {
2972 /* Dragging south does not need to change the start tile. */
2973 end_tile = TileAddByDir(end_tile, DIR_S);
2974 } else {
2975 /* Dragging east. */
2976 start_tile = TileAddByDir(start_tile, DIR_SW);
2977 end_tile = TileAddByDir(end_tile, DIR_SE);
2978 }
2979 [[fallthrough]];
2980
2981 case HT_POINT:
2982 h0 = TileHeight(start_tile);
2983 h1 = TileHeight(end_tile);
2984 break;
2985 default: { // All other types, this is mostly only line/autorail
2986 static const HighLightStyle flip_style_direction[] = {
2987 HT_DIR_X, HT_DIR_Y, HT_DIR_HL, HT_DIR_HU, HT_DIR_VR, HT_DIR_VL
2988 };
2989 static const std::pair<TileIndexDiffC, TileIndexDiffC> start_heightdiff_line_by_dir[] = {
2990 { {1, 0}, {1, 1} }, // HT_DIR_X
2991 { {0, 1}, {1, 1} }, // HT_DIR_Y
2992 { {1, 0}, {0, 0} }, // HT_DIR_HU
2993 { {1, 0}, {1, 1} }, // HT_DIR_HL
2994 { {1, 0}, {1, 1} }, // HT_DIR_VL
2995 { {0, 1}, {1, 1} }, // HT_DIR_VR
2996 };
2997 static const std::pair<TileIndexDiffC, TileIndexDiffC> end_heightdiff_line_by_dir[] = {
2998 { {0, 1}, {0, 0} }, // HT_DIR_X
2999 { {1, 0}, {0, 0} }, // HT_DIR_Y
3000 { {0, 1}, {0, 0} }, // HT_DIR_HU
3001 { {1, 1}, {0, 1} }, // HT_DIR_HL
3002 { {1, 0}, {0, 0} }, // HT_DIR_VL
3003 { {0, 0}, {0, 1} }, // HT_DIR_VR
3004 };
3005 static_assert(std::size(start_heightdiff_line_by_dir) == HT_DIR_END);
3006 static_assert(std::size(end_heightdiff_line_by_dir) == HT_DIR_END);
3007
3008 distance %= 2; // we're only interested if the distance is even or uneven
3009 style &= HT_DIR_MASK;
3010 assert(style < HT_DIR_END);
3011
3012 /* To handle autorail, we do some magic to be able to use a lookup table.
3013 * Firstly if we drag the other way around, we switch start&end, and if needed
3014 * also flip the drag-position. Eg if it was on the left, and the distance is even
3015 * that means the end, which is now the start is on the right */
3016 if (swap && distance == 0) style = flip_style_direction[style];

Callers 2

CalcRaildirsDrawstyleFunction · 0.85
VpSelectTilesWithMethodFunction · 0.85

Calls 8

SwapDirectionFunction · 0.85
swapFunction · 0.85
TileXFunction · 0.85
TileAddByDirFunction · 0.85
TileHeightFunction · 0.85
ToTileIndexDiffFunction · 0.85
TileAddFunction · 0.70
sizeFunction · 0.50

Tested by

no test coverage detected