/** * 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); }