Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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);
        }