Esempio n. 1
0
        /*********
        ** Private methods
        *********/
        /// <summary>Try to apply a map overlay patch.</summary>
        /// <param name="source">The source map to overlay.</param>
        /// <param name="target">The target map to overlay.</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 TryApplyMapPatch(Map source, Map target, out string error)
        {
            // read data
            Rectangle mapBounds = this.GetMapArea(source);

            if (!this.TryReadArea(this.FromArea, 0, 0, mapBounds.Width, mapBounds.Height, out Rectangle sourceArea, out error))
            {
                return(this.Fail($"the source area is invalid: {error}.", out error));
            }
            if (!this.TryReadArea(this.ToArea, 0, 0, sourceArea.Width, sourceArea.Height, out Rectangle targetArea, out error))
            {
                return(this.Fail($"the target area is invalid: {error}.", out error));
            }

            // validate area values
            string sourceAreaLabel = this.FromArea != null ? $"{nameof(this.FromArea)}" : "source map";
            string targetAreaLabel = this.ToArea != null ? $"{nameof(this.ToArea)}" : "target map";
            Point  sourceMapSize   = new Point(source.Layers.Max(p => p.LayerWidth), source.Layers.Max(p => p.LayerHeight));
            Point  targetMapSize   = new Point(target.Layers.Max(p => p.LayerWidth), target.Layers.Max(p => p.LayerHeight));

            if (!this.TryValidateArea(sourceArea, sourceMapSize, "source", out error))
            {
                return(this.Fail(error, out error));
            }
            if (!this.TryValidateArea(targetArea, targetMapSize, "target", out error))
            {
                return(this.Fail(error, out error));
            }
            if (sourceArea.Width != targetArea.Width || sourceArea.Height != targetArea.Height)
            {
                return(this.Fail($"{sourceAreaLabel} size (Width:{sourceArea.Width}, Height:{sourceArea.Height}) doesn't match {targetAreaLabel} size (Width:{targetArea.Width}, Height:{targetArea.Height}).", out error));
            }

            // apply source map
            AssetPatchUtilities.ApplyMapOverride(source: source, target: target, sourceArea: sourceArea, targetArea: targetArea);

            error = null;
            return(true);
        }
Esempio n. 2
0
        /// <summary>Load a matched asset.</summary>
        /// <param name="asset">Basic metadata about the asset being loaded.</param>
        public T Load <T>(IAssetInfo asset)
        {
            // load map
            if (asset.AssetNameEquals("Maps/Farm_Fishing"))
            {
                // load map
                Map map = this.Helper.Content.Load <Map>("assets/farm.tmx");

                // add islands
                if (this.Config.EnableIslands)
                {
                    Map islands = this.Helper.Content.Load <Map>("assets/islands.tmx");
                    AssetPatchUtilities.ApplyMapOverride(source: islands, target: map, targetArea: new Rectangle(0, 26, 56, 49));
                }

                // add campfire
                if (this.Config.AddCampfire)
                {
                    var buildingsLayer = map.GetLayer("Buildings");
                    buildingsLayer.Tiles[65, 23] = new StaticTile(buildingsLayer, map.GetTileSheet("zbeach"), BlendMode.Alpha, 157);              // driftwood pile
                    buildingsLayer.Tiles[64, 22] = new StaticTile(buildingsLayer, map.GetTileSheet("untitled tile sheet"), BlendMode.Alpha, 242); // campfire
                }

                // apply tilesheet recolors
                string internalRootKey = this.Helper.Content.GetActualAssetKey(Path.Combine(this.TilesheetsPath, "_default"));
                foreach (TileSheet tilesheet in map.TileSheets)
                {
                    if (tilesheet.ImageSource.StartsWith(internalRootKey + Path.DirectorySeparatorChar))
                    {
                        tilesheet.ImageSource = this.Helper.Content.GetActualAssetKey(Path.Combine(this.FakeAssetPrefix, Path.GetFileNameWithoutExtension(tilesheet.ImageSource)), ContentSource.GameContent);
                    }
                }

                return((T)(object)map);
            }

            // load tilesheet
            if (asset.AssetName.StartsWith(this.FakeAssetPrefix))
            {
                string filename = Path.GetFileName(asset.AssetName);
                if (!Path.HasExtension(filename))
                {
                    filename += ".png";
                }

                // get relative path to load
                string relativePath = new DirectoryInfo(this.GetFullPath(this.TilesheetsPath))
                                      .EnumerateDirectories()
                                      .FirstOrDefault(p => p.Name != "_default" && this.Helper.ModRegistry.IsLoaded(p.Name))
                                      ?.Name;
                relativePath = Path.Combine(this.TilesheetsPath, relativePath ?? "_default", filename);

                // load asset
                Texture2D tilesheet       = this.Helper.Content.Load <Texture2D>(relativePath);
                var       tilesheetPixels = new Lazy <Color[]>(() => this.GetPixels(tilesheet));

                // apply overlays
                foreach (DirectoryInfo folder in new DirectoryInfo(this.GetFullPath(this.OverlaysPath)).EnumerateDirectories())
                {
                    if (!this.Helper.ModRegistry.IsLoaded(folder.Name))
                    {
                        continue;
                    }

                    // get overlay
                    Texture2D overlay       = this.Helper.Content.Load <Texture2D>(Path.Combine(this.OverlaysPath, folder.Name, filename));
                    Color[]   overlayPixels = this.GetPixels(overlay);

                    // apply
                    Color[] target = tilesheetPixels.Value;
                    for (int i = 0; i < overlayPixels.Length; i++)
                    {
                        Color pixel = overlayPixels[i];
                        if (pixel.A >= ModEntry.MinOpacity)
                        {
                            target[i] = overlayPixels[i];
                        }
                    }
                }

                if (tilesheetPixels.IsValueCreated)
                {
                    tilesheet.SetData(tilesheetPixels.Value);
                }

                return((T)(object)tilesheet);
            }

            // unknown asset
            throw new NotSupportedException($"Unexpected asset '{asset.AssetName}'.");
        }