Changes

Jump to navigation Jump to search
→‎Edit assets: expand, reorganise for simplicity and clarity
Line 425: Line 425:     
====Edit assets====
 
====Edit assets====
You can intercept and change any texture or data loaded by the game. (In other words, you can edit XNB data while the game is running without changing the original files.)
+
You can edit any texture or data loaded by the game (often called 'XNB data') without changing the original files. You do this by implementing <tt>IAssetEditor</tt> in your <tt>Mod</tt> class, which adds two methods: <tt>CanEdit&lt;T&gt;</tt> returns whether the mod can edit a particular asset, and <tt>Edit&lt;T&gt;</tt> makes any changes needed. The <tt>Edit&lt;T&gt;</tt> method receives a helper for editing various data types.
   −
In most cases, you can just implement <tt>IAssetEditor</tt> in your <tt>Mod</tt> class to do it. This adds two methods: <tt>CanEdit&lt;T&gt;</tt> returns whether the mod can edit a particular asset, and <tt>Edit&lt;T&gt;</tt> makes any changes needed. For example, this mod lets crops grow in any season (example only, doesn't handle edge cases):
+
Here are a few examples:
 +
<ul>
 +
<li>This mod adds a new item (see [[Modding:Object data]]). '''Note:''' it's better to use mod frameworks like [https://www.nexusmods.com/stardewvalley/mods/1720/ Json Assets] for custom items, to avoid dealing with save issues and ID collisions.
 +
<source lang="C#">
 +
public class ModEntry : Mod, IAssetEditor
 +
{
 +
    /// <summary>Get whether this instance can edit the given asset.</summary>
 +
    /// <param name="asset">Basic metadata about the asset being loaded.</param>
 +
    public bool CanEdit<T>(IAssetInfo asset)
 +
    {
 +
        return asset.AssetNameEquals(@"Data\ObjectInformation");
 +
    }
 +
 
 +
    /// <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)
 +
    {
 +
        int id = ...;
 +
        asset
 +
            .AsDictionary<int, string>()
 +
            .Set(id, "Blood Rose/40/10/Basic -81/Blood Rose/Not the prettiest flower, but the leaves make a good salad.");
 +
    }
 +
}
 +
</source>
 +
</li>
 +
<li>This mod lets crops grow in any season (example only, doesn't handle edge cases):
 
<source lang="c#">
 
<source lang="c#">
 
public class ModEntry : Mod, IAssetEditor
 
public class ModEntry : Mod, IAssetEditor
Line 453: Line 478:  
}
 
}
 
</source>
 
</source>
 
+
</li>
The <tt>IAssetData</tt> method passed into the <tt>Edit&lt;T&gt;</tt> method contains helpers for various changes. For example, this code replaces part of a game image:
+
<li>
 +
This code replaces part of a game image:
 
<source lang="c#">
 
<source lang="c#">
/// <summary>Edit a matched asset.</summary>
+
public class ModEntry : Mod, IAssetEditor
/// <param name="asset">A helper which encapsulates metadata about an asset and enables changes to it.</param>
  −
public void Edit<T>(IAssetData asset)
   
{
 
{
     Texture2D customTexture = this.Helper.Content.Load<Texture2D>("custom-texture.png", ContentSource.ModFolder);
+
     /// <summary>Get whether this instance can edit the given asset.</summary>
    asset
+
    /// <param name="asset">Basic metadata about the asset being loaded.</param>
        .AsImage()
+
    public bool CanEdit<T>(IAssetInfo asset)
        .PatchImage(customTexture, targetArea: new Rectangle(300, 100, 200, 200));
+
    {
}
+
        return asset.AssetNameEquals(@"Portraits\Abigail");
 +
    }
 +
 
 +
    /// <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)
 +
    {
 +
        Texture2D customTexture = this.Helper.Content.Load<Texture2D>("custom-texture.png", ContentSource.ModFolder);
 +
        asset
 +
            .AsImage()
 +
            .PatchImage(customTexture, targetArea: new Rectangle(300, 100, 200, 200));
 +
    }
 
</source>
 
</source>
 +
</li>
 +
</ul>
    
For more advanced scenarios, you can inject multiple <tt>IAssetEditor</tt> instances instead. When you inject a new editor, SMAPI will automatically reload all game assets so it can intercept them. (This is resource-intensive when done outside your <tt>Entry</tt> method, so avoid adding editors unnecessarily.)
 
For more advanced scenarios, you can inject multiple <tt>IAssetEditor</tt> instances instead. When you inject a new editor, SMAPI will automatically reload all game assets so it can intercept them. (This is resource-intensive when done outside your <tt>Entry</tt> method, so avoid adding editors unnecessarily.)
translators
8,446

edits

Navigation menu