The second question is about a data structure I'm thinking about and I'd like to know if it exists. If it doesn't, is there a way to get the same effect? Here's what I want:
Code: Select all
{"1,2,3":5, "4,5,6,7":15, "8":35,...}
Moderators: dorpond, trevor, Azhrei, giliath, jay, Mr.Ice
Code: Select all
{"1,2,3":5, "4,5,6,7":15, "8":35,...}
Code: Select all
{"1":5, "2": 5, "3":5, "4":15, "5":15, "6":15, "7":15, "8":35,...}
Yeah, there's nothing wrong with that structure, but depending on the data values and number of values there's probably a more efficient way of doing it. It may help to get a little perspective on the data you're looking up and what you want to get out of it.Barlie wrote:I guess I have 2 questions here. The first, is there a function that allows you to check and see if something is an element of an array?
The second question is about a data structure I'm thinking about and I'd like to know if it exists. If it doesn't, is there a way to get the same effect? Here's what I want:
So lets say I have a numeric value, I want to run a foreach() loop to check every "key" in the above object and see if my numeric value is an element of any of the "keys". If it is, I want the value of that "key" to be returned. Is this possible?Code: Select all
{"1,2,3":5, "4,5,6,7":15, "8":35,...}
It looks like listContains() or listFind() might do what I want. Lets say I have an array of numbers (1, 2, 3,....50), and I want to check if say, 21 is in that array. The function doing it would return 1 if 21 is in that array, or 0 if it's not.wolph42 wrote:1. I don't understand the question can you give an example.
I'm building a character sheet for 2nd edition AD&D. What I want from it is for all values dependent on ability scores to be filled out automatically once the ability scores have been filled out on a token's properties tab. For the strength ability score, the table looks like this: http://www.ancientscrossroads.com/adnd_ ... _table.htm. Focusing in on the "Wgt. Allow" column, The values in that column are the maximum weight that a character can carry before he experiences some level of encumbrance (which effects his movement rate, fatigue, etc.). The level of encumbranced by the character depends on how much weight he is carrying above the "Wgt. Allow" value for his strength score.aliasmask wrote: Yeah, there's nothing wrong with that structure, but depending on the data values and number of values there's probably a more efficient way of doing it. It may help to get a little perspective on the data you're looking up and what you want to get out of it.
I considered doing it that way until I ran into the exceptional strength scores. Those are the strength scores between 18 and 19 written as 18/01, 18/02, 18/03,...,18/100. Is it better to reorder the data that way considering those exceptional strength scores?CoveredInFish wrote:Its possible. Dont have time to go in detail but you'll probably need Wiki: json.fields() and Wiki: json.contains() / Wiki: listContains().
I really doubt its efficient though. Much easier would probably be to reorder your data like thisEven though I have to handle a bigger data element I have direct access and the routines to look up data are shorter, easier=more failsafe and probably faster.Code: Select all
{"1":5, "2": 5, "3":5, "4":15, "5":15, "6":15, "7":15, "8":35,...}
Code: Select all
{
"1": {
"str": 1,
"hitProb": -5,
"damageAdj": -4,
"weight": 1,
"maxPress": 3,
"openDoors": 1,
"bendLift": 0,
"note": ""
},
"2": {
"str": 2,
"hitProb": -3,
"damageAdj": -2,
"weight": 1,
"maxPress": 5,
"openDoors": 1,
"bendLift": 0,
"note": ""
},
"3": {
"str": 3,
"hitProb": -3,
"damageAdj": -1,
"weight": 5,
"maxPress": 10,
"openDoors": 2,
"bendLift": 0,
"note": ""
},
"5": {
"str": "4-5",
"hitProb": -2,
"damageAdj": -1,
"weight": 10,
"maxPress": 25,
"openDoors": 3,
"bendLift": 0,
"note": ""
},
"7": {
"str": "6-7",
"hitProb": -1,
"damageAdj": 0,
"weight": 20,
"maxPress": 55,
"openDoors": 4,
"bendLift": 0,
"note": ""
},
"9": {
"str": "8-9",
"hitProb": 0,
"damageAdj": 0,
"weight": 35,
"maxPress": 90,
"openDoors": 5,
"bendLift": 1,
"note": ""
},
"11": {
"str": "10-11",
"hitProb": 0,
"damageAdj": 0,
"weight": 40,
"maxPress": 115,
"openDoors": 6,
"bendLift": 2,
"note": ""
},
"13": {
"str": "12-13",
"hitProb": 0,
"damageAdj": 0,
"weight": 45,
"maxPress": 140,
"openDoors": 7,
"bendLift": 4,
"note": ""
},
"15": {
"str": "14-15",
"hitProb": 0,
"damageAdj": 0,
"weight": 55,
"maxPress": 170,
"openDoors": 8,
"bendLift": 7,
"note": ""
},
"16": {
"str": 16,
"hitProb": 0,
"damageAdj": 1,
"weight": 70,
"maxPress": 195,
"openDoors": 9,
"bendLift": 10,
"note": ""
},
"17": {
"str": 17,
"hitProb": 1,
"damageAdj": 1,
"weight": 85,
"maxPress": 220,
"openDoors": 10,
"bendLift": 13,
"note": ""
},
"18": {
"str": 18,
"hitProb": 1,
"damageAdj": 2,
"weight": 110,
"maxPress": 255,
"openDoors": 11,
"bendLift": 16,
"note": ""
},
"18.05": {
"str": "18/01-50",
"hitProb": 1,
"damageAdj": 3,
"weight": 135,
"maxPress": 280,
"openDoors": 12,
"bendLift": 20,
"note": ""
},
"18.075": {
"str": "18/51-75",
"hitProb": 2,
"damageAdj": 3,
"weight": 160,
"maxPress": 305,
"openDoors": 13,
"bendLift": 25,
"note": ""
},
"18.09": {
"str": "18/76-90",
"hitProb": 2,
"damageAdj": 4,
"weight": 185,
"maxPress": 330,
"openDoors": 14,
"bendLift": 30,
"note": ""
},
"18.099": {
"str": "18/91-99",
"hitProb": 2,
"damageAdj": 5,
"weight": 235,
"maxPress": 380,
"openDoors": "15(3)",
"bendLift": 35,
"note": ""
},
"18.1": {
"str": "18/100",
"hitProb": 3,
"damageAdj": 6,
"weight": 335,
"maxPress": 480,
"openDoors": "16(6)",
"bendLift": 40,
"note": ""
},
"19": {
"str": 19,
"hitProb": 3,
"damageAdj": 7,
"weight": 485,
"maxPress": 640,
"openDoors": "16(8)",
"bendLift": 50,
"note": "Hill Giant Strength"
},
"20": {
"str": 20,
"hitProb": 3,
"damageAdj": 8,
"weight": 535,
"maxPress": 700,
"openDoors": "17(10)",
"bendLift": 60,
"note": "Stone Giant Strength"
},
"21": {
"str": 21,
"hitProb": 4,
"damageAdj": 9,
"weight": 635,
"maxPress": 810,
"openDoors": "17(12)",
"bendLift": 70,
"note": "Frost Giant Strength"
},
"22": {
"str": 22,
"hitProb": 4,
"damageAdj": 10,
"weight": 785,
"maxPress": 970,
"openDoors": "18(14)",
"bendLift": 80,
"note": "Fire Giant Strength"
},
"23": {
"str": 23,
"hitProb": 5,
"damageAdj": 11,
"weight": 935,
"maxPress": 1130,
"openDoors": "18(16)",
"bendLift": 90,
"note": "Cloud Giant Strength"
},
"24": {
"str": 24,
"hitProb": 6,
"damageAdj": 12,
"weight": 1235,
"maxPress": 1440,
"openDoors": "19(17)",
"bendLift": 95,
"note": "Storm Giant Strength"
},
"25": {
"str": 25,
"hitProb": 7,
"damageAdj": 14,
"weight": 1535,
"maxPress": 1750,
"openDoors": "19(18)",
"bendLift": 99,
"note": "Titan Strength"
}
}
Code: Select all
@@ @Test Get Data
[H: strList = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18/xx,19,20,21,22,23,24,25"]
[H: abort(input(strformat("str.input|%{strList}|Select Strength|LIST|VALUE=STRING"),"str.percent|0|Enter Percent for 18/xx Strength|TEXT"))]
[H, if(! isNumber(str.input)), code: {
[H: percent = min(100,max(1,str.percent))]
[H: strengthFormat = strformat("18/%{percent}")]
[H: strData = am.xx.getStrengthData(18,percent)]
};{
[H: strengthFormat = str.input]
[H: strData = am.xx.getStrengthData(str.input)]
}]
[dialog("Strength Data"):{
<b>STRENGTH: [r: strengthFormat]</b><br>
<pre>[R: json.indent(replace(strData,"<","<"))]</pre>
}]
!!
@@ @initStrengthChart
<!-- initStrengthChart()
This function will put the strength chart in to json and save to token. Object will be value:obj where value is the max strength
for that category. Added NA to end of raw data so listGet works properly. Removed % from openDoors in raw data because we dont
need. The percentage values should be divided by 1000 rather than 100 because 18/00 is not equal to 19 strength and the math
would convert it to that if not divided by 1000.
-->
[H: rawChart = "1 -5 -4 1 3 1 0 NA
2 -3 -2 1 5 1 0 NA
3 -3 -1 5 10 2 0 NA
4-5 -2 -1 10 25 3 0 NA
6-7 -1 0 20 55 4 0 NA
8-9 0 0 35 90 5 1 NA
10-11 0 0 40 115 6 2 NA
12-13 0 0 45 140 7 4 NA
14-15 0 0 55 170 8 7 NA
16 0 +1 70 195 9 10 NA
17 +1 +1 85 220 10 13 NA
18 +1 +2 110 255 11 16 NA
18/01-50 +1 +3 135 280 12 20 NA
18/51-75 +2 +3 160 305 13 25 NA
18/76-90 +2 +4 185 330 14 30 NA
18/91-99 +2 +5 235 380 15(3) 35 NA
18/100 +3 +6 335 480 16(6) 40 NA
19 +3 +7 485 640 16(8) 50 Hill Giant Strength
20 +3 +8 535 700 17(10) 60 Stone Giant Strength
21 +4 +9 635 810 17(12) 70 Frost Giant Strength
22 +4 +10 785 970 18(14) 80 Fire Giant Strength
23 +5 +11 935 1130 18(16) 90 Cloud Giant Strength
24 +6 +12 1235 1440 19(17) 95 Storm Giant Strength
25 +7 +14 1535 1750 19(18) 99 Titan Strength"]
[H: CR = decode("%0D")]
[H: EOL = decode("%0A")]
[H: TAB = decode("%09")]
<!-- clear Carriage return characters -->
[H: rawChart = replace(rawChart,CR,"")]
<!-- turn data in to json array -->
[H: rawChart = json.fromList(rawChart,EOL)]
<!-- read and build chart -->
[H: strengthChart = "{}"]
[H: chartKeys = json.append("","str","hitProb","damageAdj","weight","maxPress","openDoors","bendLift","note")]
[H, foreach(line,rawChart), code: {
[H: obj = "{}"]
[H, foreach(key,chartKeys), code: {
[H: value = listGet(line,roll.count,TAB)]
[H, if(value == "NA"): value = ""]
[H: obj = json.set(obj,key,value)]
}]
[H: keyIndex = listGet(line,0,TAB)]
[H: value = keyIndex]
[H, if(! isNumber(keyIndex)), code: {
[H: hasRange = listCount(keyIndex,"-") -1]
[H: hasSubRange = listCount(keyIndex,"/") -1]
[H, if(hasSubRange && ! hasRange): value = 18.1]
[H, if(hasRange && ! hasSubRange): value = listGet(keyIndex,1,"-")]
[H, if(hasRange && hasSubRange): value = 18 + (number(listGet(keyIndex,1,"-")) / 1000)]
};{}]
[H: strengthChart = json.set(strengthChart,value,obj)]
}]
[H: setLibProperty("strengthChart",strengthChart)]
[R: "<b>Strength Chart Loaded</b>"]
<!-- added for debugging -->
[dialog("D"):{<pre>[R: json.indent(replace(strengthChart,"<","<"))]</pre>}]
!!
@@ @getStrengthData
<!-- getStrengthData(strength,percent): strData
strength - base strength value 1 to 25
percent - (optional) for 18 strength with a percentile value
strData - object of strength data
This function will return the data from the strength chart.
-->
[H: str = arg(0)]
[H, if(argCount() >= 2): percent = arg(1); percent = 0]
[H: strengthChart = getLibProperty("strengthChart")]
[H: strengthIndex = json.fields(strengthChart)]
[H: strIndex = str + (percent/1000)]
[H: strData = json.get(strengthChart,strIndex)]
[H, if(json.isEmpty(strData)), code: {
[H: lastIndex = 0]
[H, foreach(index,strengthIndex), code: {
[H, if(strIndex > lastIndex && strIndex <= index): strData = json.get(strengthChart,index)]
[H: lastIndex = index]
}]
};{}]
[H: macro.return = strData]
!!
@@ @onCampaignLoad
@PROPS@ fontColor=yellow ; autoExecute=true ; fontSize=11pt ; sortBy= ; color=red ; playerEditable=false ; applyToSelected=false ; group= ; tooltip= ; minWidth=94 ;
<!-- onCampaignLoad()
This function will define all the macros on this lib token in to functions (UDF). This macro may be modified to exclude specific macros
or change the ignoreOutput and newScope settings. See comments below. User should make their own personal prefix to the function names
to represent this lib token. Usual format is "initials.code." where initials is programmers initials and code is specific to lib
token. To call a function, am.xx.macroName(). Since all output is ignored you should use broadcast() or pass back your output in
a variable to original macro clicked.
-->
<!-- In order to call a function, you must include the prefix before the macro name. This helps with compatibility with other library tokens -->
[H: prefix = "am.xx."]
[H: thisLib = getMacroLocation()]
<!-- Define functions HERE with options other than ignoreOutput = 1 and NewScope = 1. For example:
defineFunction(functionName,fullMacroName,ignoreOutput,newScope)
functionName - I recommend to still include the prefix in the name.
fullMacroName - macro name must include lib location, currently stored in "thisLib"
ignoreOutput - comments and any other raw output like html not in variables is ignored when set to 1
newScope - default 1, when set to 0 the macro can use variables from calling macro. Not recommended in most cases.
-->
[H: defineFunction(prefix+"onCampaignLoad","onCampaignLoad@"+thisLib,0,1)]
<!-- List functions names here to exclude from UDF definitions -->
[H: excludeList = json.append("","(new)","onCampaignLoad")]
<!-- default settings for all functions -->
[H: ignoreOutput = 1]
[H: newScope = 1]
<!-- This will exclude all macros with HTML formatting and non-variable valid characters in the name, including spaces.
Otherwise the html will be stripped and variable-valid characters will be used in the function definition. -->
[H: excludeHTMLMacros = 1]
<!-- get all the macro names from library and remove the excluded names -->
[H: allMacros = json.difference(getMacros("json"),excludeList)]
<!-- Define functions from the macro names. Already defined function will be ignored. -->
[H, foreach(macroName,allMacros), code: {
[H: functionName = replace(macroName,"<[^>]*?>","")]
[H: functionName = replace(functionName,"[^a-zA-Z0-9_.]","")]
[H: cleanFunctionName = strformat("%{prefix}%{functionName}")]
[H, if(excludeHTMLMacros && macroName != functionName): exclude = 1; exclude = 0]
[H, if(! isFunctionDefined(cleanFunctionName) && ! exclude): defineFunction(cleanFunctionName,strformat("%{macroName}@%{thisLib}"),ignoreOutput,newScope)]
}]
!!