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) { if (CurrentMovie != null) { asset.ReplaceWith(CurrentMovie._texture); } }
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}"); } } }
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>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 crop seasons; based on user config if (asset.AssetNameEquals("Data/Crops")) { asset .AsDictionary <int, string>() .Set((id, data) => { string[] fields = data.Split('/'); if (!this.Config.WinterAliveEnabled) { fields[1] = "spring summer fall"; } else { fields[1] = "spring summer fall winter"; } return(string.Join("/", fields)); }); } // change dirt texture else if (asset.AssetNameEquals("TerrainFeatures/hoeDirtSnow") && this.Config.WinterHoeSnow) //Allows users to set plowed snow or dirt in winter { asset.ReplaceWith(this.Helper.Content.Load <Texture2D>("TerrainFeatures/hoeDirt", ContentSource.GameContent)); } }
public void Edit <T>(IAssetData asset) { const int styleW = 16; const int styleH = 128; // Dictionary data var data = asset.AsDictionary <int, string>().Data; var newData = new Dictionary <int, string>(); // Image data Texture2D hairstylesTexture = Game1.content.Load <Texture2D> (ModConsts.GameContentHairstyleImagePath); int count = 0; Color[] pixelData = new Color[styleW * styleH]; // Find index of first non-empty slot in custom hairstyles spritesheet for (int x = (hairstylesTexture.Width / styleW) - 1; x >= 0 && count == 0; --x) { for (int y = (hairstylesTexture.Height / styleH) - 1; y >= 0 && count == 0; --y) { int cur = x + (hairstylesTexture.Width / styleW * y); hairstylesTexture.GetData(0, new Rectangle(x * styleW, y * styleH, styleW, styleH), pixelData, 0, pixelData.Length); if (!pixelData.All(colour => colour.A == 0)) { count = cur + 1; } } } Log.D($"Hairstyles to add: {count}", ModEntry.Config.DebugMode); // Add in HairData entries for every hairstyle up until the last non-empty hairstyle in the spritesheet const bool hasLeftStyle = true; const bool isBaldStyle = false; const int coveredStyleId = -1; int startId = int.Parse(ModEntry.Instance.ModManifest.UpdateKeys.First().Split(':')[1]) * 100; if (data.Keys.Count(key => key >= startId && key < startId + count) is int conflicts && conflicts > 0) { Log.W($"Identified ID conflicts with {conflicts} hairstyles: Please share a log file on the mod page!"); } for (int i = 0; i < count; ++i) { int styleId = startId + i; if (data.ContainsKey(styleId)) { string[] style = data[styleId].Split('/'); Log.W($"Overriding hairstyle at {styleId} ({style[0]} at X:{style[1]}, Y:{style[2]})"); } int x = i % 8; int y = (int)(i * 0.125) * 8; newData.Add(styleId, $"{ModConsts.HairstylesSheetId}/{x}/{y}/{hasLeftStyle}/{coveredStyleId}/{isBaldStyle}"); } Log.D(newData.Aggregate("HairData:", (total, cur) => $"{total}\n{cur.Key}: {cur.Value}"), ModEntry.Config.DebugMode); asset.ReplaceWith(data.Concat(newData).ToDictionary(pair => pair.Key, pair => pair.Value)); }
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}"); } } }
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}"); } } }
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); } } }
/// <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>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>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) { // texture Texture2D texture = asset.AsImage().Data; texture = this.GrayscaleColors(texture); asset.ReplaceWith(texture); }
private void injectCharactersFarmerShirts(IAssetData asset) { var oldTex = asset.AsImage().Data; Texture2D newTex = new Texture2D(Game1.graphics.GraphicsDevice, oldTex.Width, Math.Max(oldTex.Height, 4096)); Color[] test = new Color[newTex.Width * newTex.Height]; Color col = new Color(0, 0, 0, 0); for (int i = 0; i < test.Length; ++i) { test[i] = col; } newTex.SetData(test); asset.ReplaceWith(newTex); asset.AsImage().PatchImage(oldTex); Log.trace($"Shirts are now ({oldTex.Width}, {Math.Max(oldTex.Height, 4096)})"); foreach (var shirt in Mod.instance.shirts) { try { string rects = shirtRectPlain(shirt.GetMaleIndex()).ToString(); if (shirt.Dyeable) { rects += ", " + shirtRectDye(shirt.GetMaleIndex()).ToString(); } if (shirt.HasFemaleVariant) { rects += ", " + shirtRectPlain(shirt.GetFemaleIndex()).ToString(); if (shirt.Dyeable) { rects += ", " + shirtRectDye(shirt.GetFemaleIndex()).ToString(); } } Log.verbose($"Injecting {shirt.Name} sprites @ {rects}"); asset.AsImage().PatchExtendedTileSheet(shirt.textureMale, null, shirtRectPlain(shirt.GetMaleIndex())); if (shirt.Dyeable) { asset.AsImage().PatchExtendedTileSheet(shirt.textureMaleColor, null, shirtRectDye(shirt.GetMaleIndex())); } if (shirt.HasFemaleVariant) { asset.AsImage().PatchExtendedTileSheet(shirt.textureFemale, null, shirtRectPlain(shirt.GetFemaleIndex())); if (shirt.Dyeable) { asset.AsImage().PatchExtendedTileSheet(shirt.textureFemaleColor, null, shirtRectDye(shirt.GetFemaleIndex())); } } } catch (Exception e) { Log.error($"Exception injecting sprite for {shirt.Name}: {e}"); } } }
public void Edit <T>(IAssetData assetData) { T asset = assetData.GetData <T>(); foreach (AssetInjector <T> injector in this.GetInjectors <T>(assetData.AssetName)) { injector(assetData.AssetName, ref asset); } assetData.ReplaceWith(asset); }
public void Edit <T>(IAssetData assetData) { T asset = assetData.GetData <T>(); foreach (AssetInjector <T> injector in DeferredTypeHandler.EditMap[typeof(T)]) { injector(assetData.AssetName, ref asset); } assetData.ReplaceWith(asset); }
public void Edit <TAssetRequest>(IAssetData asset) { if (typeof(TAsset) == typeof(IAssetDataForImage)) { this.asset.Invoke((TAsset)asset.AsImage()); } else { asset.ReplaceWith(this.asset.Invoke(asset.GetData <TAsset>())); } }
// "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>Apply the patch to a list asset.</summary> /// <typeparam name="TValue">The list value type.</typeparam> /// <param name="asset">The asset to edit.</param> private void ApplyList <TValue>(IAssetData asset) { // TODO: this is a horrible hack. Dictionary <string, TValue> data = ((List <TValue>)asset.Data).ToDictionary(this.GetId); IAssetData newAsset = (IAssetData)asset .GetType() .GetConstructor(new[] { typeof(string), typeof(string), typeof(object), typeof(Func <string, string>) }) .Invoke(new[] { asset.Locale, asset.AssetName, data, asset.GetType().GetField("GetNormalisedPath", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).GetValue(asset) }); this.ApplyDictionary <string, TValue>(newAsset); asset.ReplaceWith(data.Values.ToList()); }
private void injectMapsSpringobjects(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 obj in Mod.instance.objects) { try { Log.verbose($"Injecting {obj.Name} sprites @ {objectRect(obj.GetObjectId())}"); asset.AsImage().PatchImage(obj.texture, null, objectRect(obj.GetObjectId())); if (obj.IsColored) { Log.verbose($"Injecting {obj.Name} color sprites @ {objectRect(obj.GetObjectId() + 1)}"); asset.AsImage().PatchImage(obj.textureColor, null, objectRect(obj.GetObjectId() + 1)); } var rect = objectRect(obj.GetObjectId()); int ts = 0;// TileSheetExtensions.GetAdjustedTileSheetTarget(asset.AssetName, rect).TileSheet; obj.tilesheet = asset.AssetName + (ts == 0 ? "" : (ts + 1).ToString()); obj.tilesheetX = rect.X; obj.tilesheetY = rect.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().PatchImage(boots.texture, null, objectRect(boots.GetObjectId())); var rect = objectRect(boots.GetObjectId()); int ts = 0;// TileSheetExtensions.GetAdjustedTileSheetTarget(asset.AssetName, rect).TileSheet; boots.tilesheet = asset.AssetName + (ts == 0 ? "" : (ts + 1).ToString()); boots.tilesheetX = rect.X; boots.tilesheetY = rect.Y; } catch (Exception e) { Log.error($"Exception injecting sprite for {boots.Name}: {e}"); } } }
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) { // Create a texture of the original spritesheet, and collect its data. Texture2D spriteSheet = asset.AsImage().Data; int sheetHeight = spriteSheet.Height; int sheetWidth = spriteSheet.Width; Color[] originalData = new Color[sheetHeight * sheetWidth]; spriteSheet.GetData(originalData); // Create a texture of the csvm spritesheet, and collect its data. Texture2D csvmSpriteSheet = this.helper.Content.Load <Texture2D>("Res/csvmTileSheet.png", ContentSource.ModFolder); int csvmSheetHeight = csvmSpriteSheet.Height; int csvmSheetWidth = csvmSpriteSheet.Width; Color[] csvmData = new Color[csvmSheetHeight * csvmSheetWidth]; csvmSpriteSheet.GetData(csvmData); // Combine the original and the csvm spritesheets Texture2D combinedSpriteSheet = new Texture2D(Game1.game1.GraphicsDevice, sheetWidth, sheetHeight + csvmSheetHeight, false, SurfaceFormat.Color); Color[] combinedData = new Color[originalData.Length + csvmData.Length]; originalData.CopyTo(combinedData, 0); csvmData.CopyTo(combinedData, originalData.Length); combinedSpriteSheet.SetData(combinedData); // Replace the game's spritesheet with the newly created one. asset.ReplaceWith(combinedSpriteSheet); // Assign an index to each new texture added in the itemPairs dictionary. // The key is set to the name from textures, and the index is its item // index that will be recognized in game. for (int i = 0; i < (textures.Length / 16) + 1; i++) { int remainingTextures = i == (textures.Length / 16) ? textures.Length % 16 : 16; for (int j = 0; j < remainingTextures; j++) { // Current texture is the number texture we're on. 16 * the row + the column. int currentTexture = (16 * i) + j; // Create the key value pair of texture_name: texture's index. // Note, currentTexture is not incremented by one as this is an index (Started from 0) and // not an absolute position (started from 1.) this.itemPairs[textures[currentTexture]] = ((sheetHeight / 16) * (sheetWidth / 16)) + (currentTexture); } } }
public void Edit <T>(IAssetData asset) { foreach (var injection in Injections.Where(p => asset.AssetNameEquals(p.AssetName) && (p.Method != InjectionMethod.Load) && p.ConditionsMet)) { if (injection is DataInjection dataInjection) { if (dataInjection.GetKeyType == typeof(int)) { asset.ReplaceWith(injectData <int>(asset, dataInjection)); } else if (dataInjection.GetKeyType == typeof(string)) { asset.ReplaceWith(injectData <string>(asset, dataInjection)); } } else if (injection is TextureInjection textureInjection) { if (textureInjection.Method == InjectionMethod.Replace) { asset.ReplaceWith(textureInjection.Value); } else if (textureInjection.Method == InjectionMethod.Merge || textureInjection.Method == InjectionMethod.Overlay) { asset.AsImage().PatchImage( textureInjection.Value, textureInjection.SourceArea, textureInjection.TargetArea, textureInjection.Method == InjectionMethod.Overlay ? PatchMode.Overlay : PatchMode.Replace); } } else if (injection is MapInjection mapInjection) { if (mapInjection.Method == InjectionMethod.Merge) { asset.AsMap().PatchMap(mapInjection.Value, mapInjection.SourceArea, mapInjection.TargetArea); } if (mapInjection.Method == InjectionMethod.Overlay) { asset.ReplaceWith(Helper.Content.Maps.PatchMapArea(asset.AsMap().Data, mapInjection.Value, mapInjection.TargetArea.HasValue ? new Point(mapInjection.TargetArea.Value.X, mapInjection.TargetArea.Value.Y) : Point.Zero, mapInjection.SourceArea, true, false)); } else if (mapInjection.Method == InjectionMethod.Replace) { asset.ReplaceWith(mapInjection.Value); } } else if (injection is ObjectInjection objectInjection) { asset.ReplaceWith(objectInjection.Value); } } }
public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("Maps/springobjects")) { Texture2D sprinkler = QiSprinklers.ModHelper.Content.Load <Texture2D>("Assets/qiSprinkler.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(QiSprinklerItem.INDEX)); } else if (asset.AssetNameEquals("Data/ObjectInformation")) { asset.AsDictionary <int, string>().Data.Add(QiSprinklerItem.INDEX, $"{sprinklerName}/{QiSprinklerItem.PRICE}/{QiSprinklerItem.EDIBILITY}/{QiSprinklerItem.TYPE} {QiSprinklerItem.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 Qi foreach (string key in oldDict.Data.Keys) { newDict.Add(key, oldDict.Data[key]); if (key.Equals("Iridium Sprinkler")) { if (asset.Locale != "en") { newDict.Add("Qi Sprinkler", $"645 1 913 1 915 1/Home/{QiSprinklerItem.INDEX}/false/Farming {QiSprinklerItem.CRAFTING_LEVEL}/{sprinklerName}"); } else { newDict.Add("Qi Sprinkler", $"645 1 913 1 915 1/Home/{QiSprinklerItem.INDEX}/false/Farming {QiSprinklerItem.CRAFTING_LEVEL}"); } } } asset.AsDictionary <string, string>().Data.Clear(); foreach (string key in newDict.Keys) { asset.AsDictionary <string, string>().Data.Add(key, newDict[key]); } } }
/// <inheritdoc /> public void Edit <T>(IAssetData asset) { var data = asset.AsImage().Data; asset.ReplaceWith(new Texture2D( Game1.graphics.GraphicsDevice, data.Width, Math.Max( data.Height, ((int)this.assetGraph.Objects.Select(cropPair => cropPair.Key).Max() / 24) * 16 + 16))); asset.AsImage().PatchImage(data); this.assetGraph.Objects .ToList() .ForEach(obj => asset.AsImage().PatchImage( this.helper.Content.Load <Texture2D>(obj.Value.TilesheetLocation, ContentSource.ModFolder), null, new Rectangle(((int)obj.Key % 24) * 16, ((int)obj.Key / 24) * 16, 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) { // change crop seasons if (asset.AssetNameEquals("Data/Crops")) { asset .AsDictionary <int, string>() .Set((id, data) => { string[] fields = data.Split('/'); fields[1] = "spring summer fall winter"; return(string.Join("/", fields)); }); } // change dirt texture else if (asset.AssetNameEquals("TerrainFeatures/hoeDirtSnow")) { asset.ReplaceWith(this.Helper.Content.Load <Texture2D>("TerrainFeatures/hoeDirt", ContentSource.GameContent)); } }
/// <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 crop seasons if (asset.AssetNameEquals(this.CropAssetName)) { asset .AsDictionary <int, string>() .Set((id, data) => { string[] fields = data.Split('/'); fields[1] = string.Join(" ", this.EnabledSeasons); return(string.Join("/", fields)); }); } // change dirt texture else if (asset.AssetNameEquals(this.WinterDirtAssetName)) { asset.ReplaceWith(this.Helper.Content.Load <Texture2D>("TerrainFeatures/hoeDirt", ContentSource.GameContent)); } }
public void patchCraftablesTilesheetAsset(IAssetData craftableTilesheetAsset) { //Modifying default Craftables tilesheet of the game Texture2D CraftablesSheet = craftableTilesheetAsset.AsImage().Data; int originalWidth = CraftablesSheet.Width; int originalHeight = CraftablesSheet.Height; int startingId = (originalWidth / 16) * (originalHeight / 32); IBigCraftableWrapper.getWrapper("Seed Machine").itemID = startingId; //First free id for the mod injecting IBigCraftableWrapper.getWrapper("Seed Bandit").itemID = startingId + 6; //Getting original color array Color[] originalData = new Color[originalWidth * originalHeight]; CraftablesSheet.GetData <Color>(originalData); //Getting mod's color array int customWidth = SeedMachinesSprite.Width; int customHeight = SeedMachinesSprite.Height; Color[] customData = new Color[customWidth * customHeight]; SeedMachinesSprite.GetData <Color>(customData); //Preparing new clear tilesheet Texture2D newTileSheet = new Texture2D(Game1.game1.GraphicsDevice, originalWidth, originalHeight + customHeight, false, SurfaceFormat.Color); //Join default and custom color arrays var mixedData = new Color[originalData.Length + customData.Length]; originalData.CopyTo(mixedData, 0); customData.CopyTo(mixedData, originalData.Length); //Push joined array of colors to prepared new tilesheet newTileSheet.SetData(0, new Rectangle(0, 0, originalWidth, originalHeight + customHeight), mixedData, 0, mixedData.Length); //Replace default tilesheet with joined one craftableTilesheetAsset.ReplaceWith(newTileSheet); this.craftablesTilesheetWasPatched = true; }
public void Edit <T>(IAssetData asset) { if (asset.AssetNameEquals("Data\\ObjectInformation")) { foreach (var item in Item.items) { try { asset.AsDictionary <int, string>().Data.Add(item.Value.internal_id, item.Value.GetData()); } catch { } } } else if (asset.AssetNameEquals("Data\\Monsters")) { try { var data = asset.AsDictionary <string, string>().Data; string[] slime = data["Green Slime"].Split('/'); slime[6] += " " + Item.base_id + " 0.02"; //2% chance for green slimes to drop a lockpick string slimeCompiled = string.Join("/", slime); data["Green Slime"] = slimeCompiled; } catch { } } else { var oldTex = asset.AsImage().Data; if (oldTex.Width != 4096) { Texture2D newTex = new Texture2D(StardewValley.Game1.graphics.GraphicsDevice, oldTex.Width, System.Math.Max(oldTex.Height, 4096)); asset.ReplaceWith(newTex); asset.AsImage().PatchImage(oldTex); } foreach (var obj in Item.items) { try { asset.AsImage().PatchImage(obj.Value.texture, null, new Rectangle(obj.Value.internal_id % 24 * 16, obj.Value.internal_id / 24 * 16, 16, 16)); } catch { } } } }
private void injectCharactersFarmerShoeColors(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($"Boots are now ({oldTex.Width}, {Math.Max(oldTex.Height, 4096)})"); foreach (var boots in Mod.instance.bootss) { try { Log.verbose($"Injecting {boots.Name} sprites @ {bootsRect(boots.GetTextureIndex())}"); asset.AsImage().PatchExtendedTileSheet(boots.textureColor, null, bootsRect(boots.GetTextureIndex())); } catch (Exception e) { Log.error($"Exception injecting sprite for {boots.Name}: {e}"); } } }