Skip to content

Latest commit

 

History

History
579 lines (519 loc) · 22.5 KB

dnd-5e-char-template.org

File metadata and controls

579 lines (519 loc) · 22.5 KB

Character Name

[Character Name] \hspace*{\fill}{\itshape [Race] [Class]}

Level1
Proficiency Bonus+2

Instructions

replace [Character Name] with your character’s name replace [Race] with your character’s race guess what you do with [Class]

Fill in level (and update it when you level up) Proficiency Bonus will fill in automatically if you put the appropriate values in the function at the bottom of the file

Ability Scores

AbilityValueModSave
STR8-1-1
DEX ***14+2+4
CON12+1+1
INT10+0+0
WIS13+1+1
CHA ***15+2+4

Instructions

Only need to fill in Value (and update as any of those values change)

Skills

SkillsCheck
***Acrobatics (Dex)+4
Animal Handling (Wis)+1
Arcana (Int)+0
Athletics (Str)-1
***Deception (Cha)+4
History (Int)+0
Insight (Wis)+1
Intimidation (Cha)+2
Investigation (Int)+0
Medicine (Wis)+1
Nature (Int)+0
Perception (Wis)+1
***Performance (Cha)+4
Persuasion (Cha)+2
Religion (Int)+0
***Sleight of Hand (Dex)+4
***Stealth (Dex)+4
Survival (Wis)+1
Passive Wisdom (Perception):11
Languages:
Common, …

\pagebreak

Instructions

Only put ‘***’ in the first column for skills you are proficient in, modifiers should change automatically

Fill in Languages

Stats

\FloatBarrier

Armor ClassInitiative ModMovement
14+330
Spell AbilitySave DCAttack Bonus
CHA124

Status

HP (Max 10)Temp HPHD (Total 1d8)
1001d8

Spell Slots

Spell LevelSlotsExpended
120
200
300
400
500
600
700
800
900

\FloatBarrier

Other status effects

\noindent INSPIRATION: Advantage

DEATH FAILS
XX
DEATH SAVES
X

Instructions

This section should mostly be managed manually for now. Copy paste bits from ‘other status effects’ above that header as needed.

You can of course add rules for automatically populating hit dice, initiative, and armor class. These vary with class and feats so this is left up to you if you wish.

Features

Actions

FeatureNoteUses Left
Bardic Inspiration1d64

Passive

FeatureNote
By Popular Demandmusic for food/lodging

Instructions

This section is mostly managed manually, Bard class and Entertainer background features are here as an example.

Known Spells

Cantrips KnownSpells KnownMax level
241
LevelSpell
0Prestidigitation
0Mage Hand
1Healing Word
1Sleep
1Speak with Animals
1Faerie Fire

Instructions

Fill in links to spells and (if you spelled them carefully) the descriptions will automatically appear in the Spells section. Links in the Spell Column should be org-mode links of the style:

[[Spell Name][Spell Name]]

so that pdf links (and the spell descriptions) work properly .

Equipment

Proficiencies Light armor, simple weapons, hand crossbows, longswords, rapiers, shortswords, disguise kit, …

WeaponATK BonusDamage/TypeRange
Rapier+51d8+3 piercing
Crossbow (l)+51d8+3 piercing80/320
CP0
SP0
EP0
GP0
PP0
Total (in GP)0
ItemWeightNotes#
*** Rapier51
*** Leather Armor10AC=11+DEX1
*** Crossbow (l)51
ball bearings x1000270
total weight160/120 max

\noindent *** indicates that the item is currently equipped (being worn, sheathed, on back or otherwise accessible)

Instructions

Weapons are managed manually (add your own rules to the table for each weapon if you desire).

Coin totals will be calculated automatically (just fill in how much of each).

Gear Weight are calculated automatically from the individual weights, quantity (under #). Coins are not included in this weight (who does that). Max weight is computed automatically from STR

starting equipment buy in calculator

I rolled 130 GP

itemweightprice (gp)quantity
leather armor10101
crossbow (l)5251
rapier2251
ball bearings x10002170
total157130

Character

Alignment:
Neutral

Personality traits

Ideals

Bonds

Flaws

Appearance

Backstory

Contacts

Some Guy
Notes on that dude
Some Gal
She seems pretty cool

Instructions

Fill in and replace as desired none of this section is automated.

Notes

Instructions

Fill in and replace as desired none of this section is automated.

Spells

Instructions

Should automatically execute when exporting, reads from the SPELLS_KNOWN table to populate with each spell. Additional spells you want displayed can be added to this list at the beginning of the source.

old python version

New Spells explorer (if you like python)

List spells by level/class

import json
with open('./srd_spells/spells.json') as f:
    spell_list = json.load(f)
for spell in spell_list:
    if spell['level'] == '1' and 'bard' in spell['classes']:
        print(spell['name'])
        print(spell['range'])
        print(spell['casting_time'])
        print(spell['duration'])
        print()
        print(spell['description'].replace('*', '-'))
        print()
        print()
        print()

Features

Actions

<<Bardic Inspiration>> Bardic Inspiration. You can inspire others through stirring words or music. To do so, you use a bonus action on your turn to choose one creature other than yourself within 60 feet of you who can hear you. That creature gains one Bardic Inspiration die, a d6. Once within the next 10 minutes, the creature can roll the die and add the number rolled to one ability check, attack roll, or saving throw it makes. The creature can wait until after it rolls the d20 before deciding to use the Bardic Inspiration die, but must decide before the GM says whether the roll succeeds or fails. Once the Bardic Inspiration die is rolled, it is lost. A creature can have only one Bardic Inspiration die at a time. You can use this feature a number of times equal to your Charisma modifier (a minimum of once). You regain any expended uses when you finish a long rest. Your Bardic Inspiration die changes when you reach certain levels in this class. The die becomes a d8 at 5th level, a d10 at 10th level, and a d12 at 15th level.

Passive

<<By Popular Demand>> By Popular Demand. You can always find a place to perform, usually in an inn or tavern but possibly with a circus, at a theater, or even in a noble’s court. At such a place, you receive free lodging and food of a modest or comfortable standard (depending on the quality of the establishment), as long as you perform each night. In addition, your performance makes you something of a local figure. When strangers recognize you in a town where you have performed, they typically take a liking to you.

Instructions

This bit isn’t automated yet, copy and paste from a wiki or elsewhere as you get features you’d like to list here. I’ve left two features here as examples, ‘Bardic Inspiration’ (from the Bard class) and ‘By Popular Demand’ (from the Entertainer background).

Function Definitions (run when opening file with C-c C-c)

code

;;; First few bits are workarounds
;;; to get ox-dnd to work well with our tables.

(defun org-dnd-table (table contents info)
  "Transcode a TABLE from Org to a D&D LaTeX table.
CONTENTS holds the contents of the table.  INFO is a plist holding
contextual information."
  (let ((header (car (org-element-property :header table)))
        (align (org-export-read-attribute :attr_dnd table :align))
        (color (org-export-read-attribute :attr_dnd table :color))
        (size (org-export-read-attribute :attr_dnd table :size))
        (separate (org-export-read-attribute :attr_dnd table :separate)))
    (format
     "%s%s"
     (if header (format "\\header{%s}\n" header) "")
     (replace-regexp-in-string
      "begin{tabular.*"
      (format "begin{DndTable}%s%s"
              (if color (format "[color=%s]" color) "")
              (if align (format "{%s}" align) (format "{%s}" (org-latex--align-string table info))))
      (replace-regexp-in-string
       "end{tabular}"
       "end{DndTable}"
       (replace-regexp-in-string
        "{table}\\(.*\\)\n"
        (format "{table}\\1\n%s"
              (format "\\\\DndSetFonts[table-body-style=\\\\%s]\n" (if size size "large")))
                ;(if size (format "\\\\DndSetFonts[table-body-style=\\\\%s]\n" size) ""))
        (replace-regexp-in-string
         "\\\\\\(begin\\|end\\){center}\n?"
         ""
         (replace-regexp-in-string
          "\\\\centering"
          ""
          (replace-regexp-in-string
           "\\\\hline"
           (if (not separate) ""
             (format "\\\\end{DndTable}\n\\\\begin{DndTable}%s%s"
                     (if color (format "[color=%s]" color) "")
                     (if align (format "{%s}" align) (format "{%s}" (org-latex--align-string table info)))))
           (org-latex-table table contents info))))))))))

(add-to-list 'org-latex-packages-alist '("" "placeins" `nil))
(setq org-latex-default-figure-position "htbp!")


; update table values on export
(advice-add 'org-dnd-export-to-pdf :before
            (lambda (&rest r) (org-table-iterate-buffer-tables)))


; next few are for generating spell list
(defun get-spell-data (spell_names)
  "Get alist with a key for each element of SPELL_NAMES.
Each value is the corresponding SRD data, no entry if element is not in SRD."
  (let ((spell-data 'nil)
        (json-array-type 'list) (json-false 'nil))
    (dolist (spell (json-read-file "./srd_spells/spells.json") spell-data)
      (let ((this_name (alist-get 'name spell)))
        (if (member this_name spell_names)
            (push (cons this_name spell) spell-data))))))

(defun link-to-spellname (link-string)
    (replace-regexp-in-string
     "\\[\\[\\(.*\\)\\]\\[.*\\]\\]"  "\\1" link-string))

(defun srd-alist-to-format-alist (spell_data)
  "corrections given srd alist return alist to use formatting latex strings"
  (let-alist spell_data
    (append `((component_string . ,.components.raw)
              (level . ,(if (equal .level "cantrip")
                            0 .level))
              (school . ,(if .ritual
                             (format "%s (ritual)" .school) .school))
              (higher_levels_string . ,(if .higher_levels
                                           (format "\n\n*At Higher Levels.* %s"
                                                   .higher_levels) ""))
              (description . ,(replace-regexp-in-string "*" "-" .description)))
            spell_data)))

(defun get-spell-names (spell_table additional_spells)
  "parse the spell table for spell names"
  (let ((spell_names additional_spells)) ; add aditional spells here
    (dolist (spell (cdr spell_table) spell_names)
      (push (link-to-spellname (cadr spell)) spell_names))))

(defun get-spell-string (spell_table additional_spells)
  (let* ((spell_names (-sort #'string< (get-spell-names spell_table additional_spells)))
         (spell_data (get-spell-data spell_names))
         (template "\n <<${name}>>\n#+NAME: ${name}
#+ATTR_SPELL: :level ${level} :school ${school} :range ${range} :cast ${casting_time} :duration ${duration} :comp ${component_string}
#+BEGIN_SPELL\n ${description} ${higher_levels_string}\n #+END_SPELL\n")
         (result ""))
    (dolist (spell_n spell_names result)
      (setq result
            (concat result
                    (if (a-has-key spell_data spell_n)
                        (s-format template 'aget
                                  (srd-alist-to-format-alist (a-get spell_data spell_n)))
                      (s-format template
                                (lambda (key map) (a-get map key "n/a"))
                                `(("name" . ,spell_n)
                                  ("description" . "Not available (liekly not in srd json)")))))))))

;;; Below are used in table calcualtions
(defun org-dnd-char-mod-string (mod)
  (if (> mod -1)
      (concat "+" (number-to-string mod))
    (number-to-string mod))
  )

(defun org-dnd-char-stat-to-mod (stat)
  (let ((mod
         (floor (/ (- (string-to-number stat) 10) 2.0))))
    (org-dnd-char-mod-string mod))
  )

(defun org-dnd-char-skill-to-attribute-index (skill)
  (cond
   ((or
     (string-match "Acrobatics" skill)
     (string-match "Sleight of Hand" skill)
     (string-match "Stealth" skill))
    1) ;DEX
   ((or
     (string-match "Animal Handling" skill)
     (string-match "Insight" skill)
     (string-match "Medicine" skill)
     (string-match "Perception" skill)
     (string-match "Survival" skill))
    4) ;WIS
   ((or
     (string-match "Arcana" skill)
     (string-match "History" skill)
     (string-match "Investigation" skill)
     (string-match "Nature" skill)
     (string-match "Religion" skill))
    3) ;INT
   ((string-match "Athletics" skill)
    0) ;STR
   ((or
     (string-match "Deception" skill)
     (string-match "Intimidation" skill)
     (string-match "Performance" skill)
     (string-match "Persuasion" skill))
    5))); CHA

(defun org-dnd-char-skill-mod (prof-check skill-name prof-mod attr-mods)
  (org-dnd-char-mod-string
   (+
    (string-to-number
     (nth
      (org-dnd-char-skill-to-attribute-index skill-name)
      attr-mods))
    (if (string-match "\\*\\*\\*" prof-check)
        (string-to-number prof-mod)
      0; (floor (/ (string-to-number prof-mod) 2.0)) ; replace 0 with this when we get jack of all trades
      )
    (if (string-match "\\*\\+\\*" prof-check) ; for bard feature 'Expertise'
        (string-to-number prof-mod)
      0)
    )))

(defun org-dnd-char-level-to-prof (level)
  (org-dnd-char-mod-string
   (nth (string-to-number level)
        '(2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 6 6 6 6))) ;BARD SPECIFIC, FILL IN YOUR CLASS'S VALUES HERE
  )

(defun org-dnd-char-level-to-cantrips-known (level)
  (nth (- (string-to-number level) 1 )
       '(2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4)) ;BARD SPECIFIC, FILL IN YOUR CLASS'S VALUES HERE
  )

(defun org-dnd-char-level-to-spells-known (level)
  (nth (- (string-to-number level) 1)
       '(4 5 6 7 8 9 10 11 12 14 15 15 16 18 19 19 20 22 22 22)) ;BARD SPECIFIC, FILL IN YOUR CLASS'S VALUES HERE
  )

(defun org-dnd-char-level-to-max-spell (level) ; replace with a function that calls org-dnd-char-spell-slots
  (nth (- (string-to-number level) 1)
       '(1 1 2 2 3 3 4 4 5 5 6 6 6 7 7 8 8 9 9 9)) ;BARD SPECIFIC, FILL IN YOUR CLASS'S VALUES HERE
  )

(defun org-dnd-char-spell-slots (level)
  (let ((slot-matrix
         [ ;BARD SPECIFIC, FILL IN YOUR CLASS'S VALUES HERE
          [2 0 0 0 0 0 0 0 0]
          [3 0 0 0 0 0 0 0 0]
          [4 2 0 0 0 0 0 0 0]
          [4 3 0 0 0 0 0 0 0]
          [4 3 2 0 0 0 0 0 0]
          [4 3 3 0 0 0 0 0 0]
          [4 3 3 1 0 0 0 0 0]
          [4 3 3 2 0 0 0 0 0]
          [4 3 3 3 1 0 0 0 0]
          [4 3 3 3 2 0 0 0 0]
          [4 3 3 3 2 1 0 0 0]
          [4 3 3 3 2 1 0 0 0]
          [4 3 3 3 2 1 1 0 0]
          [4 3 3 3 2 1 1 0 0]
          [4 3 3 3 2 1 1 1 0]
          [4 3 3 3 2 1 1 1 0]
          [4 3 3 3 3 1 1 1 1]
          [4 3 3 3 3 2 1 1 1]
          [4 3 3 3 3 2 2 1 1]
          ]))
    (aref slot-matrix (- (string-to-number level) 1)))
  )

Instructions

Run the above source block when opening the file before exporting.

For now you must fill in the lists and matrices according to your classes table in the player’s handbook. An example for Bards is provided, there are comments in the sections indicating what bits are Bard specific.

If a particular feature, feat, or other rule modifies your stats you can modify these functions to reflect that. There is a comment with an example for the Bard ‘Jack of All Trades’ feature. This will require a bit of elisp, but allows for straightforward homebrew.