1,043
edits
(Conversation modding for 203.11) |
(demonstrate root element) |
||
(18 intermediate revisions by 2 users not shown) | |||
Line 12: | Line 12: | ||
<syntaxhighlight lang="xml"> | <syntaxhighlight lang="xml"> | ||
<!-- ObjectBlueprints.xml--> | <!-- ObjectBlueprints.xml--> | ||
<object Name="Snapjaw Pal" Inherits="Snapjaw"> | <objects> | ||
<object Name="Snapjaw Pal" Inherits="Snapjaw"> | |||
</object> | <part Name="ConversationScript" ConversationID="FriendlySnapjaw" /> | ||
</object> | |||
</objects> | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="xml"> | |||
<!-- Conversations.xml--> | <!-- Conversations.xml--> | ||
<conversation ID="FriendlySnapjaw"> | <conversations> | ||
<conversation ID="FriendlySnapjaw"> | |||
<start ID="Welcome"> | |||
<text>ehekehe. gn. welcom.</text> | |||
<choice Target="LibDink">Thank you.</choice> | |||
</start> | |||
<node ID="LibDink"> | |||
<text>hrffff... lib? dink?</text> | |||
<text>nyeh. heh! friemd?</text> | |||
<choice Target="End">Live and drink.</choice> | |||
</conversation> | </node> | ||
</conversation> | |||
</conversations> | |||
</syntaxhighlight> | </syntaxhighlight> | ||
(Note that the outer <code>conversations</code> tag is required.) | |||
=== XML Tags === | === XML Tags === | ||
Line 49: | Line 57: | ||
|- | |- | ||
| <code><nowiki><text></nowiki></code> | | <code><nowiki><text></nowiki></code> | ||
| Contains a block of text to display for an element, multiple of these can be defined and randomly selected from if valid. | | Contains a block of text to display for an element, multiple of these can be defined and randomly selected from if valid. <br/>Additional text nodes can be recursively defined within other text nodes, allowing groups of text to use the same conditions. <br />For backwards compatibility, delimiting the text with <code>~</code> characters will behave similarly to multiple text nodes. | ||
|- | |- | ||
| <code><nowiki><part></nowiki></code> | | <code><nowiki><part></nowiki></code> | ||
Line 57: | Line 65: | ||
=== Merging === | === Merging === | ||
If multiple elements with the same <code>ID</code> are defined within the same scope, a merge will occur by default where the properties of the later element overwrite the former.<br /> | If multiple elements with the same <code>ID</code> are defined within the same scope, a merge will occur by default where the properties of the later element overwrite the former.<br /> | ||
If an explicit ID isn't defined, one will be created based on other attributes.<br/> | If an explicit ID isn't defined, one will be created based on other attributes.<br/> | ||
Line 81: | Line 88: | ||
=== Inheritance === | === Inheritance === | ||
In cases where you'd like your elements to appear in multiple places, you can inherit their properties with the <code>Inherits</code> attribute.<br /> | In cases where you'd like your elements to appear in multiple places, you can inherit their properties with the <code>Inherits</code> attribute.<br /> | ||
By default, every conversation inherits from <code>BaseConversation</code>, which holds the definitions of common elements to all conversations like trade and the water ritual.<br /> | |||
The attribute can also take a comma separated list, meaning you can inherit and merge the properties of multiple parent elements together.<br /> | The attribute can also take a comma separated list, meaning you can inherit and merge the properties of multiple parent elements together.<br /> | ||
Unlike merging, the properties of the current element have precedence over those it is inheriting from. | Unlike merging, the properties of the current element have precedence over those it is inheriting from. | ||
Line 109: | Line 116: | ||
=== Distribution === | === Distribution === | ||
An alternative to explicitly inheriting elements where you'd like them repeated is distribution, where you specify directly on the element where it should propagate.<br/> | An alternative to explicitly inheriting elements where you'd like them repeated is distribution, where you specify directly on the element where it should propagate.<br/> | ||
The <code>Distribute</code> attribute normally takes a list of element types, but if <code>Qualifier="ID"</code> is specified, a list of IDs can be provided.<br/> | The <code>Distribute</code> attribute normally takes a list of element types, but if <code>Qualifier="ID"</code> is specified, a list of IDs can be provided.<br/> | ||
Line 128: | Line 134: | ||
== Delegates == | == Delegates == | ||
Unique to conversations are their delegate attributes such as <code>IfHaveQuest="What's Eating the Watervine?"</code> or <code>GiveItem="Joppa Recoiler"</code>.<br/> | Unique to conversations are their delegate attributes such as <code>IfHaveQuest="What's Eating the Watervine?"</code> or <code>GiveItem="Joppa Recoiler"</code>.<br/> | ||
These are distinguished between two types | These are distinguished between two types: Predicates which control whether an element is accessible, and Actions which perform some task when the element is selected.<br/> | ||
After the Deep Jungle update these are now for the most part agnostic as to what their parent element is. | After the Deep Jungle update these are now for the most part agnostic as to what their parent element is. | ||
Line 143: | Line 149: | ||
=== Custom Delegates === | === Custom Delegates === | ||
It's possible to add your own delegates for you to use in XML by adding a <code>[ConversationDelegate]</code> attribute to a static method in C#.<br/> | It's possible to add your own delegates for you to use in XML by adding a <code>[ConversationDelegate]</code> attribute to a static method in C#.<br/> | ||
Depending on the return type it will either be registered as a predicate or action, and variants of the delegate will automatically be created. | Depending on the return type it will either be registered as a predicate (bool) or action (void), and variants of the delegate will automatically be created. | ||
For example the below delegate will automatically create the inversion <code>IfNotHaveItem</code>, and because we set the <code>Speaker</code> attribute parameter, another two (<code>IfSpeakerHaveItem</code>, <code>IfSpeakerNotHaveItem</code>) where <code>Context.Target</code> holds the Speaker instead of the Player. | For example the below delegate will automatically create the inversion <code>IfNotHaveItem</code>, and because we set the <code>Speaker</code> attribute parameter, another two (<code>IfSpeakerHaveItem</code>, <code>IfSpeakerNotHaveItem</code>) where <code>Context.Target</code> holds the Speaker instead of the Player. | ||
Line 152: | Line 157: | ||
public static class DelegateContainer | public static class DelegateContainer | ||
{ | { | ||
// A predicate that receives a DelegateContext object with our values assigned, this to protect mods from signature breaks. | |||
[ConversationDelegate(Speaker = true)] | |||
public static bool IfHaveItem(DelegateContext Context) | |||
{ | |||
// Context.Value holds the quoted value from the XML attribute. | |||
// Context.Target holds the game object. | |||
// Context.Element holds the parent element. | |||
return Context.Target.HasObjectInInventory(Context.Value); | |||
} | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 166: | Line 171: | ||
== Parts == | == Parts == | ||
For more advanced or specific logic not easily reduced to a generally accessible delegate, a custom part is preferred.<br/> | For more advanced or specific logic not easily reduced to a generally accessible delegate, a custom part is preferred.<br/> | ||
Similar to their equivalent for objects in | Similar to their equivalent for objects in <code>ObjectBlueprints.xml</code>, parts define custom behaviour for elements within and can be attached to most any element just like delegates. | ||
If you use a period within the part's name, it's assumed you are specifying your own namespace and won't be required to place your part within <code>XRL.World.Conversations.Parts</code>. | |||
If you use a period within the part's name, it's assumed you are specifying your own namespace and won't be required to place your part within <code>XRL.World.Conversations.Parts</code>. You can optionally declare a <code>Namespace</code> on the root <code><nowiki><conversations></nowiki></code> element, and concatenated sub-namespaces on each <code><nowiki><conversation></nowiki></code>. It will try to find your part within those first before falling back to the default namespace. | |||
<syntaxhighlight lang="xml"> | <syntaxhighlight lang="xml"> | ||
<conversation ID="JoppaZealot"> | <conversation ID="JoppaZealot"> | ||
Line 206: | Line 211: | ||
=== Events === | === Events === | ||
Conversations have their own set of events to handle, but should be immediately familiar to anyone that has tampered with the [[Modding:Events#Minimal_Events|Minimal Events]] of game objects. | Conversations have their own set of events to handle, but should be immediately familiar to anyone that has tampered with the [[Modding:Events#Minimal_Events|Minimal Events]] of game objects. | ||
Unlike min events which cascade down, conversation events will propagate up the element tree from where it was fired (See [https://en.wikipedia.org/wiki/Event_bubbling event bubbling]). This means an event fired on a choice will first be handled by parts on the choice itself, then its parent node, last the node's conversation. | Unlike min events which cascade down, conversation events will propagate up the element tree from where it was fired (See [https://en.wikipedia.org/wiki/Event_bubbling event bubbling]). This means an event fired on a choice will first be handled by parts on the choice itself, then its parent node, last the node's conversation. | ||
Finally the propagation is separated by perspective, Speaker and Listener (the listener being you, the player). In most cases when you attach a part that | Finally the propagation is separated by perspective, Speaker and Listener (the listener being you, the player). In most cases when you attach a part that modifies the text of a node, you do not want to also modify the text of its underlying choices since those are spoken by a different entity. By default parts will register for the perspective they are placed in, but can be overriden with the <code>Register</code> attribute. | ||
<syntaxhighlight lang="xml"> | <syntaxhighlight lang="xml"> | ||
<conversation ID="EventfulSnapjaw"> | <conversation ID="EventfulSnapjaw"> | ||
<part Name="SpiceContext" Register="All" /> <!-- Registers for | <part Name="SpiceContext" Register="All" /> <!-- Registers for Speaker events by default, but overrides with both --> | ||
<start ID="TasterOfTheSalt"> | <start ID="TasterOfTheSalt"> | ||
<part Name="SnapjawLaugh" /> <!-- Registers for Speaker events --> | <part Name="SnapjawLaugh" /> <!-- Registers for Speaker events --> | ||
Line 228: | Line 232: | ||
==Tables== | ==Tables== | ||
Below | Below are non-exhaustive tables of existing parts, events, delegates, and additional XML attributes. | ||
===Parts=== | |||
Described with their function, parameters and an example where applicable. | |||
{| class="wikitable" | |||
|- | |||
! Name | |||
! Description | |||
|- | |||
| AddSlynthCandidate | |||
| Adds the current location as a possible sanctuary for the slynth during the quest [[Landing Pads]]. | |||
---- | |||
'''Sanctuary''': Optional explicit sanctuary name to use instead of zone name.<br/> | |||
'''Plural''': Whether the explicit sanctuary name is plural. | |||
---- | |||
<code><nowiki><part Name="AddSlynthCandidate" Location="pariah caravans" Plural="true" /></nowiki></code> | |||
|- | |||
| ChangeTarget | |||
| Takes any number of predicates as parameters and changes the navigation target (GetTargetElementEvent) if all predicates match. | |||
---- | |||
'''Target''': The alternate navigation target if predicates match.<br/> | |||
'''Any''': Require one predicate to match rather than all. | |||
---- | |||
<code><nowiki><part Name="ChangeTarget" Target="ShowSonnet" IfHaveBlueprint="Sonnet" /></nowiki></code> | |||
|- | |||
| GiveArtifact | |||
| Make the player give an artifact from their inventory to continue navigation. | |||
|- | |||
| GiveReshephSecret | |||
| Share a secret from Resheph's life to gain some XP. | |||
|- | |||
| IPredicatePart | |||
| An extensible abstract part that takes predicates as parameters and can check all or any for a match. ChangeTarget derives from this, for example. | |||
|- | |||
| LibrarianGiveBook | |||
| Donate a book to the librarian to gain some XP. | |||
|- | |||
| PaxInfectLimb | |||
| Choose a limb to infect with Klanq. | |||
---- | |||
'''IfQuestActive''': Only display this element if the quest is active and the player has no infected limb. | |||
---- | |||
<code><nowiki><part Name="PaxInfectLimb" IfQuestActive="true" /></nowiki></code> | |||
|- | |||
| QuestHandler | |||
| Manipulates quest and step state. If a child text is provided it will replace the normal ending tag for that action, e.g. <code>[Accept Quest]</code>. | |||
---- | |||
'''QuestID''': The quest's ID, usually the same as its display name.<br/> | |||
'''StepID''': The ID of a step within the quest, if applicable.<br/> | |||
'''XP''': The XP awarded for completing the step, if applicable. This will override the value in Quests.xml if provided.<br/> | |||
'''Action''': Takes a string value of an action to perform on the quest and/or step; | |||
: '''Start''': Find an unstarted quest with QuestID and start it. | |||
: '''Step''': Complete a step within the quest, finishes the parent quest if all steps are completed. | |||
: '''Finish''': Finish a started quest, regardless of what steps are currently completed. | |||
: '''Complete''': Finish a started quest and mark all steps as complete if they weren't already. | |||
---- | |||
<code><nowiki><part Name="QuestHandler" Action="Step" QuestID="Fetch Argyve a Knickknack" StepID="Return to Argyve" XP="75" /></nowiki></code> | |||
|- | |||
| ReceiveItem | |||
| The player receives one or several potentially identified items. | |||
---- | |||
'''Blueprints''': A comma separated list of blueprints for the player to receive.<br/> | |||
'''Identify''': A comma separated list of blueprints to identify, of those given. "*" or "All" can be specified to identify all of them.<br/> | |||
'''Mods''': A dice roll of how many mods to apply to the received items.<br/> | |||
'''Pick''': Makes the player choose one item of those allotted, instead of receiving all of them.<br/> | |||
'''FromSpeaker''': Takes an existing item of the same blueprint from the speaker if available, instead of creating new ones. | |||
---- | |||
<code><nowiki><part Name="ReceiveItem" Pick="true" Mods="1" Blueprints="Long Sword4,Cudgel4,Dagger4,Battle Axe4" Identify="All" /></nowiki></code> | |||
|- | |||
| RequireReputation | |||
| Require the player's reputation with a specific faction to be at or above a certain level to continue. If the parent element is a choice, its text will be greyed out. | |||
---- | |||
'''Faction''': The ID of a faction within the current game.<br/> | |||
'''Level''': The name of a reputation level, valid values are: Loved, Liked, Indifferent, Disliked, and Hated. | |||
---- | |||
<code><nowiki><part Name="RequireReputation" Faction="Snapjaws" Level="Loved" /></nowiki></code> | |||
|- | |||
| SpiceContext | |||
| Replaces template variables in the spoken text with excerpts from history spice, e.g. replacing <code>=spice.commonPhrases.sacred.!random=</code> with <code>sanctified</code>. | |||
|- | |||
| Tag | |||
| Adds an ending tag to the parent element's text. Most parts with functionality will handle their own tags via <code>GetChoiceTagEvent</code>, this is mostly for informational purposes.<br/> | |||
The game makes a distinction between spoken and unspoken text for the purposes of filtering (e.g. the cawing of corvids), hence why unspoken tags should not be written together with the spoken text. | |||
---- | |||
<code><nowiki><part Name="Tag">{{g|[begin trade]}}</part></nowiki></code> | |||
|- | |||
| TakeItem | |||
| Items are taken from the player's inventory or body. | |||
---- | |||
'''Blueprints''': A comma separated list of blueprints to take.<br/> | |||
'''IDs''': A comma separated list of game object IDs to take.<br/> | |||
'''Amount''': A dice roll of how many items to take. "*" or "All" can be specified to take all of them.<br/> | |||
'''Unsellable''': Mark the taken items as unsellable.<br/> | |||
'''ClearQuest''': Clear quest properties from the taken items.<br/> | |||
'''Destroy''': Destroy the items instead of placing them inside the speakers inventory. | |||
---- | |||
<code><nowiki><part Name="TakeItem" Blueprints="Wire Strand" Amount="200" Destroy="true" /></nowiki></code> | |||
|- | |||
| TextFilter | |||
| Mutates the spoken text with a filter, e.g. the cawing of corvids or croaking of frogs. | |||
---- | |||
'''FilterID''': The ID of a filter, valid values are: Angry, Corvid, WaterBird, Fish, Frog, Leet, Lallated, Weird, and Cryptic Machine.<br/> | |||
'''Extras''': A comma separated list of additional noises to include in the filter, used in the Lallated and Weird filters currently.<br/> | |||
'''ProtectFormatting''': Outputs color protected text, currently used for Leet ampersands which are doubled to preserve them. | |||
---- | |||
<code><nowiki><part Name="TextFilter" FilterID="Lallated" Extras="*growl*,*whine*" /></nowiki></code> | |||
|- | |||
| TextInsert | |||
| Appends or prepends a text that can be either spoken or unspoken to the element. | |||
---- | |||
'''Prepend''': Add the text to the beginning instead of the end.<br/> | |||
'''Spoken''': Whether the inserted text is treated as spoken or unspoken for the purposes of filtering.<br/> | |||
'''NewLines''': A number of new lines to add as padding between the inserted text and the existing text. | |||
---- | |||
<code><nowiki><part Name="TextInsert" Spoken="false" NewLines="2">[Press Tab or T to open trade]</part></nowiki></code> | |||
|- | |||
| Trade | |||
| Opens the trade screen when navigating to the parent element. | |||
|- | |||
| VillageContext | |||
| Replaces template variables in the spoken text with excerpts from the village's history, e.g. replacing <code>=village.sacred=</code> with <code>the act of procreation</code>.<br/> | |||
Uses the faction of the speaker to find the village's historical context. | |||
---- | |||
'''GameState''': Try to get the village's historical context from the faction provided in specified game state. | |||
---- | |||
<code><nowiki><part Name="VillageContext" GameState="SlynthSettlementFaction" /></nowiki></code> | |||
|- | |||
| WaterRitualRandomMutation | |||
| Purchase a random mutation of specified category for reputation in the water ritual. | |||
---- | |||
'''Category''': A mutation category, valid values for the base game are: Physical, Mental. | |||
---- | |||
<code><nowiki><part Name="WaterRitualRandomMutation" Category="Physical">You gain =mutation.name=.</part></nowiki></code> | |||
|} | |||
===Events=== | |||
Source notes the deepest element that you can expect the event to propagate from. In order, the values are Conversation -> Node -> Choice -> Text.<br/> | |||
Order notation is very approximate, as the same event will be fired multiple times on different elements during a navigation. | |||
{| class="wikitable" | |||
|- | |||
! Name | |||
! Source | |||
! Description | |||
! Order | |||
|- | |||
| IsElementVisibleEvent | |||
| Text | |||
| Fired when determining whether an element is possibly available for rendering and selection, after any predicates defined on the element. | |||
| Before: GetTextElementEvent, After: EnteredElementEvent | |||
|- | |||
| GetTextElementEvent | |||
| Text | |||
| Fired when choosing a text element for preparation and can control the chosen text. | |||
| Before: PrepareTextEvent, After: IsElementVisibleEvent | |||
|- | |||
| PrepareTextEvent | |||
| Text | |||
| Fired when preparing spoken text for display after a node has been entered.<br/> | |||
This precedes the standard variable replacements like =subject.name= and allows setting a new Subject and Object. | |||
| Before: DisplayTextEvent, After: GetTextElementEvent | |||
|- | |||
| DisplayTextEvent | |||
| Choice | |||
| Fired before displaying the prepared text to screen.<br/> | |||
This is where you will typically add unspoken text like tooltips or other metagame information. | |||
| Before: ColorTextEvent, After: PrepareTextEvent | |||
|- | |||
| ColorTextEvent | |||
| Choice | |||
| Fired when coloring the display text of an element. | |||
| With: DisplayTextEvent | |||
|- | |||
| GetChoiceTagEvent | |||
| Choice | |||
| Fired when selecting an ending tag to apply to the display text such as [begin trade]. | |||
| With: DisplayTextEvent | |||
|- | |||
| EnteredElementEvent | |||
| Choice | |||
| Fired after an element has successfully been entered. | |||
| Before: PrepareTextEvent, After: EnterElementEvent | |||
|- | |||
| EnterElementEvent | |||
| Choice | |||
| Fired as an element is being entered and can prevent navigation. | |||
| Before: EnteredElementEvent, After: LeaveElementEvent | |||
|- | |||
| GetTargetElementEvent | |||
| Choice | |||
| Fired after leaving the current node and can control the navigation target. | |||
| Before: EnterElementEvent, After: LeaveElementEvent | |||
|- | |||
| LeaveElementEvent | |||
| Node | |||
| Fired as an element is being left and can prevent navigation. | |||
| Before: GetTargetElementEvent, After: GetDisplayTextEvent | |||
|- | |||
| LeftElementEvent | |||
| Node | |||
| Fired after an element has successfully been exited. | |||
| Before: EnteredElementEvent, After: GetTargetElementEvent | |||
|- | |||
| HideElementEvent | |||
| Choice | |||
| Fired when evaluating elements to display that are hidden by special outside conditions.<br/> | |||
One such condition is the last choice selected that will be hidden if navigation was successful but did not leave the current node. | |||
| Before: PrepareTextEvent, After: IsElementVisibleEvent | |||
|- | |||
| PredicateEvent | |||
| Text | |||
| Fired by the <code>IfCommand</code> predicate and controls visibility similarly to IsElementVisibleEvent. | |||
| Before: IsElementVisibleEvent, After: EnteredElementEvent | |||
|} | |||
===Delegates=== | |||
An Inverse predicate can be invoked with <code>IfNot</code> to negate its value.<br /> | |||
A Speaker delegate can be invoked with <code>IfSpeaker</code>/<code>SetSpeaker</code> to target the speaker game object.<br /> | |||
If both are applicable then it can also be invoked with <code>IfNotSpeaker</code>.<br /> | |||
{| class="wikitable" | |||
|- | |||
! Name | |||
! Type | |||
! Description | |||
! Inverse | |||
! Speaker | |||
|- | |||
| IfHaveQuest | |||
| Predicate | |||
| Continue if the player has an active or finished quest by specified ID. | |||
| Yes | |||
| No | |||
|- | |||
| IfHaveActiveQuest | |||
| Predicate | |||
| Continue if the player has an active quest by specified ID. | |||
| Yes | |||
| No | |||
|- | |||
| IfFinishedQuest | |||
| Predicate | |||
| Continue if the player has a finished quest by specified ID. | |||
| Yes | |||
| No | |||
|- | |||
| IfFinishedQuestStep | |||
| Predicate | |||
| Takes a '~' separated value of "Quest ID~Step ID" and checks if the step is completed. | |||
| Yes | |||
| No | |||
|- | |||
| IfHaveObservation | |||
| Predicate | |||
| Continue if the player knows of any gossip or lore with the specified ID. | |||
| Yes | |||
| No | |||
|- | |||
| IfHaveObservationWithTag | |||
| Predicate | |||
| Continue if the player knows of any gossip or lore with the specified tag. | |||
| Yes | |||
| No | |||
|- | |||
| IfHaveSultanNoteWithTag | |||
| Predicate | |||
| Continue if the player knows any history of a sultan with the specified tag. | |||
| Yes | |||
| No | |||
|- | |||
| IfHaveVillageNote | |||
| Predicate | |||
| Continue if the player knows any history of a village with the specified ID. | |||
| Yes | |||
| No | |||
|- | |||
| IfHaveState | |||
| Predicate | |||
| Continue if any global game state has been set by specified ID. | |||
| Yes | |||
| No | |||
|- | |||
| IfTestState | |||
| Predicate | |||
| Evaluates an expression of format "ID Operator Value", for example "SlynthSettlementFaction = Joppa", comparing the global game state to the specified value. | |||
| Yes | |||
| No | |||
|- | |||
| IfHaveConversationState | |||
| Predicate | |||
| Continue if any local conversation state has been set by specified ID. | |||
| Yes | |||
| No | |||
|- | |||
| IfHaveText | |||
| Predicate | |||
| Continue if the specified value is present within the currently displayed node text. | |||
| Yes | |||
| No | |||
|- | |||
| IfLastChoice | |||
| Predicate | |||
| Continue if the last selected choice in this conversation has the specified ID. | |||
| Yes | |||
| No | |||
|- | |||
| IfCommand | |||
| Predicate | |||
| Fires an event on the element with the specified value as its command, continue if the result is set true by a consuming part. | |||
| Yes | |||
| No | |||
|- | |||
| IfReputationAtLeast | |||
| Predicate | |||
| Continue if the player has the specified reputation level or higher, valid entries are "Loved", "Liked", "Indifferent", "Disliked", and "Hated". | |||
| Yes | |||
| No | |||
|- | |||
| IfTime | |||
| Predicate | |||
| Takes a time tick from the [[Calendar]], with valid ranges like "325-1000" (Harvest Dawn to Jeweled Dusk) or "1100-500" (Waxing Beetle Moon to Waxing Salt Sun). | |||
| Yes | |||
| No | |||
|- | |||
| IfLedBy | |||
| Predicate | |||
| Continue if the speaker is led by the specified value, valid entries are "*" (anyone), "Player" or a blueprint ID. | |||
| Yes | |||
| No | |||
|- | |||
| IfZoneID | |||
| Predicate | |||
| Continue if the current zone's ID starts with the specified value, e.g. "JoppaWorld.22.14.1.0.13" for Grit Gate, "JoppaWorld.5.2" for the entire Stilt. | |||
| Yes | |||
| No | |||
|- | |||
| IfZoneName | |||
| Predicate | |||
| Continue if the current zone's name contains the specified value, e.g. "Grit Gate". | |||
| Yes | |||
| No | |||
|- | |||
| IfZoneLevel | |||
| Predicate | |||
| Continue if the current zone's Z level is within the specified range, e.g. "10-15" to include the surface and 5 zones down. | |||
| Yes | |||
| No | |||
|- | |||
| IfZoneTier | |||
| Predicate | |||
| Continue if the current zone's [[Zone_tier#Regional_Zone_Tier|regional zone tier]] is within the specified range. | |||
| Yes | |||
| No | |||
|- | |||
| IfZoneWorld | |||
| Predicate | |||
| Continue if the current zone is within the specified world, e.g. "JoppaWorld". | |||
| Yes | |||
| No | |||
|- | |||
| IfUnderstood | |||
| Predicate | |||
| Continue if the player has seen and understands the specified blueprint. | |||
| Yes | |||
| No | |||
|- | |||
| IfIn100 | |||
| Predicate | |||
| Continue if the randomly rolled value is below or equal to the specified value. | |||
| No | |||
| No | |||
|- | |||
| IfGenotype | |||
| Predicate | |||
| Continue if the target is of the specified genotype. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfSubtype | |||
| Predicate | |||
| Continue if the target is of the specified subtype. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfTrueKin | |||
| Predicate | |||
| Continue if the target counts as a true kin and can implant cybernetics. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfMutant | |||
| Predicate | |||
| Continue if the target counts as a mutant and can gain mutations. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfHaveItem | |||
| Predicate | |||
| Continue if the target has an item of the specified blueprint in their inventory or equipped on their body. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfWearingBlueprint | |||
| Predicate | |||
| Continue if the target has an item of the specified blueprint equipped on their body. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfHaveBlueprint | |||
| Predicate | |||
| Continue if the target has an item of the specified blueprint in their inventory. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfHavePart | |||
| Predicate | |||
| Continue if the target has a part by the specified class name. Mutations are a variant of a part that this is applicable to. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfHaveTag | |||
| Predicate | |||
| Continue if the target's blueprint has the specified tag. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfHaveProperty | |||
| Predicate | |||
| Continue if the target game object has the specified property. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfHaveTagOrProperty | |||
| Predicate | |||
| Continue if the target has the specified tag or property. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfHaveLiquid | |||
| Predicate | |||
| Continue if the target has the specified liquid with an optional amount of drams, e.g. "water" for at least 1 dram of water, or "sludge:64" for 64 drams of sludge. | |||
| Yes | |||
| Yes | |||
|- | |||
| IfLevelLessOrEqual | |||
| Predicate | |||
| Continue if the target is at or below the specified value. | |||
| Yes | |||
| Yes | |||
|- | |||
| AwardXP | |||
| Action | |||
| Gives the specified amount of XP to the target, preceding the amount with an exclamation mark will suppress the XP popup, e.g. "!5000". | |||
| No | |||
| Yes | |||
|- | |||
| FinishQuest | |||
| Action | |||
| Marks a quest by the specified ID as finished. This will not complete all the quest's steps. | |||
| No | |||
| No | |||
|- | |||
| FireEvent | |||
| Action | |||
| Constructs an event from a comma and colon separated list of "EventID,Parameter1:Value1,Parameter2:Value2,Para..." then fires it on the target game object. | |||
| No | |||
| Yes | |||
|- | |||
| FireSystemsEvent | |||
| Action | |||
| Constructs an event from a comma and colon separated list of "EventID,Parameter1:Value1,Parameter2:Value2,Para..." then fires it on all game systems. | |||
| No | |||
| No | |||
|- | |||
| SetStringState | |||
| Action | |||
| Takes a comma separated list of "StateID,Value" and sets the global game state to the specified string value. If no value is specified the state is removed. | |||
| No | |||
| No | |||
|- | |||
| SetIntState | |||
| Action | |||
| Takes a comma separated list of "StateID,Value" and sets the global game state to the specified int value. If no value is specified the state is removed. | |||
| No | |||
| No | |||
|- | |||
| AddIntState | |||
| Action | |||
| Takes a comma separated list of "StateID,Value" and adds the specified value to the global game state's value. | |||
| No | |||
| No | |||
|- | |||
| SetBooleanState | |||
| Action | |||
| Takes a comma separated list of "StateID,Value" and sets the global game state to the specified boolean value. If no value is specified the state is removed. | |||
| No | |||
| No | |||
|- | |||
| ToggleBooleanState | |||
| Action | |||
| Toggles the boolean value of the global game state by specified ID. If no value existed prior, it will be set to true. | |||
| No | |||
| No | |||
|- | |||
| SetStringProperty | |||
| Action | |||
| Takes a comma separated list of "PropertyID,Value" and sets a string property on the target game object to the specified value. If no value is specified the property is removed. | |||
| No | |||
| Yes | |||
|- | |||
| SetIntProperty | |||
| Action | |||
| Takes a comma separated list of "PropertyID,Value" and sets an int property on the target game object to the specified value. If no value is specified the property is removed. | |||
| No | |||
| Yes | |||
|- | |||
| SetStringConversationState | |||
| Action | |||
| Takes a comma separated list of "StateID,Value" and sets the temporary conversation state to the specified string value. If no value is specified the state is removed. | |||
| No | |||
| No | |||
|- | |||
| SetIntConversationState | |||
| Action | |||
| Takes a comma separated list of "StateID,Value" and sets the temporary conversation state to the specified int value. If no value is specified the state is removed. | |||
| No | |||
| No | |||
|- | |||
| SetBooleanConversationState | |||
| Action | |||
| Takes a comma separated list of "StateID,Value" and sets the temporary conversation state to the specified boolean value. If no value is specified the state is removed. | |||
| No | |||
| No | |||
|- | |||
| RevealObservation | |||
| Action | |||
| Reveals a piece of gossip or lore by the specified ID. | |||
| No | |||
| No | |||
|- | |||
| GiveLiquid | |||
| Action | |||
| Fills valid liquid containers of the target with specified liquid, e.g. "water" for 1 dram of water, or "sludge:64" for 64 drams of sludge. | |||
| No | |||
| Yes | |||
|- | |||
| UseLiquid | |||
| Action | |||
| Empties valid liquid containers of the target with specified liquid, e.g. "water" for 1 dram of water, or "sludge:64" for 64 drams of sludge. | |||
| No | |||
| Yes | |||
|- | |||
| StartQuest | |||
| Part Generator | |||
| Adds a QuestHandler part to the parent element with the Start action and specified QuestID. | |||
| No | |||
| No | |||
|- | |||
| CompleteQuestStep | |||
| Part Generator | |||
| Adds a QuestHandler part to the parent element with the Step action and specified "QuestID~StepID". | |||
| No | |||
| No | |||
|- | |||
| GiveItem | |||
| Part Generator | |||
| Adds a ReceiveItem part to the parent element with the specified comma separated blueprints. | |||
| No | |||
| No | |||
|- | |||
| TakeItem | |||
| Part Generator | |||
| Adds a TakeItem part to the parent element with the specified comma separated blueprints. | |||
| No | |||
| No | |||
|} | |||
=== Choice ordering === | |||
The following attributes can be added to the <code><choice></code> XML tag to manipulate the order in which conversational choices are presented. By default, choices are ordered by how they appear in <code>Conversations.xml</code>. | |||
{| class="wikitable" | |||
|- | |||
! Name | |||
! Description | |||
|- | |||
| Priority | |||
| An integer priority that that specifies where a choice should appear; choices with a higher priority appear closer to the top. By default all choices are given a priority of zero unless explicitly specified, although some parts influence the priority of a choice. | |||
|- | |||
| Before | |||
| Place a choice before another choice with the specified ID, e.g., <code>Before="WaterRitualChoice"</code>. | |||
|- | |||
| After | |||
| Place a choice after another choice with the specified ID, e.g. <code>After="WaterRitualChoice"</code>. | |||
|} | |||
{{Modding Navbox}} | |||
[[Category:Modding]] |