I worked on a functioning statblock importer that works with D&D Beyond with the help of AliasMask and several others in this community. Although you may have different properties etc for your campaign tokens. I am no expert, never the less, this should work.
Code: Select all
[H: ids = getSelected()]
[H: abort(if(ids == "", 0, 1))]
[H: status=input("junk|Statblock info from Creature Name through Treasure line of Ecology (if it exists). Don't include flavor text/background/descriptions.||LABEL|SPAN=TRUE","junk|If Ecology section comes before Special Abilities, be sure to include Special Abilities section as well. Still no flavor text.||LABEL|SPAN=TRUE","statblock|Insert 5E statblock here|Enter statblock|TEXT|WIDTH=40")]
[H: abort(if(status < 1, 0, 1))]
[H: CRLF = decode("%0D%0A")]
[H: setPropertyType("5E-NPC")]
[H: GP=getProperty("dnd.weapons")]
[H: propnames = getPropertyNames()]
[H, foreach(propname,propnames),CODE: {
[resetProperty(propname)]
}]
[H: setProperty("dnd.weapons", GP)]
[H: '<!-- Lets clean up those pesky non-ascii characters! -->']
[H: statblock = replace(statblock, "\\xD7", "x")]
[H: statblock = replace(statblock, "\\u2013", "-")]
[H: statblock = replace(statblock, "\\u2014", "-")]
[H: statblock = replace(statblock, "%E2%80%93", "-")]
[H: statblock = replace(statblock, " ", " ")]
[H: '<!-- change brackets and braces to parens to avoid stat sheet variable input error -->']
[H: statblock = replace(statblock, "[\\[\\{]","(")]
[H: statblock = replace(statblock, "[\\]\\}]",")")]
[H: '<!-- Start formatting imported statblock and set it to GM notes -->']
[H: '<!-- Search for lines and sections of statblock individually -->']
[H: NameSearch = strfind(statblock, "(.*?)(CoS|OotA|SKT|PotA|ToD|VGM|MM|Tiny|Tags|Small|Medium|Large|Huge|Gargantuan)")]
[H: THEName= getGroup(NameSearch, 1, 1)]
[H: NameSearch=trim(THEName)]
[H: setName(trim(THEName))]
[H: setTokenShape("Top down")]
<!-- get stats -->
[H: regex1 = "((\\d+) *[(][\\d +-]+[)]\\t*){6}"]
[H: regex2 = "(\\d+) *[(][\\d +-]+[)]\\t*"]
[H: id = strfind(statblock,regex1)]
[H, if(getFindCount(id)), code: {
[H: stats = json.append("[]","Strength","Dexterity","Constitution","Intelligence","Wisdom","Charisma")]
[H: match = getGroup(id,1,0)]
[H: id = strfind(match,regex2)]
[H, foreach(stat,stats), code: {
[H: set(stat,getGroup(id,roll.count+1,1))]
}]
};{
[H: id = strfind(statblock, "(?i)(?<!base )ft.*?STR.?([0-9]*).+?DEX.?([0-9]*).+?CON.?([0-9]*).+?INT.?([0-9]*).+?WIS.?([0-9]*).+?CHA.?([0-9]*)")]
[H, IF(0< getFindCount(id)), CODE: {
[Strength=getGroup(id, 1, 1)]
[IF(Strength==""):Strength=10]
[Dexterity=getGroup(id, 1, 2)]
[IF(Dexterity==""):Dexterity=10]
[Constitution=getGroup(id, 1, 3)]
[IF(Constitution==""):Constitution=10]
[Intelligence=getGroup(id, 1, 4)]
[IF(Intelligence==""):Intelligence=10]
[Wisdom=getGroup(id, 1, 5)]
[IF(Wisdom==""):Wisdom=10]
[Charisma=getGroup(id, 1, 6)]
[IF(Charisma==""):Charisma=10]
[output="Str: "+Strength+", Dex: "+Dexterity+", Con: "+Constitution+", Int: "+Intelligence+", Wis: "+Wisdom+", Cha: "+Charisma+"<br>"]
}]
}]
[H: '<!-- STATS END -->']
[H: '<!-- SET AC -->']
[H: id = strfind(statblock, "(?i)(?<!Hit )Armor Class.([0-9]*) (.*?)\Hit Points ")]
[H, IF(0< getFindCount(id)), CODE: {
[AC=getGroup(id, 1, 1)]
[ACC=getGroup(id, 1, 2)]
[IF(AC==0):AC=10+Dx]
[AC=""+AC+" "+ACC+""]
}]
[H: '<!-- SET Speed -->']
[H: id = strfind(statblock, "(?i)(?<!STR )(Speed.|burrow.|climb.|fly.|swim.)([0-9]+)")]
[H, IF(0< getFindCount(id)), CODE: {
[Speed1=getGroup(id, 1, 2)]
[IF(Speed1==""): setProperty("Speed1","")]
[IF(Speed1!=""): Speed11=getGroup(id, 1, 2)]
[IF(Speed11==""): setProperty("Speed11","")]
[Speed1="Move: "+Speed1+""]
[Spd1=""+Speed11+""]
} ;{
[Speed1=""]
[Spd1=0]
}]
[H, IF(1< getFindCount(id)), CODE: {
[Speed2=getGroup(id, 2, 1)]
[IF(Speed2==""): setProperty("Speed2","")]
[IF(Speed2!=""): Speed22=getGroup(id, 2, 2)]
[IF(Speed22==""): setProperty("Speed22","")]
[Speed2=""+upper(Speed2,1) + ": "+Speed22+""]
[Spd2=""+Speed22+""]
};{
[Spd2=0]
}]
[H, IF(2< getFindCount(id)), CODE: {
[Speed3=getGroup(id, 3, 1)]
[IF(Speed3==""): setProperty("Speed3","")]
[IF(Speed3!=""): Speed33=getGroup(id, 3, 2)]
[IF(Speed33==""): setProperty("Speed33","")]
[Speed3=""+upper(Speed3,1) + ": "+Speed33+""]
[Spd3=""+Speed33+""]
};{
[Spd3=0]
}]
[H, IF(3< getFindCount(id)), CODE: {
[Speed4=getGroup(id, 4, 1)]
[IF(Speed4==""): setProperty("Speed4","")]
[IF(Speed4!=""): Speed44=getGroup(id, 4, 2)]
[IF(Speed44==""): setProperty("Speed44","")]
[Speed4=""+upper(Speed4,1) + ": "+Speed44+""]
[Spd4=""+Speed44+""]
};{
[Spd4=0]
}]
[H, IF(4< getFindCount(id)), CODE: {
[Speed5=getGroup(id, 5, 1)]
[IF(Speed5==""): setProperty("Speed5","")]
[IF(Speed5!=""): Speed55=getGroup(id, 5, 2)]
[IF(Speed55==""): setProperty("Speed55","")]
[Speed5=""+upper(Speed5,1) + ": "+Speed55+""]
[Spd5=""+Speed55+""]
};{
[Spd5=0]
}]
[h:Speed=" "+Speed1+" "+Speed2+" "+Speed3+" "+Speed4+" "+Speed5+"" ]
[h: Spd= Max(eval("Spd1"),eval("Spd2"),eval("Spd3"),eval("Spd4"),eval("Spd5"))]
[H: '<!-- SET Hit Points -->']
[H: id = strfind(statblock, "Hit Points (\\d+) [(]([^)]+)[)]")]
[H, IF(0< getFindCount(id)), CODE: {
[HP=getGroup(id, 1, 1)]
[MaxHP=getGroup(id, 1, 1)]
[HitDice=getGroup(id,1,2)]
}]
[H: '<!-- Hit Points END -->']
[H: '<!-- SET SIZE -->']
[H: id = strfind(statblock, "(Tiny|Small|Medium|Large|Huge|Gargantuan|\w-]+)")]
[H, IF(0< getFindCount(id)),CODE: {
[Size=getGroup(id, 1, 1)]
[setSize(Size)]
}]
[H: '<!-- SET TYPE -->']
[H: id = strfind(statblock, "(aberration.*?|beast.*?|celestial.*?|construct.*?|dragon.*?|elemental.*?|fey.*?|fiend.*?|giant.*?|humanoid.*?|monstrosity.*?|ooze.*?|plant.*?|undead.*?|-)\,")]
[H, IF(0< getFindCount(id)),CODE: {
[Type=getGroup(id, 1, 1)]
[Type=upper(Type, 1)]
}]
[H: '<!-- SET ALIGNMENT -->']
[H: id = strfind(statblock, "\,.(lawful.|neutral.|chaotic.|)(good|neutral|unaligned|evil|\w-]+)")]
[H, IF(0< getFindCount(id)),CODE: {
[Alignment1=getGroup(id, 1, 1)]
[Alignment2=getGroup(id, 1, 2)]
[Alignment1=upper(Alignment1,1)]
[Alignment2=upper(Alignment2,1)]
[Alignment1=trim(Alignment1,1)]
[Alignment2=trim(Alignment2,1)]
[IF(Alignment1==""): Alignment1=""]
[Alignment=""+Alignment1+" " + Alignment2+""]
}]
[H: id = strfind(statblock, "Passive Perception.([0-9]+)")]
[H, IF(0< getFindCount(id)), CODE: {
[pass=getGroup(id, 1, 1)]
[IF(pass>=0): setProperty("Passive Perception",pass)]
}]
[H: '<!-- Challenge BEGIN -->']
[H: id = strfind(statblock, "Challenge.([0-9]+)")]
[H, IF(0< getFindCount(id)), CODE: {
[CR=getGroup(id, 1, 1)]
[CR=trim(CR)]
[IF(CR<=4): setProperty("SkillDie",2)]
[IF(CR<=8&&CR>=5): setProperty("SkillDie",3)]
[IF(CR<=12&&CR>=9): setProperty("SkillDie",4)]
[IF(CR<=16&&CR>=13): setProperty("SkillDie",5)]
[IF(CR<=20&&CR>=17): setProperty("SkillDie",6)]
[IF(CR<=24&&CR>=21): setProperty("SkillDie",7)]
[IF(CR<=28&&CR>=25): setProperty("SkillDie",8)]
[IF(CR<=32&&CR>=29): setProperty("SkillDie",9)]
}]
[H: id = strfind(statblock, "Languages (.*) \Challenge")]
[H, IF(0< getFindCount(id)), CODE: {
[Lang1=getGroup(id, 1, 1)]
[Lang1 =trim(Lang1)]
[Lang1 =upper(Lang1,1)]
[IF(Lang1==""): setProperty("Lang1","")]
[Languages=" "+Lang1+""]
}]
[H: id = strfind(statblock, "(?i)\Damage Resistances?(.*?)(Damage Immunities|Condition Immunities|Senses)")]
[H, IF(0< getFindCount(id)), CODE: {
[Resist1=getGroup(id, 1, 1)]
[Resist1=trim(Resist1)]
[Resist1=upper(Resist1,1)]
[IF(Resist1==""): setProperty("Resistance","")]
[IF(Resist1!=""): setProperty("Resistance",Resist1)]
}]
[H: id = strfind(statblock, "(?i)\Damage Immunities?(.*?)(Condition Immunities|Senses)")]
[H, IF(0< getFindCount(id)), CODE: {
[Resist2=getGroup(id, 1, 1)]
[Resist2=trim(Resist2)]
[Resist2=upper(Resist2,1)]
[IF(Resist2==""): setProperty("Immunities","")]
[IF(Resist2!=""): setProperty("Immunities",Resist2)]
}]
[H: id = strfind(statblock, "(?i)\Condition Immunities?(.*?)(Senses)")]
[H, IF(0< getFindCount(id)), CODE: {
[Resist3=getGroup(id, 1, 1)]
[Resist3=trim(Resist3)]
[Resist3=upper(Resist3,1)]
[IF(Resist3==""): setProperty("Condition Immunities","")]
[IF(Resist3!=""): setProperty("Condition Immunities",Resist3)]
}]
[H: '<!-- SET SENSES AND SIGHT -->']
[h, IF(0==0), CODE:{
[H: id = strfind(statblock, "(Blindsight.|Darkvision.|Tremorsense.|Truesight.)([0-9]+)(.ft.).*?\,")]
[H, IF(0< getFindCount(id)), CODE: {
[Sense1=getGroup(id, 1, 1)]
[Sense2=getGroup(id, 1, 2)]
[Sense3=getGroup(id, 1, 3)]
[Sense1=trim(Sense1)]
[Sense2=trim(Sense2)]
[Sense3=trim(Sense3)]
[Sense1=upper(Sense1,1)]
[IF(Sense1==""): Sense1=""]
[IF(Sense2==""): Sense2=""]
[Senses=""+Sense1+" " + Sense2+" " + Sense3+" "]
[Sight1=(Sense1 +Sense2)]
[setSightType(Sight1)]
}]
[H, IF(2== getFindCount(id)), CODE: {
[Sense4=getGroup(id, 2, 1)]
[Sense5=getGroup(id, 2, 2)]
[Sense6=getGroup(id, 2, 3)]
[Sense4=trim(Sense4)]
[Sense5=trim(Sense5)]
[Sense6=trim(Sense6)]
[Sense4=upper(Sense4,1)]
[IF(Sense4==""): Sense4=""]
[IF(Sense5==""): Sense5=""]
[Senses=" "+Sense1+" " + Sense2+" " + Sense3+" " +Sense4+" " +Sense5+" " +Sense6+""]
[Sight2=(Sense4 +Sense5)]
[IF(Sense2>Sense5): setSightType(Sight1) ; setSightType(Sight2)]
}]
[IF(Senses==""): setProperty("Senses","")]
[IF(Senses==""): setHasSight(0)]
[IF(Senses!=""): setHasSight(1)]
}]
[H: '<!-- SET XP TO GM NAME -->']
[H: id = strfind(statblock, "Challenge.[0-9]+.(.*XP.)")]
[H, IF(0< getFindCount(id)), CODE: {
[XP=getGroup(id, 1, 1)]
[setGMName(XP)]
}]
[H: '<!-- HATE BARS -->']
[h: setBarVisible("Health", 0)]
[h: ids=getTokenNames()]
[h:gTok=getTokenImage()]
[h:iTok=getTokenHandout()]
[h:setProperty("PIC1",gTok)]
[h:setProperty("PIC2",iTok)]
[H: '<!-- GET SAVES---- GET SAVES---- GET SAVES---- GET SAVES---- GET SAVES---- GET SAVES--v>']
[H: ST1 = strfind(statblock, "(?i)(Str.?|Dex.?|Con.?|Int.?|Wis.?|Cha.?)[+]([0-9]+)")]
[H,count(getFindCount(ST1), ""), CODE:{
[SaveName=getGroup(ST1, roll.count+1, 1)]
[SaveNum=getGroup(ST1, roll.count+1, 2)]
[SaveName=trim(SaveName)]
[SaveNum=trim(SaveNum)]
[IF(SaveName=="Str"):SaveNam="Strength",SaveName=""]
[IF(SaveName=="Str"): SaveN=(St),SaveN=0]
[IF(SaveName=="Str"): srt=1,srt=1]
[IF(SaveName=="Dex"): SaveNam="Dexterity",SaveName=""]
[IF(SaveName=="Dex"): SaveN=(Dx),SaveN=0]
[IF(SaveName=="Dex"): srt=2,srt=2]
[IF(SaveName=="Con"): SaveNam="Constitution",SaveName=""]
[IF(SaveName=="Con"): SaveN=(Cn),SaveN=0]
[IF(SaveName=="Con"): srt=3,srt=3]
[IF(SaveName=="Int"): SaveNam="Intelligence",SaveName=""]
[IF(SaveName!="Int"): SaveNa="Intelligence",SaveNa=""]
[IF(SaveName=="Int"): SaveN=(In),SaveN=0]
[IF(SaveName=="Int"): srt=4,srt=4]
[IF(SaveName=="Wis"): SaveNam="Wisdom",SaveName=""]
[IF(SaveName=="Wis"): SaveN=(Ws),SaveN=0]
[IF(SaveName=="Wis"): srt=5,srt=5]
[IF(SaveName=="Cha"): SaveNam="Charisma",SaveName=""]
[IF(SaveName=="Cha"): SaveN=(Ch),SaveN=0]
[IF(SaveName=="Cha"): srt=6,srt=6]
[H,IF(SaveNum>=(SkillDie+SaveN)&&hasMacro(SaveNam)==0), CODE:{
[ButtonProps='{"color":"olive","sortBy":'+srt+',"fontColor":"black","group":"3.Saving Throws","minWidth":90}']
[h:CommandText2 = strformat('
[h:jsonData = json.set("{}", "SaveNum", "%{SaveNum}")] [MACRO("Mon'+SaveNam+'@Lib:CharacterSheet"):jsonData]')]
[tix="Meanwhile, behind the DM Screen, dice are rolled... "]
[tex="/self"]
[CommandText = strformat('
[MACRO("M'+SaveNam+'@Lib:CharacterSheet"):""]')]
[createMacro(SaveNam, tix+tex+decode(CommandText2), ButtonProps)]
}]
}]
[H,If(hasMacro("Strength")==1), CODE:{ };{
[h:jix="Strength"]
[tix="Meanwhile, behind the DM Screen, dice are rolled... "]
[ButtonProps3='{"color":"pink","fontColor":"black","sortBy":'+1+',"group":"3.Saving Throws","minWidth":90}']
[tex="/self"]
[CommandText3 = strformat('
[MACRO("'+jix+'@Lib:CharacterSheet"):""]')]
[createMacro(jix,tex+decode(CommandText3), ButtonProps3)]
}]
[H,If(hasMacro("Dexterity")==1), CODE:{ };{
[h:jix="Dexterity"]
[ButtonProps3='{"color":"pink","fontColor":"black","sortBy":'+2+',"group":"3.Saving Throws","minWidth":90}']
[tex="/self"]
[CommandText3 = strformat('
[MACRO("'+jix+'@Lib:CharacterSheet"):""]')]
[createMacro(jix, tex+decode(CommandText3), ButtonProps3)]
}]
[H,If(hasMacro("Constitution")==1), CODE:{ };{
[h:jix="Constitution"]
[ButtonProps3='{"color":"pink","fontColor":"black","sortBy":'+3+',"group":"3.Saving Throws","minWidth":90}']
[tex="/self"]
[CommandText3 = strformat('
[MACRO("'+jix+'@Lib:CharacterSheet"):""]')]
[createMacro(jix, tex+decode(CommandText3), ButtonProps3)]
}]
[H,If(hasMacro("Intelligence")==1), CODE:{ };{
[h:jix="Intelligence"]
[ButtonProps3='{"color":"pink","fontColor":"black","sortBy":'+4+',"group":"3.Saving Throws","minWidth":90}']
[tex="/self"]
[CommandText3 = strformat('
[MACRO("'+jix+'@Lib:CharacterSheet"):""]')]
[createMacro(jix, tex+decode(CommandText3), ButtonProps3)]
}]
[H,If(hasMacro("Wisdom")==1), CODE:{ };{
[h:jix="Wisdom"]
[ButtonProps3='{"color":"pink","fontColor":"black","sortBy":'+5+',"group":"3.Saving Throws","minWidth":90}']
[tex="/self"]
[CommandText3 = strformat('
[MACRO("'+jix+'@Lib:CharacterSheet"):""]')]
[createMacro(jix, tex+decode(CommandText3), ButtonProps3)]
}]
[H,If(hasMacro("Charisma")==1), CODE:{ };{
[h:jix="Charisma"]
[ButtonProps3='{"color":"pink","fontColor":"black","sortBy":'+6+',"group":"3.Saving Throws","minWidth":90}']
[tex="/self"]
[CommandText3 = strformat('
[MACRO("'+jix+'@Lib:CharacterSheet"):""]')]
[createMacro(jix, tex+decode(CommandText3), ButtonProps3)]
}]
[H: '<!-- ATTACKS BEGIN ---- ATTACKS BEGIN ---- ATTACKS BEGIN ---- ATTACKS BEGIN ---- ATTACKS BEGIN -->']
[H, IF(0==0), CODE: {
[MiscDamageBonus="0+0"]
[MiscDamageType=""]
[PrimaryStat="max(St,Dx)"]
[MagicBonus="0+0"]
[SpecialAbility=""]
[MiscAttackBonus="0"]
[MinimumCritRoll="20"]
[FlavorText=""]
[ButtonColor="black"]
[FontColor="white"]
[H: WN = strfind(statblock, "(Actions)*([A-z]+)\\. \Melee")]
[H, IF(0< getFindCount(WN)), CODE: {
[WeaponName=getGroup(WN, 1, 2)]
};{ [WeaponName=""]
}]
[H, IF(1< getFindCount(WN)), CODE: {
[WeaponName2=getGroup(WN, 2, 2)]
};{ [WeaponName2=""]
}]
[H, IF(2< getFindCount(WN)), CODE: {
[WeaponName3=getGroup(WN, 3, 2)]
};{ [WeaponName3=""]
}]
[H, IF(3< getFindCount(WN)), CODE: {
[WeaponName4=getGroup(WN, 4, 2)]
};{ [WeaponName4=""]
}]
[H: id = strfind(statblock, "([A-z][a-z. ]).*? Hit:.([0-9]+)(.+?)(.slashing|.bludgeoning|.piercing)")]
[H, IF(0< getFindCount(id)), CODE: {
[DamageType=getGroup(id, 1, 4)]
[DamageType=trim(DamageType)]
[DamageType=upper(DamageType,1)]
};{ [DamageType=""]
}]
[H, IF(1< getFindCount(id)), CODE: {
[DamageType2=getGroup(id, 2, 4)]
[DamageType2=trim(DamageType2)]
[DamageType2=upper(DamageType2,1)]
};{ [DamageType2=""]
}]
[H, IF(2< getFindCount(id)), CODE: {
[DamageType3=getGroup(id, 3, 4)]
[DamageType3=trim(DamageType3)]
[DamageType3=upper(DamageType3,1)]
};{ [DamageType3=""]
}]
[H: dd = strfind(statblock, "(\\d+d\\d+)")]
[H, IF(1< getFindCount(dd)), CODE: {
[DamageDie=getGroup(dd, 2, 1)]
};{ [DamageDie=""]
}]
[H, IF(2< getFindCount(dd)), CODE: {
[DamageDie2=getGroup(dd, 3, 1)]
};{ [DamageDie2=""]
}]
[H, IF(3< getFindCount(dd)), CODE: {
[DamageDie3=getGroup(dd, 4, 1)]
};{ [DamageDie3=""]
}]
}]<!--END OF GETTING WEAPONS-->
[h: Wrang=5]
<!--THIS IS WHERE THE MACRO GOES-->
[h:CommandTextW = strformat('[h:jsonWeaponData = json.set("{}",
"WeaponName", "%{WeaponName}",
"DamageType", "%{DamageType}",
"DamageDie", "%{DamageDie}",
"DamageDie2", "%{DamageDie}",
"PrimaryStat", "%{PrimaryStat}",
"MagicBonus","%{MagicBonus}",
"SpecialAbility","%{SpecialAbility}",
"MiscAttackBonus","%{MiscAttackBonus}",
"MiscDamageBonus","%{MiscDamageBonus}",
"MiscDamageType","%{MiscDamageType}",
"MinimumCritRoll","%{MinimumCritRoll}",
"FlavorText","%{FlavorText}",
"Wrang","%{Wrang}",
"ButtonColor","%{ButtonColor}",
"FontColor","%{FontColor}")]
[macro("NPC_WEAPON_ATTACK@campaign"):jsonWeaponData]')]
[h:CommandTextW2 = strformat('[h:jsonWeaponData = json.set("{}",
"WeaponName", "%{WeaponName2}",
"DamageType", "%{DamageType2}",
"DamageDie", "%{DamageDie2}",
"DamageDie2", "%{DamageDie2}",
"PrimaryStat", "%{PrimaryStat}",
"MagicBonus","%{MagicBonus}",
"SpecialAbility","%{SpecialAbility}",
"MiscAttackBonus","%{MiscAttackBonus}",
"MiscDamageBonus","%{MiscDamageBonus}",
"MiscDamageType","%{MiscDamageType}",
"MinimumCritRoll","%{MinimumCritRoll}",
"FlavorText","%{FlavorText}",
"Wrang","%{Wrang}",
"ButtonColor","%{ButtonColor}",
"FontColor","%{FontColor}")]
[macro("NPC_WEAPON_ATTACK@campaign"):jsonWeaponData]')]
[h:CommandTextW3 = strformat('[h:jsonWeaponData = json.set("{}",
"WeaponName", "%{WeaponName3}",
"DamageType", "%{DamageType3}",
"DamageDie", "%{DamageDie3}",
"DamageDie2", "%{DamageDie3}",
"PrimaryStat", "%{PrimaryStat}",
"MagicBonus","%{MagicBonus}",
"SpecialAbility","%{SpecialAbility}",
"MiscAttackBonus","%{MiscAttackBonus}",
"MiscDamageBonus","%{MiscDamageBonus}",
"MiscDamageType","%{MiscDamageType}",
"MinimumCritRoll","%{MinimumCritRoll}",
"ButtonColor","%{ButtonColor}",
"FlavorText","%{FlavorText}",
"Wrang","%{Wrang}",
"FontColor","%{FontColor}")]
[macro("NPC_WEAPON_ATTACK@campaign"):jsonWeaponData]')]
<!--THIS IS WHERE THE MACRO GOES-->
[h:ButtonProps='{"color":"'+ButtonColor+'","fontColor":"'+FontColor+'","group":"2.Combat (Weapons)","minWidth":90}']
[h:ButtonProps2='{"color":"'+ButtonColor+'","fontColor":"'+FontColor+'","group":"2.Combat (Weapons)","minWidth":90}']
[H, IF(0< getFindCount(WN)), CODE: {
[if(hasMacro(WeaponName)==0), CODE:{
[createMacro(WeaponName, decode(CommandTextW), ButtonProps)]
}]
}]
[H, IF(1< getFindCount(WN)), CODE: {
[if(hasMacro(WeaponName2)==0), CODE:{
[createMacro(WeaponName2, decode(CommandTextW2), ButtonProps)]
}]
}]
[H, IF(2< getFindCount(WN)), CODE: {
[if(hasMacro(WeaponName3)==0), CODE:{
[createMacro(WeaponName3, decode(CommandTextW3), ButtonProps)]
}]
}]
[h:ButtonProps9='{"color":"black","sortBy":"zz","fontColor":"white","group":"2.Combat (Weapons)","minWidth":90}']
[H: MA = strfind(statblock, "(Multiattack)")]
[H, IF(0< getFindCount(MA)), CODE: {
[MAD=getGroup(MA, 1, 1)]
[tex="/self"]
[if(hasMacro(MAD)==0), CODE:{
[CommandText = strformat('
[MACRO("'+MAD+'@global"):""]')]
[createMacro(MAD, tex+decode(CommandText), ButtonProps9)]
};{
[MAD=""]
}]
}]
[H: id = strfind(statblock,"(Abberant Ground|Action Surge|Acid Absorption|Adhesive|Advanced Telepathy|Aggressive|Air Form|Ambusher|Amorphous|Amphibious|Angelic Weapons|Antimagic Cone|Antimagic Susceptibility|Artificers Lore|Assassinate|Aversion of Fire|Aversion of Damage Type|Avoidance|Axiomatic Mind|Band of the Black Earth|Barbed Hide|Beast of Burden|Berserk|Berserk|Blessing of Mother Night|Blind Senses|Blood Frenzy|Bonded Mount|Bound|Brave|Brave Devotion|Brute|Call to the Wave|Cantrip|Cavalry Training|Celestial Legacy|Celestial Resistance|Chameleon Carapace|Chameleon Skin|Charge|Chilling Mist|Cold Aura|Confer X Resistance|Confusing Gaze|Consume Life|Corrode Metal|Corrosive Form|Cunning Action|Damage Absorption|Damage Resistance Draconic Ancestry|Damage Resistance|Damage Transfer|Dark Advantage|Dark Devotion|Death Burst|Death Burst|Deathly Choir|Death Throes|Detect Invisibility|Detect Life|Detect Sentience|Devils Sight|Devils Tongue|Discorporation|Disintegration|Displacement|Distress Spores|Dive|Divine Awareness|Divine Eminence|Draconic Majesty|Draconic Majesty|Draconic Majesty|Dragon Fanatic|Dreadful Glare|Drone|Drow Magic|Drow Weapon Training|Duergar Magic|Duergar Resilience|Duergar Resilience|Dwarven Armor Training|Dwarven Combat Training|Dwarven Resilience|Dwarven Toughness|Earthen Defeat|Earthen Passage|Earth Glide|Earth Walk|Echolocation|Eerie Resemblance|Elemental Demise|Elf Weapon Training|Empowered Attacks|Ephemeral|Ethereal Jaunt|Ethereal Sight|Etherealness|Evasion|Extra Language|Extraordinary Feature|False Appearance|Fanatical Advantage|Faultless Tracker|Fear Aura|Fear of Fire|Fear of Damage|Feat|Feral|Fey Ancestry|Fey Step|Fiendish Blessing|Fire Aura|Fire Absorption|Fire Form|Fleet of Foot|Flaming Weapon|Flight|Flyby|Foul|Freedom of Movement|Frightful Presence|Freeze|Funeral Pyre|Fungus Stride|Giant Slayer|Gibbering|Gnome Cunning|Grappler|Grasping Tendrils|Grim Harvest|Gruumshs Fury|Guiding Wind|Halfling Nimbleness|Heart of Hruggek|Heart Sight|Heated Body|Heated Weapon|Hellfire|Hellish Weapons|Hellish Rejuvenation|Hellish Resistance|Hold Breath|Horrific Appearance|Howling Defeat|Ice Walk|Ignite Enemy|Ignited Illumination|Illumination|Immolation|Immutable Form|Improved Critical|Incite Rampage|Incorporeal Movement|Indomitable|Infernal Legacy|Innate Spellcasting|Ignited Illumination|Insanity|Inscrutable|Invisibility|Invisible in Water|Iron Scent|Keen Hearing and Smell|Keen Smell|Keen Senses|Keen Sight|Keen Sight and Smell|Labyrinthine Recall|Legendary Resistance|Light Sensitivity|Limited Amphibiousness|Limited Flight|Limited Magic Immunity|Limited Spines|Limited Telepathy|Limited Telepathy|Limited Telepathy|Living Shadow|Lucky|Magic Resistance|Magic Weapons|Malison Type|Marshal Undead|Martial Advantage|Mask of the Wild|Master of Undeath|Menacing|Merge with Stone|Mimicry|Mingle with the Wind|Misty Escape|Mountain Born|Mucous Cloud|Multiple Heads|Mushroom Portal|Natural Athlete|Natural Illusionist|Naturally Stealthy|Negative Energy Cone|Nimble Escape|Nondetection|Olyhydras Armor|Ooze Cube|Otherworldly Perception|Pack Tactics|Petrifying Gaze|Petrifying Gaze|Poison Sense|Poison Spores|Poor Depth Perception|Phalanx Formation|Potent Cantrips|Pounce|Powerful Build|Probing Telepathy|Prone Deficiency|Psychic Defense|Rampage|Reach to the Blaze|Reactive|Reactive Heads|Reckless|Reflective Carapace|Regeneration|Regeneration|Rejuvenation|Rejuvenation|Rejuvenation|Rejuvenation|Rejuvenation|Relentless|Relentless Endurance|Rolling Charge|Running Leap|Rust Metal|Savage Attacks|Sculpt Spells|Searing Armor|Second Wind|Sense Magic|Shadow Stealth|Shapechanger|Shapechanger|Shark Telepathy|Shell Camouflage|Shielded Mind|Shrapnel Explosion|Siege Monster|Silent Speech|Slippery|Skewer|Skill Versatility|Sneak Attack|Speak with Beasts and Plants|Speak with Frogs and Toads|Speak with Small Beasts|Spectral Armor and Shield|Spell Turning|Spell Storing|Special Equipment|Spellcasting|Spell Immunity|Spider Climb|Standing Leap|Steadfast|Stench|Stone Camouflage|Stonecunning|Stones Endurance|Stout Resilience|Stunning Strike|Summon Mephits|Sun Sickness|Sunlight Sensitivity|Sunlight Weakness|Superior Darkvision|Superior Invisibility|Sure-Footed|Surprise Attack|Swarm|Swift Animation|Swim|Tail Spike Regrowth|Talons|Telepathic Bond|Telepathic Bond|Telepathic Shroud|Terrain Camouflage|Tiamats Blessing of Retribution|Tinker|Tool Proficiency|Trampling Charge|Trance|Transparent|Treasure Sense|Tree Stride|Tunneler|Turn Immunity|Turn Resistance|Turning Defiance|Two Heads|Unarmoured Defence|Unarmoured Movement|Unending Breath|Undead Fortitude|Undead Slayer|Undetectable|Vampire Weaknesses|Variable Illumination|Vengeful Tracker|Wakeful|Wakeful|War Magic|Water Bond|Water Breathing|Water Form|Water Susceptibility|Water Walk|Watery Fall|Weapon Bond|Web Sense|Web Walker|Winged|Wounded Fury|Wreathed in Flame)")]
[h:ButtonProps='{"color":"pink","fontColor":"black","group":"Traits and Features","minWidth":90}']
[H,count(getFindCount(id), ""), CODE:{
[TraitName=getGroup(id, roll.count+1, 1)]
[tex="/self"]
[if(hasMacro(TraitName)==0), CODE:{
[CommandText = strformat('
[MACRO("'+TraitName+'@global"):""]')]
[createMacro(TraitName, tex+decode(CommandText), ButtonProps)]
}]
}]
[H: id = strfind(statblock,"(Acrobatics.?|Animal Handling.?|Arcana.?|Athletics.?|Deception.?|History.?|Insight.?|Intimidation.?|Investigation.?|Medicine.?|Nature.?|Perception.?|Performance.?|Persuasion.?|Religion.?|Sleight of Hand.?|Stealth.?|Survival.?)[+]([0-9]+)")]
[h:ButtonProps='{"color":"olive","fontColor":"black","group":"6.Skills","minWidth":90}']
[H,count(getFindCount(id), ""), CODE:{
[SkillName=getGroup(id, roll.count+1, 1)]
[SkillNum=getGroup(id, roll.count+1, 2)]
[SkillName=trim(SkillName)]
[tex="/self"]
[h,if(hasMacro(SkillName)==0), CODE:{
[h:CommandText = strformat('
[h:jsonData = json.set("{}", "SkillNum", "%{SkillNum}")] [MACRO("-'+SkillName+'@Lib:CharacterSheet"):jsondata]')]
[createMacro(SkillName, tex+decode(CommandText), ButtonProps)]
}]
}]