Using Parameters with the Text Processor - ThePix/QuestJS GitHub Wiki
Using parameters is more complicated, but very powerful. If you can get you head around it, there are all sorts of tricks you can use, in particular to make responses that are neutral with respect to the objects involved.
You can send a set of parameters to the msg
function, as a dictionary. The text processor directive can then access these to modify your text.
For the basics of using the text processor, see here.
For more on using these for neutral language, see also here.
Conventions
A lot of features of Quest 6 use text processor parameters, and it is convenient to pass the same dictionary to other functions too. It is therefore necessary to be consistent with regards to what is in that dictionary.
Name | Comment |
---|---|
char | The character doing the action, usually the player |
item | The item that is being manipulated |
npc | Other character (could be the player) |
obj | Other object |
whole | The object that item is a component of |
multiple | True if this is one of multiple items to be handled in a command |
count | The count for the object, item |
[name]_count | The count for the named object |
Most of these will not be applicable most of the time. Only "char" will be present always, "item" nearly always.
show
The simplest way to use parameters is just to access them via the show
directive. You can either provide a string, which is used as is; or an object together with an attribute name, to have the attribute inserted.
msg("Here is some {show:my_text}.", {my_text:"interesting text"});
-> Here is some interesting text.
msg("Here is a {show:item:alias}.", {item:w.coin});
-> Here is a gold coin.
// can also be used without parameters!
msg("Here is a {show:coin:alias}.");
-> Here is a gold coin.
If the attribute is a function, it will be run, with the parameters sent as a dictionary, and the value returned - which must be a string - will be inserted.
If the attribute is a Boolean, the string used is determined by lang.tp_true
and lang.tp_false
- "true" and "false" by default.
This rather contrived example is taken from the unit tests:
w.book.func1 = function() { return "test1" }
w.book.func2 = function(options) { return "It is " + options.char.alias + " reading the book." }
msg("Simple text: p2={show:item:func1}", {item:w.book})
msg("Simple text: p2={show:item:func2}", {item:w.book, char:w.Kyle})
->
Simple text: p2=test1
Simple text: p2=It is Kyle reading the book.
If you want to display a number, you might want to look at the number
or ordinal
directives.
Note that show
can also be used to display object values, as discussed here. It will try to match an object in the parameters first, before looking for one in the game world.
multi
Gives the item's alias, followed by a colon, if "multiple" in the params is true. This has a very specific role, and it probably but much use outside of that, but for the role is very use.
If the player does GET ALL, the response for each individual pick-up needs to make clear what item is being processed. There are broadly two approaches; either giving a long phrase that must it clear, such as "You pick up the book." or prefix a short phrase, such as "Book: Taken." Quest 6 tends to do the former, while Quest 5 generally the latter.
If you want to use the latter, then this directive is the answer. This will automatically insert the alias of the item when needed. Here is an example:
lang.take_successful = "{multi}Taken."
Other directives
Some of the directives already discussed supports params; "show", "money" and the various conditional directives. If the name of the object is actually the name of a parameter, this will be used instead.
msg("{nm:item:the:true} is {$:item}", {item:w.carrot})
nm and nms
To print the name of an object (i.e., what it is called, its alias, rather than the "name" attribute), use the nm
directive. Behind the scenes this uses the getName
function in lang-en.js (so it is language neutral), and you can specify if "the" or "a" should be prepended as required. You can add true
as a further parameter to have it capitalised.
msg("Here is {nm:item:the}.", {item:"Kyle"});
-> Here is Kyle.
msg("Here is {nm:item:the}.", {item:"umbrella"});
-> Here is the umbrella.
If the item has an owner, Quest will indicate that. You can use "THE" and "A" instead of "the" and "a" to stop that.
w.umbrella.owner = "Kyle"
msg("Here is {nm:item:the}.", {item:"umbrella"});
-> Here is Kyle's umbrella.
msg("Here is {nm:item:THE}.", {item:"umbrella"});
-> Here is the umbrella.
To get the possessive form, use nms
. This will append 's
to the name, or replace it with "your" or "my" if appropriate.
msg("It is {nms:char:the} book.", {char:game.player})
-> It is your book.
msg("It is {nms:char:the} book.", {char:w.Kyle})
-> It is Kyle's book.
You can use "the-pa" instead of "the", and "a-pa" instead of "a" to have it use the possessive form. You need to specify whose it is with the fifth parameter. These two examples therefore have two colons together as they do not use the fourth. The first specifies the owner in the directive, the second as a parameter.
"There is {nm:obj:a-pa::Kyle}.", {obj:w.book}
"There is {nm:obj:a-pa::npc}.", {obj:w.book, npc:w.Kyle})
list
The "list" works similar to "nm", but with a list of things; the list must be in the parameters. Most of the options for "nm" will also work here. Note that this does not work well with COUNTABLEs - it will assume there is exactly one.
"You can see {list:list:a}.", {list:[w.book, w.Kyle]}
-> "You can see a book and Kyle."
The list can include strings as well as objects. Note that "the" or "a" will not be prepended to strings, as Quest will not know when that is appropriate.
"The book, Kyle and the milk jug.", processText("{list:list:the:true}.", {list:[w.book, w.Kyle, 'the milk jug']}
-> "The book, Kyle and the milk jug."
cj, nv and pv
To conjugate a verb, use cj (conjugate; which just gives the correct form of the verb), nv (noun-verb; prepends the name of the object to the verb) or pv (pronoun-verb; prepends the correct pronoun to the verb). Add a third parameter, true
, to capitalise.
// Using the name
msg("{nv:item:be:true} here.", {item:"Kyle");
-> Kyle is here.
msg("{nv:item:be:true} here.", {item:"shoes");
-> Shoes are here.
msg("{nv:item:be:true} here.", {item:game.player);
-> You are here.
// Using the pronoun
msg("{pv:item:be:true} here.", {item:"Kyle");
-> He is here.
msg("{pv:item:be:true} here.", {item:"shoes");
-> They are here.
msg("{pv:item:be:true} here.", {item:game.player);
-> You are here.
ob, sb, ps, pa, rf
These will produce the pronoun for the given item. You can again add "true" as an additional parameter to capitalise.
msg("Kyle is {pa:item} bear.", {item:game.player);
-> Kyle is your bear.
msg("Kyle is {pa:item} bear.", {item:"Lara");
-> Kyle is her bear.
- ob: The object; I, you, he, she, it or they
- sb: The subject; me, you, him, her, it, them
- ps: The possessive; mine, yours, his, hers, its, theirs
- pa: The possessive adjective; my, your, his, her, its, theirs
- rf: The reflexive; myself, yourself, etc.
pa2
The "pa2" directive expects to be given two items. It will give the possessive adjective on the first object if they use different pronouns, or the possessive form of the name if they use the same pronouns. If that does not make sense, take a look at the examples, which use the same string, but different characters.
msg("'Please stop!' exclaims {nm:chr1:the} when {nv:chr2:rip} {pa2:chr1:chr2} book to shred.", {chr1:w.Kyle, chr2:game.player});
-> 'Please stop!' exclaims Kyle when you rip his book to shred.
msg("'Please stop!' exclaims {nm:chr1:the} when {nv:chr2:rip} {pa2:chr1:chr2} book to shred.", {chr1:w.Kyle, chr2:w.Boris});
-> 'Please stop!' exclaims Kyle when Boris rips Kyle's book to shred.
In the first, it is clear "his" refers to Kyle, as the other person is you. In the second it could refer to Kyle or Boris, so we want the name to make it clear.
Are similar directives needed for other pronouns? Let me know!