public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("Data/Furniture")) { foreach (ItemFrameData ifd in ItemFrameMod.itemFrameDatum) { string lw = $"{(int)(ifd.texture.Width / 16)} {(int)(ifd.texture.Height / 16)}"; string bb = $"{(int)(ifd.texture.Width / 16)} {Math.Min(2, (int)(ifd.texture.Height / 16))}"; string entry = $"'{ifd.displayName}'/painting/{lw}/{bb}/1/100"; this.Monitor.Log($"Adding {ifd.id} {entry}", LogLevel.Trace); asset.AsDictionary <int, string>().Data.Add(ifd.id, entry); } } else if (asset.AssetNameEquals("TileSheets/furniture")) { //int newHeight = this.nextID/16 + 32; //this.Monitor.Log($"Setting Tilesheet height to {newHeight} based on last tile {this.nextID}", LogLevel.Debug); var oldTex = asset.AsImage().Data; Texture2D newTex = new Texture2D(Game1.graphics.GraphicsDevice, oldTex.Width, Math.Max(oldTex.Height, 4096)); asset.ReplaceWith(newTex); asset.AsImage().PatchImage(oldTex); foreach (ItemFrameData ifd in ItemFrameMod.itemFrameDatum) { Rectangle target = furnitureRect(ifd.id, ifd.texture); this.Monitor.Log($"Inserting texture at ({target.X}, {target.Y})", LogLevel.Trace); asset.AsImage().PatchImage(ifd.texture, targetArea: target); } } }
public void Edit <T>(IAssetData assetData) { AssetTexture assetTexture; string assetName = assetData.AssetName.Replace("/", $"\\"); if (!AssetTextures.ContainsKey(assetName)) { Texture2D texture = this.HDAssetManager.LoadAsset(assetName); assetTexture = new AssetTexture(assetName, assetData.AsImage().Data, texture, this.Config.AssetScale, WhiteBoxFixAssets.Contains(assetName)); AssetTextures.Add(assetName, assetTexture); } else { assetTexture = AssetTextures.GetValueSafe(assetName); if (assetData.AsImage().Data.Bounds.Equals(assetTexture.Bounds)) { assetTexture.SetOriginalTexture(assetData.AsImage().Data); } else { AssetTextures[assetName] = assetTexture = new AssetTexture(assetName, assetData.AsImage().Data, assetTexture.HDTexture, this.Config.AssetScale, WhiteBoxFixAssets.Contains(assetName)); } } this.ContentPackManager.EditAsset(assetName); if (GraphicsDevice == null) { GraphicsDevice = assetTexture.GraphicsDevice; } assetData.AsImage().ReplaceWith(assetTexture); }
private void injectTileSheetsCrops(IAssetData asset) { var oldTex = asset.AsImage().Data; Texture2D newTex = new Texture2D(Game1.graphics.GraphicsDevice, oldTex.Width, Math.Max(oldTex.Height, 4096)); asset.ReplaceWith(newTex); asset.AsImage().PatchImage(oldTex); foreach (var crop in Mod.instance.crops) { try { Log.verbose($"Injecting {crop.Name} crop images @ {cropRect(crop.GetCropSpriteIndex())}"); asset.AsImage().PatchExtendedTileSheet(crop.texture, null, cropRect(crop.GetCropSpriteIndex())); var rect = cropRect(crop.GetCropSpriteIndex()); var target = TileSheetExtensions.GetAdjustedTileSheetTarget(asset.AssetName, rect); int ts = target.TileSheet; crop.tilesheet = asset.AssetName + (ts == 0 ? "" : (ts + 1).ToString()); crop.tilesheetX = rect.X; crop.tilesheetY = target.Y; } catch (Exception e) { Log.error($"Exception injecting crop sprite for {crop.Name}: {e}"); } } }
private void injectCharactersFarmerHats(IAssetData asset) { var oldTex = asset.AsImage().Data; Texture2D newTex = new Texture2D(Game1.graphics.GraphicsDevice, oldTex.Width, Math.Max(oldTex.Height, 4096)); asset.ReplaceWith(newTex); asset.AsImage().PatchImage(oldTex); Log.trace($"Hats are now ({oldTex.Width}, {Math.Max(oldTex.Height, 4096)})"); foreach (var hat in Mod.instance.hats) { try { Log.verbose($"Injecting {hat.Name} sprites @ {hatRect(hat.GetHatId())}"); asset.AsImage().PatchExtendedTileSheet(hat.texture, null, hatRect(hat.GetHatId())); var rect = hatRect(hat.GetHatId()); var target = TileSheetExtensions.GetAdjustedTileSheetTarget(asset.AssetName, rect); int ts = target.TileSheet; hat.tilesheet = asset.AssetName + (ts == 0 ? "" : (ts + 1).ToString()); hat.tilesheetX = rect.X; hat.tilesheetY = target.Y; } catch (Exception e) { Log.error($"Exception injecting sprite for {hat.Name}: {e}"); } } }
private void injectTileSheetsWeapons(IAssetData asset) { var oldTex = asset.AsImage().Data; Texture2D newTex = new Texture2D(Game1.graphics.GraphicsDevice, oldTex.Width, Math.Max(oldTex.Height, 4096)); asset.ReplaceWith(newTex); asset.AsImage().PatchImage(oldTex); Log.trace($"Weapons are now ({oldTex.Width}, {Math.Max(oldTex.Height, 4096)})"); foreach (var weapon in Mod.instance.weapons) { try { Log.verbose($"Injecting {weapon.Name} sprites @ {weaponRect(weapon.GetWeaponId())}"); asset.AsImage().PatchImage(weapon.texture, null, weaponRect(weapon.GetWeaponId())); var rect = weaponRect(weapon.GetWeaponId()); int ts = 0;// TileSheetExtensions.GetAdjustedTileSheetTarget(asset.AssetName, rect).TileSheet; weapon.tilesheet = asset.AssetName + (ts == 0 ? "" : (ts + 1).ToString()); weapon.tilesheetX = rect.X; weapon.tilesheetY = rect.Y; } catch (Exception e) { Log.error($"Exception injecting sprite for {weapon.Name}: {e}"); } } }
private void injectTileSheetsFruitTrees(IAssetData asset) { var oldTex = asset.AsImage().Data; Texture2D newTex = new Texture2D(Game1.graphics.GraphicsDevice, oldTex.Width, Math.Max(oldTex.Height, 4096)); asset.ReplaceWith(newTex); asset.AsImage().PatchImage(oldTex); foreach (var fruitTree in Mod.instance.fruitTrees) { try { Log.verbose($"Injecting {fruitTree.Name} fruit tree images @ {fruitTreeRect(fruitTree.GetFruitTreeIndex())}"); asset.AsImage().PatchExtendedTileSheet(fruitTree.texture, null, fruitTreeRect(fruitTree.GetFruitTreeIndex())); var rect = fruitTreeRect(fruitTree.GetFruitTreeIndex()); int ts = TileSheetExtensions.GetAdjustedTileSheetTarget(asset.AssetName, rect).TileSheet; fruitTree.tilesheet = asset.AssetName + (ts == 0 ? "" : (ts + 1).ToString()); fruitTree.tilesheetX = rect.X; fruitTree.tilesheetY = rect.Y; } catch (Exception e) { Log.error($"Exception injecting fruit tree sprite for {fruitTree.Name}: {e}"); } } }
/// <summary>Edit a matched asset.</summary> /// <param name="asset">A helper which encapsulates metadata about an asset and enables changes to it.</param> public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("Maps/Mines/mine") || asset.AssetNameEquals("Maps/Mines/mine_dark") || asset.AssetNameEquals("Maps/Mines/mine_dino") || asset.AssetNameEquals("Maps/Mines/mine_frost") || asset.AssetNameEquals("Maps/Mines/mine_lava") || asset.AssetNameEquals("Maps/Mines/mine_frost_dark") || asset.AssetNameEquals("Maps/Mines/minequarryshaft") || asset.AssetNameEquals("Maps/Mines/mine_lava_dark") || asset.AssetNameEquals("Maps/Mines/mine_slime") || asset.AssetNameEquals("Maps/Mines/mine") || asset.AssetNameEquals("Maps/Mines/mine_dark")) { Texture2D customTexture = this.Helper.Content.Load <Texture2D>("Maps/Mines/mine_desert", ContentSource.GameContent); asset .AsImage() .PatchImage(customTexture, sourceArea: new Rectangle(224, 160, 16, 16), targetArea: new Rectangle(224, 160, 16, 16)); } else if (asset.AssetNameEquals("TileSheets/Craftables")) { Texture2D customTexture = this.Helper.Content.Load <Texture2D>("Maps/Mines/mine_desert", ContentSource.GameContent); asset .AsImage() .PatchImage(customTexture, sourceArea: new Rectangle(224, 160, 16, 16), targetArea: new Rectangle(112, 144, 16, 16)); } else if (asset.AssetNameEquals("Data/CraftingRecipes")) { IDictionary <string, string> data = asset.AsDictionary <string, string>().Data; data.Add("Mine Shaft", $"{Config.ShaftCost}/Field/39/true/{Config.SkillReq}"); } else if (asset.AssetNameEquals("Data/BigCraftablesInformation")) { IDictionary <int, string> data = asset.AsDictionary <int, string>().Data; data.Add(39, "Mine Shaft/0/-300/Crafting -9/Use this to move down several levels in the mines./true/false/1/Mine Shaft"); } }
public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("Maps\\springobjects")) { Texture2D data = ((IAssetData <Texture2D>)asset.AsImage()).Data; Texture2D texture2D = new Texture2D(Game1.graphics.GraphicsDevice, data.Width, Math.Max(data.Height, 4096)); ((IAssetData <object>)asset).ReplaceWith((object)texture2D); asset.AsImage().PatchImage(data, new Rectangle?(), new Rectangle?(), (PatchMode)0); try { asset.AsImage().PatchImage(TextureSet.voidShroomSpore, new Rectangle?(), new Rectangle?(this.objectRect(spore.ParentSheetIndex)), (PatchMode)0); } catch (Exception) { } } else if (asset.AssetNameEquals("Data\\ObjectInformation")) { IDictionary <int, string> data = ((IAssetData <IDictionary <int, string> >)asset.AsDictionary <int, string>()).Data; if (!data.ContainsKey(spore.ParentSheetIndex)) { data.Add(spore.ParentSheetIndex, spore.getObjectData()); } } }
/// <summary>Cuts the empty image from the texture.</summary> /// <param name="asset">The asset to cut</param> /// <param name="newHeight">The assets new height</param> /// <param name="newWidth">The assets new width</param> private void CutEmptyImage(IAssetData asset, int newHeight, int newWidth) { Texture2D oldTexture = asset.AsImage().Data; Texture2D cutTexture = new Texture2D(Game1.graphics.GraphicsDevice, oldTexture.Width, newHeight); asset.ReplaceWith(cutTexture); asset.AsImage().PatchImage(oldTexture, new Rectangle(0, 0, newWidth, newHeight), new Rectangle(0, 0, newWidth, newHeight)); }
/// <summary> /// Creates a new texture from the data of the old texture. /// </summary> private void CreateNewTexture() { Texture2D oldTexture = Asset.AsImage().Data; Texture2D newTexture = new Texture2D(Game1.graphics.GraphicsDevice, oldTexture.Width, Math.Max(oldTexture.Height, 4096)); Asset.ReplaceWith(newTexture); Asset.AsImage().PatchImage(oldTexture); }
/// <summary>Implements <see cref="IAssetEditor.Edit"/>.</summary> public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("Characters/Haley") || asset.AssetNameEquals("Portraits/Haley")) { this.Monitor.Log($"Edit asset {asset.AssetName}"); IAssetDataForImage baseImage = asset.AsImage(); Texture2D overlay; // Support for Cold Weather Haley. if (hasColdWeatherHaley_ && Game1.IsWinter) { overlay = this.Helper.Content.Load <Texture2D>($"assets/{asset.AssetName}_winter_overlay_hair_gray.png"); // Workaround for the missing sleeping sprite of Cold Weather Haley. if (asset.AssetNameEquals("Characters/Haley")) { Texture2D sleepingHaley = this.Helper.Content.Load <Texture2D>($"assets/{asset.AssetName}_sleeping.png"); baseImage.PatchImage(sleepingHaley, patchMode: PatchMode.Overlay); } } // Support for RandomFlowerQueen. else if (hasRandomFlowerQueen_ && asset.AssetNameEquals("Characters/Haley")) { // We must replace the flowerqueen part of the base image since it contains unwanted pixels. Texture2D haleyNoFlowercrown = this.Helper.Content.Load <Texture2D>($"assets/{asset.AssetName}_no_flowercrown.png"); baseImage.PatchImage(haleyNoFlowercrown, targetArea: new Rectangle(0, 320, 64, 64), patchMode: PatchMode.Replace); overlay = this.Helper.Content.Load <Texture2D>($"assets/{asset.AssetName}_no_flowercrown_overlay_hair_gray.png"); } else { overlay = this.Helper.Content.Load <Texture2D>($"assets/{asset.AssetName}_overlay_hair_gray.png"); } baseImage.PatchImage(ColorBlend(overlay, actualHairColor_), patchMode: PatchMode.Overlay); } else if (asset.AssetNameEquals("Characters/Haley_Beach") || asset.AssetNameEquals("Portraits/Haley_Beach")) { this.Monitor.Log($"Edit asset {asset.AssetName}"); IAssetDataForImage baseImage = asset.AsImage(); Texture2D overlay = this.Helper.Content.Load <Texture2D>($"assets/{asset.AssetName}_overlay_hair_gray.png"); baseImage.PatchImage(ColorBlend(overlay, actualHairColor_), patchMode: PatchMode.Overlay); } else if (asset.AssetNameEquals("LooseSprites/cowPhotos") || asset.AssetNameEquals("LooseSprites/cowPhotosWinter")) { this.Monitor.Log($"Edit asset {asset.AssetName}"); IAssetDataForImage baseImage = asset.AsImage(); Texture2D overlay = this.Helper.Content.Load <Texture2D>("assets/Characters/Haley_cowPhotos_overlay_hair_gray.png"); baseImage.PatchImage(ColorBlend(overlay, actualHairColor_), patchMode: PatchMode.Overlay); } else { throw new ArgumentException($"Invalid asset {asset.AssetName}"); } }
public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals(@"TerrainFeatures/Flooring")) { Texture2D image = helper.Content.Load <Texture2D>(@"Floors/WoodFloor.png", ContentSource.ModFolder); Rectangle targetArea = Game1.getSourceRectForStandardTileSheet(asset.AsImage().Data, 0, 64, 64); asset.AsImage().PatchImage(image, null, targetArea, PatchMode.Replace); } }
public void Edit <T>(IAssetData asset) { Texture2D customTexture = this.Helper.Content.Load <Texture2D>("assets/BuffsInsert.png", ContentSource.ModFolder); asset .AsImage() .ExtendImage(192, 48); asset.AsImage() .PatchImage(customTexture, targetArea: new Rectangle(0, 32, 192, 16)); }
/// <inheritdoc/> public void Edit <T>(IAssetData asset) { var customBuffIconsTexture = this.Helper.Content.Load <Texture2D>("assets/CustomBuffIcons.png"); // replace the max stamina icon asset.AsImage().PatchImage(customBuffIconsTexture, sourceArea: new Rectangle(0, 0, 16, 16), targetArea: new Rectangle(64, 16, 16, 16)); // add the custom icons asset.AsImage().PatchImage(customBuffIconsTexture, sourceArea: new Rectangle(16, 0, 96, 16), targetArea: new Rectangle(80, 32, 96, 16)); }
private void injectMapsSpringobjects(IAssetData asset) { var oldTex = asset.AsImage().Data; asset.AsImage().ExtendImage(oldTex.Width, 4096); //Texture2D newTex = new Texture2D(Game1.graphics.GraphicsDevice, oldTex.Width, Math.Max(oldTex.Height, 4096)); //asset.ReplaceWith(newTex); //asset.AsImage().PatchImage(oldTex); foreach (var obj in Mod.instance.objects) { try { Log.verbose($"Injecting {obj.Name} sprites @ {objectRect(obj.GetObjectId())}"); asset.AsImage().PatchExtendedTileSheet(obj.texture, null, objectRect(obj.GetObjectId())); if (obj.IsColored) { Log.verbose($"Injecting {obj.Name} color sprites @ {objectRect(obj.GetObjectId() + 1)}"); asset.AsImage().PatchExtendedTileSheet(obj.textureColor, null, objectRect(obj.GetObjectId() + 1)); } var rect = objectRect(obj.GetObjectId()); var target = TileSheetExtensions.GetAdjustedTileSheetTarget(asset.AssetName, rect); int ts = target.TileSheet; obj.tilesheet = asset.AssetName + (ts == 0 ? "" : (ts + 1).ToString()); obj.tilesheetX = rect.X; obj.tilesheetY = target.Y; } catch (Exception e) { Log.error($"Exception injecting sprite for {obj.Name}: {e}"); } } foreach (var boots in Mod.instance.bootss) { try { Log.verbose($"Injecting {boots.Name} sprites @ {objectRect(boots.GetObjectId())}"); asset.AsImage().PatchExtendedTileSheet(boots.texture, null, objectRect(boots.GetObjectId())); var rect = objectRect(boots.GetObjectId()); var target = TileSheetExtensions.GetAdjustedTileSheetTarget(asset.AssetName, rect); int ts = target.TileSheet; boots.tilesheet = asset.AssetName + (ts == 0 ? "" : (ts + 1).ToString()); boots.tilesheetX = rect.X; boots.tilesheetY = target.Y; } catch (Exception e) { Log.error($"Exception injecting sprite for {boots.Name}: {e}"); } } }
// "918": "Hyper Speed-Gro/70/-300/Basic -19/Hyper Speed-Gro/Greatly stimulates leaf production. Guaranteed to increase growth rate by at least 33%. Mix into tilled soil.", // "466": "Deluxe Speed-Gro/40/-300/Basic -19/Deluxe Speed-Gro/Stimulates leaf production. Guaranteed to increase growth rate by at least 25%. Mix into tilled soil.", public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("Maps/springobjects")) { Texture2D sprinkler = ModEntry.ModHelper.Content.Load <Texture2D>("assets/radioactiveSprinkler.png"); //Texture2D rfertimg = ModEntry.ModHelper.Content.Load<Texture2D>("assets/radioactiveFertilizer.png"); Texture2D old = asset.AsImage().Data; asset.ReplaceWith(new Texture2D(Game1.graphics.GraphicsDevice, old.Width, System.Math.Max(old.Height, 1200 / 24 * 16))); asset.AsImage().PatchImage(old); asset.AsImage().PatchImage(sprinkler, targetArea: this.GetRectangle(RadioactiveSprinklerItem.INDEX)); //asset.AsImage().PatchImage(rfertimg, targetArea: this.GetRectangle(RadioactiveFertilizerItem.INDEX)); } else if (asset.AssetNameEquals("Data/ObjectInformation")) { asset.AsDictionary <int, string>().Data.Add(RadioactiveSprinklerItem.INDEX, $"{this.sprinklerName}/{RadioactiveSprinklerItem.PRICE}/{RadioactiveSprinklerItem.EDIBILITY}/{RadioactiveSprinklerItem.TYPE} {RadioactiveSprinklerItem.CATEGORY}/{this.sprinklerName}/{this.sprinklerDesc}"); //asset.AsDictionary<int, string>().Data.Add(RadioactiveFertilizerItem.INDEX, $"{this.rfertName}/{RadioactiveFertilizerItem.PRICE}/{RadioactiveFertilizerItem.EDIBILITY}/{RadioactiveFertilizerItem.TYPE} {RadioactiveFertilizerItem.CATEGORY}/{this.rfertName}/{this.rfertDesc}"); } else if (asset.AssetNameEquals("Data/CraftingRecipes")) { IAssetDataForDictionary <string, string> oldDict = asset.AsDictionary <string, string>(); Dictionary <string, string> newDict = new Dictionary <string, string>(); // somehow the Dictionary maintains ordering, so reconstruct it with new sprinkler recipe immediately after radioactive foreach (string key in oldDict.Data.Keys) { newDict.Add(key, oldDict.Data[key]); if (key.Equals("Iridium Sprinkler")) { if (asset.Locale != "en") { newDict.Add("Radioactive Sprinkler", $"910 2 787 2/Home/{RadioactiveSprinklerItem.INDEX}/false/Farming {RadioactiveSprinklerItem.CRAFTING_LEVEL}/{this.sprinklerName}"); //newDict.Add("Radioactive Fertilizer", $"910 2 787 2/Home/{RadioactiveFertilizerItem.INDEX}/false/Farming {RadioactiveFertilizerItem.CRAFTING_LEVEL}/{this.rfertName}"); } else { newDict.Add("Radioactive Sprinkler", $"910 2 787 2/Home/{RadioactiveSprinklerItem.INDEX}/false/Farming {RadioactiveSprinklerItem.CRAFTING_LEVEL}"); //newDict.Add("Radioactive Fertilizer", $"910 2 787 2/Home/{RadioactiveFertilizerItem.INDEX}/false/Farming {RadioactiveFertilizerItem.CRAFTING_LEVEL}"); } } } asset.AsDictionary <string, string>().Data.Clear(); foreach (string key in newDict.Keys) { asset.AsDictionary <string, string>().Data.Add(key, newDict[key]); } } else if (asset.AssetNameEquals("TileSheets\\tools")) { asset.AsImage().PatchImage(ModEntry.ToolsTexture, null, null, PatchMode.Overlay); } else if (asset.AssetNameEquals("TileSheets\\weapons")) { //asset.AsImage().PatchImage(ModEntry.WeaponsTexture, null, null, PatchMode.Overlay); } }
/// <summary>Edit a matched asset.</summary> /// <param name="asset">A helper which encapsulates metadata about an asset and enables changes to it.</param> public void Edit <T>(IAssetData asset) { // Update the name of the copper pan to just "Pan". if (asset.AssetNameEquals("Strings/StringsFromCSFiles")) { IDictionary <string, string> data = asset.AsDictionary <string, string>().Data; if (data.Keys.Contains("Pan.cs.14180")) { data["Pan.cs.14180"] = "Pan"; } } // Update the tools tilesheet to include our new pan icons. if (asset.AssetNameEquals("TileSheets/tools")) { var editor = asset.AsImage(); editor.PatchImage(panIcons, targetArea: new Rectangle(272, 0, 64, 16)); } // Update the farmer tilesheets to include our new pan sprites. if (asset.AssetNameEquals("Characters/Farmer/farmer_base") || asset.AssetNameEquals("Characters/Farmer/farmer_base_bald") || asset.AssetNameEquals("Characters/Farmer/farmer_girl_base") || asset.AssetNameEquals("Characters/Farmer/farmer_girl_base_bald")) { var editor = asset.AsImage(); // Add the new pan sprites. editor.PatchImage(panSprites, targetArea: new Rectangle(96, 656, 192, 16), patchMode: PatchMode.Overlay); // Update feature offset arrays to support additional frames. int[] featureOffsetsY = new int[126 + 18]; int[] featureOffsetsX = new int[126 + 18]; Array.Copy(FarmerRenderer.featureYOffsetPerFrame, featureOffsetsY, FarmerRenderer.featureYOffsetPerFrame.Length); featureOffsetsY[123 + 6] = featureOffsetsY[123]; featureOffsetsY[124 + 6] = featureOffsetsY[124]; featureOffsetsY[125 + 6] = featureOffsetsY[125]; featureOffsetsY[123 + 12] = featureOffsetsY[123]; featureOffsetsY[124 + 12] = featureOffsetsY[124]; featureOffsetsY[125 + 12] = featureOffsetsY[125]; featureOffsetsY[123 + 18] = featureOffsetsY[123]; featureOffsetsY[124 + 18] = featureOffsetsY[124]; featureOffsetsY[125 + 18] = featureOffsetsY[125]; FarmerRenderer.featureYOffsetPerFrame = featureOffsetsY; Array.Copy(FarmerRenderer.featureXOffsetPerFrame, featureOffsetsX, FarmerRenderer.featureXOffsetPerFrame.Length); FarmerRenderer.featureXOffsetPerFrame = featureOffsetsX; } }
public void Edit <T>(IAssetData asset) { Texture2D image = asset.AsImage().Data; int width = image.Width; int oWith = Assets.Find(a => asset.AssetNameEquals(a.Key)).Value; if (oWith < width) { float scale = (float)(Convert.ToDouble(width) / Convert.ToDouble(oWith)); int height = (int)(image.Height / scale); var scaled = ScaledTexture2D.FromTexture(image.getArea(new Rectangle(0, 0, oWith, height)), image, scale); asset.AsImage().ReplaceWith(scaled); } }
public void Edit <T>(IAssetData asset) { Texture2D emptyBox = this.Helper.Content.Load <Texture2D>("assets/" + prefix + "Box.png", ContentSource.ModFolder); Texture2D eyesBox = this.Helper.Content.Load <Texture2D>("assets/" + prefix + "BoxEyes.png", ContentSource.ModFolder); if (!eyes) { asset.AsImage().PatchImage(emptyBox, targetArea: new Rectangle(192, 0, 16, 16)); } else { asset.AsImage().PatchImage(eyesBox, targetArea: new Rectangle(192, 0, 16, 16)); } }
/// <summary>Edit a matched asset.</summary> /// <param name="asset">A helper which encapsulates metadata about an asset and enables changes to it.</param> public void Edit <T>(IAssetData asset) { // Add info about the mattock to the weapons data. if (asset.AssetNameEquals("Data/weapons")) { IDictionary <int, string> data = asset.AsDictionary <int, string>().Data; data[70] = "Mattock/A piece of dwarf history, it's a very versatile tool./16/16/1/0/0/0/0/-1/-1/2/.02/4"; } // Add info about the mattock artifact to the object info data. if (asset.AssetNameEquals("Data/ObjectInformation")) { IDictionary <int, string> data = asset.AsDictionary <int, string>().Data; data[934] = "Dwarf Mattock/250/-300/Arch/Dwarf Mattock/It's an ancient dwarf tool, used for mining and clearing rubble. It's in bad shape, maybe it could be repaired?/Volcano .01/Money 1 500"; } // Add the dwarf mattock artifact as a liked gift for the dwarf. if (asset.AssetNameEquals("Data/NPCGiftTastes")) { IDictionary <string, string> data = asset.AsDictionary <string, string>().Data; string[] currentTastes = data["Dwarf"].Split('/'); currentTastes[3] += " 934"; data["dwarf"] = String.Join("/", currentTastes); } // Add the mattock artifact to the item sprite sheet. if (asset.AssetNameEquals("Maps/springobjects")) { var editor = asset.AsImage(); editor.PatchImage(mattockIcons, sourceArea: new Rectangle(0, 0, 32, 16), targetArea: new Rectangle(352, 608, 32, 16)); } if (asset.AssetNameEquals("Maps/Blacksmith")) { var map = asset.AsMap(); // Add an invisible tile to the front layer so later we can replace it. map.Data.GetLayer("Front").Tiles[6, 12] = new StaticTile(map.Data.GetLayer("Front"), map.Data.TileSheets[0], BlendMode.Alpha, 48); map.Data.GetLayer("Front").Tiles[5, 10] = new StaticTile(map.Data.GetLayer("Front"), map.Data.TileSheets[0], BlendMode.Alpha, 48); map.Data.GetLayer("Front").Tiles[6, 10] = new StaticTile(map.Data.GetLayer("Front"), map.Data.TileSheets[0], BlendMode.Alpha, 48); map.Data.GetLayer("Front").Tiles[5, 11] = new StaticTile(map.Data.GetLayer("Front"), map.Data.TileSheets[0], BlendMode.Alpha, 48); map.Data.GetLayer("Front").Tiles[6, 11] = new StaticTile(map.Data.GetLayer("Front"), map.Data.TileSheets[0], BlendMode.Alpha, 48); } // Add the mattock weapon icons to the weapon sprite sheet. if (asset.AssetNameEquals("TileSheets/weapons")) { var editor = asset.AsImage(); editor.PatchImage(mattockIcons, sourceArea: new Rectangle(16, 0, 32, 16), targetArea: new Rectangle(96, 128, 32, 16)); } }
public void Edit <T>(IAssetData asset) { Texture2D customTexture = this.Helper.Content.Load <Texture2D>("assets/BlankPixel.png", ContentSource.ModFolder); Texture2D bloodMoonTexture = this.Helper.Content.Load <Texture2D>("assets/DaytimeBloodMoon.png", ContentSource.ModFolder); asset .AsImage() .PatchImage(customTexture, targetArea: new Rectangle(643, 833, 41, 45)); if (OurMoon.CurrentPhase() == MoonPhase.BloodMoon) { asset.AsImage().PatchImage(bloodMoonTexture, targetArea: new Rectangle(342, 440, 7, 7)); } }
public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("Maps/springobjects")) { Texture2D bar = ModEntry.ModHelper.Content.Load <Texture2D>("Assets/prismaticBar.png", ContentSource.ModFolder); Texture2D sprinkler = ModEntry.ModHelper.Content.Load <Texture2D>("Assets/prismaticSprinkler.png", ContentSource.ModFolder); Texture2D old = asset.AsImage().Data; asset.ReplaceWith(new Texture2D(Game1.graphics.GraphicsDevice, old.Width, System.Math.Max(old.Height, 1200 / 24 * 16))); asset.AsImage().PatchImage(old); asset.AsImage().PatchImage(bar, targetArea: Rektangle(PrismaticBarItem.INDEX)); asset.AsImage().PatchImage(sprinkler, targetArea: Rektangle(PrismaticSprinklerItem.INDEX)); } else if (asset.AssetNameEquals("Data/ObjectInformation")) { asset.AsDictionary <int, string>().Data.Add(PrismaticBarItem.INDEX, $"{barName}/{PrismaticBarItem.PRICE}/{PrismaticBarItem.EDIBILITY}/{PrismaticBarItem.TYPE} {PrismaticBarItem.CATEGORY}/{barName}/{barDesc}"); asset.AsDictionary <int, string>().Data.Add(PrismaticSprinklerItem.INDEX, $"{sprinklerName}/{PrismaticSprinklerItem.PRICE}/{PrismaticSprinklerItem.EDIBILITY}/{PrismaticSprinklerItem.TYPE} {PrismaticSprinklerItem.CATEGORY}/{sprinklerName}/{sprinklerDesc}"); } else if (asset.AssetNameEquals("Data/CraftingRecipes")) { IAssetDataForDictionary <string, string> oldDict = asset.AsDictionary <string, string>(); Dictionary <string, string> newDict = new Dictionary <string, string>(); // somehow the Dictionary maintains ordering, so reconstruct it with new sprinkler recipe immediately after prismatic foreach (string key in oldDict.Data.Keys) { newDict.Add(key, oldDict.Data[key]); if (key.Equals("Iridium Sprinkler")) { if (asset.Locale != "en") { newDict.Add("Prismatic Sprinkler", $"{PrismaticBarItem.INDEX} 2 787 2/Home/{PrismaticSprinklerItem.INDEX}/false/Farming {PrismaticSprinklerItem.CRAFTING_LEVEL}/{sprinklerName}"); } else { newDict.Add("Prismatic Sprinkler", $"{PrismaticBarItem.INDEX} 2 787 2/Home/{PrismaticSprinklerItem.INDEX}/false/Farming {PrismaticSprinklerItem.CRAFTING_LEVEL}"); } } } asset.AsDictionary <string, string>().Data.Clear(); foreach (string key in newDict.Keys) { asset.AsDictionary <string, string>().Data.Add(key, newDict[key]); } } else if (asset.AssetNameEquals("TileSheets\\tools")) { asset.AsImage().PatchImage(ModEntry.toolsTexture, null, null, PatchMode.Overlay); } }
public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("Data\\ObjectInformation")) { var data = asset.AsDictionary <int, string>().Data; foreach (var crop_ in CropData.crops) { var crop = crop_.Value; Log.trace($"Injecting to objects: {crop.GetProductId()}: {crop.GetProductObjectInformation()}"); data.Add(crop.GetProductId(), crop.GetProductObjectInformation()); Log.trace($"Injecting to objects: {crop.GetSeedId()}: {crop.GetSeedObjectInformation()}"); data.Add(crop.GetSeedId(), crop.GetSeedObjectInformation()); } } else if (asset.AssetNameEquals("Data\\Crops")) { var data = asset.AsDictionary <int, string>().Data; foreach (var crop_ in CropData.crops) { var crop = crop_.Value; Log.trace($"Injecting to crops: {crop.GetSeedId()}: {crop.GetCropInformation()}"); data.Add(crop.GetSeedId(), crop.GetCropInformation()); } } else if (asset.AssetNameEquals("Maps\\springobjects")) { var oldTex = asset.AsImage().Data; Texture2D newTex = new Texture2D(Game1.graphics.GraphicsDevice, oldTex.Width, Math.Max(oldTex.Height, 4096)); asset.ReplaceWith(newTex); asset.AsImage().PatchImage(oldTex); foreach (var crop_ in CropData.crops) { var crop = crop_.Value; Log.trace($"Injecting {crop.Id} sprites"); asset.AsImage().PatchImage(Mod.instance.Helper.Content.Load <Texture2D>($"Crops/{crop.Id}/product.png"), null, objectRect(crop.GetProductId())); if (crop.Colors != null && crop.Colors.Count > 0) { asset.AsImage().PatchImage(Mod.instance.Helper.Content.Load <Texture2D>($"Crops/{crop.Id}/product-color.png"), null, objectRect(crop.GetProductId() + 1)); } asset.AsImage().PatchImage(Mod.instance.Helper.Content.Load <Texture2D>($"Crops/{crop.Id}/seeds.png"), null, objectRect(crop.GetSeedId())); } } else if (asset.AssetNameEquals("TileSheets\\crops")) { var oldTex = asset.AsImage().Data; Texture2D newTex = new Texture2D(Game1.graphics.GraphicsDevice, oldTex.Width, Math.Max(oldTex.Height, 4096)); asset.ReplaceWith(newTex); asset.AsImage().PatchImage(oldTex); foreach (var crop_ in CropData.crops) { var crop = crop_.Value; Log.trace($"Injecting {crop.Id} crop images"); asset.AsImage().PatchImage(Mod.instance.Helper.Content.Load <Texture2D>($"Crops/{crop.Id}/crop.png"), null, cropRect(crop.GetCropSpriteIndex())); } } }
public void Edit <T>(IAssetData asset) { Log.T($"Editing {asset.AssetName}.", _isDebugging); // Expand the base tilesheet if needed. var src = ModEntry.Instance.Helper.Content.Load <Texture2D>(ModValues.MachinePath); var dest = asset.AsImage(); var srcRect = new Rectangle(0, 0, 16, 32); var destRect = Propagator.getSourceRectForBigCraftable(ModValues.PropagatorIndex); if (destRect.Bottom > dest.Data.Height) { Log.D("Expanding bigCraftables tilesheet.", _isDebugging); var original = dest.Data; var texture = new Texture2D(Game1.graphics.GraphicsDevice, original.Width, destRect.Bottom); Log.D($"Original: {original.Width}x{original.Height}" + $"\nExpanded: {texture.Width}x{texture.Height}", _isDebugging); dest.ReplaceWith(texture); dest.PatchImage(original); } // Append machine sprite onto the default tilesheet. dest.PatchImage(src, srcRect, destRect); }
public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("Data/Bundles")) { asset.AsDictionary <string, string>().ReplaceWith(Bundles.Data()); Bundles.Fix(false); } if (asset.AssetNameEquals("Strings/UI")) { Func <string, Translation> t = Helper.Translation.Get; var dict = asset.AsDictionary <string, string>().Data; foreach (var room in new string[] { "Boiler", "Crafts", "Pantry", "Vault", "FishTank" }) { var key = "JunimoNote_Reward" + room; var r = room; if (room == "Crafts" || room == "Boiler") { r += "Room"; } VanillaRewards[r] = dict[key]; dict[key] = t(key); } } if (asset.AssetNameEquals("LooseSprites/JunimoNote")) { var tex = Helper.Content.Load <Texture2D>("assets/icons.png", ContentSource.ModFolder); asset.AsImage().PatchImage(tex, targetArea: new Rectangle(0, 180, 640, 64)); } }
public void Edit <T>(IAssetData asset) { // Append sprites to the asset: var src = _helper.Content.Load <Texture2D>( Path.Combine("assets", $"{ModConsts.HairstylesSpritesheet}.png")); var dest = asset.AsImage(); var srcRect = new Rectangle(0, 0, src.Width, src.Height); var destRect = GetDestRect(dest.Data.Bounds, src.Bounds); Log.D($"Dest: (X:{dest.Data.Bounds.X}, Y:{dest.Data.Bounds.Y}" + $", W:{dest.Data.Bounds.Width}, H:{dest.Data.Bounds.Height})" + $"\nSource: (X:{srcRect.X}, Y:{srcRect.Y}, W:{srcRect.Width}, H:{srcRect.Height})" + $"\nResult: (X:{destRect.X}, Y:{destRect.Y}, W:{destRect.Width}, H:{destRect.Height})", ModEntry.Instance.Config.DebugMode); // Substitute the asset with a taller version to accomodate our sprites. var original = dest.Data; var texture = new Texture2D(Game1.graphics.GraphicsDevice, original.Width, destRect.Bottom); dest.ReplaceWith(texture); dest.PatchImage(original); // Patch the sprites into the expanded asset. dest.PatchImage(src, srcRect, destRect); }
public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("TileSheets\\tools")) { asset.AsImage().PatchImage(ModEntry.instance.Helper.Content.Load <Texture2D>("assets/cobalt-tools.png"), null, null, PatchMode.Overlay); } }
public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("Data\\ObjectInformation")) { var data = asset.AsDictionary <int, string>().Data; foreach (BugModel bugModel in BugCatchingMod.AllBugs) { data.Add(bugModel.ParentSheetIndex, bugModel.QuickItemDataString); } } if (asset.AssetNameEquals("TileSheets\\tools")) { Texture2D toolSpriteSheet = asset.AsImage().Data; Color[] originalTools = new Color[toolSpriteSheet.Width * toolSpriteSheet.Height]; toolSpriteSheet.GetData <Color>(originalTools); Texture2D bugNetToolSpriteSheet = ToolsSprites; Color[] addonTools = new Color[bugNetToolSpriteSheet.Width * bugNetToolSpriteSheet.Height]; bugNetToolSpriteSheet.GetData <Color>(addonTools); Texture2D newSpriteSheet = new Texture2D(Game1.game1.GraphicsDevice, toolSpriteSheet.Width, toolSpriteSheet.Height + bugNetToolSpriteSheet.Height, false, SurfaceFormat.Color); var allTools = new Color[originalTools.Length + addonTools.Length]; originalTools.CopyTo(allTools, 0); addonTools.CopyTo(allTools, originalTools.Length); newSpriteSheet.SetData(allTools); asset.ReplaceWith(newSpriteSheet); } }
/// <summary>Apply the patch to an asset.</summary> /// <typeparam name="T">The asset type.</typeparam> /// <param name="asset">The asset to edit.</param> public void Apply <T>(IAssetData asset) { // validate if (typeof(T) != typeof(Texture2D)) { this.Monitor.Log($"Can't apply edit-image patch by {this.ContentPack.Manifest.Name} to {this.AssetName}: this file isn't an image file (found {typeof(T)}).", LogLevel.Warn); return; } // fetch data Texture2D source = this.AssetLoader.Load <Texture2D>(this.ContentPack, this.FromLocalAsset); IAssetDataForImage editor = asset.AsImage(); // extend tilesheet if needed Rectangle affectedArea = this.GetTargetArea(source, this.FromArea, this.ToArea); if (affectedArea.Bottom > editor.Data.Height) { Texture2D original = editor.Data; Texture2D texture = new Texture2D(Game1.graphics.GraphicsDevice, original.Width, affectedArea.Bottom); editor.ReplaceWith(texture); editor.PatchImage(original); } // apply source image editor.PatchImage(source, this.FromArea, this.ToArea); }
/// <summary>Edit a matched asset.</summary> /// <param name="asset">A helper which encapsulates metadata about an asset and enables changes to it.</param> public void Edit <T>(IAssetData asset) { // Change the town interior image if (asset.AssetNameEquals("townInterior")) { Texture2D townInteriorTexture = this.Helper.Content.Load <Texture2D>("Assets/townInterior.png", ContentSource.ModFolder); asset.AsImage().PatchImage(townInteriorTexture, sourceArea: new Rectangle(0, 0, 512, 1088), targetArea: new Rectangle(0, 0, 512, 1088), PatchMode.Overlay); } // Change the town interior image if (asset.AssetNameEquals("Maps/townInterior")) { Texture2D townInteriorTexture = this.Helper.Content.Load <Texture2D>("Assets/townInterior.png", ContentSource.ModFolder); asset.AsImage().PatchImage(townInteriorTexture, sourceArea: new Rectangle(0, 0, 512, 1088), targetArea: new Rectangle(0, 0, 512, 1088), PatchMode.Overlay); } }