Line 488: |
Line 488: |
| | | |
| ==Game state queries== | | ==Game state queries== |
− | <span style="color: red;">'''TODO'''</span> | + | A ''game state query'' is a vanilla way to specify conditions for some content like shop data, inspired by [[Modding:Content Patcher|Content Patcher]]'s conditions. A query consists of a comma-delimited list of conditions in the form {{t|type}} {{o|arguments}}, where {{t|type}} is case-sensitive. The type can be prefixed with <code>!</code> to negate it. The query is true if it's null/blank, or if every listed condition exists and is true. For example, <code>!SEASON Spring, WEATHER Sun</code> is true on sunny non-[[spring]] days. |
| + | |
| + | ===Conditions=== |
| + | ; World |
| + | :{| class="wikitable" |
| + | |- |
| + | ! Condition |
| + | ! effect |
| + | |- |
| + | | <samp>DAY_OF_MONTH {{t|day}}</samp> |
| + | | Check the day of month. |
| + | |- |
| + | | <samp>DAY_OF_WEEK {{t|day}}</samp> |
| + | | Check the day of week, formatted as an integer between 0 (Sunday) through 6 (Saturday). |
| + | |- |
| + | | <samp>FARM_CAVE {{t|type}}</samp> |
| + | | The current [[The Farm#The Cave|farm cave]] (one of <samp>Bats</samp>, <samp>Mushrooms</samp>, or <samp>None</samp>). |
| + | |- |
| + | | <samp>FARM_NAME {{t|name}}</samp> |
| + | | Check the name of the farm. |
| + | |
| + | '''Note:''' this only works for farm names that don't contain spaces. |
| + | |- |
| + | | <samp>FARM_TYPE {{t|type}}</samp> |
| + | | Check the [[Farm Maps|farm type]]. The {{t|type}} is one of <samp>1</samp> (standard), <samp>2</samp> (riverland), <samp>3</samp> (forest), <samp>4</samp> (hilltop), <samp>4</samp> (combat), <samp>5</samp> (four corners), <samp>6</samp> (beach), or the ID for a custom farm type. |
| + | |- |
| + | | <samp>IS_HOST</samp> |
| + | | Check whether the current player is the main/host player. |
| + | |- |
| + | | <samp>IS_CUSTOM_FARM_TYPE</samp> |
| + | | Check whether the [[Farm Maps|farm type]] is a custom one created by a mod. (This returns false for mods which edit/replace a vanilla farm type.) |
| + | |- |
| + | | <samp>SEASON {{t|season}}</samp> |
| + | | Check the season (one of <samp>spring</samp>, <samp>summer</samp>, <samp>fall</samp>, or <samp>winter</samp>). |
| + | |- |
| + | | <samp>LOCATION_ACCESSIBLE {{t|name}}</samp> |
| + | | Check whether the given location is accessible (one of <samp>CommunityCenter</samp>, <samp>JojaMart</samp>, or <samp>Railroad</samp>). Returns true for any other name, regardless of whether it's accessible. |
| + | |- |
| + | | <samp>WEATHER {{t|weather}}</samp> |
| + | | Check the weather in the local player's current location (one of <samp>rainy</samp> or <samp>sunny</samp>). |
| + | |- |
| + | | <samp>WORLD_STATE {{t|id}}</samp> |
| + | | Check whether any world state flag with the given {{t|id}} is set. |
| + | |- |
| + | | <samp>YEAR</samp> |
| + | | Check if the year is equal '''or more than''' the given value. For example, <code>YEAR 2</code> is true in year 2 and all later years. |
| + | |} |
| + | |
| + | ; Player info & progress |
| + | :{| class="wikitable" |
| + | |- |
| + | ! Condition |
| + | ! effect |
| + | |- |
| + | | <samp>PLAYER_COMBAT_LEVEL {{t|player}} {{t|level}}</samp><br /><samp>PLAYER_FARMING_LEVEL {{t|player}} {{t|level}}</samp><br /><samp>PLAYER_FISHING_LEVEL {{t|player}} {{t|level}}</samp><br /><samp>PLAYER_FORAGING_LEVEL {{t|player}} {{t|level}}</samp><br /><samp>PLAYER_MINING_LEVEL {{t|player}} {{t|level}}</samp> |
| + | | Check the [[skills|skill levels]] for the [[#Player ID|specified player(s)]]. |
| + | |- |
| + | | <samp>PLAYER_CURRENT_MONEY {{t|player}} {{t|amount}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] currently have at least {{t|amount}} gold. |
| + | |- |
| + | | <samp>PLAYER_FARMHOUSE_UPGRADE {{t|player}} {{t|level}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] have upgraded their [[farmhouse]] or [[cabin]] to at least the given level (see [https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-tokens-guide.md#FarmhouseUpgrade possible levels]). |
| + | |- |
| + | | <samp>PLAYER_GENDER {{t|player}} {{t|gender}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] are <samp>Male</samp> or <samp>Female</samp>. |
| + | |- |
| + | | <samp>PLAYER_HAS_CAUGHT_FISH {{t|player}} {{t|id}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] has caught at least one fish with the given ID. |
| + | |- |
| + | | <samp>PLAYER_HAS_CONVERSATION_TOPIC {{t|player}} {{t|id}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] has a [[Modding:Dialogue#Conversation topics|conversation topic]] with the ID {{t|id}} active. |
| + | |- |
| + | | <samp>PLAYER_HAS_CRAFTING_RECIPE {{t|player}} {{t|recipe name}}</samp><br /><samp>PLAYER_HAS_COOKING_RECIPE {{t|player}} {{t|recipe name}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] know the crafting/cooking recipe identified by its internal name (spaces allowed). For example, <code>PLAYER_HAS_CRAFTING_RECIPE CURRENT Field Snack</code>. |
| + | |- |
| + | | <samp>PLAYER_HAS_DIALOGUE_ANSWER {{t|player}} {{t|id}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] has chosen the given dialogue answer in a previous dialogue. |
| + | |- |
| + | | <samp>PLAYER_HAS_FLAG {{t|player}} {{t|id}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] have the given [[Modding:Mail data|mail flag]] set (with spaces allowed in the {{t|id}}). |
| + | |- |
| + | | <samp>PLAYER_HAS_ITEM {{t|player}} {{t|item}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] has at least one of a normal item (not bigcraftable, furniture, etc) in their inventory. The {{t|item}} can be <samp>858</samp> (Qi Gems), <samp>73</samp> (Walnuts), or the unqualified item ID. |
| + | |- |
| + | | <samp>PLAYER_HAS_ITEM_NAMED {{t|player}} {{t|item name}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] has at least one item in their inventory with the given {{t|item name}} (spaces allowed). |
| + | |- |
| + | | <samp>PLAYER_HAS_READ_LETTER {{t|player}} {{t|id}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] have read a letter, where {{t|id}} is the internal mail ID (spaces allowed). For example, <code>PLAYER_HAS_READ_LETTER Any Visited_Island</code>. |
| + | |- |
| + | | <samp>PLAYER_HAS_SECRET_NOTE {{t|player}} {{t|id}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] have read a secret note, where {{t|id}} is the secret note's integer ID. |
| + | |- |
| + | | <samp>PLAYER_HAS_SEEN_EVENT {{t|player}} {{t|id}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] have seen the event with given {{t|id}}. |
| + | |- |
| + | | <samp>PLAYER_MOD_DATA {{t|player}} {{t|key}} {{t|value}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] have a <samp>player.modData</samp> entry added by a mod with the given {{t|key}} and {{t|value}}. |
| + | |- |
| + | | <samp>PLAYER_MONEY_EARNED {{t|player}} {{t|amount}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] have earned at least {{t|amount}} gold. |
| + | |} |
| + | |
| + | ; Player relationships |
| + | :{| class="wikitable" |
| + | |- |
| + | ! Condition |
| + | ! effect |
| + | |- |
| + | | <samp>PLAYER_HAS_CHILDREN {{t|player}} {{t|count}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] has least {{t|count}} children. |
| + | |- |
| + | | <samp>PLAYER_HAS_PET {{t|player}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] has a [[pet]]. |
| + | |- |
| + | | <samp>PLAYER_HEARTS {{t|player}} {{t|npc}} {{t|heart level}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] have a friend with at least {{t|heart level}} hearts of [[friendship]]. The {{t|npc}} can be an NPC's internal name, <samp>Any</samp> (check every NPC), or <samp>AnyDateable</samp> (check every romanceable NPC). |
| + | |- |
| + | | <samp>PLAYER_HAS_MET {{t|player}} {{t|npc}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] have talked to an NPC at least once. The {{t|npc}} is an NPC's internal name. |
| + | |- |
| + | | <samp>PLAYER_IS_DATING {{t|player}} {{t|npc}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] has given a [[bouquet]] to an NPC. The {{t|npc}} can be an NPC's internal name, or <samp>Any</samp> (check every romanceable NPC). |
| + | |- |
| + | | <samp>PLAYER_IS_DIVORCED {{t|player}} {{t|npc}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] is divorced. The {{t|npc}} can be an NPC's internal name or <samp>Any</samp> (with any NPC). |
| + | |- |
| + | | <samp>PLAYER_IS_ENGAGED {{t|player}} {{t|target}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] is engaged. The {{t|target}} can be an NPC's internal name, <samp>Any</samp> (with any NPC), or <samp>Player</samp> (with any player). |
| + | |- |
| + | | <samp>PLAYER_IS_MARRIED {{t|player}} {{t|target}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] is married. The {{t|target}} can be an NPC's internal name, <samp>Any</samp> (to any NPC), or <samp>Player</samp> (to any player). |
| + | |- |
| + | | <samp>PLAYER_IS_ROOMMATE {{t|player}} {{t|target}}</samp> |
| + | | Check whether the [[#Player ID|specified player(s)]] has a roommate. The {{t|target}} can be an NPC's internal name, <samp>Any</samp> (with any NPC), or <samp>Player</samp> (always false). |
| + | |- |
| + | | <samp>PLAYER_PREFERRED_PET {{t|player}} {{t|pet}}</samp> |
| + | | Check whether the preferred pet for the [[#Player ID|specified player(s)]] is <samp>Cat</samp> or <samp>Dog</samp>. |
| + | |} |
| + | |
| + | ; Save stats |
| + | :{| class="wikitable" |
| + | |- |
| + | ! Condition |
| + | ! effect |
| + | |- |
| + | | <samp>DAYS_PLAYED {{t|count}}</samp> |
| + | | Check if at least {{t|count}} days have been played in the current save (including the current one). |
| + | |- |
| + | | <samp>MINE_LOWEST_LEVEL_REACHED {{t|level}}</samp> |
| + | | Check if any player has reached at least level {{t|level}} in [[The Mines|the mines]]. |
| + | |} |
| + | |
| + | ; Randomization |
| + | :{| class="wikitable" |
| + | |- |
| + | ! Condition |
| + | ! effect |
| + | |- |
| + | | <samp>RANDOM {{t|value}}</samp> |
| + | | Perform a random probability check. For example, <code>RANDOM 0.4</code> is true 40% of the time. This recalculates the result each time it's called. |
| + | |- |
| + | | <samp>TICK_CHOOSE {{t|min}} {{t|min}} {{t|value}} {{o|seed offset}}</samp> |
| + | | Chooses a random value between {{t|min}} and {{t|max}} using the game's update tick count as a seed, and checks if it's equal to {{t|value}}. For example, <samp>TICK_CHOOSE 1 10 2</samp> has a 10% chance (check if 2 is equal to a random number between 1 and 10). All <samp>TICK_CHOOSE</samp> checks within the same tick are synchronized, so this can be used for logic like choosing only one of three options in one list. The {{o|seed offset}} value (if specified) is just added to the tick count, for cases where you need to choose a different value on the same tick. |
| + | |- |
| + | | <samp>PICKED_VALUE {{t|min}} {{t|max}} {{t|value}}</samp> |
| + | | '''Not recommended for content packs, except in shop dialogues.'''<br />Equivalent to <samp>TICK_CHOOSE</samp>, but checks the value selected by calling the <code>GameStateQuery.PickRandomValue(random)</code> method in code. The game only calls this method when opening a shop menu for [[#Custom shops|shop data with dialogue]]. |
| + | |} |
| + | |
| + | ===Player ID=== |
| + | Some conditions have a {{t|player}} argument. This can be one of... |
| + | * <samp>Any</samp> (at least one player, regardless of whether they're online); |
| + | * <samp>All</samp> (every player, regardless of whether they're online); |
| + | * <samp>Current</samp> (the local player); |
| + | * <samp>Host</samp> (the main player); |
| + | * or the unique multiplayer ID for the player to check. |
| + | |
| + | ===Using queries elsewhere=== |
| + | C# code can use the <samp>GameStateQuery</samp> class to work with queries, like <code>GameStateQuery.CheckCondition(query)</code>. |
| + | |
| + | You can also use game state queries in [[Modding:Event data|event preconditions]] using the new <samp>G</samp> condition flag, like <code>some_event_id/G !SEASON Spring, WEATHER Sun</code>. |
| + | |
| + | ===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. |
| | | |
| ==XNB impact== | | ==XNB impact== |