NOTE: This version is now up on the development GIST. It is working for me, but as it is very new there are likely to be some cases where weird things will happen. Please let me know if you encounter anything strange when using these new tags. Also, the examples below just scratch the surface of what is possible with the --template and --replacement tags, especially when used in combination. I'll probably end up making another youtube video on these options at some point when I'm confident the code is generally sound.
2018-06-18 Version 3.7.7- Now supporting templates and replacement values! This is a pretty major update, and will stay on the development GIST for a while before moving to One-Click. PowerCards now supports two new reserved tags:
--template : Imports the tags defined in a handout called "PowerCard Templates". Templates are named sets of tags that can include parameters that get passed in by the content of the --template tag when the PowerCard is evaluated. The format for the Templates handout is similar to the PowerCard Formats handout: One line per template (they can wrap around as much as you like, but lines are ended with a carriage return). Templates start with a name, followed by a colon. Then a list of tags denoted by the standard -- prefix. A template can allow for value substitution by including ~#! in the line, where # is a parameter number starting at 0 (so, ~0! is the first parameter, ~1! is the second, and so on).
When a template tag is used in a PowerCard macro, it is in the format:
--template|TemplateName|Parameter0;Parameter1;Parameter2
@{} notation (like @{selected|character_name}, etc) is supported when calling the template, but not within the template itself (the API doesn't have the necessary information to deal with that notation as it is done by the chat server, which just passes IDs).
The position of the template tag in the PowerCard is preserved, so other lines can appear before or after it.
--replacement : Basically the opposite of templates. Another new handout called "PowerCard Replacements" can define replacement sets by name, followed by a colon, followed by a list of replacement keys and values. Key/Value pairs are separated from each other with semicolons, and keys and values themselves are separated by vertical bars (|).
A replacement tag will look at all of the other tags in the PowerCard and replace the keys with the given values. Keys in a PowerCard are denoted with ~keyname$ notation (start with a ~ and end with a $).
Both --template and --replacement can be used multiple times with the "Same Tag" modifier (--template*1, --template*2, etc). They can also be used together. All --template lines are processed first, then all --replacement lines, so values passed in as parameters to templates could be specified by replacement entries.
Multiple uses of the replacement tag are cumulative, with earliest definition of a replacement key being the one that will get used.
Note on Inline Rolls : Inline rolls are processed by the chat server before being sent to PowerCards, but PowerCards will reparse inline rolls if they are added to the card after the initial chat server processing. For this reason, inline rolls work normally in templates (since PowerCards itself is adding them to the card), but not in replacements directly. It IS possible to define replacements that substitute in [[ and ]] so rolls can be generated by replacements.
Time for some examples. All of these will use the following templates handout:
weapon:--name|~0! --leftsub|~1! --rightsub|~2! --Attack:|[[ [$Atk] ~3! ]] vs AC ~4! --Damage|[[ [$Dmg] ~5! ]]
character:--name|~0! --attribute_summary|~1! --ogl_pc_attack_list|~1! --spell_slots|~1! --spell_list|~1!
description:--!desc|~0!
And the following replacements handout:
Kara:Name|Kara;Weapon|Shillelagh;DType|bludgeoning;DamageDie|1d8;CritDie|2d8
Skeleton:M_Name|Skeleton;M_AC|12;M_HP|12;C_HP|12
RollVars:RB|[[;RE|]]
This card:
!power {{
--template*1|weapon|Longsword;Melee Attack; 5 ft. Reach;2d20kh1;@{target|AC};1d8+@{selected|strength_mod}
}}Will use the "weapon" template, passing in "Longsword" for parameter ~0!, "Melee Attack" for parameter ~1!, etc. The output is:
We can combine templates and replacement values as well:
!power {{
--replacement|Kara
--template*1|weapon|~Name$ attacks with ~Weapon$;Melee Attack; 5 ft. Reach;2d20kh1;@{target|AC};~DamageDie$ + @{selected|strength_mod}
}}which gives:
Here is a card that includes conditional hit or miss logic:
!power {{
--replacement*1|Kara
--replacement*2|Skeleton
--replacement*3|RollVars
--name|~Name$ attacks ~M_Name$
--Attack|~Name$ attacks ~M_Name$ with ~Weapon$ [[ [$Atk] 1d20 + @{selected|strength_mod} [Strength] + @{selected|pb} [Proficiency] ]] vs AC ~M_AC$
--hroll|~RB$ [$Dmg] ~DamageDie$ ~RE$, ~RB$ [$Crit] ~CritDie$ ~RE$
--?? $Atk < ~M_AC$ ??Miss|The attack missed!
--?? $Atk >= ~M_AC$ AND $Atk.base <> 20 ??Hit|~Name$ deals [^Dmg] ~DType$ damage to ~M_Name$.
--?? $Atk.base == 20 ??Critical Hit|~Name$ deals [^Crit] ~DType$ damage to ~M_Name$.
}}which, as you would expect produces something like:
One important thing to see here is how the ~RB$ and ~RE$ replacements are used to generate [[ and ]] so that we can create an inline roll that uses a replacement variable inside it. If we tried to just use [[ and ]] in the PowerCard macro, the chat server would throw an error because it doesn't know what ~DamageDie$ is.
Going a bit further, if we add the following to the templates handout:
AttackConds:--?? $Atk < ~M_AC$ ??Miss|The attack missed! --?? $Atk >= ~M_AC$ AND $Atk.base <> 20 ??Hit|~Name$ deals [^Dmg] ~DType$ damage to ~M_Name$. --?? $Atk.base == 20 ??Critical Hit|~Name$ deals [^Crit] ~DType$ damage to ~M_Name$.
We can use that template instead of the three conditional lines:
!power {{
--replacement*1|Kara
--replacement*2|Skeleton
--replacement*3|RollVars
--name|~Name$ attacks ~M_Name$
--Attack|~Name$ attacks ~M_Name$ with ~Weapon$ [[ [$Atk] 1d20 + @{selected|strength_mod} [Strength] + @{selected|pb} [Proficiency] ]] vs AC ~M_AC$
--hroll|~RB$ [$Dmg] ~DamageDie$ ~RE$, ~RB$ [$Crit] ~CritDie$ ~RE$
--template|AttackConds
}} Potentially saving quite a bit of entry and maintenance in macros.