@@PF Statblock2Token (1.8) @PROPS@ fontColor=white;autoExecute=true;fontSize=0.95em;sortBy=99;color=black;playerEditable=true;applyToSelected=true;group=;tooltip=;minWidth= /self [H: ids = getSelected()] [H: abort(if(ids == "", 0, 1))] [H: keywords = "(XP|Init|Senses|"+ "DEFENSE|AC|hp|Fort|Ref|Will|Defensive Abilities|"+ "OFFENSE|Speed|Melee|Ranged|Special Attacks|Spell-Like Abilities|"+ "(\\S+) Spells Prepared|Domains|"+ "STATISTICS|Base (Atk|Attack)|CMB|CMD|Feats|Skills|"+ "Languages|Combat Gear|Other Gear|Boon)" ] [H: status=input("statblock|Insert statblock here|Enter statblock|TEXT|WIDTH=40")] [H: abort(if(status < 1, 0, 1))] [H: setPropertyType("Pathfinder")] [H: propnames = getPropertyNames()] [H, foreach(propname,propnames): resetProperty(propname) ] [H: setGMNotes(statblock)] [H: output="Token Updated:
"] [H: id = strfind(statblock, "^(.+).*CR ")] [H, IF(0 [H: id = strfind(statblock, "(Fine|Diminutive|Tiny|Small|Medium|Large|Huge|Gargantuan|Colossal).([a-zA-Z]+\\s?[a-zA-Z]*?)\\s?(\\((.+)\\))?.?Init")] [H, IF(0"] [subtypes="['"+replace(subtypes,", *","','")+"']"] [Race = json.set(Race, "subtype",subtypes)] } ] [H: id = strfind(statblock, "Senses ([lL]ow-?light|[dD]arkvision)")] [H, IF(0 [H: id = strfind(statblock, "Str.?([0-9]+)(/[0-9]+)?.+?Dex.?([0-9]+)(/[0-9]+)?.+?Con.?([0-9]+)(/[0-9]+)?.+?Int.?([0-9]+)(/[0-9]+)?.+?Wis.?([0-9]+)(/[0-9]+)?.+?Cha.?([0-9]+)")] [H, IF(0"] }] [H: id = strfind(statblock, "Fort(itude)?.?([0-9]+)")] [H, IF(0"] }] [H: id = strfind(statblock, "hp ([0-9]+).+?([0-9]+)")] [H, IF(0"] }] [H: id = strfind(statblock, "Base (Atk|Attack)?(.?[0-9]+);")] [H, IF(0 [H: id = strfind(statblock, "(.?[0-9]+) natural")] [H, IF(0"] }] [H: id = strfind(statblock, "(Speed|Spd) ([0-9]+)")] [H, IF(0"] [H: tSkillsJ ="[]"] [H: output=output+"Skills: "] [H, FOREACH(s, SkillsJ), CODE: { [skN = json.get(s, "name")] [id = strfind(statblock, skN+"\\s*([+-]?[0-9]+)")] [IF(0 [skStat = getStrProp(SkillStat, skN)] [skVal = getGroup(id, 1, 1)] [output = output + skN + " " + skVal + ", "] [s = json.set( s, "rank", skVal-eval(skStat))] } ] [tSkillsJ = json.append(tSkillsJ,s)] } ] [H: output=output+"
"] [H: SkillsJ=tSkillsJ] [H: output=output+"Feats: "] [H: featJSON = json.append("", json.append("", "(Improved Initiative)", "ImprovedInitiative"), json.append("", "(Improved Bull Rush)", "ImprovedBullRush"), json.append("", "(Improved Disarm)", "ImprovedDisarm"), json.append("", "(Improved Grapple)", "ImprovedGrapple"), json.append("", "(Improved Overrun)", "ImprovedOverrun"), json.append("", "(Improved Sunder)", "ImprovedSunder"), json.append("", "(Improved Trip)", "ImprovedTrip"), json.append("", "(Improved Channeling)", "ImprovedChanneling"), json.append("", "(Agile Maneuvers)", "AgileManeuvers"), json.append("", "(Two.?Weapon Fighting)", "TwoWeaponFighting"), json.append("", "(Multi.?[Aa]ttack)", "MultiAttack"), json.append("", "(Weapon Finesse)", "WeaponFinesse"), json.append("", "(Uncanny Dodge)", "UncannyDodge"), json.append("", "(Die.?[Hh]ard)", "DieHard") ) ] [H, FOREACH(featPair, featJSON), CODE: { [ id = strfind(statblock, json.get(featPair,0)) ] [ propName = jsonget(featPair,1) ] [ IF(0"] [H: id = strfind(statblock, "Special Attacks (.+)(Statis|STATIS)")] [H, IF(0"] };{ [SpecialATK=""] }] [H: wpnstr=getPropertyDefault( "Weapon0" )] [H, c(7,""),CODE: { [wpn="Weapon"+roll.count] [setProperty(wpn, wpnstr)] }] [H: atkno = 0] [H: id = strfind(statblock, "(?i)Melee (.+?)(Tactic|Face|Space|Reach|Special|Ranged|Stat)")] [H, IF(0 [allmelee=stringToList(allmelee, "( (and|or) (Melee)?)|(Melee)",":")] [atkno = listCount(allmelee, ":")] }] [H: wpnarray=""] [H: wpnno=0] [H, FOR(i,0,atkno,1), CODE: { [atkstr=listget(allmelee, i, ":")] [atkstr=stringToList(atkstr, "( and )|(, )",":")] [wpns = listCount(atkstr, ":")] [FOR(j,0,wpns,1), CODE: { [WpnName = "Weapon" + wpnno] [wpnarray=json.append(wpnarray, trim(listGet(atkstr,j,":")))] [ x = eval(WpnName) ] [IF(j>0):eval(WpnName + "= '" + replace(x,"Primary=\\d+", "Primary=2")+ "'")] [eval(WpnName + "= '" + replace(x,"OHLight=\\d+", "OHLight=2")+ "'")] [wpnno = wpnno +1] }] }] [H: atkno = 0] [H: id = strfind(statblock, "(?i)Ranged (.+?)(Tac|Face|Space|Reach|Special|Ranged|Stat)")] [H, IF(0 [allranged=stringToList(allranged, "(\\s?or (Ranged)?)|(Ranged)",":")] [atkno = listCount(allranged, ":")] }] [H, FOR(i,0,atkno,1), CODE: { [atkstr=listget(allranged, i, ":")] [atkstr=stringToList(atkstr, "( and )|(, )",":")] [wpns = listCount(atkstr, ":")] [FOR(j,0,wpns,1), CODE: { [WpnName = "Weapon" + wpnno] [wpnarray=json.append(wpnarray, trim(listGet(atkstr,j,":")))] [eval(WpnName + "= '" + setStrProp(eval(WpnName),"Ranged", 1)+ "'")] [wpnno = wpnno +1] }] }] [H: wpnno=0] [H, FOREACH(atkstr, wpnarray), CODE: { [atkstr=trim(atkstr)] [id = strfind(atkstr, "([+-]\\d+)?(\\d+)?(\\d?\\s?[a-zA-Z ]+?) ([+-]\\d+)[/+\\-0-9\\s]*?\\((.+)\\)")] [IF(0 [wquant = 1] [wbonus = ""] [IF(getGroup(id,1,1)==""): wquant = getGroup(id, 1, 2); wbonus="+ "+getGroup(id,1,1)] [IF(getGroup(id,1,2)==""): wquant = 1] [IF(1 [id2 = strfind(atkstr, "(slam|bite|claw|gore|hoof|tentacle|wing|pincer|tail|sting|talon)")] [IF(0==getFindCount(id2)):eval(WpnName + "= '" + setStrProp(eval(WpnName),"Manufactured", 1)+ "'")] [watkbonus=getGroup(id, 1, 4)] [Ranged=getStrProp(eval(WpnName),"Ranged")] [IF(Ranged>0):watkbonus=watkbonus-BAB-DexB;watkbonus=watkbonus-BAB-StrB-SizeM] [eval(WpnName + "= '" + setStrProp(eval(WpnName),"AtkBonus", watkbonus)+ "'")] [wdam=getGroup(id, 1, 5)] [CritMult=2] [id2 = strfind(wdam, "/[xX](\\d)")] [IF(0 [CritRange=20] [id2 = strfind(wdam, "/(1[0-9])")] [IF(0 [Damage="0d4 plus" + wdam] [id2 = strfind(wdam, "(\\dd\\d+)[^p]*(plus .+)?")] [IF(0 [eval(WpnName + "= '" + setStrProp(eval(WpnName),"TwoHanded", 0)+ "'")] [id2 = strfind(atkstr, "(longspear|quarterstaff| spear|falchion|glaive|greataxe|greatclub|greatsword|guisarme|halberd|lance|ranseur|scythe|spiked chain|elven curve blade|dire flail|two-bladed sword|urgrosh|hooked hammer)")] [IF(0"] [R,S,G: output]