/** * 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())); } } }
void CopyPastePlaceRailWaypoint(GenericTileIndex tile, StationID sid, Axis axis, RailType rt, StationGfx gfx, StationClassID stat_class, byte stat_type, int specindex, bool adjacent) { if (IsMainMapTile(tile)) { TileIndex t = AsMainMapTile(tile); /* check if required track is already there, try to build one if not */ if (!IsTileOwner(t, _current_company) || (!IsRailWaypointTile(tile) && !IsPlainRailTile(tile)) || GetRailType(t) != rt || (IsTileType(t, MP_STATION) ? GetRailStationAxis(tile) != axis : !HasBit(GetTrackBits(t), AxisToTrack(axis)))) { CopyPastePlaceTracks(tile, rt, AxisToTrackBits(axis)); if (_current_pasting->last_result.Failed()) return; } /* build the waypoint */ _station_cmd_specindex_to_paste = specindex; uint32 p1 = 0; SB(p1, 0, 4, rt); SB(p1, 4, 1, axis); SB(p1, 8, 8, 1); // width SB(p1, 16, 8, 1); // height SB(p1, 24, 1, adjacent); uint32 p2 = 0; SB(p2, 0, 8, stat_class); SB(p2, 8, 8, stat_type); SB(p2, 16, 16, sid); _current_pasting->DoCommand(t, p1, p2, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT)); } else { MakeRailWaypoint(tile, OWNER_NONE, sid, axis, gfx & ~1, rt); assert(IsInsideMM(specindex, 0, MAX_UVALUE(byte) + 1)); SetCustomStationSpecIndex(tile, (byte)specindex); _clipboard_stations_builder.AddRailPart(sid, stat_class, stat_type, (byte)specindex); } }
/** * Do a sequential copy-pasting by calling appropriate CopyPasteCommandProc on each selected tile. * @param copy_paste What, where and how we are copying. */ static inline void DoCopyPaste(const CopyPasteParams ©_paste) { /* Copying to the clipboard buffer should always success. * Some content may be intransformable (e.g. airport) so we can't use any transformation. */ assert(IsMainMapTile(copy_paste.dst_area.tile) || (copy_paste.transformation == DTR_IDENTITY && (copy_paste.mode & CPM_TERRAFORM_MASK) == CPM_TERRAFORM_FULL)); if ((copy_paste.mode & CPM_TERRAFORM_MASK) == CPM_TERRAFORM_FULL) { CopyPasteHeights(copy_paste.src_area, copy_paste.dst_area.tile, copy_paste.transformation, copy_paste.height_delta); if (IsPastingInterrupted()) return; } for (TransformationTileIteratorT<true, true> ti(copy_paste.src_area, copy_paste.src_area.TransformedNorth(copy_paste.dst_area.tile, copy_paste.transformation), copy_paste.transformation); IsValidTileIndex(ti); ++ti) { CopyPasteTileProc *proc = _tile_type_procs[GetTileType(ti.SrcTile())]->copy_paste_tile_proc; if (proc == NULL) continue; proc(ti.SrcTile(), ti.DstTile(), copy_paste); if (IsPastingInterrupted()) break; } if (IsMainMapTile(copy_paste.dst_area.tile)) { AfterPastingStations(copy_paste); } else { AfterCopyingStations(copy_paste); } }
void CopyPastePlaceBuoy(GenericTileIndex tile, StationID sid, WaterClass wc) { if (IsMainMapTile(tile)) { TileIndex t = AsMainMapTile(tile); /* build a piece of canal if not on water */ if (!HasTileWaterGround(t)) { CopyPastePlaceCannal(tile); if (_current_pasting->last_result.Failed()) return; } /* build the buoy */ _current_pasting->DoCommand(t, 0, 0, CMD_BUILD_BUOY | CMD_MSG(STR_ERROR_CAN_T_POSITION_BUOY_HERE)); } else { SetTileOwner(tile, OWNER_NONE); MakeBuoy(tile, sid, wc); _clipboard_stations_builder.AddPart(sid); } }