/** * Test if a given TileArea is valid. * @return \c true if the area is non-empty and fits inside the map, \c false otherwise. */ static CommandCost ValParamCopyPasteArea(const GenericTileArea &ta) { if (!IsValidTile(ta.tile) || !IsInsideBS(ta.w, 1, _settings_game.construction.clipboard_capacity) || !IsInsideBS(ta.h, 1, _settings_game.construction.clipboard_capacity)) { return CMD_ERROR; } if (TileX(ta.tile) + ta.w > MapMaxX(MapOf(ta.tile)) || TileY(ta.tile) + ta.h > MapMaxY(MapOf(ta.tile))) { return_cmd_error(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB); } return CommandCost(); }
/** * Copy and paste heights from one map to another. * * @param src_area Area to read heights from. It consists of tiles, not of tile corners * e.g. if you pass a single tile area then 4 corners will be terraformed. * @param dst_area_north Norhern tile of the area to write heigths at. * @param transformation Transformation to perform on tile indices. * @param height_delta Offset, number of units to add to each height. */ void CopyPasteHeights(const GenericTileArea &src_area, GenericTileIndex dst_area_north, DirTransformation transformation, int height_delta) { /* include also corners at SW and SE edges */ GenericTileArea src_corners(src_area.tile, src_area.w + 1, src_area.h + 1); /* transform the most northern corner */ GenericTileIndex transformed_north_corner = src_corners.TransformedNorth(dst_area_north, transformation); #ifdef WITH_ASSERT { assert(IsValidTileIndex(dst_area_north)); uint x = TileX(dst_area_north); uint y = TileY(dst_area_north); assert(!IsMainMapTile(dst_area_north) || !_settings_game.construction.freeform_edges || (x > 0 && y > 0)); Dimension dst_dim = { src_corners.w, src_corners.h }; dst_dim = TransformDimension(dst_dim, transformation); assert(x + dst_dim.width <= MapSizeX(MapOf(dst_area_north)) && y + dst_dim.height <= MapSizeY(MapOf(dst_area_north))); } #endif /* WITH_ASSERT */ if (IsMainMapTile(dst_area_north)) { HeightsCopyPastingIterator iter(src_corners, AsMainMapTile(transformed_north_corner), transformation, height_delta); TerraformPasteTiles(&iter); } else { for (TransformationTileIteratorT<true, true> iter(src_corners, transformed_north_corner, transformation); IsValidTileIndex(iter); ++iter) { SetTileHeight(iter.DstTile(), TileHeight(iter.SrcTile())); } } }
GenericTileIndex TileAddXY(GenericTileIndex tile, int dx, int dy, const char *exp, const char *file, int line) { uint x = TileX(tile) + dx; uint y = TileY(tile) + dy; if (x >= MapSizeX(MapOf(tile)) || y >= MapSizeY(MapOf(tile))) { char buf[512]; snprintf(buf, lengthof(buf), "TILE_ADDXY(%s) when adding 0x%.4X and <0x%.4X, 0x%.4X> failed", exp, IndexOf(tile), dx, dy); #if !defined(_MSC_VER) || defined(WINCE) fprintf(stderr, "%s:%d %s\n", file, line, buf); #else _assert(buf, (char*)file, line); #endif } return TileXY<true>(x, y, MapOf(tile)); }
static typename TileIndexT<Tgeneric>::T GetBridgeEnd(typename TileIndexT<Tgeneric>::T tile, DiagDirection dir) { TileIndexDiff delta = TileOffsByDiagDir<Tgeneric>(dir, MapOf(tile)); dir = ReverseDiagDir(dir); do { tile += delta; } while (!IsBridgeTile(tile) || GetTunnelBridgeDirection(tile) != dir); return tile; }
typename TileIndexT<Tgeneric>::T GetOtherTunnelEnd(typename TileIndexT<Tgeneric>::T tile) { assert(IsTunnelTile(tile)); DiagDirection dir = GetTunnelBridgeDirection(tile); TileIndexDiff delta = TileOffsByDiagDir<Tgeneric>(dir, MapOf(tile)); uint h = TileHeight(tile); if (dir == DIAGDIR_NE || dir == DIAGDIR_NW) { h--; continue_ne_nw: do { tile += delta; } while (TileHeight(tile) != h); } else { continue_se_sw: tile += delta; do { tile += delta; } while (TileHeight(tile) != h); tile -= delta; } if (IsTunnelTile(tile) && GetTunnelBridgeDirection(tile) == ReverseDiagDir(dir)) { } else { /* Handle Chunnels. * Only look for tunnel when hight level changes. * And only at sea level. */ assert(h <= 1); (h == 0) ? h = 1 : h = 0; if (dir == DIAGDIR_NE || dir == DIAGDIR_NW) { goto continue_ne_nw; } else { goto continue_se_sw; } } return tile; }
virtual TileIterator &operator ++() { this->Advance(&IndexOf(this->src_tile), MapOf(this->src_tile), this->MyIndex(), this->MyMap()); return *this; }