Changes

Jump to navigation Jump to search
→‎Custom items: Mark as migrated to Modding:Items
Line 173: Line 173:  
==What's new for items==
 
==What's new for items==
 
===Custom items===
 
===Custom items===
{{/doc status|[[Modding:Items]]|done=false}}
+
{{/doc status|[[Modding:Items]]|done=true}}
    
====Overview====
 
====Overview====
Line 318: Line 318:  
====Define a custom item====
 
====Define a custom item====
 
You can define custom items for most vanilla item types using only [[Modding:Content Patcher|Content Patcher]] or [[Modding:Modder Guide/APIs/Content|SMAPI's content API]].
 
You can define custom items for most vanilla item types using only [[Modding:Content Patcher|Content Patcher]] or [[Modding:Modder Guide/APIs/Content|SMAPI's content API]].
  −
For example, this content pack adds a new Pufferchick item with a custom image, custom gift tastes, and a custom crop that produces it. Note that item references in other data assets like <samp>Data/Crops</samp> and <samp>Data/NPCGiftTastes</samp> use the item ID.
  −
  −
{{#tag:syntaxhighlight|<nowiki>
  −
{
  −
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
  −
    "Changes": [
  −
        // add item
  −
        {
  −
            "Action": "EditData",
  −
            "Target": "Data/Objects",
  −
            "Entries": {
  −
                "{{ModId}}_Pufferchick": {
  −
                    "Name": "{{ModId}}_Pufferchick", // best practice to match the ID, since it's sometimes used as an alternate ID (e.g. in Data/CraftingRecipes)
  −
                    "Displayname": "Pufferchick",
  −
                    "Description": "An example object.",
  −
                    "Type": "Seeds",
  −
                    "Category": -74,
  −
                    "Price": 1200,
  −
  −
                    "Texture": "Mods/{{ModId}}/Objects",
  −
                    "SpriteIndex": 0
  −
                }
  −
            }
  −
        },
  −
  −
        // add gift tastes
  −
        {
  −
            "Action": "EditData",
  −
            "Target": "Data/NPCGiftTastes",
  −
            "TextOperations": [
  −
                {
  −
                    "Operation": "Append",
  −
                    "Target": ["Entries", "Universal_Love"],
  −
                    "Value": "{{ModId}}_Pufferchick",
  −
                    "Delimiter": " " // if there are already values, add a space between them and the new one
  −
                }
  −
            ]
  −
        },
  −
  −
        // add crop (Pufferchick is both seed and produce, like coffee beans)
  −
        {
  −
            "Action": "EditData",
  −
            "Target": "Data/Crops",
  −
            "Entries": {
  −
                "{{ModId}}_Pufferchick": {
  −
                    "Seasons": [ "spring", "summer", "fall" ],
  −
                    "DaysInPhase": [ 1, 1, 1, 1, 1 ],
  −
                    "HarvestItemId": "{{ModId}}_Pufferchick",
  −
  −
                    "Texture": "Mods/{{ModId}}/Crops",
  −
                    "SpriteIndex": 0
  −
                }
  −
            }
  −
        },
  −
  −
        // add item + crop images
  −
        {
  −
            "Action": "Load",
  −
            "Target": "Mods/{{ModId}}/Crops, Mods/{{ModId}}/Objects",
  −
            "FromFile": "assets/{{TargetWithoutPath}}.png" // assets/Crops.png, assets/Objects.png
  −
        }
  −
    ]
  −
}</nowiki>|lang=javascript}}
      
Most item data assets work just like <samp>Data/Objects</samp>. See also specific info for [[#Custom fruit trees|custom fruit trees]], [[#Custom tools|custom tools]], and [[#Custom melee weapon data|melee weapons]].
 
Most item data assets work just like <samp>Data/Objects</samp>. See also specific info for [[#Custom fruit trees|custom fruit trees]], [[#Custom tools|custom tools]], and [[#Custom melee weapon data|melee weapons]].
Line 391: Line 327:     
====For C# mods====
 
====For C# mods====
<dl style="margin-left: 2em;">
  −
  −
<dt>Compare items</dt>
  −
<dd>
  −
Since <samp>Item.QualifiedItemId</samp> is globally unique, it can be used to simplify comparing items. For example:
  −
  −
{| class="wikitable"
  −
|-
  −
! old code
  −
! new code
  −
|-
  −
|-
  −
| <samp>item.ParentSheetIndex == 128</samp>
  −
| <samp>item.QualifiedItemId == "(O)128"</samp>
  −
|-
  −
| <samp>IsNormalObjectAtParentSheetIndex(item, 128)</samp>
  −
| <samp>item.QualifiedItemId == "(O)128"</samp>
  −
|-
  −
| <samp>!item.bigCraftable && item.ParentSheetIndex == 128</samp>
  −
| <samp>item.QualifiedItemId == "(O)128"</samp>
  −
|-
  −
| <samp>item is Boots && item.ParentSheetIndex == 505</samp>
  −
| <samp>item.QualifiedItemId == "(B)505"</samp>
  −
|}
  −
  −
You can also use <samp>ItemRegistry.QualifyItemId</samp> to convert any item ID into a qualified one (if it's valid), and <samp>ItemRegistry.HasItemId</samp> to check if an item has a qualified or unqualified item ID.
  −
  −
Note that flavored item don't have their own ID. For example, Blueberry Wine and Wine are both <samp>(O)348</samp>. This affects flavored jellies, juices, pickles, and wines. In those cases you should still compare their separate fields like <samp>preservedParentSheetIndex</samp> (which actually contains the preserved item's <samp>ItemId</samp>, not its <samp>ParentSheetIndex</samp>).
  −
</dd>
  −
  −
<dt>Construct items</dt>
  −
<dd>Creating items works just like before, except that you now specify the item's <samp>ItemId</samp> (''not'' <samp>QualifiedItemId</samp>) instead of its <samp>ParentSheetIndex</samp>. For example:
  −
  −
<syntaxhighlight lang="c#">
  −
new Object("128", 1);                      // vanilla item
  −
new Object("Example.ModId_Watermelon", 1); // custom item
  −
</syntaxhighlight>
  −
  −
You can use a new utility method to construct items from their <samp>QualifiedItemId</samp>:
  −
  −
<syntaxhighlight lang="c#">
  −
Item item = ItemRegistry.Create("(B)505"); // Rubber Boots
  −
</syntaxhighlight>
  −
</dd>
     −
<dt>Define custom item types</dt>
+
Stardew Valley 1.6 added new ways to compare/construct items, define custom item types, and work with item metadata. Please see [[Modding:Items]] for the migrated docs.
<dd>You can implement <samp>IItemDataDefinition</samp> for your own item type, and call <samp>ItemRegistry.AddTypeDefinition</samp> to register it. This provides all the logic needed by the game to handle the item type: where to get item data, how to draw them, etc.
  −
 
  −
'''This is extremely specialized''', and multiplayer compatibility is unknown. Most mods should add custom items within the existing types instead.</dd>
  −
 
  −
<dt>New <samp>Is*</samp> methods</dt>
  −
<dd>1.6 adds some <samp>StardewValley.Object</samp> methods to handle custom items in a generic way (and to let mods patch the logic):
  −
{| class="wikitable"
  −
|-
  −
! method
  −
! effect
  −
|-
  −
| <samp>object.IsBar()</samp>
  −
| Whether the item is a [[Copper Bar|copper bar]], [[Iron Bar|iron bar]], [[Gold Bar|gold bar]], [[Iridium Bar|iridium bar]], or [[Radioactive Bar|radioactive bar]].
  −
|-
  −
| <samp>object.IsBreakableStone()</samp>
  −
| Whether the item is a stone debris item which can be broken by a pickaxe.
  −
|-
  −
| <samp>object.IsFence()</samp>
  −
| Whether the item is a [[Crafting#Fences|fence]].
  −
|-
  −
| <samp>object.IsFruitTreeSapling()</samp>
  −
| Whether the item is a [[Fruit Trees|fruit tree]] sapling. This checks the <samp>Data\fruitTrees</samp> keys, so it works with custom fruit trees too.
  −
|-
  −
| <samp>object.IsHeldOverHead()</samp>
  −
| Whether the player is shown holding up the item when it's selected in their toolbar. Default true (except for furniture).
  −
|-
  −
| <samp>object.IsIncubator()</samp>
  −
| Whether the item can incubate [[Animals|farm animal]] eggs when placed in a building.
  −
|-
  −
| <samp>object.IsTapper()</samp>
  −
| Whether the item is a [[Tapper|tapper]] or [[Heavy Tapper|heavy tapper]].
  −
|-
  −
| <samp>object.IsTeaSapling()</samp>
  −
| Whether the item is a [[Tea Sapling|tea sapling]].
  −
|-
  −
| <samp>object.IsTwig()</samp>
  −
| Whethere the item is a twig debris item.
  −
|-
  −
| <samp>object.IsWeeds()</samp>
  −
| Whether the item is a weed debris item.
  −
|}
  −
</dd>
  −
 
  −
<dt>Work with item metadata</dt>
  −
<dd>
  −
1.6 adds an <samp>ItemRegistry</samp> API for working with the new item system. Some of the provided methods are:
  −
 
  −
{| class="wikitable"
  −
|-
  −
! method
  −
! effect
  −
|-
  −
| <samp>ItemRegistry.Create</samp>
  −
| Create an item from its item ID (qualified or unqualified). If the ID doesn't match a real item, the optional <samp>allowNull</samp> parameter indicates whether to return null or an Error Item. For example:
  −
<syntaxhighlight lang="c#">
  −
Item item = ItemRegistry.Create("(B)505"); // Rubber Boots
  −
</syntaxhighlight>
  −
 
  −
You can also get a specific value type instead of <samp>Item</samp> if needed. This will throw a descriptive exception if the type isn't compatible (e.g. you try to convert furniture to boots).
  −
<syntaxhighlight lang="c#">
  −
Boots item = ItemRegistry.Create<Boots>("(B)505"); // Rubber Boots
  −
</syntaxhighlight>
  −
|-
  −
| <samp>ItemRegistry.Exists</samp>
  −
| Get whether a qualified or unqualified item ID matches an existing item. For example:
  −
<syntaxhighlight lang="c#">
  −
bool pufferfishExist = ItemRegistry.Exists("(O)128");
  −
</syntaxhighlight>
  −
|-
  −
| <samp>ItemRegistry.IsQualifiedId</samp>
  −
| Get whether the given item ID is qualified with the type prefix (like <samp>(O)128</samp> instead of <samp>128</samp>).
  −
|-
  −
| <samp>ItemRegistry.QualifyItemId</samp>
  −
| Get the unique qualified item ID given an unqualified or qualified one. For example:
  −
<syntaxhighlight lang="c#">
  −
string qualifiedId = ItemRegistry.QualifyItemId("128"); // returns (O)128
  −
</syntaxhighlight>
  −
|-
  −
| <samp>ItemRegistry.GetMetadata</samp>
  −
| This lets you get high-level info about an item:
  −
<syntaxhighlight lang="c#">
  −
// get info about Rubber Boots
  −
ItemMetadata info = ItemRegistry.GetMetadata("(B)505");
  −
 
  −
// get item ID info
  −
$"The item has unqualified ID {info.LocalId}, qualified ID {info.QualifiedId}, and is defined by the {info.TypeIdentifier} item data definition.";
  −
 
  −
// does the item exist in the data files?
  −
bool exists = info.Exists();
  −
</syntaxhighlight>
  −
 
  −
And get common parsed item data:
  −
<syntaxhighlight lang="c#">
  −
// get parsed info
  −
ParsedItemData data = info.GetParsedData();
  −
$"The internal name is {data.InternalName}, translated name {data.DisplayName}, description {data.Description}, etc.";
  −
 
  −
// draw an item sprite
  −
Texture2D texture = data.GetTexture();
  −
Rectangle sourceRect = data.GetSourceRect();
  −
spriteBatch.Draw(texture, Vector2.Zero, sourceRect, Color.White);
  −
</syntaxhighlight>
  −
 
  −
And create an item:
  −
<syntaxhighlight lang="c#">
  −
Item item = metadata.CreateItem();
  −
</syntaxhighlight>
  −
 
  −
And get the type definition (note that this is very specialized, and you should usually use <samp>ItemRegistry</samp> instead to benefit from its caching and optimizations):
  −
<syntaxhighlight lang="c#">
  −
IItemDataDefinition typeDefinition = info.GetTypeDefinition();
  −
</syntaxhighlight>
  −
|-
  −
| <samp>ItemRegistry.ResolveMetadata</samp>
  −
| Equivalent to <samp>ItemRegistry.GetMetadata</samp>, except that it'll return null if the item doesn't exist.
  −
|-
  −
| <samp>ItemRegistry.GetData</samp>
  −
| Get the parsed data about an item, or <samp>null</samp> if the item doesn't exist. This is a shortcut for <code>ItemRegistry.ResolveMetadata(id)?.GetParsedData()</code>; see the previous method for info on the parsed data.
  −
|-
  −
| <samp>ItemRegistry.GetDataOrErrorItem</samp>
  −
| Equivalent to <samp>ItemRegistry.GetData</samp>, except that it'll return info for an Error Item if the item doesn't exist (e.g. for drawing in inventory).
  −
|-
  −
| <samp>ItemRegistry.GetErrorItemName</samp>
  −
| Get a translated ''Error Item'' label.
  −
|}
  −
</dd>
  −
</dl>
      
===Custom big craftables===
 
===Custom big craftables===
138

edits

Navigation menu