* Determines height at given coordinate of a slope. * * At the northern corner (0, 0) the result is always a multiple of TILE_HEIGHT. * When the height is a fractional Z, then the height is rounded down. For example, * when at the height is 0 at x = 0 and the height is 8 at x = 16 (actually x = 0 * of the next tile), then height is 0 at x = 1, 1 at x = 2, and 7 at x = 15. * @param x x coordi
| 230 | * @return height of given point of given slope |
| 231 | */ |
| 232 | uint GetPartialPixelZ(int x, int y, Slope corners) |
| 233 | { |
| 234 | if (IsHalftileSlope(corners)) { |
| 235 | /* A foundation is placed on half the tile at a specific corner. This means that, |
| 236 | * depending on the corner, that one half of the tile is at the maximum height. */ |
| 237 | switch (GetHalftileSlopeCorner(corners)) { |
| 238 | case CORNER_W: |
| 239 | if (x > y) return GetSlopeMaxPixelZ(corners); |
| 240 | break; |
| 241 | |
| 242 | case CORNER_S: |
| 243 | if (x + y >= (int)TILE_SIZE) return GetSlopeMaxPixelZ(corners); |
| 244 | break; |
| 245 | |
| 246 | case CORNER_E: |
| 247 | if (x <= y) return GetSlopeMaxPixelZ(corners); |
| 248 | break; |
| 249 | |
| 250 | case CORNER_N: |
| 251 | if (x + y < (int)TILE_SIZE) return GetSlopeMaxPixelZ(corners); |
| 252 | break; |
| 253 | |
| 254 | default: NOT_REACHED(); |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | switch (RemoveHalftileSlope(corners)) { |
| 259 | case SLOPE_FLAT: return 0; |
| 260 | |
| 261 | /* One corner is up.*/ |
| 262 | case SLOPE_N: return x + y <= (int)TILE_SIZE ? (TILE_SIZE - x - y) >> 1 : 0; |
| 263 | case SLOPE_E: return y >= x ? (1 + y - x) >> 1 : 0; |
| 264 | case SLOPE_S: return x + y >= (int)TILE_SIZE ? (1 + x + y - TILE_SIZE) >> 1 : 0; |
| 265 | case SLOPE_W: return x >= y ? (x - y) >> 1 : 0; |
| 266 | |
| 267 | /* Two corners next to each other are up. */ |
| 268 | case SLOPE_NE: return (TILE_SIZE - x) >> 1; |
| 269 | case SLOPE_SE: return (y + 1) >> 1; |
| 270 | case SLOPE_SW: return (x + 1) >> 1; |
| 271 | case SLOPE_NW: return (TILE_SIZE - y) >> 1; |
| 272 | |
| 273 | /* Three corners are up on the same level. */ |
| 274 | case SLOPE_ENW: return x + y >= (int)TILE_SIZE ? TILE_HEIGHT - ((1 + x + y - TILE_SIZE) >> 1) : TILE_HEIGHT; |
| 275 | case SLOPE_SEN: return y < x ? TILE_HEIGHT - ((x - y) >> 1) : TILE_HEIGHT; |
| 276 | case SLOPE_WSE: return x + y <= (int)TILE_SIZE ? TILE_HEIGHT - ((TILE_SIZE - x - y) >> 1) : TILE_HEIGHT; |
| 277 | case SLOPE_NWS: return x < y ? TILE_HEIGHT - ((1 + y - x) >> 1) : TILE_HEIGHT; |
| 278 | |
| 279 | /* Two corners at opposite sides are up. */ |
| 280 | case SLOPE_NS: return x + y < (int)TILE_SIZE ? (TILE_SIZE - x - y) >> 1 : (1 + x + y - TILE_SIZE) >> 1; |
| 281 | case SLOPE_EW: return x >= y ? (x - y) >> 1 : (1 + y - x) >> 1; |
| 282 | |
| 283 | /* Very special cases. */ |
| 284 | case SLOPE_ELEVATED: return TILE_HEIGHT; |
| 285 | |
| 286 | /* Steep slopes. The top is at 2 * TILE_HEIGHT. */ |
| 287 | case SLOPE_STEEP_N: return (TILE_SIZE - x + TILE_SIZE - y) >> 1; |
| 288 | case SLOPE_STEEP_E: return (TILE_SIZE + 1 + y - x) >> 1; |
| 289 | case SLOPE_STEEP_S: return (1 + x + y) >> 1; |