Changes

move item queries into their own section (no longer specific to shops)
Line 542: Line 542:  
| One of...
 
| One of...
 
* the [[#Custom items|qualified or unqualified item ID]] for the produced item;
 
* the [[#Custom items|qualified or unqualified item ID]] for the produced item;
* ''or'' an [[#Item search query|item query]] which returns the produced item (if the query returns multiple items, only the first one is used);
+
* ''or'' an [[#Item queries|item query]] which returns the produced item (if the query returns multiple items, only the first one is used);
 
* ''or'' <samp>DROP_IN</samp> for the item placed into the machine.
 
* ''or'' <samp>DROP_IN</samp> for the item placed into the machine.
   Line 1,799: Line 1,799:  
| One of:
 
| One of:
 
* the [[#Custom items|qualified item ID]] (like <samp>(O)128</samp> for a [[pufferfish]]);
 
* the [[#Custom items|qualified item ID]] (like <samp>(O)128</samp> for a [[pufferfish]]);
* or a [[#Item search query|search query]] to dynamically choose an item (if it returns multiple items, only the first one will be used).
+
* or a [[#Item queries|search query]] to dynamically choose an item (if it returns multiple items, only the first one will be used).
 
|-
 
|-
 
| <samp>RandomItemId</samp>
 
| <samp>RandomItemId</samp>
Line 3,728: Line 3,728:  
| One of:
 
| One of:
 
* the [[#Custom items|qualified item ID]] (like <samp>(O)128</samp> for a [[pufferfish]]);
 
* the [[#Custom items|qualified item ID]] (like <samp>(O)128</samp> for a [[pufferfish]]);
* or a [[#Item search query|search query]] to dynamically choose one or more items.
+
* or an [[#Item queries|item query]] to dynamically choose one or more items.
 
|-
 
|-
 
| <samp>RandomItemId</samp>
 
| <samp>RandomItemId</samp>
Line 3,941: Line 3,941:  
|}
 
|}
   −
====Item search query====
+
====Open a custom shop====
''Item search queries'' in a [[#Format|shop item's <samp>ItemId</samp> or <samp>RandomItemId</samp> field]] choose one or more items dynamically, instead of specifying an item ID.
+
You can place an [[#Map/tile property changes|<samp>Action OpenShop</samp> tile property]] on the map, which will open the given shop ID when the player clicks it.
 +
 
 +
In C# code, you can get the inventory for a custom shop using <code>Utility.GetShopStock("shop id here")</code>, open a shop menu using <code>Utility.OpenShopMenu("shop id", …)</code>, and add temporary items to an open menu using <code>shopMenu.AddForSale(…)</code>. The ID of the opened shop is stored in the shop menu's <samp>storeContext</samp> field.
   −
The supported search queries are:
+
====Examples====
{| class="wikitable"
+
You can add or replace entire shops. For example, this content pack adds a shop that sells ice cream in summer, and pufferfish all year:
|-
  −
! query
  −
! effect
  −
|-
  −
| <samp>ALL_ITEMS {{o|type ID}}</samp>
  −
| Every item provided by the [[#Custom items|item data definitions]]. If {{o|type ID}} is set to an item type identifier (like <samp>(O)</samp> for object), only returns items from the matching item data definition.
  −
|-
  −
| <samp>DISH_OF_THE_DAY</samp>
  −
| The [[The Stardrop Saloon#Rotating Stock|Saloon's dish of the day]].
  −
|-
  −
| <samp>FLAVORED_ITEM {{t|type}} {{t|flavor ID}}</samp>
  −
| A flavored item like Apple Wine. The {{t|type}} can be one of [[Aged Roe|<samp>AgedRoe</samp>]], [[Honey|<samp>Honey</samp>]], [[Jellies and Pickles|<samp>Jelly</samp>]], [[Juice|<samp>Juice</samp>]], [[Jellies and Pickles|<samp>Pickle</samp>]], [[Roe|<samp>Roe</samp>]], or [[Wine|<samp>Wine</samp>]]. The {{t|flavor ID}} is the qualified or unqualified item ID which provides the flavor (like Apple in Apple Wine). For <samp>Honey</samp>, you can set the {{t|flavor ID}} to <samp>-1</samp> for Wild Honey.
  −
|-
  −
| <samp>ITEMS_SOLD_BY_PLAYER {{t|shop location}}</samp>
  −
| Random items the player has recently sold to the {{t|shop location}}, which can be one of <samp>SeedShop</samp> (Pierre's store) or <samp>FishShop</samp> (Willy's fish shop).
  −
|-
  −
| <samp>RANDOM_BASE_SEASON_ITEM</samp>
  −
| A random seasonal vanilla item which can be found by searching garbage cans, breaking containers in the mines, etc.
  −
|-
  −
| <samp>RANDOM_ITEMS {{t|type definition ID}} {{o|options}}</samp>
  −
| Random items from the given [[#Item types|type definition ID]], with any combination of the following criteria and options (in any order, all optional):
     −
{| class="wikitable"
+
{{#tag:syntaxhighlight|<nowiki>
|-
+
{
! format
+
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
! item criteria
+
    "Changes": [
|-
+
        {
!colspan="2"| search criteria
+
            "Action": "EditData",
|-
+
            "Target": "Data/Shops",
| <samp>@has_category {{o|category}}</samp>
+
            "Entries": {
| Must have one of the given [[Modding:Items#Categories|object categories]] (space-delimited), or any valid category if none specified. Can be negated with <samp>@!has_category</samp>.
+
                "Example.ModId_CustomShop": {
|-
+
                    "Owners": [
| <samp>@has_id {{t|id}}+</samp>
+
                        {
| Must have one of the given unqualified item IDs. Can be negated with <samp>@!has_id</samp>.
+
                            "Name": "Any",
|-
+
                            "Dialogues": [
| <samp>@has_id_in_base_range {{t|min}} {{t|max}}</samp>
+
                                // dialogue on sunny summer days
| Must have a numeric ID between the {{t|min}} and {{t|max}} values (inclusive). Can be negated with <samp>@!has_id_in_base_range </samp>.
+
                                {
|-
+
                                    "Id": "Example.ModId_SunnySummer",
| <samp>@has_id_prefix {{t|prefix}}+</samp>
+
                                    "Condition": "SEASON Summer, WEATHER Sun",
| Must have an unqualified item ID starting with one of the given prefixes. For example, <samp>@has_id_prefix ExampleAuthor_ExampleMod_</samp> for a mod's items. Can be negated with <samp>@!has_id_prefix</samp>.
+
                                    "Dialogue": "Ice-cream is perfect for a day like this."
|-
+
                                },
| <samp>@has_object_type {{o|type}}+</samp>
  −
| Must have one of the given object ty pes (space-delimited), or any valid type if none specified. Can be negated with <samp>@!has_object_type</samp>.
  −
|-
  −
!colspan="2"| options
  −
|-
  −
| <samp>@allow_missing_price</samp>
  −
| Allow items with a base sell price of 0 or lower. If omitted, those items are skipped.
  −
|-
  −
| <samp>@count {{t|count}}</samp>
  −
| The number of random items to add to the shop. Default 1.
  −
|}
     −
For example, you can sell a random [[wallpaper]] for {{price|200}}:
+
                                // dialogue any other time
<syntaxhighlight lang="js">
+
                                {
{
+
                                    "Id": "Example.ModId_Default",
    "ItemId": "RANDOM_ITEMS (WP)",
+
                                    "Dialogue": "Welcome to the only place in town for pufferfish!"
    "Price": 200
+
                                }
}
+
                            ]
</syntaxhighlight>
+
                        }
 +
                    ],
   −
Or a random [[House Plant|house plant]]:
+
                    "Items": [
<syntaxhighlight lang="js">
+
                        // ice-cream in summer, default price
{
+
                        {
    "ItemId": "RANDOM_ITEMS (F) @has_id_in_base_range 1376 1390"
+
                            "Id": "Example.ModId_IceCream",
}
+
                            "Condition": "SEASON Summer",
</syntaxhighlight>
+
                            "ItemId": "(O)233"
 +
                        },
   −
Or a random [[#Custom items|custom item]] added by a mod by its item ID prefix:
+
                        // pufferfish for 1000g, limited to one per day per player
<syntaxhighlight lang="js">
+
                        {
{
+
                            "Id": "Example.ModId_PufferFish",
    "ItemId": "RANDOM_ITEMS (O) @has_id_prefix AuthorName_ModName_"
+
                            "ItemId": "(O)128",
}
+
                            "Price": 1000,
</syntaxhighlight>
+
                            "AvailableStock": 1,
 +
                            "AvailableStockLimit": "Player"
 +
                        }
 +
                    ]
 +
                }
 +
            }
 +
        }
 +
    ]
 +
}</nowiki>|lang=javascript}}
   −
Or 10 random objects with any category except <samp>-13</samp> or <samp>-14</samp>:
+
You can also add, replace, edit, or reorder items in a specific shop by targeting the shop's <samp>Items</samp> field. For example, this removes Trout Soup (item #219) and adds Pufferfish above bait (item #685):
<syntaxhighlight lang="js">
+
{{#tag:syntaxhighlight|<nowiki>
 
{
 
{
    "ItemId": "RANDOM_ITEMS (O) @has_category @!has_category -13 -14 @count 10"
+
     "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
}
+
     "Changes": [
</syntaxhighlight>
+
         {
|-
  −
| <samp>SHOP_TOWN_KEY</samp>
  −
| The special [[Key To The Town|town key]] item. This is only valid in shops.
  −
|-
  −
| <samp>TOOL_UPGRADES {{o|tool ID}}</samp>
  −
| The tool upgrades listed in <samp>Data/Shops</samp> whose conditions match the player's inventory (i.e. the same rules as [[Blacksmith|Clint's tool upgrade shop]]). If {{o|tool ID}} is specified, only upgrades which consume that tool ID are shown.
  −
|}
  −
 
  −
====Open a custom shop====
  −
You can place an [[#Map/tile property changes|<samp>Action OpenShop</samp> tile property]] on the map, which will open the given shop ID when the player clicks it.
  −
 
  −
In C# code, you can get the inventory for a custom shop using <code>Utility.GetShopStock("shop id here")</code>, open a shop menu using <code>Utility.OpenShopMenu("shop id", …)</code>, and add temporary items to an open menu using <code>shopMenu.AddForSale(…)</code>. The ID of the opened shop is stored in the shop menu's <samp>storeContext</samp> field.
  −
 
  −
====Examples====
  −
You can add or replace entire shops. For example, this content pack adds a shop that sells ice cream in summer, and pufferfish all year:
  −
 
  −
{{#tag:syntaxhighlight|<nowiki>
  −
{
  −
     "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
  −
     "Changes": [
  −
         {
   
             "Action": "EditData",
 
             "Action": "EditData",
 
             "Target": "Data/Shops",
 
             "Target": "Data/Shops",
 +
            "TargetField": [ "FishShop", "Items" ],
 
             "Entries": {
 
             "Entries": {
                 "Example.ModId_CustomShop": {
+
                 "(O)219": null,
                    "Owners": [
+
                "Example.ModId_Pufferfish": {
                        {
+
                    "Id": "Example.ModId_Pufferfish",
                            "Name": "Any",
+
                    "ItemId": "(O)128",
                            "Dialogues": [
+
                    "Price": 2000
                                // dialogue on sunny summer days
+
                }
                                {
+
            },
                                    "Id": "Example.ModId_SunnySummer",
+
            "MoveEntries": [
                                    "Condition": "SEASON Summer, WEATHER Sun",
+
                { "Id": "Example.ModId_Pufferfish", "BeforeId": "(O)685" }
                                    "Dialogue": "Ice-cream is perfect for a day like this."
+
            ]
                                },
+
         }
 
  −
                                // dialogue any other time
  −
                                {
  −
                                    "Id": "Example.ModId_Default",
  −
                                    "Dialogue": "Welcome to the only place in town for pufferfish!"
  −
                                }
  −
                            ]
  −
                        }
  −
                    ],
  −
 
  −
                    "Items": [
  −
                        // ice-cream in summer, default price
  −
                        {
  −
                            "Id": "Example.ModId_IceCream",
  −
                            "Condition": "SEASON Summer",
  −
                            "ItemId": "(O)233"
  −
                        },
  −
 
  −
                        // pufferfish for 1000g, limited to one per day per player
  −
                        {
  −
                            "Id": "Example.ModId_PufferFish",
  −
                            "ItemId": "(O)128",
  −
                            "Price": 1000,
  −
                            "AvailableStock": 1,
  −
                            "AvailableStockLimit": "Player"
  −
                        }
  −
                    ]
  −
                }
  −
            }
  −
         }
   
     ]
 
     ]
 
}</nowiki>|lang=javascript}}
 
}</nowiki>|lang=javascript}}
   −
You can also add, replace, edit, or reorder items in a specific shop by targeting the shop's <samp>Items</samp> field. For example, this removes Trout Soup (item #219) and adds Pufferfish above bait (item #685):
+
====Vanilla shop IDs====
{{#tag:syntaxhighlight|<nowiki>
+
Vanilla shops are now defined in <samp>Data/Shops</samp> too (except a few special cases like [[:Category:Dressers|dressers]] and home renovations), using these shop IDs:
{
+
 
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
+
{| class="wikitable sortable"
    "Changes": [
+
|-
        {
+
! shop
            "Action": "EditData",
+
! ID
            "Target": "Data/Shops",
+
|-
            "TargetField": [ "FishShop", "Items" ],
  −
            "Entries": {
  −
                "(O)219": null,
  −
                "Example.ModId_Pufferfish": {
  −
                    "Id": "Example.ModId_Pufferfish",
  −
                    "ItemId": "(O)128",
  −
                    "Price": 2000
  −
                }
  −
            },
  −
            "MoveEntries": [
  −
                { "Id": "Example.ModId_Pufferfish", "BeforeId": "(O)685" }
  −
            ]
  −
        }
  −
    ]
  −
}</nowiki>|lang=javascript}}
  −
 
  −
====Vanilla shop IDs====
  −
Vanilla shops are now defined in <samp>Data/Shops</samp> too (except a few special cases like [[:Category:Dressers|dressers]] and home renovations), using these shop IDs:
  −
 
  −
{| class="wikitable sortable"
  −
|-
  −
! shop
  −
! ID
  −
|-
   
| [[Abandoned House|Abandoned house shop]]
 
| [[Abandoned House|Abandoned house shop]]
 
| <samp>HatMouse</samp>
 
| <samp>HatMouse</samp>
Line 4,957: Line 4,863:  
====Extensibility====
 
====Extensibility====
 
C# mods can define custom conditions by calling <code>GameStateQuery.RegisterQueryType("condition name", (string[] fields) => ...)</code>. To avoid conflicts, prefixing custom condition names with your mod ID (like <samp>Example.ModId_SomeCondition</samp>) is strongly recommended.
 
C# mods can define custom conditions by calling <code>GameStateQuery.RegisterQueryType("condition name", (string[] fields) => ...)</code>. To avoid conflicts, prefixing custom condition names with your mod ID (like <samp>Example.ModId_SomeCondition</samp>) is strongly recommended.
 +
 +
===Item queries===
 +
''Item queries'' in a [[#Format|shop item's <samp>ItemId</samp> or <samp>RandomItemId</samp> field]] choose one or more items dynamically, instead of specifying an item ID.
 +
 +
The supported search queries are:
 +
{| class="wikitable"
 +
|-
 +
! query
 +
! effect
 +
|-
 +
| <samp>ALL_ITEMS {{o|type ID}}</samp>
 +
| Every item provided by the [[#Custom items|item data definitions]]. If {{o|type ID}} is set to an item type identifier (like <samp>(O)</samp> for object), only returns items from the matching item data definition.
 +
|-
 +
| <samp>DISH_OF_THE_DAY</samp>
 +
| The [[The Stardrop Saloon#Rotating Stock|Saloon's dish of the day]].
 +
|-
 +
| <samp>FLAVORED_ITEM {{t|type}} {{t|flavor ID}}</samp>
 +
| A flavored item like Apple Wine. The {{t|type}} can be one of [[Aged Roe|<samp>AgedRoe</samp>]], [[Honey|<samp>Honey</samp>]], [[Jellies and Pickles|<samp>Jelly</samp>]], [[Juice|<samp>Juice</samp>]], [[Jellies and Pickles|<samp>Pickle</samp>]], [[Roe|<samp>Roe</samp>]], or [[Wine|<samp>Wine</samp>]]. The {{t|flavor ID}} is the qualified or unqualified item ID which provides the flavor (like Apple in Apple Wine). For <samp>Honey</samp>, you can set the {{t|flavor ID}} to <samp>-1</samp> for Wild Honey.
 +
|-
 +
| <samp>ITEMS_SOLD_BY_PLAYER {{t|shop location}}</samp>
 +
| Random items the player has recently sold to the {{t|shop location}}, which can be one of <samp>SeedShop</samp> (Pierre's store) or <samp>FishShop</samp> (Willy's fish shop).
 +
|-
 +
| <samp>RANDOM_BASE_SEASON_ITEM</samp>
 +
| A random seasonal vanilla item which can be found by searching garbage cans, breaking containers in the mines, etc.
 +
|-
 +
| <samp>RANDOM_ITEMS {{t|type definition ID}} {{o|options}}</samp>
 +
| Random items from the given [[#Item types|type definition ID]], with any combination of the following criteria and options (in any order, all optional):
 +
 +
{| class="wikitable"
 +
|-
 +
! format
 +
! item criteria
 +
|-
 +
!colspan="2"| search criteria
 +
|-
 +
| <samp>@has_category {{o|category}}</samp>
 +
| Must have one of the given [[Modding:Items#Categories|object categories]] (space-delimited), or any valid category if none specified. Can be negated with <samp>@!has_category</samp>.
 +
|-
 +
| <samp>@has_id {{t|id}}+</samp>
 +
| Must have one of the given unqualified item IDs. Can be negated with <samp>@!has_id</samp>.
 +
|-
 +
| <samp>@has_id_in_base_range {{t|min}} {{t|max}}</samp>
 +
| Must have a numeric ID between the {{t|min}} and {{t|max}} values (inclusive). Can be negated with <samp>@!has_id_in_base_range </samp>.
 +
|-
 +
| <samp>@has_id_prefix {{t|prefix}}+</samp>
 +
| Must have an unqualified item ID starting with one of the given prefixes. For example, <samp>@has_id_prefix ExampleAuthor_ExampleMod_</samp> for a mod's items. Can be negated with <samp>@!has_id_prefix</samp>.
 +
|-
 +
| <samp>@has_object_type {{o|type}}+</samp>
 +
| Must have one of the given object ty pes (space-delimited), or any valid type if none specified. Can be negated with <samp>@!has_object_type</samp>.
 +
|-
 +
!colspan="2"| options
 +
|-
 +
| <samp>@allow_missing_price</samp>
 +
| Allow items with a base sell price of 0 or lower. If omitted, those items are skipped.
 +
|-
 +
| <samp>@count {{t|count}}</samp>
 +
| The number of random items to add to the shop. Default 1.
 +
|}
 +
 +
For example, you can sell a random [[wallpaper]] for {{price|200}}:
 +
<syntaxhighlight lang="js">
 +
{
 +
    "ItemId": "RANDOM_ITEMS (WP)",
 +
    "Price": 200
 +
}
 +
</syntaxhighlight>
 +
 +
Or a random [[House Plant|house plant]]:
 +
<syntaxhighlight lang="js">
 +
{
 +
    "ItemId": "RANDOM_ITEMS (F) @has_id_in_base_range 1376 1390"
 +
}
 +
</syntaxhighlight>
 +
 +
Or a random [[#Custom items|custom item]] added by a mod by its item ID prefix:
 +
<syntaxhighlight lang="js">
 +
{
 +
    "ItemId": "RANDOM_ITEMS (O) @has_id_prefix AuthorName_ModName_"
 +
}
 +
</syntaxhighlight>
 +
 +
Or 10 random objects with any category except <samp>-13</samp> or <samp>-14</samp>:
 +
<syntaxhighlight lang="js">
 +
{
 +
    "ItemId": "RANDOM_ITEMS (O) @has_category @!has_category -13 -14 @count 10"
 +
}
 +
</syntaxhighlight>
 +
|-
 +
| <samp>SHOP_TOWN_KEY</samp>
 +
| The special [[Key To The Town|town key]] item. This is only valid in shops.
 +
|-
 +
| <samp>TOOL_UPGRADES {{o|tool ID}}</samp>
 +
| The tool upgrades listed in <samp>Data/Shops</samp> whose conditions match the player's inventory (i.e. the same rules as [[Blacksmith|Clint's tool upgrade shop]]). If {{o|tool ID}} is specified, only upgrades which consume that tool ID are shown.
 +
|}
    
===More <samp>modData</samp> fields===
 
===More <samp>modData</samp> fields===
Line 5,343: Line 5,343:  
| ''Syntax:'' <samp>iq {{t|query}}</samp>
 
| ''Syntax:'' <samp>iq {{t|query}}</samp>
   −
Open a shop menu with all the items matching an [[#Item search query|item query]] (all items free). For example:
+
Open a shop menu with all the items matching an [[#Item queries|item query]] (all items free). For example:
 
* <samp>debug iq ALL_ITEMS</samp> shows all items;
 
* <samp>debug iq ALL_ITEMS</samp> shows all items;
 
* <samp>debug iq ALL_ITEMS (W)</samp> shows all weapons;
 
* <samp>debug iq ALL_ITEMS (W)</samp> shows all weapons;
translators
8,456

edits