What I'm trying to end up with is a macro button on the token that just contains the variables needed to define the power. When clicked, the macro passes those variables to an attack macro on the Lib token, which opens a dialog window for number of targets, conditional bonuses, etc. I'm trying to do this without using Lib properties to store the power variables, so one could take that token and drop it in another campaign without having to worry about calling on non-existent props. The only Lib property in use is the base "blank power" template that is initially called in the input macro.
Empty Power Template
Code: Select all
{"pname":"Power Name", "pflavor":"--none--","usage":"at-will","recharge":"","action":"standard","rangetype":"melee","isAOE":0,"targType":"single creature","rangeText":"melee weapon","attBonus":"StrBonus","defense":"AC","woi":0,"slot":"main","dmgDice":"1MHW+Str","critDice":0,"dmgType":"untyped","trigger":"--none--","hit":"--none--","miss":"--none--","effect":"--none--","sustain":"--none--","special":"--none--", "mto":0, "ppCost":0}
The macro sequence runs as follows:
1.) Player clicks New Attack Power on the token.
2.) "New Attack Power calls the UDF esh.inputAttackPower, which opens an input dialog to specify the power.
3.) Player fills out the dialog and clicks OK
4.) esh.inputAttackPower creates a JSON, which it passes to the UDF esh.buildAttackMacro
esh.inputAttackPower output
Code: Select all
[h:macroBuilderInfo = json.set(template, "pname", pname, "pflavor", flavor, "usage", usage, "recharge", recharge, "action", action, "rangetype", rangetype, "isAOE", numtargets, "targType", targType, "rangeText", rangeText, "attBonus", attBonus, "defense", defense, "woi", woi, "slot", slot, "dmgDice", dmgDice, "critDice", critDice, "dmgType", dmgType, "trigger", trigger, "hit", hit, "miss", miss, "effect", effect, "sustain", sustain, "special", special, "mto", mto, "ppCost", ppCost)]
[h:esh.buildAttackMacro(macroBuilderInfo)]
Error Message
Code: Select all
java.lang.NullPointerException error executing expression h,finalCmd = strformat('%{cmdvars}%{n}%{n}%{cmdJSONbuilder}%{n}%{n}%{cmdpdata}%{n}%{n}%{cmdargbuilder}%{n}%{cmdAttackDialog}').
esh.buildAttackMacro (full code)
Code: Select all
[h:info = arg(0)]
<!-- check that the incoming data is just one object -->
[h,if(argCount() != 1): assert(0, "MacroBuilder requires exactly one argument", 0); jsonObject = arg(0)]
<!-- Convert the JSON object to a series of variables & assign values to those variables -->
[h:varList=json.fields(jsonObject)]
[h,foreach(var,varList),CODE:
{
[value = json.get(jsonObject,var)]
[set(var,value)]
}]
<!-- Create a JSON object to define macro button label/group/sort -->
[h:label = esh.getLabel(usage, rangetype, pname, action, recharge, trigger)]
[h:props = macro.return]
[h,switch(lower(usage)):
case "at-will": pcolor = "green";
case "encounter": pcolor="red";
case "daily": pcolor="black";
case "recharge": pcolor = "blue"]
[h:fcolor="white"]
[h:n = decode("%0A")]
<!-- Create a string to define the macro button tooltip -->
[h:"Generating tooltip/card"]
[h,if(trigger == "--none--"): trigPart = ""; trigPart = strformat("<b>Trigger</b>: %{trigger}<br>")]
[h,if(hit == "--none--"): hitPart = strformat("<b>Hit</b>: %{dmgDice} %{dmgType} damage<br>"); hitPart = strformat("<b>Hit</b>: %{dmgDice} %{dmgType} damage; %{hit}<br>")]
[h,if(miss == "--none--"): missPart = ""; missPart = strformat("<b>Miss</b>: %{miss}<br>")]
[h,if(effect == "--none--"): effectPart = ""; effectPart = strformat("<b>Effect</b>: %{effect}<br>")]
[attPart = strformat("<b>Attack</b>: %{attBonus} vs. %{defense} (%{rangeText})<br>")]
[targPart = strformat("<b>Target</b>: %{targType}<br>")]
[h,if(sustain == "--none--"): sustPart = ""; sustPart = strformat("<b>Sustain</b>: %{sustain}<br>")]
[h,if(special == "--none--"): specPart = ""; specPart = strformat("<b>Special</b>: %{special}")]
[h:pct2 = strformat("%{trigPart}%{attPart}%{targPart}%{hitPart}%{missPart}%{effectPart}%{sustPart}%{specPart}")]
<!-- Create a string to define the power variables -->
[h:cmdvars = strformat('[h:pname = "%{pname}"]%{n}[h:usage="%{usage}"]%{n}[h:recharge="%{recharge}"]%{n}[h:action="%{action}"]%{n}[h:rangetype="%{rangetype}"]%{n}[h:isAOE=%{isAOE}]%{n}[h:targType="%{targType}"]%{n}[h:rangeText="%{rangeText}"]%{n}[h:attBonus="%{attBonus}"]%{n}[h:defense="%{defense}"]%{n}[h:woi=%{woi}]%{n}[h:slot="%{slot}"]%{n}[h:dmgDice="%{dmgDice}"]%{n}[h:critDice="%{critDice}"]%{n}[h:dmgType="%{dmgType}"]%{n}[h:trigger="%{trigger}"]%{n}[h:hit="%{hit}"]%{n}[h:miss="%{miss}"]%{n}[h:effect="%{effect}"]%{n}[h:sustain="%{sustain}"]%{n}[h:special="%{special}"]%{n}[h:mto=%{mto}]%{n}[h:ppCost=%{ppCost}]%{n}%{n}[h:pcolor="%{pcolor}"]%{n}[h:fcolor="%{fcolor}"]%{n}%{n}[h,if(dmgType != "untyped"):dtype = dmgType; dtype = ""]<!--Display cleanup so it does not say "damage damage"-->%{n}%{n}[h:pflavor="%{pflavor}"]%{n}[h:pct2="%{pct2}"]%{n}')]
<!-- Stick the power variables in a JSON -->
[h:cmdJSONbuilder = strformat('[h:powerData = json.set("{}", "pname", pname, "pflavor", pflavor, "usage", usage, "recharge", recharge, "action", action, "rangetype", rangetype, "isAOE", isAOE, "targType", targType, "rangeText", rangeText, "attBonus", attBonus, "defense", defense, "woi", woi, "slot", slot, "dmgDice", dmgDice, "critDice", critDice, "dmgType", dmgType, "trigger", trigger, "hit", hit, "miss", miss, "effect", effect, "sustain", sustain, "special", special, "mto", mto, "ppCost", ppCost)]')]
<!-- Define more tooltip data -->
[h:pct = strformat("<table width=300 bgcolor=white><tr bgcolor=%{pcolor} color=%{fcolor}><td>%{pname} (%{action})</td></tr><tr><td><b>Trigger</b>: %{trigger}<br><b>Attack</b>: %{attBonus} vs. %{defense} (%{rangeText})<br><b>Hit</b>: %{dmgDice} %{dmgType} damage; %{hit}<br><b>Miss</b>: %{miss}<br><b>Effect</b>: %{effect}<br><b>Special</b>: %{special}</td></tr></table>")]
<!-- define a Power Card (to be linked from the chat display... theoretically) -->
[h:cmdpdata = '[h:pCardTable= strformat("<table width=400 bgcolor=white><tr bgcolor=%{pcolor} color=%{fcolor}><td><h4>%{pname} (%{action})</h4></td></tr><tr><td>%{pct2}</td></tr></table>")]']
<!-- define macro args for opening attack dialog -->
[h:cmdargbuilder = strformat('[h:token=getName()]%{n}[h:dialogArgs = json.append("[]", token, pcardtable, getMacroName(), powerData)]')]
<!-- define which macro to call when power is used -->
[h:cmdAttackDialog=strformat('%{n}{[macro("esh.showAttackDialog@Lib:MacroControl"):dialogArgs]%{n}}]')]
<!-- combine all of the above into the command parameter for createMacro ERROR HERE? -->
[h,finalCmd = strformat('%{cmdvars}%{n}%{n}%{cmdJSONbuilder}%{n}%{n}%{cmdpdata}%{n}%{n}%{cmdargbuilder}%{n}%{cmdAttackDialog}')]
<!-- check for existing macro with this label & delete if present -->
[h,if(hasMacro(label)),CODE:
{
[h:indexes = getMacroIndexes(label)]
[foreach(index, indexes): removeMacro(index)]
}]
<!-- set tooltip for createMacro -->
[h:tooltip = strformat("<html>%{pct}</html>")]
[h:tooltip2 = strformat("<html><p width=300>%{pct2}</p></html>")]]
[h:props = json.set(props, "tooltip", tooltip2)]
<!-- create macro using all of the above -->
[h:createMacro(label, finalCmd, props)]