Lets share our work if you don't mind?
A couple things I've added to note are:
1. Fix bad characters (note, I've found non-ascii x's as well as emdash)
[H: statblock = replace(statblock, "\\xD7", "x")]
[H: statblock = replace(statblock, "\\u2013", "-")]
[H: statblock = replace(statblock, "Ecolo gy", "Ecology")]
2. Added Fast Healing & Regeneration
3. Perception from Statblock (vs skills section for simplicty to show on statsheet)
4. Hero Labs Friendly: I've made a few changes so it doesn't choke on reading StatBlocks from Hero Labs, mostly around the weapons area.
5. More changes/fixes around weapons. Still chokes on a few odd things. Still not 100% either.
6. Treasure Type: This goes with my Treasure Roll macro which uses standard Pathfinder core rules to generate random coin/gem values. (It does a basic job of breaking down total by copper/silver/gold/plat/gems as well.)
Note: I removed the input box for favor of cut/paste into GM text. That way I have a RAW semi formatted original stat block to refer back to for anything special or to rerun if needed. I heavily use the StatSheet as well and as we are F2F so I like the quick reference on hover.
I've also made changes to the Calculate XP macro if interested. It calculates XP and marks the token with a XP state and then saves the XP to the PC tokens. If the PC has enough XP to level, a LevelUp state is applied.
I note this as I use the StatBlock2Token macro of PC's (from Hero Labs) and needed to keep several properties from being erased like XP.
Statblock2Token
Jamz: Now paste formatted text into GM text (which stays formatted) and handles CR now.
Jamz: Added Fast-Healing, Regeneration, adjusted Weapons to be Hero Labs friendly
Changes: HD fixed, Resets token, Skills with space in the name except SleightOfHand
Macro takes a Pathfinder statblock as input and updates selected token with various stats.
Macro assumes pathfinder properties in the selected token.
Statblock format should mirror PF bestiary format.
Not handled: SQ, Spells
-->
[H: ids = getSelected()]
[H: abort(if(ids == "", 0, 1))]
<!-- Lets keep nice formated text in GMNotes and paste there first manually and then retrieve it from there
H: status=input("statblock|Insert statblock here|Enter statblock|TEXT|WIDTH=40")
H: abort(if(status < 1, 0, 1))
H: setGMNotes(statblock)
-->
[H: setPropertyType("Pathfinder")]
<!--Lets keep my custom Nerps properties if already populated-->
[H: Nerps_WikiTemp=getProperty("Nerps_Wiki")]
[H: Nerps_TreasureTemp=getProperty("Nerps_Treasure")]
[H: XPTemp=getProperty("XP")]
[H: NewXPTemp=getProperty("NewXP")]
[H: XPadvancmentPaceTemp=getProperty("XPadvancmentPace")]
[H: propnames = getPropertyNames()]
[H, foreach(propname,propnames),CODE:
{
[resetProperty(propname)]
}]
[H: setProperty("Nerps_Wiki", Nerps_WikiTemp)]
[H: setProperty("Nerps_Treasure", Nerps_TreasureTemp)]
[H: setProperty("XP", XPTemp)]
[H: setProperty("NewXP", NewXPTemp)]
[H: setProperty("XPadvancmentPace", XPadvancmentPaceTemp)]
[H: statblock = getGMNotes()]
[H: statblock = replace(statblock, "\\xD7", "x")]
[H: statblock = replace(statblock, "\\u2013", "-")]
[H: statblock = replace(statblock, "Ecolo gy", "Ecology")]
[H: setGMNotes(statblock)]
[H: statblockOrig = statblock]
[H: statblock = replace(statblock, "\\n", " ")]
[H: output="Token Updated:<br>"]
[H: id = strfind(statblock, "^(.+).*CR ")]
[H, IF(0<getFindCount(id)),CODE: {
[currentName = getName()]
[newName=trim(getGroup(id, 1, 1))]
[n1 = upper(currentName)]
[n2 = upper(newName)]
[if(n1 == n2): newName = currentName)]
[setName(newName)]
[Race = json.set(Race, "name", newName)]
[output=output+"Name: "+newName+", "]
}]
<!-- Setting ECL to CR from statblock. For CR 1/3 & 1/6 we will set it to .338 & .1625 so XP calcs correctly. -->
[H: id = strfind(statblockOrig, "(?<=[ |\\t]CR )([0-9]+)(/[0-9]+)?")]
[H, IF(0<getFindCount(id)),CODE:
{
[ECL=trim(getGroup(id, 1, 0))]
[output=output+"CR: "+ECL+", "]
[IF(ECL == "1/3"),CODE:{
[ECL=".338"]
}]
[IF(ECL == "1/6"),CODE:{
[ECL=".1625"]
}]
[Levels = setStrProp(Levels, "ECL", ECL)]
}]
<!-- Getting Perception. -->
[H: id = strfind(statblockOrig, "(?<=Perception )(.?[0-9]+)")]
[H, IF(0<getFindCount(id)),CODE:
{
[Perception=trim(getGroup(id, 1, 0))]
[output=output+"Perception: "+Perception+", "]
[Skills = setStrProp(Skills, "Perception", Perception)]
}]
[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<getFindCount(id)),CODE:
{
[Size_txt=getGroup(id, 1, 1)]
[setSize(Size_txt)]
[sizeList = table( "SysVars", json.get( table( "SysVars", 0 ), "sizeList" ) ) ]
[sizeModList = "8,4,2,1,0,-1,-2,-4,-8"]
[Size=listFind(sizeList, Size_txt)]
[SizeM = listGet(sizeModList, Size)]
[type=upper(substring(getGroup(id, 1, 2),0,1))+substring(getGroup(id, 1, 2),1)]
[Race = json.set(Race, "type", type)]
[subtypes=getGroup(id, 1, 4)]
[output=output+"Size: "+Size_txt+", type: "+type+", subtypes: "+subtypes+"<br>"]
[subtypes="['"+replace(subtypes,", *","','")+"']"]
[Race = json.set(Race, "subtype",subtypes)]
}]
[H: id = strfind(statblock, "Init ([+-][0-9]+);")]
[H, IF(0<getFindCount(id)),CODE:
{
[InitMod=getGroup(id, 1, 1)]
[output=output+"Init: "+InitMod+", "]
}]
[H: id = strfind(statblock, "Senses ([lL]ow-?light|[dD]arkvision)")]
[H, IF(0<getFindCount(id)),CODE:
{
[sighttype=upper(substring(getGroup(id, 1, 1),0,1))+substring(getGroup(id, 1, 1),1)]
[sighttype=replace(sighttype, "-", "")]
[setSightType(sighttype)]
[setHasSight(1)]
[output=output+"Sighttype: "+sighttype+", "]
}]
[H: id = strfind(statblock, "Reach ([0-9]+)")]
[H, IF(0<getFindCount(id)),CODE:
{
[Reach=getGroup(id, 1, 1)]
[output=output+"Reach: "+Reach+", "]
}]
[H: id = strfind(statblock, "DR(.?[0-9]+)/(.+?)[;O]")]
[H, IF(0<getFindCount(id)),CODE:
{
[DR=getGroup(id, 1, 1)+"/"+getGroup(id, 1, 2))]
[output=output+"DR: "+DR+", "]
}]
[H: id = strfind(statblock, "Resist (\\w+) (\\d+)")]
[H, IF(0<getFindCount(id)),CODE:
{
[resist = getGroup(id, 1, 1)+" "+getGroup(id, 1, 2))]
[DR=DR+" Resist "+resist]
[output=output+"Resist: "+resist+", "]
}]
[H: id = strfind(statblock, "SR ([0-9]+)")]
[H, IF(0<getFindCount(id)),CODE:
{
[SR=getGroup(id, 1, 1)]
[SpecialQual="SR "+SR]
[output=output+"SR: "+SR+", "]
}]
<!-- STATS BEGIN -->
[H: id = strfind(statblockOrig, "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=output+"Str: "+Strength+", Dex: "+Dexterity+", Con: "+Constitution+", Int: "+Intelligence+", Wis: "+Wisdom+", Cha: "+Charisma+"<br>"]
}]
<!-- STATS END -->
<!-- SAVES BEGIN -->
[H: id = strfind(statblock, "Fort (.?[0-9]+)")]
[H, IF(0<getFindCount(id)),CODE:
{
[Fort=getGroup(id, 1, 1)-ConB]
[output=output+"Fort: "+fort+", "]
}]
[H: id = strfind(statblock, "Ref (.?[0-9]+)")]
[H, IF(0<getFindCount(id)),CODE:
{
[Reflex=getGroup(id, 1, 1)-DexB]
[output=output+"Ref: "+reflex+", "]
}]
[H: id = strfind(statblock, "Will (.?[0-9]+)")]
[H, IF(0<getFindCount(id)),CODE:
{
[Will=getGroup(id, 1, 1)-WisB]
[output=output+"Will: "+Will+"<br>"]
}]
<!-- SAVES END -->
[H: id = strfind(statblock, "hp ([0-9]+).+?([0-9]+)")]
[H, IF(0<getFindCount(id)),CODE:
{
[HP=getGroup(id, 1, 1)]
[HPmax=HP]
[HPavg=HP]
[HD=getGroup(id, 1, 2)]
[Level = max(1,HD)]
[output=output+"HP: "+HP+", HD: "+HD+"<br>"]
}]
[H: id = strfind(statblock, "(hp [0-9]+ )\\(([0-9]+d[0-9]+([+-][0-9]+)?(\\)))")]
[H, IF(0<getFindCount(id)),CODE:
{
[HitDice=getGroup(id, 1, 2)]
[HitDice=substring(HitDice,0, length(HitDice)-1)]
[output=output+"Hit Dice: "+HitDice+"<br>"]
}]
[H: id = strfind(statblock, "Base Atk.?(.?[0-9]+);")]
[H, IF(0<getFindCount(id)), CODE:
{
[BAB=getGroup(id, 1, 1)]
[output=output+"Base Atk: "+BAB+", "]
}]
[H: id = strfind(statblock, "CMB.?(.?[0-9]+);")]
[H, IF(0<getFindCount(id)), CODE:
{
[CMBMod=getGroup(id, 1, 1)]
[output=output+"CMB: "+CMBMod+", "]
}]
<!-- AC BEGIN -->
[H: id = strfind(statblock, "(.?[0-9]+) natural")]
[H, IF(0<getFindCount(id)): natural=getGroup(id, 1, 1); natural=0]
[H: ArmorClass = setStrProp(ArmorClass, "Natural", natural)]
[H: id = strfind(statblock, "(.?[0-9]+) armor")]
[H, IF(0<getFindCount(id)): armor=getGroup(id, 1, 1);armor=0]
[H: ArmorClass = setStrProp(ArmorClass, "Armor", armor)]
[H: id = strfind(statblock, "(.?[0-9]+) deflection")]
[H, IF(0<getFindCount(id)): deflect=getGroup(id, 1, 1); deflect=0]
[H: ArmorClass = setStrProp(ArmorClass, "Deflection", deflect)]
[H: id = strfind(statblock, "(.?[0-9]+) dodge")]
[H, IF(0<getFindCount(id)): dodge=getGroup(id, 1, 1); dodge=0]
[H: ArmorClass = setStrProp(ArmorClass, "Dodge", dodge)]
[H: id = strfind(statblock, "(.?[0-9]+) shield")]
[H, IF(0<getFindCount(id)): shield=getGroup(id, 1, 1); shield=0]
[H: ArmorClass = setStrProp(ArmorClass, "Shield", shield)]
[H: id = strfind(statblock, "AC ([0-9]+),")]
[H, IF(0<getFindCount(id)), CODE:
{
[AC=getGroup(id, 1, 1)]
[tch=AC-armor-shield]
[FF=AC-dodge-DexB]
[CMD=10+BAB+StrB+DexB-SizeM+dodge+deflect]
[CMDFF=CMD-DexB-dodge]
[AC=concat(AC,"/",tch,"/",FF,"/",CMD,"/",CMDFF)]
[output=output+"AC/tch/FF/CMD/CMDFF: "+AC+"<br>"]
}]
<!-- AC END -->
[H: id = strfind(statblock, "(Speed|Spd) ([0-9]+) ft")]
[H, IF(0<getFindCount(id)), CODE:
{
[spd=getGroup(id, 1, 2)]
[output=output+"Spd: "+spd]
[Speed = json.set(Speed, "base",spd)]
}]
[H: id = strfind(statblock, "fly ([0-9]+) ft")]
[H, IF(0<getFindCount(id)), CODE:
{
[spd=getGroup(id, 1, 1)]
[output=output+", Fly: "+spd]
[Speed = json.set(Speed, "fly",spd)]
}]
[H: id = strfind(statblock, "swim ([0-9]+) ft")]
[H, IF(0<getFindCount(id)), CODE:
{
[spd=getGroup(id, 1, 1)]
[output=output+", Swim: "+spd]
[Speed = json.set(Speed, "swim",spd)]
}]
[H: id = strfind(statblock, "burrow ([0-9]+) ft")]
[H, IF(0<getFindCount(id)), CODE:
{
[spd=getGroup(id, 1, 1)]
[output=output+", Burrow: "+spd]
[Speed = json.set(Speed, "burrow",spd)]
}]
[H: id = strfind(statblock, "climb ([0-9]+) ft")]
[H, IF(0<getFindCount(id)), CODE:
{
[spd=getGroup(id, 1, 1)]
[output=output+", Climb: "+spd]
[Speed = json.set(Speed, "climb",spd)]
}]
[H: output=output+"<br>"]
<!-- SKILLS BEGIN -->
[H: tSkillsJ ="[]"]
[H: output=output+"Skills: "]
[H, FOREACH(s, SkillsJ), CODE:
{
[skN = json.get(s, "name")]
[id=0]
[id = strfind(statblock, skN+"\\s(.?[0-9]+)")]
[H, IF(0<getFindCount(id)), CODE:
{
[skN = replace(skN, " ", "")] <!-- Remove spaces from skill name -->
[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+"<br>"]
[H: SkillsJ=tSkillsJ]
<!-- SKILLS END -->
<!-- FEATS BEGIN -->
[H: output=output+"Feats: "]
[H: id = strfind(statblock, "(Improved Initiative)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "ImprovedInitiative",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "ImprovedInitiative",0)]
}]
[H: id = strfind(statblock, "(Agile Maneuvers)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "AgileManeuvers",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "AgileManeuvers",0)]
}]
[H: id = strfind(statblock, "(Improved Bull Rush)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "ImprovedBullRush",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "ImprovedBullRush",0)]
}]
[H: id = strfind(statblock, "(Improved Disarm)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "ImprovedDisarm",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "ImprovedDisarm",0)]
}]
[H: id = strfind(statblock, "(Improved Grapple)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "ImprovedGrapple",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "ImprovedGrapple",0)]
}]
[H: id = strfind(statblock, "(Improved Overrun)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "ImprovedOverrun",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "ImprovedOverrun",0)]
}]
[H: id = strfind(statblock, "(Improved Sunder)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "ImprovedSunder",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "ImprovedSunder",0)]
}]
[H: id = strfind(statblock, "(Improved Trip)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "ImprovedTrip",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "ImprovedTrip",0)]
}]
[H: id = strfind(statblock, "(Improved Channeling)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "ImprovedChanneling",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "ImprovedChanneling",0)]
}]
[H: id = strfind(statblock, "(Two.?Weapon Fighting)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "TwoWeaponFighting",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "TwoWeaponFighting",0)]
}]
[H: id = strfind(statblock, "(Multi.?[aA]ttack)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "MultiAttack",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "MultiAttack",0)]
}]
[H: id = strfind(statblock, "(Power Attack)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "PowerAttack",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "PowerAttack",0)]
}]
[H: id = strfind(statblock, "(Weapon Finesse)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "WeaponFinesse",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "WeaponFinesse",0)]
}]
[H: id = strfind(statblock, "(Uncanny Dodge)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "UncannyDodge",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "UncannyDodge",0)]
}]
[H: id = strfind(statblock, "(Die.?[hH]ard)")]
[H, IF(0<getFindCount(id)), CODE:
{
[Feats=setStrProp(Feats, "DieHard",1)]
[H: output=output+getGroup(id, 1, 1)+", "]
};{
[Feats=setStrProp(Feats, "DieHard",0)]
}]
[H: output=output+"<br>"]
<!-- FEATS END -->
[H: id = strfind(statblockOrig, "Special Attacks (.+)")]
[H, IF(0<getFindCount(id)), CODE:
{
[SpecialATK=getGroup(id, 1, 1)]
[SpecialATK=trim(SpecialATK)]
[SpecialATK=substring(SpecialATK,0,min(length(SpecialATK),100))]
[output=output+"SA: "+SpecialATK+"<br>"]
};{
[SpecialATK=""]
}]
<!-- ATTACKS BEGIN -->
<!-- Insert empty weapon strings -->
[H: wpnstr=getPropertyDefault( "Weapon0" )]
[H, c(7,""),CODE:
{
[wpn="Weapon"+roll.count]
[eval(wpn + " = '" + wpnstr+ "'")]
}]
[H: atkno = 0]
<!-- MELEE -->
<!-- The '(?i)' makes the expression case-insensitive -->
[H: id = strfind(statblock, "Melee (.+?)(?i)(?=Tactic|Face|Space|Reach|Special|Ranged|Stat|Spell-Like Abilities|---)")]
[H, IF(0<getFindCount(id)), CODE:
{
[allmelee=getGroup(id, 1, 1)]
[setProperty("OriginalMeleeLine", allmelee)]
<!-- separate each attack option -->
[allmelee=stringToList(allmelee, "( or (Melee)?)|(Melee)",":")]
[atkno = listCount(allmelee, ":")]
}]
<!-- Loop through each attack option and divide into weapons -->
[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")+ "'")]
<!-- Set attack options after first to secondary attacks -->
[eval(WpnName + "= '" + replace(x,"OHLight=\\d+", "OHLight=2")+ "'")]
<!-- Default to not multiattack -->
[wpnno = wpnno +1]
}]
}]
<!-- RANGED -->
[H: atkno = 0]
[H: id = strfind(statblock, "Ranged (.+?)(?=Tac|Face|Space|Reach|Special|Ranged|STAT|Stat|Spell-Like Abilities|---)")]
[H, IF(0<getFindCount(id)), CODE:
{
[allranged=getGroup(id, 1, 1)]
[setProperty("OriginalRangedLine", allranged)]
<!-- separate each attack option -->
[allranged=stringToList(allranged, "(\\s?or (Ranged)?)|(Ranged)",":")]
[atkno = listCount(allranged, ":")]
}]
<!-- Loop through each attack option and divide into weapons -->
[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]
}]
}]
<!-- extract info from each attack -->
[H: wpnno=0]
[H, FOREACH(atkstr, wpnarray), CODE: {
[atkstr=trim(atkstr)]
[id = strfind(atkstr, "([+-]\\d+)?(\\d+)?(.+(?= [\\+-]\\d+ \\()) ([+-]\\d+)[/+\\-0-9\\s]*?\\((.+)\\)")]
[regexptofindweaponname = ".+(?= (/?[\\+-]\\d+)+ \\()"]
[IF(0<getFindCount(id)), CODE:
{
[WpnName = "Weapon" + wpnno]
[eval(WpnName + "= '" + setStrProp(eval(WpnName),"Name", getGroup(id, 1, 3)) + "'")]
<!-- Quantity -->
[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<wquant):eval(WpnName + "= '" + setStrProp(eval(WpnName),"Quantity", wquant)+ "'")]
<!-- Manufactored ? -->
[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)+ "'")]
<!-- Not a natural weapon -->
<!-- Attack bonus (assumes StrB for melee and DexB for ranged) -->
[watkbonus=getGroup(id, 1, 4)]
[Ranged=getStrProp(eval(WpnName),"Ranged")]
[IF(Ranged>0):watkbonus=watkbonus-BAB-DexB-SizeM;watkbonus=watkbonus-BAB-StrB-SizeM]
[eval(WpnName + "= '" + setStrProp(eval(WpnName),"AtkBonus", watkbonus)+ "'")]
<!-- CritMult-->
[wdam=getGroup(id, 1, 5)]
[CritMult=2]
[id2 = strfind(wdam, "/[xX](\\d)")]
[IF(0<getFindCount(id2)):CritMult=getGroup(id2, 1, 1)]
[eval(WpnName + "= '" + setStrProp(eval(WpnName),"CritMult", CritMult)+ "'")]
<!-- CritRange-->
[CritRange=20]
[id2 = strfind(wdam, "/(1[0-9])")]
[IF(0<getFindCount(id2)):CritRange=getGroup(id2, 1, 1)]
[eval(WpnName + "= '" + setStrProp(eval(WpnName),"CritRange", CritRange)+ "'")]
<!-- Damage -->
[Damage="0d4 plus" + wdam]
[id2 = strfind(wdam, "(\\dd\\d+)[^p]*(plus .+)?")]
[IF(0<getFindCount(id2)):Damage=getGroup(id2, 1, 1)+wbonus+" "+getGroup(id2, 1, 2)]
[Damage123=replace(Damage, " ", "")]
[eval(WpnName + "= '" + setStrProp(eval(WpnName),"Damage", Damage)+ "'")]
<!-- Two handed ? -->
<!-- Default to onehanded weapon -->
[eval(WpnName + "= '" + setStrProp(eval(WpnName),"TwoHanded", 0)+ "'")]
[id2 = strfind(atkstr, "(?i)(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<getFindCount(id2)):eval(WpnName + "= '" + setStrProp(eval(WpnName),"TwoHanded", 1)+ "'")]
}]
[wpnno = wpnno +1]
}]
[H: output = output + "Weapons: " + wpnarray+"<br>"]
<!--
Name=Slam ; Primary=1 ; Quantity=1 ; Manufactured=0 ; AtkBonus=0 ; CritMult=2 ; CritRange=20 ; Damage=1d4 ; DmgMax=4 ; DmgExtra=0d6 ; DmgExtraCrit=0d10 ; DmgExtraName= ; DmgBonusCap=50 ; TwoHanded=0 ; Finesse=0 ; OHLight=0 ; Ranged=0 ;
ATTACKS END -->
<!-- Getting treasure from Ecology section. -->
[H: id = strfind(statblockOrig, "(?i)(?<=Treasure )(None|Standard|Double|Triple|Incidental|NPC gear)")]
[H, IF(0<getFindCount(id)),CODE:
{
[TreasureType=getGroup(id, 1, 0)]
[output=output+"Treasure Type: "+TreasureType+"<br>"]
}]
<!-- Setting Fast Healing if present -->
[H: id = strfind(statblockOrig, "(?i)(?<=Fast Healing )([0-9]+)")]
[H, IF(0<getFindCount(id)),CODE:
{
[FastHealing=getGroup(id, 1, 0)]
[output=output+"Fast Healing: "+FastHealing+"<br>"]
}]
<!-- Setting Regeneration if present -->
[H: id = strfind(statblockOrig, "(?i)(?<=Regeneration )([0-9]+)")]
[H, IF(0<getFindCount(id)),CODE:
{
[Regeneration=getGroup(id, 1, 0)]
[output=output+"Regeneration: "+Regeneration+"<br>"]
}]
<!-- Setting Anti Regeneration damage type if present -->
[H: id = strfind(statblockOrig, "(?i)(?<=Regeneration )([0-9]+.+)")]
[H, IF(0<getFindCount(id)),CODE:
{
[AntiRegen=getGroup(id, 1, 0)]
[output=output+"Anti-Regen Damage Type: "+AntiRegen+"<br>"]
}]
<!-- Statblock from HeroLab -->
[H: id = strfind(statblockOrig, "(?i)(Hero Lab logo are Registered Trademarks)")]
[H, IF(0<getFindCount(id)),CODE:
{
[HeroLab=1]
[output=output+"Stat block generated from Hero Lab.<br>"]
}]
[R,S,G: output]
[H: HP = HPmax ]
[H: HPNonLethalDMG = 0]
[H: tToken = currentToken() ]
[H, MACRO( "subUpdateHPStatesBars@Lib:libDnD35Pathfinder" ): "Token=" + tToken]
[H: setState("Prone", 0)]
[H: setState("Unconscious", 0)]
[H: setLayer("TOKEN") ]