{ "NAME":"Ability 1" , "Attack_Bonus":10 , "Parry_Bonus":20 , "DESCRIPTION":"blablabla" , ... }
These abilities are then grouped and stored in the properties of a token in form of a JSON-Array, e.g.:
Property AbilitiesFight = [ {"NAME":"Ability 1" , ...} , {"NAME":"Ability 2" , ...} , ... ]
Property AbilitiesSocial = [ ... ]
The same system is used for the inventory of a character.
To edit the JSON-Objects/Abilities and JSON-Arrays/Properties I have written two UDFs that allow to do that with input dialogs. I am posting the code for those UDFs for two reasons:
a) Though the code seems to do what it is supposed to do I think it is pretty clumsy and I would appreciate any help/hints to make it more efficient/elegant.
b) If anyone is trying to do the same thing maybe the codes can help (or just be copied and used ). And of course if you find out that it does not work in certain cases I would appreciate the feedback.
Thanks again for the help I got when I was trying to write the Object-edit-UDF.
edit object udf
Code: Select all
[h: '<!-- function output: Object
object.edit(Object object, ArrayOfKeys keysToEdit) -->']
[h: macro = "object.edit" ]
[h: arguments = "(object,keysToEdit)" ]
[h: noArgsWanted = 2]
[h: '<!-- variables to get a nice output for error messages -->']
[h: type = "function" ]
[h: this = getMacroLocation() ]
[h: macroName = strformat("%{this}.%{macro}%{arguments}") ]
[h: '<!-- test if number of arguments is correct -->']
[h: noArgsInput = argCount()]
[h: errorMessage = strformat("<b>%{type} %{macroName}</b> needs <i><b>%{noArgsWanted}</b> </i>argument(s)<i> (actual arguments:%{noArgsInput})</i>")]
[h: assert( noArgsInput == noArgsWanted, errorMessage ) ]
[h: '<!-- get the arguments -->']
[h: object = arg(0)]
[h: errorMessage = strformat("%{type} <b>%{macroName}</b>: Object is empty.") ]
[h: assert ( !json.isEmpty(object), errorMessage) ]
[h: keysToEdit = arg(1) ]
[h: errorMessage = strformat("%{type} <b>%{macroName}</b>: No Keys to edit.") ]
[h: assert ( !json.isEmpty(keysToEdit), errorMessage) ]
[h: '<!-- just some reminders of the structure of things
object { "KEY1":"Value11", "KEY2":"Value12", "KEY3":"Value13" }
arrayOfKeys [ "KEY1", "KEY2", "KEY3" ]
[ for(counter,start,end,stepsize): command ]
input(variableName|value|prompt|inputType|options ] -->' ]
[h: promt = " "]
[h: inputType = "TEXT" ]
[h: options = ""]
[h: inputStringList = ""]
[h: noKeysToEdit = json.length(keysToEdit)]
[h, for(i,0,noKeysToEdit,1), code:
{
[key = json.get(keysToEdit,i) ]
[errorMessage = strformat("%{type} <b>%{macroName}</b>: Object does not contain key.") ]
[assert( json.contains(object,key), errorMessage) ]
[value = json.get(object,key) ]
[set(key,value) ]
[inputStringList = listAppend(inputStringList,strformat(" %{key} | %{value} | %{promt} | %{inputType} | %{options}"),"##") ]
}]
[h: input(inputStringList)]
[h: keysToEditVarList = json.toList(keysToEdit)]
[h: newObjectStrProp = strPropFromVars(keysToEditVarList,"UNSUFFIXED")]
[h: newObject = json.remove(json.fromStrProp(newObjectStrProp),"")]
[h: macro.return = newObject]
edit array udf
Code: Select all
[h: '<!-- function output: ArrayOfObjects
array.edit(ArrayOfObjects array, ArrayOfKeys keysToEdit) -->']
[h: macro = "array.edit" ]
[h: arguments = "(array,keysToEdit)" ]
[h: noArgsWanted = 2]
[h: '<!-- variables to get a nice output for error messages -->']
[h: type = "function" ]
[h: this = getMacroLocation() ]
[h: macroName = strformat("%{this}.%{macro}%{arguments}") ]
[h: '<!-- test if number of arguments is correct -->']
[h: noArgsInput = argCount()]
[h: errorMessage = strformat("<b>%{type} %{macroName}</b> needs <i><b>%{noArgsWanted}</b> </i>argument(s)<i> (actual arguments:%{noArgsInput})</i>")]
[h: assert( noArgsInput == noArgsWanted, errorMessage ) ]
[h: '<!-- get the arguments -->']
[h: array = arg(0)]
[h: errorMessage = strformat("%{type} <b>%{macroName}</b>: Array is empty.") ]
[h: assert ( !json.isEmpty(array), errorMessage) ]
[h: keysToEdit = arg(1) ]
[h: errorMessage = strformat("%{type} <b>%{macroName}</b>: No Keys to edit.") ]
[h: assert ( !json.isEmpty(keysToEdit), errorMessage) ]
[h: '<!-- just some reminders of the structure of things
arrayOfObjects [ object1, object2, object2 ]
object { "KEY1":"Value11", "KEY2":"Value12", "KEY3":"Value13" }
arrayOfKeys [ "KEY1", "KEY2", "KEY3" ]
[ for(counter,start,end,stepsize): command ]
input(variableName|value|prompt|inputType|options ] -->' ]
[h: noObjects = json.length(array) ]
[h: noKeysToEdit = json.length(keysToEdit)]
[h: '<-- outer loop: create a tab for each Object, variableName is tabVar%{i} -->']
[h: inputStringList = ""]
[h: promt = " "]
[h: options = ""]
[h: tabVarList = ""]
[h, for(i,0,noObjects,1), code:
{
[inputType = "TAB" ]
[tabVar = strformat("tabVar%{i}")]
[tabVarList = listAppend(tabVarList,tabVar)]
[tabLabel = strformat("Object%{i}") ]
[inputStringList = listAppend(inputStringList,strformat(" %{tabVar} | %{tabLabel} | %{promt} | %{inputType} | %{options}"),"##") ]
['<-- inner loop: create text fields for the Keys of the object -->']
[inputType = "TEXT" ]
[promt = " "]
[options = ""]
[object = json.get(array,i)]
[for(j,0,noKeysToEdit,1), code:
{
[key = json.get(keysToEdit,j) ]
[errorMessage = strformat("Object does not contain key.") ]
[assert( json.contains(object,key), errorMessage) ]
[value = json.get(object,key) ]
[set(key,value) ]
[inputStringList = listAppend(inputStringList,strformat(" %{key} | %{value} | %{promt} | %{inputType} | %{options}"),"##") ]
}]
}]
[h: input(inputStringList)]
[h: '<!-- input() gets StringPropertyLists as values for the tabVars
tabVar0 = "KEY1=newValueA1,KEY2="newValueA2,KEY3=newValueA3"
tabVar1 = "KEY1=newValueB1,KEY2="newValueB2,KEY3=newValueB3"
tabVar3 = "KEY1=newValueC1,KEY2="newValueC2,KEY3=newValueC3"
the names of the tabVars have been saved to tabVarList (in form of a StringList)
tabVarList = "tabVar0, tabVar1, tabVar2" -->']
[h: '<!-- strPropFromVars() puts the values of the tabVars in a StringPropertyList
inputAsStrPropList = " tabVar0 = KEY1=newValueA1 ## KEY2=newValueA2 ## KEY3=newValueA3 ## ;
tabVar1 = KEY1=newValueB1 ## KEY2=newValueB2 ## KEY3=newValueB3 ## ;
tabVar2 = KEY1=newValueC1 ## KEY2=newValueC2 ## KEY3=newValueC3 ## ;" -->']
[h: inputAsStrPropList = strPropFromVars(tabVarList,"UNSUFFIXED")]
[h: '<!-- json.fromStrProp() converts the StrPropList into a jsonObject
inputAsJsonObj = { "tabVar0":"KEY1=newValueA1 ## KEY2=newValueA2 ## KEY3=newValueA3 ##",
"tabVar1":"KEY1=newValueB1 ## KEY2=newValueB2 ## KEY3=newValueB3 ##",
"tabVar2":"KEY1=newValueC1 ## KEY2=newValueC2 ## KEY3=newValueC3 ##" } -->']
[h: inputAsJsonObj = json.remove(json.fromStrProp(inputAsStrPropList,";"),"")]
[h: arrayOut = array]
[h, for(i,0,noObjects,1), code:
{
['<!-- json.get() gets the oldObject out of the original array
oldObject = { "KEY1":"ValueA1", "KEY2":"ValueA2", "KEY3":"ValueA3" } [i=0] -->']
[oldObject = json.get(arrayOut,i)]
['<!-- json.get() gets the new values in form of a StrPropList
inputObjectStrPropList = "KEY1=newValueA1 ## KEY2=newValueA2 ## KEY3=newValueA3 ##" [i=0] -->' ]
[inputObjectStrPropList = json.get(inputAsJsonObj,strformat("tabVar%{i}"))]
['<!-- json.fromStringProp() converts the StrPropList into a jsonObject
inputObject = { "KEY1":"newValueA1", "KEY2":"newValueA2", "KEY3":"newValueA3" } [i=0] -->']
[inputObject = json.remove(json.fromStrProp(inputObjectStrPropList,"##"),"")]
['<!-- json.merge() merges the inputObject with the oldObject,
in case some keyValues have not been edited they will still appear in the newObject
newObject = { "KEY1":"newValueA1", "KEY2":"newValueA2", "KEY3":"newValueA3" } [i=0] -->']
[newObject = json.merge(oldObject,inputObject)]
['<!-- json.set() puts the newObject in place of the old object in the output array -->']
[arrayOut = json.set(arrayOut,i,newObject)]
}]
[h: macro.return = arrayOut]
test edit.object
Code: Select all
[h: '<!-- macro tests function
object.edit(object,keysToEdit) -->']
[h: object =json.set("", "KEY1", "Value1", "KEY2", "Value2", "KEY3", "Value3") ]
[h: keysToEdit = json.append("", "KEY1", "KEY2", "KEY3") ]
[h: newObject = object.edit(object,keysToEdit) ]
<b><u>Test:</u> function LIB:JSON object.edit(object,keysToEdit)</b><br>
<i>input: object =</i> [r:object]<br>
<i>keysToEdit = </i> [r:keysToEdit] <br>
<i>output = </i> [r:newObject]
test edit.array
Code: Select all
[h: '<!-- macro tests function
array.edit(array,keysToEdit) -->']
[h: objectA =json.set("", "KEY1", "A1", "KEY2", "A2", "KEY3", "A3") ]
[h: objectB =json.set("", "KEY1", "B1", "KEY2", "B2", "KEY3", "B3") ]
[h: objectC =json.set("", "KEY1", "C1", "KEY2", "C2", "KEY3", "C3") ]
[h: array = json.append("",objectA,objectB,objectC) ]
[h: keysToEdit = json.append("", "KEY1", "KEY2", "KEY3") ]
[h: newArray = array.edit(array,keysToEdit) ]
<b><u>Test:</u> function LIB:JSON array.edit(array,keysToEdit)</b><br>
<i>input: array is</i> [r:array]<br>
<i>keysToEdit is</i> [r:keysToEdit] <br>
<i>output is </i> [r:newArray]