/**
* Draw canal or river edges.
* @param canal True if canal edges should be drawn, false for river edges.
* @param offset Sprite offset.
* @param tile Tile to draw.
*/
static void DrawWaterEdges(bool canal, uint offset, TileIndex tile)
{
CanalFeature feature;
SpriteID base = 0;
if (canal) {
feature = CF_DIKES;
base = GetCanalSprite(CF_DIKES, tile);
if (base == 0) base = SPR_CANAL_DIKES_BASE;
} else {
feature = CF_RIVER_EDGE;
base = GetCanalSprite(CF_RIVER_EDGE, tile);
if (base == 0) return; // Don't draw if no sprites provided.
}
uint wa;
/* determine the edges around with water. */
wa = IsWateredTile(TILE_ADDXY(tile, -1, 0), DIR_SW) << 0; // NE
wa += IsWateredTile(TILE_ADDXY(tile, 0, 1), DIR_NW) << 1; // SE
wa += IsWateredTile(TILE_ADDXY(tile, 1, 0), DIR_NE) << 2; // SW
wa += IsWateredTile(TILE_ADDXY(tile, 0, -1), DIR_SE) << 3; // NW
Slope tileh = GetTileSlope(tile);
if (!(wa & 1)) {
DrawWaterSprite(base, offset, feature, tile);
if (tileh == SLOPE_N) DrawWaterSprite(base, offset + 48, feature, tile);
if (tileh == SLOPE_E) DrawWaterSprite(base, offset + 12, feature, tile);
}
if (!(wa & 2)) {
DrawWaterSprite(base, offset + 1, feature, tile);
if (tileh == SLOPE_E) DrawWaterSprite(base, offset + 25, feature, tile);
if (tileh == SLOPE_S) DrawWaterSprite(base, offset + 37, feature, tile);
}
if (!(wa & 4)) {
DrawWaterSprite(base, offset + 2, feature, tile);
if (tileh == SLOPE_S) DrawWaterSprite(base, offset + 14, feature, tile);
if (tileh == SLOPE_W) DrawWaterSprite(base, offset + 50, feature, tile);
}
if (!(wa & 8)) {
DrawWaterSprite(base, offset + 3, feature, tile);
if (tileh == SLOPE_W) DrawWaterSprite(base, offset + 39, feature, tile);
if (tileh == SLOPE_N) DrawWaterSprite(base, offset + 27, feature, tile);
}
/* right corner */
switch (wa & 0x03) {
case 0: DrawWaterSprite(base, offset + 4, feature, tile); break;
case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1), DIR_W)) DrawWaterSprite(base, offset + 8, feature, tile); break;
}
/* bottom corner */
switch (wa & 0x06) {
case 0: DrawWaterSprite(base, offset + 5, feature, tile); break;
case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1), DIR_N)) DrawWaterSprite(base, offset + 9, feature, tile); break;
}
/* left corner */
switch (wa & 0x0C) {
case 0: DrawWaterSprite(base, offset + 6, feature, tile); break;
case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1), DIR_E)) DrawWaterSprite(base, offset + 10, feature, tile); break;
}
/* upper corner */
switch (wa & 0x09) {
case 0: DrawWaterSprite(base, offset + 7, feature, tile); break;
case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1), DIR_S)) DrawWaterSprite(base, offset + 11, feature, tile); break;
}
}
static void DrawRiverWater(const TileInfo *ti)
{
SpriteID image = SPR_FLAT_WATER_TILE;
uint offset = 0;
uint edges_offset = 0;
if (ti->tileh != SLOPE_FLAT || HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
image = GetCanalSprite(CF_RIVER_SLOPE, ti->tile);
if (image == 0) {
switch (ti->tileh) {
case SLOPE_NW: image = SPR_WATER_SLOPE_Y_DOWN; break;
case SLOPE_SW: image = SPR_WATER_SLOPE_X_UP; break;
case SLOPE_SE: image = SPR_WATER_SLOPE_Y_UP; break;
case SLOPE_NE: image = SPR_WATER_SLOPE_X_DOWN; break;
default: image = SPR_FLAT_WATER_TILE; break;
}
} else {
/* Flag bit 0 indicates that the first sprite is flat water. */
offset = HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE) ? 1 : 0;
switch (ti->tileh) {
case SLOPE_SE: edges_offset += 12; break;
case SLOPE_NE: offset += 1; edges_offset += 24; break;
case SLOPE_SW: offset += 2; edges_offset += 36; break;
case SLOPE_NW: offset += 3; edges_offset += 48; break;
case SLOPE_E: offset = 0; edges_offset = 0; break;
case SLOPE_S: offset = 0; edges_offset = 0; break;
case SLOPE_W: offset = 0; edges_offset = 0; break;
case SLOPE_N: offset = 0; edges_offset = 0; break;
default: offset = 0; break;
}
offset = GetCanalSpriteOffset(CF_RIVER_SLOPE, ti->tile, offset);
}
}
DrawGroundSprite(image + offset, PAL_NONE);
/* Draw river edges if available. */
DrawWaterEdges(false, edges_offset, ti->tile);
}