Changes

Jump to navigation Jump to search
m
→‎Extensibility: Tweak code example (two "out string error" lines will produce a compiler error)
Line 1: Line 1: −
{{upcoming|1.6}}
  −
   
← [[Modding:Index|Index]]
 
← [[Modding:Index|Index]]
   Line 7: Line 5:  
==Overview==
 
==Overview==
 
===Introduction===
 
===Introduction===
Each trigger action is comprised of three main parts:
+
A ''trigger action'' consists of two main parts:
* The '''trigger''' is when to apply the trigger action, either defined by the base game (like <samp>LocationChanged</samp>) or added by C# mods.
+
* The ''trigger'' is what causes the action to happen. This can be an entry in <samp>Data/TriggerActions</samp>, an event command, etc. See [[#Triggers|built-in triggers]].
* '''Actions''' are what to do (like send mail or start a quest).
+
* The ''action'' is a space-delimited string which defines what to do. For example, <code>AddMail Current Robin</code> adds the <samp>Robin</samp> letter to the player's [[Modding:Mail data|mailbox]] tomorrow. See [[#Argument format|argument format]] and [[#Actions|built-in actions]].
* '''Conditions''' are optional [[Modding:Game state queries|game state queries]] to decide whether the trigger action should be applied.
     −
For example, consider this [[Modding:Content Patcher|Content Patcher]] patch:
+
===Argument format===
{{#tag:syntaxhighlight|<nowiki>
+
Arguments are space-delimited. For example, <code>AddMail Current Abigail_LeoMoved Now</code> calls the <samp>AddMail</samp> action with three arguments (player: <samp>Current</samp>, mail ID: <samp>Abigail_LeoMoved</samp>, and mail type: <samp>Now</samp>).
{
  −
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
  −
    "Changes": [
  −
        {
  −
            "Action": "EditData",
  −
            "Target": "Data/TriggerActions",
  −
            "Entries": {
  −
                "SomeMod.Id_OnLeoMoved": {
  −
                    "Trigger": "LocationChanged",
  −
                    "Location": "Farm",
  −
                    "Condition": "PLAYER_HAS_FLAG Host leoMoved",
  −
                    "Actions": [
  −
                        "AddMail Current Abigail_LeoMoved Today",
  −
                        "AddConversationTopic LeoMoved 5"
  −
                    ]
  −
                }
  −
            }
  −
        }
  −
    ]
  −
}
  −
</nowiki>|lang=js}}
  −
 
  −
You can read that like: "''When the player arrives in the Farm location, if Leo has moved to the valley, then [[Modding:Mail data|send a letter]] and start [[Modding:Dialogue#Conversation topics|a conversation topic]]''".
  −
 
  −
Actions only run once by default, though you can use the <samp>MarkActionApplied</samp> action to re-enable one.
  −
 
  −
===Action format===
  −
An ''action'' consists of an action name with space-delimited arguments. For example, <code>AddMail Current Abigail_LeoMoved Today</code> has action name <samp>AddMail</samp> with three arguments (<samp>Current</samp>, <samp>Abigail_LeoMoved</samp>, and <samp>Today</samp>).
      
If you have spaces within an argument, you can surround it with quotes to keep it together. For example, <code>AddFriendshipPoints "Mister Qi" 10</code> has two arguments (<samp>Mister Qi</samp> and <samp>10</samp>). You can escape inner quotes with backslashes, like <code>AddFriendshipPoints "Mister \"Qi\"" 10</code>.
 
If you have spaces within an argument, you can surround it with quotes to keep it together. For example, <code>AddFriendshipPoints "Mister Qi" 10</code> has two arguments (<samp>Mister Qi</samp> and <samp>10</samp>). You can escape inner quotes with backslashes, like <code>AddFriendshipPoints "Mister \"Qi\"" 10</code>.
Line 47: Line 16:  
Remember that quotes and backslashes inside JSON strings need to be escaped too. For example, <code>"AddFriendshipPoints \"Mister Qi\" 10"</code> will send <code>AddFriendshipPoints "Mister Qi" 10</code> to the game code. Alternatively, you can use single-quotes for the JSON string instead, like <code>'AddFriendshipPoints "Mister Qi" 10'</code>.
 
Remember that quotes and backslashes inside JSON strings need to be escaped too. For example, <code>"AddFriendshipPoints \"Mister Qi\" 10"</code> will send <code>AddFriendshipPoints "Mister Qi" 10</code> to the game code. Alternatively, you can use single-quotes for the JSON string instead, like <code>'AddFriendshipPoints "Mister Qi" 10'</code>.
   −
==Data format==
+
==Actions==
Trigger actions are stored in the <samp>Data/TriggerActions</samp> asset. This consists of a list of models with these fields:
+
===Built-in actions===
 +
These are the built-in actions which can be used by any [[#Triggers|trigger]]. (Other custom actions may be [[#For C# mod authors|added by C# mods]].)
    
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! action
! effect
  −
|-
  −
| <samp>Id</samp>
  −
| The [[Modding:Modder Guide/Game Fundamentals#Unique string IDs|unique string ID]] for this trigger action.
  −
|-
  −
| <samp>Trigger</samp>
  −
| When to apply the trigger action. This must be a [[#Triggers|valid trigger type]].
  −
|-
  −
| <samp>Actions</samp>
  −
| The actions to perform. This consists of a list of strings matching the [[#Actions|action format]].
  −
|-
  −
| <samp>Location</samp>
  −
| ''(Optional)'' If set, the internal location name where this action should be applied. This is a shortcut for (and more efficient than) using a <samp>LOCATION_NAME</samp> game state query. Default none.
  −
|-
  −
| <samp>HostOnly</samp>
  −
| ''(Optional)'' Whether this trigger action can only run for the main player. If true, the action will be ignored for farmhands in [[multiplayer]].
  −
|-
  −
| <samp>Condition</samp>
  −
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this action can be applied currently. Defaults to always true.
  −
|}
  −
 
  −
See [[#Overview|example under ''Overview'']].
  −
 
  −
==Valid values==
  −
===Triggers===
  −
The game has one built-in trigger which can be used in the <samp>Trigger</samp> field. (Other custom triggers may be [[#For C# mod authors|added by C# mods]].)
  −
 
  −
{| class="wikitable"
  −
|-
  −
! trigger
   
! effect
 
! effect
 
|-
 
|-
| <samp>LocationChanged</samp>
+
| <samp>AddBuff {{t|buff ID}}</samp><br /><samp>RemoveBuff {{t|buff ID}}</samp>
| Raised when the player arrives in a location.
+
| Apply or remove a buff ID for the current player.
|}
  −
 
  −
===Actions===
  −
These are the built-in actions which can be used in the <samp>Actions</samp> field. (Other custom actions may be [[#For C# mod authors|added by C# mods]].)
  −
 
  −
{| class="wikitable"
  −
|-
  −
! action
  −
! effect
   
|-
 
|-
 
| <samp>AddConversationTopic {{t|topic ID}} {{t|day duration}}</samp>
 
| <samp>AddConversationTopic {{t|topic ID}} {{t|day duration}}</samp>
Line 102: Line 33:  
| <samp>RemoveConversationTopic {{t|topic ID}}</samp>
 
| <samp>RemoveConversationTopic {{t|topic ID}}</samp>
 
| End a [[Modding:Dialogue#Conversation topics|conversation topic]], if it's active.
 
| End a [[Modding:Dialogue#Conversation topics|conversation topic]], if it's active.
|-
  −
| <samp>AddCookingRecipe {{t|player}} {{t|recipe ID}}</samp><br /><samp>AddCraftingRecipe {{t|player}} {{t|recipe key}}</samp>
  −
| Add a [[Modding:Recipe data|cooking or crafting recipe]] to the [[#Target player|specified player(s)]].
   
|-
 
|-
 
| <samp>AddFriendshipPoints {{t|NPC name}} {{t|count}}</samp>
 
| <samp>AddFriendshipPoints {{t|NPC name}} {{t|count}}</samp>
Line 115: Line 43:  
| Deduct items by [[Modding:Migrate to Stardew Valley 1.6#Custom items|qualified or unqualified item ID]] from the current player's inventory, up to a max combined stack size of {{o|count}} (default 1).
 
| Deduct items by [[Modding:Migrate to Stardew Valley 1.6#Custom items|qualified or unqualified item ID]] from the current player's inventory, up to a max combined stack size of {{o|count}} (default 1).
 
|-
 
|-
| <samp>AddMail {{t|player}} {{t|mail ID}} {{t|type}}</samp><br /><samp>RemoveMail {{t|player}} {{t|mail ID}} {{o|type}}</samp>
+
| <samp>AddMail {{t|player}} {{t|mail ID}} {{o|type}}</samp><br /><samp>RemoveMail {{t|player}} {{t|mail ID}} {{o|type}}</samp>
 
| Add or remove a [[Modding:Mail data|mail flag or letter]] for the [[#Target player|specified player(s)]].
 
| Add or remove a [[Modding:Mail data|mail flag or letter]] for the [[#Target player|specified player(s)]].
   Line 134: Line 62:  
|-
 
|-
 
| <samp>all</samp>
 
| <samp>all</samp>
| (''remove only'') Remove it everywhere (mailbox, tomorrow's mailbox, and received mail).
+
| Add or remove it everywhere (mailbox, tomorrow's mailbox, and received mail).
 
|}
 
|}
   −
For remove only, {{t|type}} defaults to <samp>all</samp>.
+
If omitted, the {{t|type}} defaults to <samp>tomorrow</samp> for <samp>AddMail</samp> and <samp>all</samp> for <samp>RemoveMail</samp>.
 
|-
 
|-
 
| <samp>AddMoney {{t|amount}}</samp>
 
| <samp>AddMoney {{t|amount}}</samp>
Line 143: Line 71:  
|-
 
|-
 
| <samp>AddQuest {{t|quest ID}}</samp><br /><samp>RemoveQuest {{t|quest ID}}</samp>
 
| <samp>AddQuest {{t|quest ID}}</samp><br /><samp>RemoveQuest {{t|quest ID}}</samp>
| Add or remove a [[Modding:Quest data|quest]] for the [[#Target player|specified player(s)]].
+
| Add or remove a [[Modding:Quest data|quest]] for the current player.
 
|-
 
|-
 
| <samp>AddSpecialOrder {{t|order ID}}</samp><br /><samp>RemoveSpecialOrder {{t|order ID}}</samp>
 
| <samp>AddSpecialOrder {{t|order ID}}</samp><br /><samp>RemoveSpecialOrder {{t|order ID}}</samp>
| Add or remove a [[Modding:Special orders|special order]] for the [[#Target player|specified player(s)]].
+
| Add or remove a [[Modding:Special orders|special order]].
 +
|-
 +
| <samp>If {{t|query}} ## {{t|action if true}}</samp><br /><samp>If {{t|query}} ## {{t|action if true}} ## {{t|action if false}}</samp>
 +
| Check a [[Modding:Game state queries|game state query]] and perform an action based on the result.
 +
 
 +
For example, this only sends a mail if the player doesn't have it in their received, mailbox, or queued-for-tomorrow mail:
 +
<syntaxhighlight lang="js">
 +
"ActionsOnPurchase": [
 +
    "If !PLAYER_HAS_MAIL Current SomeFlag ## AddMail Current SomeFlag"
 +
]
 +
</syntaxhighlight>
 
|-
 
|-
| <samp>MarkEventSeen {{t|event ID}} {{o|seen}}</samp>
+
| <samp>IncrementStat {{t|stat key}} {{o|amount}}</samp>
| Mark [[Modding:Event data|an event]] as seen (if {{o|seen}} is <samp>true</samp>) or not seen (if <samp>false</samp>).
+
| Increment a stat value by the given amount (default 1) for the current player. This can be a vanilla stat key (see the <samp>PLAYER_STAT</samp> [[Modding:Game state queries|game state query]] for a list) or a custom stat key. The amount can be negative to decrement it.
 
|-
 
|-
| <samp>MarkQuestionAnswered {{t|answer ID}} {{o|answered}}</samp>
+
| <samp>MarkActionApplied {{t|player}} {{t|answer ID}} {{o|applied}}</samp>
| Mark [[Modding:Dialogue#Response IDs|a dialogue answer]] as selected (if {{o|answered}} is <samp>true</samp>) or not selected (if <samp>false</samp>).
+
| Mark a <samp>Data/TriggerActions</samp> entry as applied or non-applied for the [[#Target player|specified player(s)]], depending on {{o|applied}} (default <samp>true</samp>). This can be used to skip or re-run an entry, since <samp>Data/TriggerActions</samp> entries are only applied once by default.
 +
 
 +
Note that an entry can't use this to mark ''itself'' unapplied; see [[#Make Data/TriggerActions repeat|''Make <samp>Data/TriggerActions</samp> repeat'']] if you want to do that.
 
|-
 
|-
| <samp>MarkActionApplied {{t|answer ID}} {{o|applied}}</samp>
+
| <samp>MarkCookingRecipeKnown {{t|player}} {{t|recipe ID}} {{o|known}}</samp><br /><samp>MarkCraftingRecipeKnown {{t|player}} {{t|recipe key}} {{o|known}}</samp>
| Mark another trigger action as applied (if {{o|applied}} is <samp>true</samp>) or not applied (if <samp>false</samp>). This can be used to skip or re-run an action, since actions are only applied once by default.
+
| Set whether [[#Target player|specified player(s)]] know a [[Modding:Recipe data|cooking or crafting recipe]], depending on {{o|known}} (default <samp>true</samp>).
 +
 
 +
Note that forgetting a recipe will also reset its times-cooked/crafted counter to zero.
 +
|-
 +
| <samp>MarkEventSeen {{t|player}} {{t|event ID}} {{o|seen}}</samp>
 +
| Mark [[Modding:Event data|an event]] as seen or unseen for the [[#Target player|specified player(s)]], depending on {{o|seen}} (default <samp>true</samp>).
 +
|-
 +
| <samp>MarkQuestionAnswered {{t|player}} {{t|answer ID}} {{o|answered}}</samp>
 +
| Mark [[Modding:Dialogue#Response IDs|a dialogue answer]] as selected or non-selected for the [[#Target player|specified player(s)]], depending on {{o|answered}} (default <samp>true</samp>).
 +
|-
 +
| <samp>MarkSongHeard {{t|player}} {{t|song ID}} {{o|heard}}</samp>
 +
| Mark a song track's cue name heard or non-heard for the [[#Target player|specified player(s)]], depending on {{o|heard}} (default <samp>true</samp>). This affects whether the song appears in the [[jukebox]] selection.
 +
|-
 +
| <samp>Null</samp>
 +
| ''(Specialized)'' Does nothing. This is used internally; there's generally no benefit to using it yourself.
 +
|-
 +
| <samp>RemoveTemporaryAnimatedSprites</samp>
 +
| Remove all temporary animated sprites in the current location. For example, this can be used in the [[Modding:Event data|event]] <samp>setSkipActions</samp> command to clean up the event's temporary sprites.
 
|-
 
|-
 
| <samp>SetNpcInvisible {{t|NPC name}} {{t|day duration}}</samp>
 
| <samp>SetNpcInvisible {{t|NPC name}} {{t|day duration}}</samp>
 
| Hide an NPC so they disappear and can't be interacted with for the given number of days. This is used when NPCs go away for a while (e.g. [[Elliott#Fourteen Hearts|Elliott's 14-heart event]]).
 
| Hide an NPC so they disappear and can't be interacted with for the given number of days. This is used when NPCs go away for a while (e.g. [[Elliott#Fourteen Hearts|Elliott's 14-heart event]]).
 +
 +
'''TODO: can you call this from the farmhand? Atra doesn't think so.'''
 
|-
 
|-
 
| <samp>SetNpcVisible {{t|NPC name}}</samp>
 
| <samp>SetNpcVisible {{t|NPC name}}</samp>
 
| End the NPC's invisibility, if applicable.
 
| End the NPC's invisibility, if applicable.
 +
 +
'''TODO: check to see if can be called from farmhand. Will probably make the NPC visible again, but the daysUntilNotInvisible is NOT synced.'''
 
|}
 
|}
   Line 180: Line 141:  
| Apply to the main player.
 
| Apply to the main player.
 
|}
 
|}
 +
 +
==Triggers==
 +
===<samp>Data/TriggerActions</samp>===
 +
<samp>Data/TriggerActions</samp> is a data asset which lets you dynamically perform actions when the conditions are met.
 +
 +
For example, consider this [[Modding:Content Patcher|Content Patcher]] patch:
 +
{{#tag:syntaxhighlight|<nowiki>
 +
{
 +
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
 +
    "Changes": [
 +
        {
 +
            "Action": "EditData",
 +
            "Target": "Data/TriggerActions",
 +
            "Entries": {
 +
                "{{ModId}}_OnLeoMoved": {
 +
                    "Id": "{{ModId}}_OnLeoMoved",
 +
                    "Trigger": "DayEnding",
 +
                    "Condition": "PLAYER_HAS_MAIL Host leoMoved",
 +
                    "Actions": [
 +
                        "AddMail Current {{ModId}}_Abigail_LeoMoved",
 +
                        "AddConversationTopic {{ModId}}_LeoMoved 5"
 +
                    ]
 +
                }
 +
            }
 +
        }
 +
    ]
 +
}
 +
</nowiki>|lang=js}}
 +
 +
You can read that like: "''When the player is going to sleep, if Leo has moved to the valley, then [[Modding:Mail data|send a letter]] and start [[Modding:Dialogue#Conversation topics|a conversation topic]]''".
 +
 +
Each entry in <samp>Data/TriggerActions</samp> only runs once by default, though you can use the <samp>MarkActionApplied</samp> action to re-enable one.
 +
 +
<samp>Data/TriggerActions</samp> consists of a list of models with these fields:
 +
 +
{| class="wikitable"
 +
|-
 +
! field
 +
! effect
 +
|-
 +
| <samp>Id</samp>
 +
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this trigger action.
 +
|-
 +
| <samp>Trigger</samp>
 +
| When to apply the trigger action. This must be one or more of these values (space-delimited):
 +
 +
{| class="wikitable"
 +
|-
 +
! trigger
 +
! effect
 +
|-
 +
| <samp>DayStarted</samp>
 +
| Raised when the player starts a day, after either sleeping or loading.
 +
|-
 +
| <samp>DayEnding</samp>
 +
| Raised when the player is going to sleep. This happens immediately before the game changes the date, sets up the new day, and saves.
 +
|-
 +
| <samp>LocationChanged</samp>
 +
| Raised when the player arrives in a location.
 +
|-
 +
| ''other''
 +
| Other custom triggers may be [[#For C# mod authors|added by C# mods]].
 +
|}
 +
|-
 +
| <samp>Actions</samp>
 +
| ''(Optional)'' The actions to perform, as a list of strings matching the [[#Actions|action format]].
 +
|-
 +
| <samp>Action</samp>
 +
| ''(Optional)'' A single action to perform, matching the [[#Actions|action format]].
 +
 +
This is just a shortcut for <samp>Actions</samp> with one action. Technically you can use both together, but usually you should just pick one property to set.
 +
|-
 +
| <samp>HostOnly</samp>
 +
| ''(Optional)'' Whether this trigger action can only run for the main player. If true, the action will be ignored for farmhands in [[multiplayer]].
 +
|-
 +
| <samp>MarkActionApplied</samp>
 +
| ''(Optional)'' Whether to mark the action applied when it's applied. Default true.
 +
 +
* If true: the action is added to the player's <samp>triggerActionsRun</samp> list, [[Modding:Game state queries|queries]] like <samp>PLAYER_HAS_RUN_TRIGGER_ACTION</samp> will return true, and the action won't run again (unless you use the <samp>MarkActionApplied</samp> action to mark it unapplied).
 +
* If false: the action can repeat immediately when the same trigger is raised, and [[Modding:Game state queries|queries]] like <samp>PLAYER_HAS_RUN_TRIGGER_ACTION</samp> will return false for it.
 +
|-
 +
| <samp>Condition</samp>
 +
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this action can be applied currently. Defaults to always true.
 +
|-
 +
| <samp>CustomFields</samp>
 +
| ''(Optional)'' The [[Modding:Migrate to Stardew Valley 1.6#Custom data fields|custom fields]] for this entry.
 +
|}
 +
 +
===Elsewhere===
 +
You can also run an action directly from...
 +
 +
<ul>
 +
<li>A [[Modding:Dialogue|dialogue string]] using the <samp>$action</samp> command. For example:
 +
<syntaxhighlight lang="js">
 +
"Mon": "Hi there! Here's 10g and a parsnip, don't spend it all at once.#$action AddMoney 10#$action AddItem (O)24"
 +
</syntaxhighlight></li>
 +
 +
<li>An [[Modding:Event data|event script]] using the <samp>action</samp> command. For example:
 +
<syntaxhighlight lang="js">
 +
"{{ModId}}_Event": "continue/64 15/farmer 64 16 2 Abigail 64 18 0/pause 1500/speak Abigail \"Hi. Here's 10g and a parsnip.\"/action AddMoney 10/action AddItem (O)24/pause 500/end"
 +
</syntaxhighlight>
 +
 +
See also the <samp>setSkipActions</samp> command.
 +
</li>
 +
 +
<li>A [[Modding:Mail data|mail letter]] using the <samp>%action</samp> command. For example:
 +
<syntaxhighlight lang="js">
 +
"{{ModId}}_Letter": "Hey there!^Here's 10g and a parsnip. Take care!^  -Abigail%action AddMoney 10%% %action Additem (O)24%%[#]A gift from Abigail"
 +
</syntaxhighlight></li>
 +
 +
<li>The [[Modding:Console commands|SMAPI console window]] using the <samp>debug action</samp> console command. For example:
 +
<pre>> debug action "AddMoney 10"
 +
 +
Applied action 'AddMoney 10'.</pre></li>
 +
</ul>
    
==For C# mod authors==
 
==For C# mod authors==
Line 188: Line 264:  
C# mods can use the <samp>StardewValley.Triggers.TriggerActionManager</samp> class to interact with trigger actions.
 
C# mods can use the <samp>StardewValley.Triggers.TriggerActionManager</samp> class to interact with trigger actions.
   −
For example, you can add a new trigger type:
+
For example, you can...
 +
<ul>
 +
<li>Add and raise a new trigger type:
 
<syntaxhighlight lang="js">
 
<syntaxhighlight lang="js">
 
// register custom trigger type
 
// register custom trigger type
 
TriggerActionManager.RegisterTrigger("Some.ModId_OnItemReceived");
 
TriggerActionManager.RegisterTrigger("Some.ModId_OnItemReceived");
   −
// run actions for the custom trigger
+
// run actions in Data/TriggerActions for the custom trigger
 
TriggerActionManager.Raise("Some.ModId_OnItemReceived", new[] { item, index }); // trigger can pass optional trigger arguments
 
TriggerActionManager.Raise("Some.ModId_OnItemReceived", new[] { item, index }); // trigger can pass optional trigger arguments
</syntaxhighlight>
+
</syntaxhighlight></li>
   −
Or you can add a new action handler:
+
<li>Or add a new action:
 
<syntaxhighlight lang="js">
 
<syntaxhighlight lang="js">
 
TriggerActionManager.RegisterAction("Some.ModId_PlaySound", this.PlaySound);
 
TriggerActionManager.RegisterAction("Some.ModId_PlaySound", this.PlaySound);
Line 204: Line 282:     
/// <inheritdoc cref="TriggerActionDelegate" />
 
/// <inheritdoc cref="TriggerActionDelegate" />
public static bool PlaySound(string[] args, string trigger, string[] triggerArgs, TriggerActionData data)
+
public static bool PlaySound(string[] args, TriggerActionContext context, out string error)
 
{
 
{
 
     // get args
 
     // get args
     if (!ArgUtility.TryGet(args, 1, out string soundId, out string error, allowBlank: false))
+
     if (!ArgUtility.TryGet(args, 1, out string soundId, out error, allowBlank: false))
         return TriggerActionManager.Helpers.LogActionError(args, trigger, data, error);
+
         return false;
    
     // apply
 
     // apply
Line 214: Line 292:  
     return true;
 
     return true;
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight></li>
 +
 
 +
<li>Or run an action string:
 +
<syntaxhighlight lang="js">
 +
// NOTE: this is just an example of how to run an action. This is meant to support actions specified in data or content
 +
// packs. If you want to send mail (or perform other actions) in C#, it's better to call the C# APIs directly instead.
 +
string action = "AddMail Current Robin Now";
 +
if (!TriggerActionManager.TryRunAction(action, out string error, out Exception ex))
 +
    Game1.log.Error($"Failed running action '{action}': {error}", ex);
 +
</syntaxhighlight></li>
 +
</ul>
 +
 
 +
To avoid conflicts, custom trigger names should be [[Modding:Common data field types#Unique string ID|unique string IDs]].
 +
 
 +
==FAQs==
 +
===Trigger actions vs map actions===
 +
''Actions'' can refer to two different systems:
 +
 
 +
* ''Trigger actions'' (this page) let you perform generic background tasks that can be done anytime, like sending a letter or starting a quest. These can be triggered automatically based on conditions, or via commands in dialogue, events, etc.
 +
* ''[[Modding:Maps|Map actions]]'' refer to the <samp>Action</samp> and <samp>TouchAction</samp> map properties, which do something when you walk on or interact with a map tile. These can perform a wide array of map- and interaction-specific things like showing a message box, changing the map, opening shop menus, etc. These only work in maps, and generally don't make sense in other contexts.
 +
 
 +
Aside from the similar names, they're not interchangeable and there's fairly little overlap.
 +
 
 +
===Make <samp>Data/TriggerActions</samp> repeat===
 +
By default, each entry in <samp>Data/TriggerActions</samp> is only applied once per player.
 +
 
 +
There are two main ways to repeat actions:
 +
<ul>
 +
<li>To make it repeatable immediately, set <samp>"MarkActionApplied": false</samp> on the <samp>Data/TriggerActions</samp> entry.</li>
 +
<li>To enable repeating at a different time, you can use the <samp>MarkActionApplied</samp> action to forget that it was applied.
 +
 
 +
For example, this patch will set alternating 'work' or 'weekend' mail flags depending on the day of week:
 +
{{#tag:syntaxhighlight|<nowiki>
 +
{
 +
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
 +
    "Changes": [
 +
        {
 +
            "Action": "EditData",
 +
            "Target": "Data/TriggerActions",
 +
            "Entries": {
 +
                // set 'work' flag on weekdays, and reset weekend action
 +
                "{{ModId}}_Work": {
 +
                    "Id": "{{ModId}}_Work",
 +
                    "Trigger": "DayStarted",
 +
                    "Condition": "!DAY_OF_WEEK Saturday Sunday",
 +
                    "Actions": [
 +
                        "AddMail Current {{ModId}}_Work Received",
 +
                        "RemoveMail Current {{ModId}}_Weekend",
 +
                        "MarkActionApplied Current {{ModId}}_Weekend false"
 +
                    ]
 +
                },
   −
To avoid conflicts, custom trigger names should be [[Modding:Modder Guide/Game Fundamentals#Unique string IDs|unique string IDs]].
+
                // set 'weekend' flag on weekends, and reset work action
 +
                "{{ModId}}_Weekend": {
 +
                    "Id": "{{ModId}}_Weekend",
 +
                    "Trigger": "DayStarted",
 +
                    "Condition": "DAY_OF_WEEK Saturday Sunday",
 +
                    "Actions": [
 +
                        "AddMail Current {{ModId}}_Weekend Received",
 +
                        "RemoveMail Current {{ModId}}_Work",
 +
                        "MarkActionApplied Current {{ModId}}_Work false"
 +
                    ]
 +
                },
 +
            }
 +
        }
 +
    ]
 +
}
 +
</nowiki>|lang=js}}
    
[[Category:Modding]]
 
[[Category:Modding]]
28

edits

Navigation menu