Using JSON Datatypes in Macros: Difference between revisions
m (Conversion script moved page Using JSON Datatypes in Macros to using JSON Datatypes in Macros: Converting page titles to lowercase) |
m (Taustin moved page using JSON Datatypes in Macros to Using JSON Datatypes in Macros over redirect) |
||
(One intermediate revision by the same user not shown) | |||
Line 9: | Line 9: | ||
* Attack penalty per shot (so more than one shot around has an attack penalty). | * Attack penalty per shot (so more than one shot around has an attack penalty). | ||
So if we were to define this in JavaScript we could just do it as | So if we were to define this in JavaScript we could just do it as | ||
< | <syntaxhighlight lang="javascript" line> | ||
weapon = { | weapon = { | ||
"name": "Handgun", | "name": "Handgun", | ||
Line 15: | Line 15: | ||
"damage": "1d10" | "damage": "1d10" | ||
} | } | ||
</ | </syntaxhighlight> | ||
If you already know what your JSON object looks like defining it in MapTool is not too different. | If you already know what your JSON object looks like defining it in MapTool is not too different. | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[r: weapon = '{ | [r: weapon = '{ | ||
"name": "Handgun", | "name": "Handgun", | ||
Line 24: | Line 24: | ||
"damage": "1d10" | "damage": "1d10" | ||
}'] | }'] | ||
</ | </syntaxhighlight> | ||
If you copy and paste this into MapTool you will notice that the output is returned on one line | If you copy and paste this into MapTool you will notice that the output is returned on one line | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[r: weapon = '{ "name": "Handgun", "shots": 6, "damage": "1d10" }'] | [r: weapon = '{ "name": "Handgun", "shots": 6, "damage": "1d10" }'] | ||
</ | </syntaxhighlight> | ||
This is because the chat window displays html and new line characters are not displayed. If you wanted to see the carriage returns as you typed them then you could do | This is because the chat window displays html and new line characters are not displayed. If you wanted to see the carriage returns as you typed them then you could do | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
<pre> | <pre> | ||
[r: weapon = '{ | [r: weapon = '{ | ||
Line 40: | Line 40: | ||
}'] | }'] | ||
</pre> | </pre> | ||
</ | </syntaxhighlight> | ||
Which says the output is already preformatted so new line characters will be displayed. | Which says the output is already preformatted so new line characters will be displayed. | ||
Line 46: | Line 46: | ||
So to create the above weapon you could use | So to create the above weapon you could use | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[r: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10" )] | [r: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10" )] | ||
</ | </syntaxhighlight> | ||
Where {{code|"{}"}} is an empty JSON object, for convenience {{code|""}} can be used as the first argument to {{func|json.set}} to represent an empty object. | Where {{code|"{}"}} is an empty JSON object, for convenience {{code|""}} can be used as the first argument to {{func|json.set}} to represent an empty object. | ||
{{func|json.set}} takes an object as well a list of key and value pairs and returns a new object with the specified keys set . '''It is important to rememeber this last bit, all of the json functions do not modify the object, instead they create a new object with the changes.''' | {{func|json.set}} takes an object as well a list of key and value pairs and returns a new object with the specified keys set . '''It is important to rememeber this last bit, all of the json functions do not modify the object, instead they create a new object with the changes.''' | ||
For example | For example | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[h: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10" )] | [h: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10" )] | ||
[h: weapon2 = json.set(weapon, "name", "Bigger Handgun")] | [h: weapon2 = json.set(weapon, "name", "Bigger Handgun")] | ||
[r: weapon] <br> | [r: weapon] <br> | ||
[r: weapon2] | [r: weapon2] | ||
</ | </syntaxhighlight> | ||
Displays | Displays | ||
Line 67: | Line 67: | ||
The original value in weapon has not been modified. | The original value in weapon has not been modified. | ||
If you placed {{code|< | If you placed {{code|<syntaxhighlight lang="text" enclose="none"><pre> </pre></syntaxhighlight>}} around the output you will notice that json.set() creates the object on one line, not formatted nicely across multiple lines as it was when we created it manually. If you want to "format" this nicely you can use the {{func|json.indent}} command. | ||
For example: | For example: | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
<pre>[r: json.indent('{"name":"Handgun","shots":6,"damage":"1d10"}', 4)]</pre> | <pre>[r: json.indent('{"name":"Handgun","shots":6,"damage":"1d10"}', 4)]</pre> | ||
</ | </syntaxhighlight> | ||
Produces: | Produces: | ||
Line 85: | Line 85: | ||
Using JSON arrays is similar | Using JSON arrays is similar | ||
Lets to our weapon above, in this mythical system that the gun belongs to you are able to fire all of the shots in one round but each after the first has a two hit penalty. We can represent this as an array with 6 elements (we will include the first shot for simplicities sake even if it would always be 0). | Lets to our weapon above, in this mythical system that the gun belongs to you are able to fire all of the shots in one round but each after the first has a two hit penalty. We can represent this as an array with 6 elements (we will include the first shot for simplicities sake even if it would always be 0). | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[r: modifiers = '[0, 1, 3, 5, 8, 12]'] | [r: modifiers = '[0, 1, 3, 5, 8, 12]'] | ||
</ | </syntaxhighlight> | ||
The {{func|json.append}} function allows you to append items to the end of an array, if the array is empty then it will create a new one. | The {{func|json.append}} function allows you to append items to the end of an array, if the array is empty then it will create a new one. | ||
Line 94: | Line 94: | ||
For example if I wanted to change the 3rd index in the array above to 4 I could do | For example if I wanted to change the 3rd index in the array above to 4 I could do | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[h: modifiers = json.set(modifiers, 2, 4) | [h: modifiers = json.set(modifiers, 2, 4) | ||
</ | </syntaxhighlight> | ||
The value for index is {{code|2}} because indexes in the array start at {{code|0}}. | The value for index is {{code|2}} because indexes in the array start at {{code|0}}. | ||
So given what we learned earlier you could add the modifiers to our weapon object in the following way | So given what we learned earlier you could add the modifiers to our weapon object in the following way | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[r: modifiers = '[0, 1, 3, 5, 8, 12]'] | [r: modifiers = '[0, 1, 3, 5, 8, 12]'] | ||
[r: weapon = json.set(weapon, "modifiers", modifiers)] | [r: weapon = json.set(weapon, "modifiers", modifiers)] | ||
</ | </syntaxhighlight> | ||
Or you could do it as | Or you could do it as | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[h: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10", | [h: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10", | ||
"modifiers", "[0, 1, 3, 5, 8, 12]" )] | "modifiers", "[0, 1, 3, 5, 8, 12]" )] | ||
<pre>[r: json.indent(weapon,4)]</pre> | <pre>[r: json.indent(weapon,4)]</pre> | ||
</ | </syntaxhighlight> | ||
Which will display | Which will display | ||
Line 131: | Line 131: | ||
Of course if you know all the details up front you can create the whole objects as before such as. | Of course if you know all the details up front you can create the whole objects as before such as. | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[r: weapon = '{ | [r: weapon = '{ | ||
"name" : "Handgun", | "name" : "Handgun", | ||
Line 138: | Line 138: | ||
"modifiers" : "[0, 1, 3, 5, 8, 12]" | "modifiers" : "[0, 1, 3, 5, 8, 12]" | ||
}'] | }'] | ||
</ | </syntaxhighlight> | ||
Line 146: | Line 146: | ||
So | So | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[h: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10", | [h: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10", | ||
"modifiers", "[0, 1, 3, 5, 8, 12]" )] | "modifiers", "[0, 1, 3, 5, 8, 12]" )] | ||
Line 154: | Line 154: | ||
[h: modifiers = json.get(weapon, "modifiers")] | [h: modifiers = json.get(weapon, "modifiers")] | ||
Modifiers [r,c(json.get(weapon, "shots")): json.get(modifiers, roll.count)] | Modifiers [r,c(json.get(weapon, "shots")): json.get(modifiers, roll.count)] | ||
</ | </syntaxhighlight> | ||
Line 167: | Line 167: | ||
You could also use {{func|json.length}} to change the line that displays the modifiers to | You could also use {{func|json.length}} to change the line that displays the modifiers to | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
Modifiers [r,c(json.length(modfiers)): json.get(modifiers, roll.count)] | Modifiers [r,c(json.length(modfiers)): json.get(modifiers, roll.count)] | ||
</ | </syntaxhighlight> | ||
But there is an easier way to loop through every value in the array and that is using [[foreach (roll option)|foreach]] | But there is an easier way to loop through every value in the array and that is using [[foreach (roll option)|foreach]] | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
Modifiers [r,foreach(val,modifiers): val] | Modifiers [r,foreach(val,modifiers): val] | ||
</ | </syntaxhighlight> | ||
json.length() and foreach can be used on JSON objects as well as arrays. In this case json.length() returns the number of key/value pairs, and foreach will loop through the keys in the object. | json.length() and foreach can be used on JSON objects as well as arrays. In this case json.length() returns the number of key/value pairs, and foreach will loop through the keys in the object. | ||
So using the above objects | So using the above objects | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[r: json.length(weapon)] | [r: json.length(weapon)] | ||
</ | </syntaxhighlight> | ||
Displays {{code|4}}. | Displays {{code|4}}. | ||
and | and | ||
< | <syntaxhighlight lang="mtmacro" line> | ||
[r,foreach(val,weapon): val] | [r,foreach(val,weapon): val] | ||
</ | </syntaxhighlight> | ||
Displays | Displays |
Latest revision as of 20:45, 15 March 2023
If you don't know JavaScript or JSON already I highly suggest you read Introduction to JSON Datatypes first even though it is JavaScript based.
So how do you create JSON Objects and JSON Arrays in MapTool macro script? Well the easy way if you already know everything you want is to create it as a string. Lets define a data structure that will hold the details for a weapon.
The weapon will be a gun which has the following details:
- Number of shots before reload
- Damage done
- Attack penalty per shot (so more than one shot around has an attack penalty).
So if we were to define this in JavaScript we could just do it as
weapon = {
"name": "Handgun",
"shots": 6,
"damage": "1d10"
}
If you already know what your JSON object looks like defining it in MapTool is not too different.
[r: weapon = '{
"name": "Handgun",
"shots": 6,
"damage": "1d10"
}']
If you copy and paste this into MapTool you will notice that the output is returned on one line
[r: weapon = '{ "name": "Handgun", "shots": 6, "damage": "1d10" }']
This is because the chat window displays html and new line characters are not displayed. If you wanted to see the carriage returns as you typed them then you could do
<pre>
[r: weapon = '{
"name": "Handgun",
"shots": 6,
"damage": "1d10"
}']
</pre>
Which says the output is already preformatted so new line characters will be displayed.
The above is well and good if you know what you want to store ahead of time, but how do you create a JSON object based on user input or results of a macro. For this you use json.set().
So to create the above weapon you could use
[r: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10" )]
Where "{}"
is an empty JSON object, for convenience ""
can be used as the first argument to json.set() to represent an empty object.
json.set() takes an object as well a list of key and value pairs and returns a new object with the specified keys set . It is important to rememeber this last bit, all of the json functions do not modify the object, instead they create a new object with the changes. For example
[h: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10" )]
[h: weapon2 = json.set(weapon, "name", "Bigger Handgun")]
[r: weapon] <br>
[r: weapon2]
Displays
{"name":"Handgun","shots":6,"damage":"1d10"} {"name":"Bigger Handgun","shots":6,"damage":"1d10"}
The original value in weapon has not been modified.
If you placed
around the output you will notice that json.set() creates the object on one line, not formatted nicely across multiple lines as it was when we created it manually. If you want to "format" this nicely you can use the json.indent() command.
<pre> </pre>
For example:
<pre>[r: json.indent('{"name":"Handgun","shots":6,"damage":"1d10"}', 4)]</pre>
Produces:
{ "name": "Handgun", "shots": 6, "damage": "1d10" }
Using JSON arrays is similar Lets to our weapon above, in this mythical system that the gun belongs to you are able to fire all of the shots in one round but each after the first has a two hit penalty. We can represent this as an array with 6 elements (we will include the first shot for simplicities sake even if it would always be 0).
[r: modifiers = '[0, 1, 3, 5, 8, 12]']
The json.append() function allows you to append items to the end of an array, if the array is empty then it will create a new one.
If the input is an "[]"
it is an empty array, for convenience ""
also represents an empty array. json.set() can be used on arrays but only to set a value for an index, the array must already have that index.
For example if I wanted to change the 3rd index in the array above to 4 I could do
[h: modifiers = json.set(modifiers, 2, 4)
The value for index is 2
because indexes in the array start at 0
.
So given what we learned earlier you could add the modifiers to our weapon object in the following way
[r: modifiers = '[0, 1, 3, 5, 8, 12]']
[r: weapon = json.set(weapon, "modifiers", modifiers)]
Or you could do it as
[h: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10",
"modifiers", "[0, 1, 3, 5, 8, 12]" )]
<pre>[r: json.indent(weapon,4)]</pre>
Which will display
{ "name": "Handgun", "shots": 6, "damage": "1d10", "modifiers": [ 0, 1, 3, 5, 8, 12 ] }
Of course if you know all the details up front you can create the whole objects as before such as.
[r: weapon = '{
"name" : "Handgun",
"shots" : 6,
"damage" : 1d10,
"modifiers" : "[0, 1, 3, 5, 8, 12]"
}']
The next question is now that we have all the information in a JSON object or array how do we get it out when we need it?
To get things out of objects or arrays we use json.get()
So
[h: weapon = json.set("{}", "name", "Handgun", "shots", 6, "damage", "1d10",
"modifiers", "[0, 1, 3, 5, 8, 12]" )]
Weapon Name: [r: json.get(weapon, "name")]<br>
Damage: [r: json.get(weapon, "damage")] <br>
Shots: [r: json.get(weapon, "shots")] <br>
[h: modifiers = json.get(weapon, "modifiers")]
Modifiers [r,c(json.get(weapon, "shots")): json.get(modifiers, roll.count)]
Which displays
Weapon Name: Handgun Damage: 1d10 Shots: 6 Modifiers 0, 1, 3, 5, 8, 12
You could also use json.length() to change the line that displays the modifiers to
Modifiers [r,c(json.length(modfiers)): json.get(modifiers, roll.count)]
But there is an easier way to loop through every value in the array and that is using foreach
Modifiers [r,foreach(val,modifiers): val]
json.length() and foreach can be used on JSON objects as well as arrays. In this case json.length() returns the number of key/value pairs, and foreach will loop through the keys in the object.
So using the above objects
[r: json.length(weapon)]
Displays 4
.
and
[r,foreach(val,weapon): val]
Displays
name, shots, damage, modifiers