Esempio n. 1
0
        /// <summary>Try to apply a map tile patch.</summary>
        /// <param name="map">The target map to patch.</param>
        /// <param name="tilePatch">The tile patch info.</param>
        /// <param name="error">An error indicating why applying the patch failed, if applicable.</param>
        /// <returns>Returns whether applying the patch succeeded.</returns>
        private bool TryApplyTile(Map map, EditMapPatchTile tilePatch, out string error)
        {
            // parse tile data
            if (!this.TryReadTile(tilePatch, out string layerName, out Location position, out int?setIndex, out string setTilesheetId, out IDictionary <string, string> setProperties, out bool removeTile, out error))
            {
                return(this.Fail(error, out error));
            }
            bool hasEdits = setIndex != null || setTilesheetId != null || setProperties.Any();

            // get layer
            var layer = map.GetLayer(layerName);

            if (layer == null)
            {
                return(this.Fail($"{nameof(PatchMapTileConfig.Layer)} specifies a '{layerName}' layer which doesn't exist.", out error));
            }

            // get tilesheet
            TileSheet setTilesheet = null;

            if (setTilesheetId != null)
            {
                setTilesheet = map.GetTileSheet(setTilesheetId);
                if (setTilesheet == null)
                {
                    return(this.Fail($"{nameof(PatchMapTileConfig.SetTilesheet)} specifies a '{setTilesheetId}' tilesheet which doesn't exist.", out error));
                }
            }

            // get original tile
            if (!layer.IsValidTileLocation(position))
            {
                return(this.Fail($"{nameof(PatchMapTileConfig.Position)} specifies a tile position '{position.X}, {position.Y}' which is outside the map area.", out error));
            }
            Tile original = layer.Tiles[position];

            // if adding a new tile, the min tile info is required
            if (hasEdits && (removeTile || original == null) && (setTilesheet == null || setIndex == null))
            {
                return(this.Fail($"the map has no tile at {layerName} ({position.X}, {position.Y}). To add a tile, the {nameof(PatchMapTileConfig.SetTilesheet)} and {nameof(PatchMapTileConfig.SetIndex)} fields must be set.", out error));
            }

            // apply new tile
            if (removeTile)
            {
                layer.Tiles[position] = null;
            }
            if (setTilesheet != null || setIndex != null || setProperties.Any())
            {
                var tile = new StaticTile(layer, setTilesheet ?? original.TileSheet, original?.BlendMode ?? BlendMode.Alpha, setIndex ?? original.TileIndex);
                foreach (var pair in setProperties)
                {
                    tile.Properties[pair.Key] = pair.Value;
                }
                layer.Tiles[position] = tile;
            }

            error = null;
            return(true);
        }
Esempio n. 2
0
        /// <summary>Try to read a map tile patch to apply.</summary>
        /// <param name="tile">The map tile patch.</param>
        /// <param name="layerName">The parsed layer name.</param>
        /// <param name="position">The parsed tile position.</param>
        /// <param name="setIndex">The parsed tile index.</param>
        /// <param name="setTilesheetId">The parsed tilesheet ID.</param>
        /// <param name="properties">The parsed tile properties.</param>
        /// <param name="remove">The parsed remove flag.</param>
        /// <param name="error">An error indicating why parsing failed, if applicable.</param>
        /// <returns>Returns whether parsing the tile succeeded.</returns>
        private bool TryReadTile(EditMapPatchTile tile, out string?layerName, out Location position, out int?setIndex, out string?setTilesheetId, out IDictionary <string, string?> properties, out bool remove, [NotNullWhen(false)] out string?error)
        {
            // init
            setIndex   = null;
            position   = Location.Origin;
            properties = new Dictionary <string, string?>();
            remove     = false;

            // layer & tilesheet
            layerName      = tile.Layer?.Value;
            setTilesheetId = tile.SetTilesheet?.Value;

            // set index
            if (tile.SetIndex.IsMeaningful())
            {
                if (!int.TryParse(tile.SetIndex.Value, out int parsed))
                {
                    return(this.Fail($"{nameof(PatchMapTileConfig.SetIndex)} specifies '{tile.SetIndex}', which isn't a valid number.", out error));
                }
                setIndex = parsed;
            }

            // position
            if (!tile.Position.TryGetLocation(out position, out error))
            {
                return(this.Fail($"{nameof(PatchMapTileConfig.Position)} specifies '{tile.Position.X}, {tile.Position.Y}', which isn't a valid position.", out error));
            }

            // tile properties
            foreach ((ITokenString key, ITokenString? value) in tile.SetProperties)
            {
                properties[key.Value !] = value?.Value;
Esempio n. 3
0
        /// <summary>Try to read a map tile patch to apply.</summary>
        /// <param name="tile">The map tile patch.</param>
        /// <param name="layerName">The parsed layer name.</param>
        /// <param name="position">The parsed tile position.</param>
        /// <param name="setIndex">The parsed tile index.</param>
        /// <param name="setTilesheetId">The parsed tilesheet ID.</param>
        /// <param name="properties">The parsed tile properties.</param>
        /// <param name="remove">The parsed remove flag.</param>
        /// <param name="error">An error indicating why parsing failed, if applicable.</param>
        /// <returns>Returns whether parsing the tile succeeded.</returns>
        private bool TryReadTile(EditMapPatchTile tile, out string layerName, out Location position, out int?setIndex, out string setTilesheetId, out IDictionary <string, string> properties, out bool remove, out string error)
        {
            // init
            layerName      = null;
            setIndex       = null;
            setTilesheetId = null;
            position       = Location.Origin;
            properties     = new Dictionary <string, string>();
            remove         = false;

            // layer & tilesheet
            layerName      = tile.Layer?.Value;
            setTilesheetId = tile.SetTilesheet?.Value;

            // set index
            if (tile.SetIndex.IsMeaningful())
            {
                if (!int.TryParse(tile.SetIndex.Value, out int parsed))
                {
                    return(this.Fail($"{nameof(PatchMapTileConfig.SetIndex)} specifies '{tile.SetIndex}', which isn't a valid number.", out error));
                }
                setIndex = parsed;
            }

            // position
            if (!tile.Position.TryGetLocation(out position, out error))
            {
                return(this.Fail($"{nameof(PatchMapTileConfig.Position)} specifies '{tile.Position.X}, {tile.Position.Y}', which isn't a valid position.", out error));
            }

            // tile properties
            if (tile.SetProperties != null)
            {
                foreach (var pair in tile.SetProperties)
                {
                    properties[pair.Key.Value] = pair.Value.Value;
                }
            }

            // remove
            if (tile.Remove.IsMeaningful())
            {
                if (!bool.TryParse(tile.Remove.Value, out remove))
                {
                    return(this.Fail($"{nameof(PatchMapTileConfig.Remove)} specifies '{tile.Remove}', which isn't a valid boolean value (must be 'true' or 'false').", out error));
                }
            }

            error = null;
            return(true);
        }