public static void ClientPaste(Vector2Ushort tilePosition) { if (lastBufferEntry is null) { return; } var bufferEntry = lastBufferEntry.Value; if (ClientEditorAreaSelectorHelper.Instance is not null) { NotificationSystem.ClientShowNotification( title: null, message: "You're already in object placement mode." + ObjectPlacementGuide, color: NotificationColor.Neutral); return; } NotificationSystem.ClientShowNotification( title: null, message: $"{bufferEntry.Entries.Count} tiles ready for paste!" + ObjectPlacementGuide, color: NotificationColor.Good); var originalSize = bufferEntry.Size; // ReSharper disable once ObjectCreationAsStatement new ClientEditorAreaSelectorHelper(tilePosition, originalSize, selectedCallback: PlaceSelectedCallback); void PlaceSelectedCallback(Vector2Ushort selectedTilePosition) { var entries = bufferEntry.Entries .Select(e => e.ApplyOffset(selectedTilePosition)) .ToList(); TerrainEditingSystem.ClientModifyTerrain(entries); } }
private void ClientPlaceAt(List <Vector2Ushort> tilePositions, IProtoTile selectedProtoTile, bool isRepeat) { var terrainHeightMode = this.settings.SelectedHeightMode.Value; var isAllowTileKindChange = this.settings.IsAllowTileKindChange; var isAllowTileProtoChangeOnlyOnTheSameHeight = this.settings.IsAllowTileProtoChangeOnlyOnTheSameHeight; var isApplyOnlyOnTheSameTileProto = this.settings.IsApplyOnlyOnTheSameTileProto; if (this.settings.IsFillMode) { if (isRepeat) { // fill doesn't support repeat return; } tilePositions = EditorTileHelper.GatherAllTilePositionsOfTheSameProtoTile( tilePositions[0], onlyOnTheSameHeight: isAllowTileProtoChangeOnlyOnTheSameHeight, ignoreCliffsAndSlopes: false); // don't change the tile heights in the fill mode terrainHeightMode = TerrainHeightMode.Keep; } var worldService = Client.World; byte targetHeight = 0; IProtoTile targetProto = null; if (isRepeat) { // use target height from previous iteration targetHeight = this.lastTargetHeight; targetProto = this.lastTargetProto; } else { if (isApplyOnlyOnTheSameTileProto) { targetProto = EditorTileHelper.CalculateMostFrequentTileProto(tilePositions); } switch (terrainHeightMode) { case TerrainHeightMode.Keep: case TerrainHeightMode.Flatten: // calculate average height for all the tiles targetHeight = EditorTileHelper.CalculateAverageHeight(tilePositions); break; case TerrainHeightMode.Increase: targetHeight = byte.MaxValue; goto case TerrainHeightMode.Decrease; case TerrainHeightMode.Decrease: // calculate target height foreach (var tilePosition in tilePositions) { var tile = worldService.GetTile(tilePosition); var calculatedNewTileHeight = this.CalculateNewTileHeight(tile, terrainHeightMode); if (terrainHeightMode == TerrainHeightMode.Increase && calculatedNewTileHeight < targetHeight || terrainHeightMode == TerrainHeightMode.Decrease && calculatedNewTileHeight > targetHeight) { targetHeight = calculatedNewTileHeight; } } break; } } this.lastTargetHeight = targetHeight; this.lastTargetProto = targetProto; var tilesToModify = new List <TerrainEditingSystem.TileModifyRequest>(); foreach (var tilePosition in tilePositions) { var tile = worldService.GetTile(tilePosition); var previousProtoTile = tile.ProtoTile; var previousTileHeight = tile.Height; var previousIsSlope = tile.IsSlope; var newProtoTile = selectedProtoTile ?? previousProtoTile; var newIsSlope = tile.IsSlope; if (isApplyOnlyOnTheSameTileProto && previousProtoTile != targetProto) { continue; } if (isAllowTileProtoChangeOnlyOnTheSameHeight && this.lastTargetHeight != previousTileHeight) { continue; } if (!isAllowTileKindChange && previousProtoTile.Kind != newProtoTile.Kind && previousProtoTile.Kind != TileKind.Placeholder) { continue; } var newTileHeight = previousTileHeight; if (terrainHeightMode == TerrainHeightMode.Flatten) { if (IsValidHeightFotTile(tile, targetHeight)) { // can set tile height to target height newTileHeight = targetHeight; } } else if (terrainHeightMode == TerrainHeightMode.Increase || terrainHeightMode == TerrainHeightMode.Decrease) { newTileHeight = this.CalculateNewTileHeight(tile, terrainHeightMode); if (newTileHeight != targetHeight) { // cannot change tile height newTileHeight = previousTileHeight; } } if (previousProtoTile == newProtoTile && newTileHeight == previousTileHeight && newIsSlope == previousIsSlope) { // nothing to change - the tile is already as desired continue; } tilesToModify.Add(new TerrainEditingSystem.TileModifyRequest( tilePosition, newProtoTile.SessionIndex, newTileHeight, newIsSlope)); } TerrainEditingSystem.ClientModifyTerrain(tilesToModify); }