From 70b54405be51fc07c91401065dc6385ff47fc33b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 12:01:52 +0000 Subject: [PATCH 1/8] feat: add componentized sheet templates and auto-build workflow Agent-Logs-Url: https://github.com/bart-sysf/pf-csheets/sessions/cda4b437-1adc-419f-a049-f7f125bae9a4 Co-authored-by: bart-sysf <16703428+bart-sysf@users.noreply.github.com> --- .github/workflows/build-sheets.yml | 43 + .../xmlhtml/csheet_known_spells.htm.ftl | 6 + .../xmlhtml/csheet_prepared_spells.htm.ftl | 5 + README.md | 38 +- components/feats.ftl | 55 ++ components/inventory.ftl | 74 ++ components/prepared_spells.ftl | 63 ++ components/skills.ftl | 71 ++ components/spellbook.ftl | 65 ++ components/weapons.ftl | 101 ++ scripts/build_sheets.py | 59 ++ .../xmlhtml/csheet_known_spells.htm.ftl | 917 ++++++++++++++++++ .../xmlhtml/csheet_prepared_spells.htm.ftl | 917 ++++++++++++++++++ 13 files changed, 2408 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/build-sheets.yml create mode 100644 components/feats.ftl create mode 100644 components/inventory.ftl create mode 100644 components/prepared_spells.ftl create mode 100644 components/skills.ftl create mode 100644 components/spellbook.ftl create mode 100644 components/weapons.ftl create mode 100644 scripts/build_sheets.py create mode 100644 templates/d20/fantasy/xmlhtml/csheet_known_spells.htm.ftl create mode 100644 templates/d20/fantasy/xmlhtml/csheet_prepared_spells.htm.ftl diff --git a/.github/workflows/build-sheets.yml b/.github/workflows/build-sheets.yml new file mode 100644 index 0000000..2220f5d --- /dev/null +++ b/.github/workflows/build-sheets.yml @@ -0,0 +1,43 @@ +name: Build Sheets + +on: + workflow_dispatch: + push: + paths: + - 'templates/**' + - 'components/**' + - 'scripts/build_sheets.py' + - '.github/workflows/build-sheets.yml' + +permissions: + contents: write + +jobs: + build-sheets: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Build sheets from templates + run: python scripts/build_sheets.py + + - name: Commit built sheets if changed + run: | + if git diff --quiet -- OutputSheets; then + echo "No OutputSheets changes detected" + exit 0 + fi + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add OutputSheets + git commit -m "chore: rebuild OutputSheets from templates" + git push diff --git a/OutputSheets/d20/fantasy/xmlhtml/csheet_known_spells.htm.ftl b/OutputSheets/d20/fantasy/xmlhtml/csheet_known_spells.htm.ftl index 4c62cf8..04a27fa 100644 --- a/OutputSheets/d20/fantasy/xmlhtml/csheet_known_spells.htm.ftl +++ b/OutputSheets/d20/fantasy/xmlhtml/csheet_known_spells.htm.ftl @@ -375,6 +375,7 @@ +
|
+ ${pcstring('ABILITYALL.Feat.VISIBLE.${ft}')} + [${pcstring('ABILITYALL.Feat.VISIBLE.${ft}.SOURCE')}] + ${pcstring('ABILITYALL.Feat.VISIBLE.${ft}.BENEFIT')} + |
+
|
+ ${pcstring('ABILITYALL.Special Ability.VISIBLE.${tr}.TYPE=Trait')} + [${pcstring('ABILITYALL.Special Ability.VISIBLE.${tr}.TYPE=Trait.SOURCE')}] + ${pcstring('ABILITYALL.Special Ability.VISIBLE.${tr}.TYPE=Trait.DESC')} + |
+
|
+ ${pcstring('DOMAIN.${dm}')} + ${pcstring('DOMAIN.${dm}.POWER')} + |
+
| Item | +Location | +Qty | +Weight | +Cost | +Uses (check off when used) | +
|---|---|---|---|---|---|
| ${pcstring('EQ.Not.Coin.NOT.Gem.${eq}.NAME.MAGIC~~')} | +${pcstring('EQ.Not.Coin.NOT.Gem.${eq}.LOCATION')} | +${pcstring('EQ.Not.Coin.NOT.Gem.${eq}.QTY')} | +${pcstring('EQ.Not.Coin.NOT.Gem.${eq}.WT')} | +${pcstring('EQ.Not.Coin.NOT.Gem.${eq}.COST')} | ++ <#if isUsable> + <#if eqCharges gt 0> + <@loop from=1 to=eqCharges>☐@loop> + <#else> + <@loop from=1 to=eqQty?int>☐@loop> + #if> + #if> + | +
| + <#if (eqSprop != "")>Special: ${eqSprop}<#if (eqDesc != "")> — #if>#if><#if (eqDesc != "")>${eqDesc}#if> + | +|||||
| Totals: | +${pcstring('TOTAL.WEIGHT')} | +${pcstring('TOTAL.VALUE')} | ++ | ||
| Spell | +Uses | +Save, DC & SR | +Range, Time & Duration | +Effect / Description | +
|---|---|---|---|---|
|
+ ${pcstring('SPELLMEM.${class}.${spellbook}.${level}.${spell}.BONUSSPELL')}${pcstring('SPELLMEM.${class}.${spellbook}.${level}.${spell}.NAME')} + ${pcstring('SPELLMEM.${class}.${spellbook}.${level}.${spell}.SCHOOL')} + [${pcstring('SPELLMEM.${class}.${spellbook}.${level}.${spell}.SOURCE')}] + |
+ + <#if (level = 0)>∞<#else><@loop from=1 to=pcvar("SPELLMEM.${class}.${spellbook}.${level}.${spell}.TIMES")>☐@loop>#if> + | +
+ <#if !hasNoSave>${spSaveShort} DC ${spDC} #if> + SR: <#if (spSR != "")>${spSR}<#else>—#if> + |
+
+ ${pcstring('SPELLMEM.${class}.${spellbook}.${level}.${spell}.RANGE')} + ${pcstring('SPELLMEM.${class}.${spellbook}.${level}.${spell}.CASTINGTIME')} + ${pcstring('SPELLMEM.${class}.${spellbook}.${level}.${spell}.DURATION')} + |
+ ${pcstring('SPELLMEM.${class}.${spellbook}.${level}.${spell}.EFFECT')} | +
| Skill | +Total | ++ Rnks | ++ Misc | +
|---|---|---|---|
|
+ <#if pcboolean("SKILLSIT.${sk}.UNTRAINED")>◆#if>${pcstring('SKILLSIT.${sk}')}<#if (pcstring('SKILLSIT.${sk}.ACPv') != "v")>*#if>
+ ${pcstring('SKILLSIT.${sk}.ABILITY')} (+${pcstring('SKILLSIT.${sk}.ABMOD')}) + |
+ ${pcstring('SKILLSIT.${sk}.TOTAL')} | +${pcstring("SKILLSIT.${sk}.RANK")?replace("\\.0","","rf")} | +${pcstring('SKILLSIT.${sk}.MISC')} | +
| Skill | +Total | ++ Rnks | ++ Misc | +
|---|---|---|---|
|
+ <#if pcboolean("SKILLSIT.${sk}.UNTRAINED")>◆#if>${pcstring('SKILLSIT.${sk}')}<#if (pcstring('SKILLSIT.${sk}.ACPv') != "v")>*#if>
+ ${pcstring('SKILLSIT.${sk}.ABILITY')} (+${pcstring('SKILLSIT.${sk}.ABMOD')}) + |
+ ${pcstring('SKILLSIT.${sk}.TOTAL')} | +${pcstring("SKILLSIT.${sk}.RANK")?replace("\\.0","","rf")} | +${pcstring('SKILLSIT.${sk}.MISC')} | +
| Spell | +Uses | +Save, DC & SR | +Range, Time & Duration | +Effect / Description | +
|---|---|---|---|---|
|
+ ${pcstring('SPELLMEM.${class}.0.${level}.${spell}.NAME')} + ${pcstring('SPELLMEM.${class}.0.${level}.${spell}.SCHOOL')} + [${pcstring('SPELLMEM.${class}.0.${level}.${spell}.SOURCE')}] + |
+ + <#if (level = 0)>∞<#else>${pcstring('SPELLLISTCAST.${class}.${level}')}#if> + | +
+ <#if !hasNoSave>${spSaveShort} DC ${spDC} #if> + SR: <#if (spSR != "")>${spSR}<#else>—#if> + |
+
+ ${pcstring('SPELLMEM.${class}.0.${level}.${spell}.RANGE')} + ${pcstring('SPELLMEM.${class}.0.${level}.${spell}.CASTINGTIME')} + ${pcstring('SPELLMEM.${class}.0.${level}.${spell}.DURATION')} + |
+ ${pcstring('SPELLMEM.${class}.0.${level}.${spell}.EFFECT')} | +
| Weapon | +1H-P | +2H | +2W-P | +DMG (2H) | +Crit | +||||
|---|---|---|---|---|---|---|---|---|---|
|
+ ${pcstring('WEAPON.${wp}.NAME')}<#if isLight> △#if> + ${wTypeFull} + |
+ <#if isRanged>
+ ${pcstring('WEAPON.${wp}.TOTALHIT')} (ranged, ${pcstring('WEAPON.${wp}.RANGE')}) | +${pcstring('WEAPON.${wp}.DAMAGE')} | + <#else> +${pcstring('WEAPON.${wp}.BASEHIT')} | +${pcstring('WEAPON.${wp}.THHIT')} | +${pcstring('WEAPON.${wp}.TWPHITH')} | +
+ ${pcstring('WEAPON.${wp}.BASICDAMAGE')} + 2H: ${pcstring('WEAPON.${wp}.THDAMAGE')} + |
+ #if>
+ ${pcstring('WEAPON.${wp}.CRIT')}/x${pcstring('WEAPON.${wp}.MULT')} | +||
| + Range increments (−2 per increment): + | 2x: ${pcstring('WEAPON.${wp}.RANGELIST.1.TOTALHIT')} + | 3x: ${pcstring('WEAPON.${wp}.RANGELIST.2.TOTALHIT')} + | 4x: ${pcstring('WEAPON.${wp}.RANGELIST.3.TOTALHIT')} + | 5x: ${pcstring('WEAPON.${wp}.RANGELIST.4.TOTALHIT')} + (max 5) + | +|||||||||
| + Special: ${pcstring('WEAPON.${wp}.SPROP')} + | +|||||||||
|
+ Unarmed △ + Bludgeoning + |
+ ${pcstring('ATTACK.MELEE.TOTAL')} | +${pcstring('ATTACK.MELEE.TOTAL')} | +${pcstring('ATTACK.MELEE.TOTAL')} | +
+ ${unarmedDie}${strMod} + 2H: ${unarmedDie}${strMod} + |
+ 20/x2 | +||||
| ${pcstring('PLAYERNAME')} | +Lvl ${pcstring('TOTALLEVELS')} (${pcstring('EXP.CURRENT')} / ${pcstring('EXP.NEXT')}) | +${pcstring('RACE')} | +${pcstring('GENDER')} (${pcstring('AGE')}) | +${pcstring('HEIGHT')} (${pcstring('SIZELONG')}) | +${pcstring('WEIGHT')} | +
| Player | +Level (XP) | +Race | +Gender (Age) | +Height (Size) | +Weight | +
| ${pcstring('DEITY')}, ${pcstring('ALIGNMENT')} | +${pcstring('LANGUAGES')} | +||||
| Deity & Alignment | +Languages | +||||
Max HP${pcstring('HP')} |
+ HP Lost Today |
+ Current HP |
+ Initiative${pcstring('INITIATIVEMOD')} |
+ Speed<@loop from=0 to=pcvar('COUNT[MOVE]-1') ; mv , mv_has_next>${pcstring('MOVE.${mv}.RATE')}@loop> |
+ DR<#if (pcstring('DR') != '')>${pcstring('DR')}<#else>0#if> |
+
| + AC + ${pcstring('AC.Total')} + | +: | +Touch${pcstring('AC.Touch')} | +: | +Flat${pcstring('AC.Flatfooted')} | += | +Base${pcstring('AC.Base')} | ++ | +Armor*${pcstring('AC.Armor')} | ++ | +Shield${pcstring('AC.Shield')} | ++ | +Dex${pcstring('AC.Ability')} | ++ | +Size${pcstring('AC.Size')} | ++ | +Nat${pcstring('AC.NaturalArmor')} | ++ | +Dodge${pcstring('AC.Dodge')} | ++ | +Defl${pcstring('AC.Deflection')} | ++ | +Misc${pcstring('AC.Misc')} | +
BAB${pcstring('ATTACK.MELEE')} |
+ Melee Hit${pcstring('ATTACK.MELEE.TOTAL')} |
+ Ranged Hit${pcstring('ATTACK.RANGED.TOTAL')} |
+ Hit Die${pcstring('HITDICE')} |
+ CMB${pcstring('VAR.CMB.INTVAL.SIGN')} |
+ CMD${pcstring('VAR.CMD.INTVAL')} |
+ SR<#if (pcstring('SR') != '')>${pcstring('SR')}<#else>0#if> |
+
| + | Total | +Base | +Magic | +Misc | ++ |
|
+ ${pcstring('CHECK.${chk}.NAME')}
+ <#if (pcstring('CHECK.${chk}.NAME') = 'Fortitude')> CON (${pcstring('CHECK.${chk}.STATMOD')}) #if>
+ <#if (pcstring('CHECK.${chk}.NAME') = 'Reflex')>DEX (${pcstring('CHECK.${chk}.STATMOD')}) #if>
+ <#if (pcstring('CHECK.${chk}.NAME') = 'Will')>WIS (${pcstring('CHECK.${chk}.STATMOD')}) #if>
+ |
+ ${pcstring('CHECK.${chk}.TOTAL')} | +${pcstring('CHECK.${chk}.BASE')} | +${pcstring('CHECK.${chk}.MAGIC')} | +${pcstring('CHECK.${chk}.MISC.NOMAGIC.NOSTAT')} | ++ |
|
+ ${pcstring('ABILITYALL.Special Ability.VISIBLE.${sq}.TYPE=SpecialQuality')} + [${pcstring('ABILITYALL.Special Ability.VISIBLE.${sq}.TYPE=SpecialQuality.SOURCE')}] + ${pcstring('ABILITYALL.Special Ability.VISIBLE.${sq}.TYPE=SpecialQuality.DESC')} + |
+
|
+ ${pcstring('ABILITYALL.Special Ability.VISIBLE.${sa}.TYPE=SpecialAttack')} + [${pcstring('ABILITYALL.Special Ability.VISIBLE.${sa}.TYPE=SpecialAttack.SOURCE')}] + ${pcstring('ABILITYALL.Special Ability.VISIBLE.${sa}.TYPE=SpecialAttack.DESC')} + |
+
+ <#assign saUses = pcstring('ABILITYALL.Special Ability.VISIBLE.${sa}.TYPE=SpecialAttack.ASPECT.UsesPerDay') />
+ <#if (saUses != "")>
+ Uses/day: ${saUses} + <#assign saUsesN = pcvar('ABILITYALL.Special Ability.VISIBLE.${sa}.TYPE=SpecialAttack.ASPECT.UsesPerDay.INTVAL') /> + <#if (saUsesN > 0)> + <@loop from=1 to=saUsesN>☐@loop> + #if> + #if> + |
+
| Maneuver | +CMB | +CMD | +Notes | +
|---|---|---|---|
| Grapple | +${pcstring('VAR.CMB_Grapple.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Grapple.INTVAL')} | +Pin, tie up, damage, or move a grappled foe. Grappled = −2 attack/AC, no two-handed. | +
| Trip | +${pcstring('VAR.CMB_Trip.INTVAL.SIGN')} | +<#if (pcvar("CantBeTripped") != 0)>Immune<#else>${pcstring('VAR.CMD_Trip.INTVAL')}#if> | +Knock prone. Prone = −4 melee attack, −4 AC vs melee, +4 AC vs ranged. | +
| Disarm | +${pcstring('VAR.CMB_Disarm.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Disarm.INTVAL')} | +Knock weapon from foe. Beat CMD by 10+ = item lands 10ft away. | +
| Bull Rush | +${pcstring('VAR.CMB_BullRush.INTVAL.SIGN')} | +${pcstring('VAR.CMD_BullRush.INTVAL')} | +Push foe back 5ft + 5ft per 5 over CMD. You may follow. | +
| Sunder | +${pcstring('VAR.CMB_Sunder.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Sunder.INTVAL')} | +Damage a held/worn item. Broken = −2 attack/damage or halved effectiveness. | +
| Overrun | +${pcstring('VAR.CMB_Overrun.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Overrun.INTVAL')} | +Move through foe's space. Fail = blocked; beat by 5+ = foe prone. | +
| Dirty Trick | +${pcstring('VAR.CMB_DirtyTrick.INTVAL.SIGN')} | +${pcstring('VAR.CMD_DirtyTrick.INTVAL')} | +Blind, entangle, or sicken 1 round (+1 per 5 over CMD). Std action to remove. | +
| Drag | +${pcstring('VAR.CMB_Drag.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Drag.INTVAL')} | +Pull foe 5ft + 5ft per 5 over CMD toward you. Must move with them. | +
| Reposition | +${pcstring('VAR.CMB_Reposition.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Reposition.INTVAL')} | +Move foe to any adjacent square. Foe must remain adjacent. | +
| Steal | +${pcstring('VAR.CMB_Steal.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Steal.INTVAL')} | +Take one carried/worn item (not wielded). No free hand required. | +
| Item | +Type | +AC Bonus | +Max Dex* | +Check Pen† | +Spell Fail | ++ |
|---|---|---|---|---|---|---|
| ${pcstring('ARMOR.EQUIPPED.${ar}.NAME')} | +${pcstring('ARMOR.EQUIPPED.${ar}.TYPE')} | +${pcstring('ARMOR.EQUIPPED.${ar}.TOTALAC')} | +${pcstring('ARMOR.EQUIPPED.${ar}.MAXDEX')} | +${pcstring('ARMOR.EQUIPPED.${ar}.ACCHECK')} | +${pcstring('ARMOR.EQUIPPED.${ar}.SPELLFAIL')} | ++ |
| When A Check Is Required | +Concentration DC | +
|---|---|
| Cast defensively (to avoid provoking) | +15 + (2 × spell level) | +
| Take damage while casting | +10 + damage dealt + spell level | +
| Taking continuous damage while casting | +10 + half last damage dealt + spell level | +
| Vigorous motion (mount, rough vehicle, choppy water) | +10 + spell level | +
| Violent motion (violent weather, heavy turbulence) | +15 + spell level | +
| Extra violent motion (earthquake-level disruption) | +20 + spell level | +
| Weather with high wind, rain, or debris | +5 + spell level | +
| Entangled while casting | +15 + spell level | +
| Grappled or pinned while casting | +10 + grappler CMB + spell level | +
| Action | +Notes | +
|---|---|
| Move out of threatened square | +5-ft step, withdraw (first square), or Acrobatics can avoid | +
| Ranged attack in melee | +Any ranged attack while threatened | +
| Cast spell in melee | +Cast defensively to avoid provoking (Concentration check) | +
| Drink potion / use scroll | +Using items in melee commonly provokes | +
| Stand up from prone | +Common trigger after trip | +
| Combat maneuver (without Improved feat) | +Trip, disarm, grapple, etc.; improved feat usually prevents | +
| Retrieve stowed item | +Digging in backpack/pouch while threatened | +
| Pick up item | +Picking up from ground in melee | +
| Load crossbow | +Most loading actions in melee provoke | +
| Unarmed strike without Improved Unarmed Strike | +Barehanded attacks vs armed foes can provoke | +
| Ability | +Score / Mod | +Primary Effects On This Sheet | +Current Derived Values | +
|---|---|---|---|
| STR | +14 (+2) | +Melee attack, melee damage, CMB, CMD, carry/lift limits | +Melee: +2 | CMB: +2 | CMD: 13 | +
| DEX | +12 (+1) | +Ranged attack, initiative, AC ability bonus, CMD, Dexterity skills, Reflex save | +Ranged: +1 | Init: +1 | AC ability: 1 | +
| CON | +14 (+2) | +Hit points per level/HD, Fortitude save, concentration-related checks | +Max HP: 10 | Hit Dice: (1d8)+2 | +
| INT | +11 (+0) | +Bonus skill ranks/level, INT-based skills, knowledge checks, some feat prerequisites | +See Skills table for INT-based totals | +
| WIS | +16 (+3) | +Will save, WIS-based skills, divine spellcasting checks/DCs when applicable | +See Saves/Skills and Prepared Spells sections | +
| CHA | +12 (+1) | +Social skills, class features that key from CHA, turning/channel effects when used | +See class feature and ability notes | +
| Condition / Situation | +Main Effect | +Quick Modifier | +
|---|---|---|
| Shaken | +General fear penalties | +−2 attacks, saves, skills, ability checks | +
| Frightened | +As shaken; must flee if possible | +−2 attacks, saves, skills, checks | +
| Courage | +Morale combat boost | ++1 to hit; +1 saves vs fear | +
| Guidance | +Single-use bonus | ++1 attack, +1 save, or +1 skill check | +
| Sickened | +Nausea/weakness penalties | +−2 attacks, weapon dmg, saves, skills, checks | +
| Fatigued | +Tired; cannot run/charge | +−2 Str, −2 Dex | +
| Exhausted | +Severe fatigue; slower movement | +−6 Str, −6 Dex | +
| Prone | +Worse in melee, better vs ranged | +−4 melee attacks, −4 AC vs melee, +4 AC vs ranged | +
| Flat-Footed | +Not ready to react | +Lose Dex to AC (and dodge bonuses) | +
| Entangled | +Restricted movement/offense | +−2 attack, −4 Dex, move at half speed | +
| Grappled | +Limited actions in grapple | +−2 attacks and AC; no AoO | +
| Pinned | +Immobile in grapple | +Cannot move; very limited actions | +
| Staggered | +Only one major action | +Either one standard or one move action | +
| Stunned | +Drop items; no actions | +Drop everything, −2 AC, lose Dex to AC, no actions | +
| Flanking | +Attacking same foe from opposite sides | ++2 melee attack | +
| Charge | +Move then strike aggressively | ++2 attack, −2 AC until next turn | +
| Fighting Defensively | +Trade attack for defense | +−4 attack, +2 AC | +
| Total Defense | +No attacks; full defense | ++4 AC | +
| Blinded | +Cannot see | +−2 AC, lose Dex to AC, −4 many Str/Dex checks, move half speed | +
| Invisible Attacker | +Defender cannot see attacker | +Attacker often +2 melee; target loses Dex to AC; may require miss chance | +
| Helpless / Coup de Grace | +Helpless targets are vulnerable | +Coup de grace: auto crit; target Fort save (DC 10 + damage dealt) or die | +
HP${pcstring('HP')} |
+ Init${pcstring('INITIATIVEMOD')} |
+ Move<@loop from=0 to=pcvar('COUNT[MOVE]-1') ; mv , mv_has_next>${pcstring('MOVE.${mv}.RATE')}@loop> |
+ AC${pcstring('AC.Total')} |
+ Touch${pcstring('AC.Touch')} |
+ Flat${pcstring('AC.Flatfooted')} |
+ BAB${pcstring('ATTACK.MELEE')} |
+ Melee${pcstring('ATTACK.MELEE.TOTAL')} |
+ Ranged${pcstring('ATTACK.RANGED.TOTAL')} |
+
| Save | +Total | +Quick Notes | +
|---|---|---|
| Fortitude | ${pcstring('CHECK.0.TOTAL')} | Poison, disease, body effects |
| Reflex | ${pcstring('CHECK.1.TOTAL')} | Area effects, traps, avoid damage |
| Will | ${pcstring('CHECK.2.TOTAL')} | Mental control, fear, compulsion |
| Skill | +Total | +
|---|---|
| ${pcstring('SKILLSIT.${skq1}')} | +${pcstring('SKILLSIT.${skq1}.TOTAL')} | +
| Skill | +Total | +
|---|---|
| ${pcstring('SKILLSIT.${skq2}')} | +${pcstring('SKILLSIT.${skq2}.TOTAL')} | +
| ${pcstring('PLAYERNAME')} | +Lvl ${pcstring('TOTALLEVELS')} (${pcstring('EXP.CURRENT')} / ${pcstring('EXP.NEXT')}) | +${pcstring('RACE')} | +${pcstring('GENDER')} (${pcstring('AGE')}) | +${pcstring('HEIGHT')} (${pcstring('SIZELONG')}) | +${pcstring('WEIGHT')} | +
| Player | +Level (XP) | +Race | +Gender (Age) | +Height (Size) | +Weight | +
| ${pcstring('DEITY')}, ${pcstring('ALIGNMENT')} | +${pcstring('LANGUAGES')} | +||||
| Deity & Alignment | +Languages | +||||
Max HP${pcstring('HP')} |
+ HP Lost Today |
+ Current HP |
+ Initiative${pcstring('INITIATIVEMOD')} |
+ Speed<@loop from=0 to=pcvar('COUNT[MOVE]-1') ; mv , mv_has_next>${pcstring('MOVE.${mv}.RATE')}@loop> |
+ DR<#if (pcstring('DR') != '')>${pcstring('DR')}<#else>0#if> |
+
| + AC + ${pcstring('AC.Total')} + | +: | +Touch${pcstring('AC.Touch')} | +: | +Flat${pcstring('AC.Flatfooted')} | += | +Base${pcstring('AC.Base')} | ++ | +Armor*${pcstring('AC.Armor')} | ++ | +Shield${pcstring('AC.Shield')} | ++ | +Dex${pcstring('AC.Ability')} | ++ | +Size${pcstring('AC.Size')} | ++ | +Nat${pcstring('AC.NaturalArmor')} | ++ | +Dodge${pcstring('AC.Dodge')} | ++ | +Defl${pcstring('AC.Deflection')} | ++ | +Misc${pcstring('AC.Misc')} | +
BAB${pcstring('ATTACK.MELEE')} |
+ Melee Hit${pcstring('ATTACK.MELEE.TOTAL')} |
+ Ranged Hit${pcstring('ATTACK.RANGED.TOTAL')} |
+ Hit Die${pcstring('HITDICE')} |
+ CMB${pcstring('VAR.CMB.INTVAL.SIGN')} |
+ CMD${pcstring('VAR.CMD.INTVAL')} |
+ SR<#if (pcstring('SR') != '')>${pcstring('SR')}<#else>0#if> |
+
| + | Total | +Base | +Magic | +Misc | ++ |
|
+ ${pcstring('CHECK.${chk}.NAME')}
+ <#if (pcstring('CHECK.${chk}.NAME') = 'Fortitude')> CON (${pcstring('CHECK.${chk}.STATMOD')}) #if>
+ <#if (pcstring('CHECK.${chk}.NAME') = 'Reflex')>DEX (${pcstring('CHECK.${chk}.STATMOD')}) #if>
+ <#if (pcstring('CHECK.${chk}.NAME') = 'Will')>WIS (${pcstring('CHECK.${chk}.STATMOD')}) #if>
+ |
+ ${pcstring('CHECK.${chk}.TOTAL')} | +${pcstring('CHECK.${chk}.BASE')} | +${pcstring('CHECK.${chk}.MAGIC')} | +${pcstring('CHECK.${chk}.MISC.NOMAGIC.NOSTAT')} | ++ |
|
+ ${pcstring('ABILITYALL.Special Ability.VISIBLE.${sq}.TYPE=SpecialQuality')} + [${pcstring('ABILITYALL.Special Ability.VISIBLE.${sq}.TYPE=SpecialQuality.SOURCE')}] + ${pcstring('ABILITYALL.Special Ability.VISIBLE.${sq}.TYPE=SpecialQuality.DESC')} + |
+
|
+ ${pcstring('ABILITYALL.Special Ability.VISIBLE.${sa}.TYPE=SpecialAttack')} + [${pcstring('ABILITYALL.Special Ability.VISIBLE.${sa}.TYPE=SpecialAttack.SOURCE')}] + ${pcstring('ABILITYALL.Special Ability.VISIBLE.${sa}.TYPE=SpecialAttack.DESC')} + |
+
+ <#assign saUses = pcstring('ABILITYALL.Special Ability.VISIBLE.${sa}.TYPE=SpecialAttack.ASPECT.UsesPerDay') />
+ <#if (saUses != "")>
+ Uses/day: ${saUses} + <#assign saUsesN = pcvar('ABILITYALL.Special Ability.VISIBLE.${sa}.TYPE=SpecialAttack.ASPECT.UsesPerDay.INTVAL') /> + <#if (saUsesN > 0)> + <@loop from=1 to=saUsesN>☐@loop> + #if> + #if> + |
+
| Maneuver | +CMB | +CMD | +Notes | +
|---|---|---|---|
| Grapple | +${pcstring('VAR.CMB_Grapple.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Grapple.INTVAL')} | +Pin, tie up, damage, or move a grappled foe. Grappled = −2 attack/AC, no two-handed. | +
| Trip | +${pcstring('VAR.CMB_Trip.INTVAL.SIGN')} | +<#if (pcvar("CantBeTripped") != 0)>Immune<#else>${pcstring('VAR.CMD_Trip.INTVAL')}#if> | +Knock prone. Prone = −4 melee attack, −4 AC vs melee, +4 AC vs ranged. | +
| Disarm | +${pcstring('VAR.CMB_Disarm.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Disarm.INTVAL')} | +Knock weapon from foe. Beat CMD by 10+ = item lands 10ft away. | +
| Bull Rush | +${pcstring('VAR.CMB_BullRush.INTVAL.SIGN')} | +${pcstring('VAR.CMD_BullRush.INTVAL')} | +Push foe back 5ft + 5ft per 5 over CMD. You may follow. | +
| Sunder | +${pcstring('VAR.CMB_Sunder.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Sunder.INTVAL')} | +Damage a held/worn item. Broken = −2 attack/damage or halved effectiveness. | +
| Overrun | +${pcstring('VAR.CMB_Overrun.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Overrun.INTVAL')} | +Move through foe's space. Fail = blocked; beat by 5+ = foe prone. | +
| Dirty Trick | +${pcstring('VAR.CMB_DirtyTrick.INTVAL.SIGN')} | +${pcstring('VAR.CMD_DirtyTrick.INTVAL')} | +Blind, entangle, or sicken 1 round (+1 per 5 over CMD). Std action to remove. | +
| Drag | +${pcstring('VAR.CMB_Drag.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Drag.INTVAL')} | +Pull foe 5ft + 5ft per 5 over CMD toward you. Must move with them. | +
| Reposition | +${pcstring('VAR.CMB_Reposition.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Reposition.INTVAL')} | +Move foe to any adjacent square. Foe must remain adjacent. | +
| Steal | +${pcstring('VAR.CMB_Steal.INTVAL.SIGN')} | +${pcstring('VAR.CMD_Steal.INTVAL')} | +Take one carried/worn item (not wielded). No free hand required. | +
| Item | +Type | +AC Bonus | +Max Dex* | +Check Pen† | +Spell Fail | ++ |
|---|---|---|---|---|---|---|
| ${pcstring('ARMOR.EQUIPPED.${ar}.NAME')} | +${pcstring('ARMOR.EQUIPPED.${ar}.TYPE')} | +${pcstring('ARMOR.EQUIPPED.${ar}.TOTALAC')} | +${pcstring('ARMOR.EQUIPPED.${ar}.MAXDEX')} | +${pcstring('ARMOR.EQUIPPED.${ar}.ACCHECK')} | +${pcstring('ARMOR.EQUIPPED.${ar}.SPELLFAIL')} | ++ |
| When A Check Is Required | +Concentration DC | +
|---|---|
| Cast defensively (to avoid provoking) | +15 + (2 × spell level) | +
| Take damage while casting | +10 + damage dealt + spell level | +
| Taking continuous damage while casting | +10 + half last damage dealt + spell level | +
| Vigorous motion (mount, rough vehicle, choppy water) | +10 + spell level | +
| Violent motion (violent weather, heavy turbulence) | +15 + spell level | +
| Extra violent motion (earthquake-level disruption) | +20 + spell level | +
| Weather with high wind, rain, or debris | +5 + spell level | +
| Entangled while casting | +15 + spell level | +
| Grappled or pinned while casting | +10 + grappler CMB + spell level | +
| Action | +Notes | +
|---|---|
| Move out of threatened square | +5-ft step, withdraw (first square), or Acrobatics can avoid | +
| Ranged attack in melee | +Any ranged attack while threatened | +
| Cast spell in melee | +Cast defensively to avoid provoking (Concentration check) | +
| Drink potion / use scroll | +Using items in melee commonly provokes | +
| Stand up from prone | +Common trigger after trip | +
| Combat maneuver (without Improved feat) | +Trip, disarm, grapple, etc.; improved feat usually prevents | +
| Retrieve stowed item | +Digging in backpack/pouch while threatened | +
| Pick up item | +Picking up from ground in melee | +
| Load crossbow | +Most loading actions in melee provoke | +
| Unarmed strike without Improved Unarmed Strike | +Barehanded attacks vs armed foes can provoke | +
| Ability | +Score / Mod | +Primary Effects On This Sheet | +Current Derived Values | +
|---|---|---|---|
| STR | +14 (+2) | +Melee attack, melee damage, CMB, CMD, carry/lift limits | +Melee: +2 | CMB: +2 | CMD: 13 | +
| DEX | +12 (+1) | +Ranged attack, initiative, AC ability bonus, CMD, Dexterity skills, Reflex save | +Ranged: +1 | Init: +1 | AC ability: 1 | +
| CON | +14 (+2) | +Hit points per level/HD, Fortitude save, concentration-related checks | +Max HP: 10 | Hit Dice: (1d8)+2 | +
| INT | +11 (+0) | +Bonus skill ranks/level, INT-based skills, knowledge checks, some feat prerequisites | +See Skills table for INT-based totals | +
| WIS | +16 (+3) | +Will save, WIS-based skills, divine spellcasting checks/DCs when applicable | +See Saves/Skills and Prepared Spells sections | +
| CHA | +12 (+1) | +Social skills, class features that key from CHA, turning/channel effects when used | +See class feature and ability notes | +
| Condition / Situation | +Main Effect | +Quick Modifier | +
|---|---|---|
| Shaken | +General fear penalties | +−2 attacks, saves, skills, ability checks | +
| Frightened | +As shaken; must flee if possible | +−2 attacks, saves, skills, checks | +
| Courage | +Morale combat boost | ++1 to hit; +1 saves vs fear | +
| Guidance | +Single-use bonus | ++1 attack, +1 save, or +1 skill check | +
| Sickened | +Nausea/weakness penalties | +−2 attacks, weapon dmg, saves, skills, checks | +
| Fatigued | +Tired; cannot run/charge | +−2 Str, −2 Dex | +
| Exhausted | +Severe fatigue; slower movement | +−6 Str, −6 Dex | +
| Prone | +Worse in melee, better vs ranged | +−4 melee attacks, −4 AC vs melee, +4 AC vs ranged | +
| Flat-Footed | +Not ready to react | +Lose Dex to AC (and dodge bonuses) | +
| Entangled | +Restricted movement/offense | +−2 attack, −4 Dex, move at half speed | +
| Grappled | +Limited actions in grapple | +−2 attacks and AC; no AoO | +
| Pinned | +Immobile in grapple | +Cannot move; very limited actions | +
| Staggered | +Only one major action | +Either one standard or one move action | +
| Stunned | +Drop items; no actions | +Drop everything, −2 AC, lose Dex to AC, no actions | +
| Flanking | +Attacking same foe from opposite sides | ++2 melee attack | +
| Charge | +Move then strike aggressively | ++2 attack, −2 AC until next turn | +
| Fighting Defensively | +Trade attack for defense | +−4 attack, +2 AC | +
| Total Defense | +No attacks; full defense | ++4 AC | +
| Blinded | +Cannot see | +−2 AC, lose Dex to AC, −4 many Str/Dex checks, move half speed | +
| Invisible Attacker | +Defender cannot see attacker | +Attacker often +2 melee; target loses Dex to AC; may require miss chance | +
| Helpless / Coup de Grace | +Helpless targets are vulnerable | +Coup de grace: auto crit; target Fort save (DC 10 + damage dealt) or die | +
HP${pcstring('HP')} |
+ Init${pcstring('INITIATIVEMOD')} |
+ Move<@loop from=0 to=pcvar('COUNT[MOVE]-1') ; mv , mv_has_next>${pcstring('MOVE.${mv}.RATE')}@loop> |
+ AC${pcstring('AC.Total')} |
+ Touch${pcstring('AC.Touch')} |
+ Flat${pcstring('AC.Flatfooted')} |
+ BAB${pcstring('ATTACK.MELEE')} |
+ Melee${pcstring('ATTACK.MELEE.TOTAL')} |
+ Ranged${pcstring('ATTACK.RANGED.TOTAL')} |
+
| Save | +Total | +Quick Notes | +
|---|---|---|
| Fortitude | ${pcstring('CHECK.0.TOTAL')} | Poison, disease, body effects |
| Reflex | ${pcstring('CHECK.1.TOTAL')} | Area effects, traps, avoid damage |
| Will | ${pcstring('CHECK.2.TOTAL')} | Mental control, fear, compulsion |
| Skill | +Total | +
|---|---|
| ${pcstring('SKILLSIT.${skq1}')} | +${pcstring('SKILLSIT.${skq1}.TOTAL')} | +
| Skill | +Total | +
|---|---|
| ${pcstring('SKILLSIT.${skq2}')} | +${pcstring('SKILLSIT.${skq2}.TOTAL')} | +