Initial commit
Initial project scaffolding
This commit is contained in:
14
lib/compat.sty
Normal file
14
lib/compat.sty
Normal file
@@ -0,0 +1,14 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Compatibility with external packages
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
\cs_if_free:NT \str_case_e:nnF
|
||||
{
|
||||
% \str_case_x was renamed \str_case_e mid-2018. \str_case_x will be removed
|
||||
% at the end of 2019:
|
||||
%
|
||||
% https://github.com/latex3/latex3/blob/8fcb571ddda61c01773d9746d32cecdbe63afb26/l3kernel/l3obsolete.txt#L65
|
||||
\cs_new_eq:NN \str_case_e:nnF \str_case_x:nnF
|
||||
}
|
||||
73
lib/languages/_template.sty
Normal file
73
lib/languages/_template.sty
Normal file
@@ -0,0 +1,73 @@
|
||||
\ExplSyntaxOn % Use tilde (~) for spaces.
|
||||
|
||||
\addto\captions<language> % Replace <language> tag with your language
|
||||
{
|
||||
% Monster basics
|
||||
\renewcommand\armorclassname{Armor~Class}
|
||||
\renewcommand\hitpointsname{Hit~Points}
|
||||
\renewcommand\speedname{Speed}
|
||||
% Monster ability scores
|
||||
\renewcommand\strstatname{STR}
|
||||
\renewcommand\dexstatname{DEX}
|
||||
\renewcommand\constatname{CON}
|
||||
\renewcommand\intstatname{INT}
|
||||
\renewcommand\wisstatname{WIS}
|
||||
\renewcommand\chastatname{CHA}
|
||||
% Monster details
|
||||
\renewcommand\skillsname{Skills}
|
||||
\renewcommand\dimmname{Damage~Immunities}
|
||||
\renewcommand\dvulname{Damage~Vulnerabilities}
|
||||
\renewcommand\dresname{Damage~Resistances}
|
||||
\renewcommand\cimmname{Condition~Immunities}
|
||||
\renewcommand\savesname{Saving~Throws}
|
||||
\renewcommand\sensesname{Senses}
|
||||
\renewcommand\defaultsensesname{passive~Perception~10}
|
||||
\renewcommand\languagesname{Languages}
|
||||
\renewcommand\challengename{Challenge}
|
||||
\renewcommand\xpname{XP}
|
||||
% Monster attack
|
||||
\renewcommand\unitsname{ft.}
|
||||
\renewcommand\weaponname{Weapon}
|
||||
\renewcommand\spellname{Spell}
|
||||
\renewcommand\meleeattackname{Melee~|1|~Attack}
|
||||
\renewcommand\rangedattackname{Ranged~|1|~Attack}
|
||||
\renewcommand\meleeorrangedattackname{Melee~or~Ranged~|1|~Attack}
|
||||
\renewcommand\orname{or}
|
||||
\renewcommand\tohitname{|1|~to~hit}
|
||||
\renewcommand\defaulttargetsname{one~target}
|
||||
\renewcommand\reachname{reach}
|
||||
\renewcommand\rangename{range}
|
||||
\renewcommand\hitname{Hit}
|
||||
\renewcommand\damagename{damage}
|
||||
\renewcommand\plusname{plus}
|
||||
% Spell levels
|
||||
\renewcommand\spellcantripsname{Cantrips}
|
||||
\renewcommand\spellfirstlevelname{1st~level}
|
||||
\renewcommand\spellsecondlevelname{2nd~level}
|
||||
\renewcommand\spellthirdlevelname{3rd~level}
|
||||
\renewcommand\spellfourthlevelname{4th~level}
|
||||
\renewcommand\spellfifthlevelname{5th~level}
|
||||
\renewcommand\spellsixthlevelname{6th~level}
|
||||
\renewcommand\spellseventhlevelname{7th~level}
|
||||
\renewcommand\spelleighthlevelname{8th~level}
|
||||
\renewcommand\spellninthlevelname{9th~level}
|
||||
% Spell slots
|
||||
\renewcommand\spellatwillname{at~will}
|
||||
\renewcommand\spelloneslotname{1~slot}
|
||||
\renewcommand\spelltwoslotsname{2~slots}
|
||||
\renewcommand\spellthreeslotsname{3~slots}
|
||||
\renewcommand\spellfourslotsname{4~slots}
|
||||
% Innate spellcasting
|
||||
\renewcommand\innateatwillname{At~will}
|
||||
\renewcommand\numberperdayname{|1|/day}
|
||||
\renewcommand\numberperdayeachname{|1|/day~each}
|
||||
% Spell header
|
||||
\renewcommand\spellcastingtimename{Casting~Time}
|
||||
\renewcommand\spellrangename{Range}
|
||||
\renewcommand\spellcomponentsname{Components}
|
||||
\renewcommand\spelldurationname{Duration}
|
||||
% Miscellaneous
|
||||
\renewcommand\tocchapterabbreviationname{Ch.}
|
||||
\renewcommand\pageabbreviationname{pg.}
|
||||
\renewcommand\dname{d}
|
||||
}
|
||||
73
lib/languages/french.sty
Normal file
73
lib/languages/french.sty
Normal file
@@ -0,0 +1,73 @@
|
||||
\ExplSyntaxOn % Use tilde (~) for spaces.
|
||||
|
||||
\addto\captionsfrench%
|
||||
{
|
||||
% Monster basics
|
||||
\renewcommand\armorclassname{Classe~d'armure}
|
||||
\renewcommand\hitpointsname{Points~de~vie}
|
||||
\renewcommand\speedname{Vitesse}
|
||||
% Monster ability scores
|
||||
\renewcommand\strstatname{FOR}
|
||||
\renewcommand\dexstatname{DEX}
|
||||
\renewcommand\constatname{CON}
|
||||
\renewcommand\intstatname{INT}
|
||||
\renewcommand\wisstatname{SAG}
|
||||
\renewcommand\chastatname{CHA}
|
||||
% Monster details
|
||||
\renewcommand\skillsname{Compétences}
|
||||
\renewcommand\dimmname{Immunité~contre~les~dégâts}
|
||||
\renewcommand\dvulname{Vulnérabilité~aux~dégâts}
|
||||
\renewcommand\dresname{Résistances~aux~dégâts}
|
||||
\renewcommand\cimmname{Immunité~contre~les~états}
|
||||
\renewcommand\savesname{Jets~de~sauvegarde}
|
||||
\renewcommand\sensesname{Sens}
|
||||
\renewcommand\defaultsensesname{Perception~passive~10}
|
||||
\renewcommand\languagesname{Langues}
|
||||
\renewcommand\challengename{Dangerosité}
|
||||
\renewcommand\xpname{PX}
|
||||
% Monster attack
|
||||
\renewcommand\unitsname{m}
|
||||
\renewcommand\weaponname{d'arme}
|
||||
\renewcommand\spellname{de~sort}
|
||||
\renewcommand\meleeattackname{Attaque~|1|~au~corps~à~corps}
|
||||
\renewcommand\rangedattackname{Attaque~|1|~à~distance}
|
||||
\renewcommand\meleeorrangedattackname{Attaque~|1|~au~corps~à~corps~ou~à~distance}
|
||||
\renewcommand\orname{ou}
|
||||
\renewcommand\tohitname{|1|~pour~toucher}
|
||||
\renewcommand\defaulttargetsname{une~cible}
|
||||
\renewcommand\reachname{allonge}
|
||||
\renewcommand\rangename{portée}
|
||||
\renewcommand\hitname{Touché}
|
||||
\renewcommand\damagename{dégâts}
|
||||
\renewcommand\plusname{plus}
|
||||
% Spell levels
|
||||
\renewcommand\spellcantripsname{Tour~de~magie}
|
||||
\renewcommand\spellfirstlevelname {Niveau~1}
|
||||
\renewcommand\spellsecondlevelname {Niveau~2}
|
||||
\renewcommand\spellthirdlevelname {Niveau~3}
|
||||
\renewcommand\spellfourthlevelname {Niveau~4}
|
||||
\renewcommand\spellfifthlevelname {Niveau~5}
|
||||
\renewcommand\spellsixthlevelname {Niveau~6}
|
||||
\renewcommand\spellseventhlevelname{Niveau~7}
|
||||
\renewcommand\spelleighthlevelname {Niveau~8}
|
||||
\renewcommand\spellninthlevelname {Niveau~9}
|
||||
% Spell slots
|
||||
\renewcommand\spellatwillname{à~volonté}
|
||||
\renewcommand\spelloneslotname{1~emplacement}
|
||||
\renewcommand\spelltwoslotsname{2~emplacements}
|
||||
\renewcommand\spellthreeslotsname{3~emplacements}
|
||||
\renewcommand\spellfourslotsname{4~emplacements}
|
||||
% Innate spellcasting
|
||||
\renewcommand\innateatwillname{À~volonté}
|
||||
\renewcommand\numberperdayname{|1|/jour}
|
||||
\renewcommand\numberperdayeachname{|1|/jour~chacun}
|
||||
% % Spell header
|
||||
\renewcommand\spellcastingtimename{Durée~d'incantation}
|
||||
\renewcommand\spellrangename{Portée}
|
||||
\renewcommand\spellcomponentsname{Composantes}
|
||||
\renewcommand\spelldurationname{Durée}
|
||||
% % Miscellaneous
|
||||
\renewcommand\pageabbreviationname{p.}
|
||||
\renewcommand\dname{d}
|
||||
\renewcommand\tocchapterabbreviationname{Ch.}
|
||||
}
|
||||
75
lib/languages/italian.sty
Normal file
75
lib/languages/italian.sty
Normal file
@@ -0,0 +1,75 @@
|
||||
\ExplSyntaxOn
|
||||
% Use tilde (~) for spaces.
|
||||
|
||||
% Italian captions
|
||||
\addto\captionsitalian
|
||||
{
|
||||
% Monster basics
|
||||
\renewcommand\armorclassname{Classe~Armatura}
|
||||
\renewcommand\hitpointsname{Punti~Ferita}
|
||||
\renewcommand\speedname{Velocit\`a}
|
||||
% Monster ability scores
|
||||
\renewcommand\strstatname{FOR}
|
||||
\renewcommand\dexstatname{DES}
|
||||
\renewcommand\constatname{COS}
|
||||
\renewcommand\intstatname{INT}
|
||||
\renewcommand\wisstatname{SAG}
|
||||
\renewcommand\chastatname{CAR}
|
||||
% Monster details
|
||||
\renewcommand\skillsname{Abilit\`a}
|
||||
\renewcommand\dimmname{Immunità~Danni}
|
||||
\renewcommand\dvulname{Debolezze~Danni}
|
||||
\renewcommand\dresname{Resistenze~Danni}
|
||||
\renewcommand\cimmname{Immunit\`a~Condizioni}
|
||||
\renewcommand\savesname{Tiri~Salvezza}
|
||||
\renewcommand\sensesname{Sensi}
|
||||
% \renewcommand\defaultsensesname{passive~Perception~10}
|
||||
\renewcommand\languagesname{Linguaggi}
|
||||
\renewcommand\challengename{Sfida}
|
||||
\renewcommand\xpname{PE}
|
||||
% Monster attack
|
||||
\renewcommand\unitsname{m.}
|
||||
\renewcommand\weaponname{Arma}
|
||||
\renewcommand\spellname{Sillabare}
|
||||
\renewcommand\meleeattackname{Attacco~con~|1|~da~Mischia}
|
||||
\renewcommand\rangedattackname{Attacco~con~|1|~a~Distanza}
|
||||
\renewcommand\meleeorrangedattackname{Attacco~con~|1|~da~Mischia~o~a~Distanza}
|
||||
\renewcommand\orname{o}
|
||||
\renewcommand\tohitname{|1|~per~colpire}
|
||||
% \renewcommand\defaulttargetsname{one~target}
|
||||
\renewcommand\reachname{portata}
|
||||
\renewcommand\rangename{gittata}
|
||||
\renewcommand\hitname{Colpito}
|
||||
\renewcommand\damagename{danno}
|
||||
% \renewcommand\plusname{plus}
|
||||
% Spell levels
|
||||
\renewcommand\spellcantripsname{Trucchetti}
|
||||
\renewcommand\spellfirstlevelname{1\degree{}~livello}
|
||||
\renewcommand\spellsecondlevelname{2\degree{}~livello}
|
||||
\renewcommand\spellthirdlevelname{3\degree{}~livello}
|
||||
\renewcommand\spellfourthlevelname{4\degree{}~livello}
|
||||
\renewcommand\spellfifthlevelname{5\degree{}~livello}
|
||||
\renewcommand\spellsixthlevelname{6\degree{}~livello}
|
||||
\renewcommand\spellseventhlevelname{7\degree{}~livello}
|
||||
\renewcommand\spelleighthlevelname{8\degree{}~livello}
|
||||
\renewcommand\spellninthlevelname{9\degree{}~livello}
|
||||
% Spell slots
|
||||
\renewcommand\spellatwillname{a~volont\`a}
|
||||
\renewcommand\spelloneslotname{1~slot}
|
||||
\renewcommand\spelltwoslotsname{2~slot}
|
||||
\renewcommand\spellthreeslotsname{3~slot}
|
||||
\renewcommand\spellfourslotsname{4~slot}
|
||||
% Innate spellcasting
|
||||
\renewcommand\innateatwillname{A~volont\`a}
|
||||
\renewcommand\numberperdayname{|1|/giorno}
|
||||
\renewcommand\numberperdayeachname{|1|/g.~ciascuno}
|
||||
% Spell header
|
||||
\renewcommand\spellcastingtimename{Tempo~di~Lancio}
|
||||
\renewcommand\spellrangename{Gittata}
|
||||
\renewcommand\spellcomponentsname{Componenti}
|
||||
\renewcommand\spelldurationname{Durata}
|
||||
% Miscellaneous
|
||||
% \renewcommand\pageabbreviationname{pg.}
|
||||
% \renewcommand\dname{d}
|
||||
% \newcommand\tocchapterabbreviationname{Ch.}
|
||||
}
|
||||
72
lib/languages/japanese.sty
Normal file
72
lib/languages/japanese.sty
Normal file
@@ -0,0 +1,72 @@
|
||||
\ExplSyntaxOn % Use tilde (~) for spaces.
|
||||
|
||||
% Japanese captions
|
||||
\addto\captionsjapanese
|
||||
{
|
||||
% Monster basics
|
||||
\renewcommand\armorclassname{AC:}
|
||||
\renewcommand\hitpointsname{hp:}
|
||||
\renewcommand\speedname{移動速度:}
|
||||
% Monster ability scores
|
||||
\renewcommand\strstatname{【筋】}
|
||||
\renewcommand\dexstatname{【敏】}
|
||||
\renewcommand\constatname{【耐】}
|
||||
\renewcommand\intstatname{【知】}
|
||||
\renewcommand\wisstatname{【判】}
|
||||
\renewcommand\chastatname{【魅】}
|
||||
% Monster details
|
||||
\renewcommand\skillsname{技能:}
|
||||
\renewcommand\dimmname{ダメージ完全耐性:}
|
||||
\renewcommand\dvulname{ダメージ脆弱性:}
|
||||
\renewcommand\dresname{ダメージ抵抗:}
|
||||
\renewcommand\cimmname{状態完全耐性:}
|
||||
\renewcommand\savesname{セーブ:}
|
||||
\renewcommand\sensesname{感覚:}
|
||||
\renewcommand\defaultsensesname{受動〈知覚〉10}
|
||||
\renewcommand\languagesname{言語:}
|
||||
\renewcommand\challengename{脅威度:}
|
||||
\renewcommand\xpname{XP}
|
||||
% Monster attack
|
||||
\renewcommand\unitsname{フィート}
|
||||
\renewcommand\meleeattackname{近接武器攻撃:}
|
||||
\renewcommand\rangedattackname{遠隔武器攻撃:}
|
||||
\renewcommand\meleeorrangedattackname{近接/遠隔武器攻撃:}
|
||||
\renewcommand\orname{または}
|
||||
\renewcommand\tohitname{攻撃|1|}
|
||||
\renewcommand\defaulttargetsname{目標1つ}
|
||||
\renewcommand\reachname{間合い}
|
||||
\renewcommand\rangename{射程}
|
||||
\renewcommand\hitname{ヒット:}
|
||||
\renewcommand\damagename{ダメージ}
|
||||
\renewcommand\plusname{および}
|
||||
% Spell levels
|
||||
\renewcommand\spellcantripsname{初級呪文}
|
||||
\renewcommand\spellfirstlevelname{1レベル}
|
||||
\renewcommand\spellsecondlevelname{2レベル}
|
||||
\renewcommand\spellthirdlevelname{3レベル}
|
||||
\renewcommand\spellfourthlevelname{4レベル}
|
||||
\renewcommand\spellfifthlevelname{5レベル}
|
||||
\renewcommand\spellsixthlevelname{6レベル}
|
||||
\renewcommand\spellseventhlevelname{7レベル}
|
||||
\renewcommand\spelleighthlevelname{8レベル}
|
||||
\renewcommand\spellninthlevelname{9レベル}
|
||||
% Spell slots
|
||||
\renewcommand\spellatwillname{無限回}
|
||||
\renewcommand\spelloneslotname{1スロット}
|
||||
\renewcommand\spelltwoslotsname{2スロット}
|
||||
\renewcommand\spellthreeslotsname{3スロット}
|
||||
\renewcommand\spellfourslotsname{4スロット}
|
||||
% Innate spellcasting
|
||||
\renewcommand\innateatwillname{無限回}
|
||||
\renewcommand\numberperdayname{|1|回/日}
|
||||
\renewcommand\numberperdayeachname{各|1|回/日}
|
||||
% Spell header
|
||||
\renewcommand\spellcastingtimename{発動時間}
|
||||
\renewcommand\spellrangename{射程}
|
||||
\renewcommand\spellcomponentsname{構成要素}
|
||||
\renewcommand\spelldurationname{持続時間}
|
||||
% Miscellaneous
|
||||
\renewcommand\tocchapterabbreviationname{章} % TODO: Update to 第|1|章 when https://github.com/rpgtex/DND-5e-LaTeX-Template/issues/308 is closed
|
||||
\renewcommand\pageabbreviationname{ページ} % TODO: Update to |1|ページ when https://github.com/rpgtex/DND-5e-LaTeX-Template/issues/308 is closed
|
||||
\renewcommand\dname{d}
|
||||
}
|
||||
68
lib/languages/ngerman.sty
Normal file
68
lib/languages/ngerman.sty
Normal file
@@ -0,0 +1,68 @@
|
||||
\ExplSyntaxOn % Use tilde (~) for spaces.
|
||||
|
||||
% German captions
|
||||
\addto\captionsngerman
|
||||
{
|
||||
\renewcommand\armorclassname{Rüstungsklasse}
|
||||
\renewcommand\hitpointsname{Trefferpunkte}
|
||||
\renewcommand\speedname{Bewegungsrate}
|
||||
\renewcommand\strstatname{STR}
|
||||
\renewcommand\dexstatname{GES}
|
||||
\renewcommand\constatname{KON}
|
||||
\renewcommand\intstatname{INT}
|
||||
\renewcommand\wisstatname{WEI}
|
||||
\renewcommand\chastatname{CHA}
|
||||
\renewcommand\skillsname{Fertigkeiten}
|
||||
\renewcommand\dimmname{Schadensimmunitäten}
|
||||
\renewcommand\dvulname{Schadensanfälligkeiten}
|
||||
\renewcommand\dresname{Schadensresistenzen}
|
||||
\renewcommand\cimmname{Zustandsimmunitäten}
|
||||
\renewcommand\savesname{Rettungswürfe}
|
||||
\renewcommand\sensesname{Sinne}
|
||||
\renewcommand\languagesname{Sprachen}
|
||||
\renewcommand\challengename{Herausforderungsgrad}
|
||||
\renewcommand\xpname{EP}
|
||||
% Monster attack
|
||||
\renewcommand\unitsname{m}
|
||||
\renewcommand\meleeattackname{Nahkampf-Waffenangriff}
|
||||
\renewcommand\rangedattackname{Fernkampf-Waffenangriff}
|
||||
\renewcommand\meleeorrangedattackname{Nah-~oder~Fernkampf-Waffenangriff}
|
||||
\renewcommand\orname{oder}
|
||||
\renewcommand\tohitname{|1|~zum~Treffen}
|
||||
\renewcommand\defaulttargetsname{ein~Ziel}
|
||||
\renewcommand\reachname{Reichweite}
|
||||
\renewcommand\rangename{Reichweite}
|
||||
\renewcommand\hitname{Treffer}
|
||||
\renewcommand\damagename{Schaden}
|
||||
\renewcommand\plusname{plus}
|
||||
% Spell levels
|
||||
\renewcommand\spellcantripsname{Zaubertricks}
|
||||
\renewcommand\spellfirstlevelname{1.~Grad}
|
||||
\renewcommand\spellsecondlevelname{2.~Grad}
|
||||
\renewcommand\spellthirdlevelname{3.~Grad}
|
||||
\renewcommand\spellfourthlevelname{4.~Grad}
|
||||
\renewcommand\spellfifthlevelname{5.~Grad}
|
||||
\renewcommand\spellsixthlevelname{6.~Grad}
|
||||
\renewcommand\spellseventhlevelname{7.~Grad}
|
||||
\renewcommand\spelleighthlevelname{8.~Grad}
|
||||
\renewcommand\spellninthlevelname{9.~Grad}
|
||||
% Spell slots
|
||||
\renewcommand\spellatwillname{beliebig oft}
|
||||
\renewcommand\spelloneslotname{1~Platz}
|
||||
\renewcommand\spelltwoslotsname{2~Plätze}
|
||||
\renewcommand\spellthreeslotsname{3~Plätze}
|
||||
\renewcommand\spellfourslotsname{4~Plätze}
|
||||
% Innate spellcasting
|
||||
\renewcommand\innateatwillname{Willentlich}
|
||||
\renewcommand\numberperdayname{|1|/Tag}
|
||||
\renewcommand\numberperdayeachname{jeweils~|1|/Tag}
|
||||
% Spell header
|
||||
\renewcommand\spellcastingtimename{Zeitaufwand}
|
||||
\renewcommand\spellrangename{Reichweite}
|
||||
\renewcommand\spellcomponentsname{Komponenten}
|
||||
\renewcommand\spelldurationname{Wirkungsdauer}
|
||||
% Miscellaneous
|
||||
\renewcommand\pageabbreviationname{S.}
|
||||
\renewcommand\dname{W}
|
||||
\renewcommand\tocchapterabbreviationname{Kap.}
|
||||
}
|
||||
73
lib/languages/portuguese.sty
Normal file
73
lib/languages/portuguese.sty
Normal file
@@ -0,0 +1,73 @@
|
||||
\ExplSyntaxOn % Use tilde (~) for spaces.
|
||||
|
||||
\addto\captionsportuguese
|
||||
{
|
||||
% Monster basics
|
||||
\renewcommand\armorclassname{Classe~de~Armadura}
|
||||
\renewcommand\hitpointsname{Pontos~de~Vida}
|
||||
\renewcommand\speedname{Deslocamento}
|
||||
% Monster ability scores
|
||||
\renewcommand\strstatname{FOR}
|
||||
\renewcommand\dexstatname{DES}
|
||||
\renewcommand\constatname{CON}
|
||||
\renewcommand\intstatname{INT}
|
||||
\renewcommand\wisstatname{SAB}
|
||||
\renewcommand\chastatname{CAR}
|
||||
% Monster details
|
||||
\renewcommand\skillsname{Habilidades}
|
||||
\renewcommand\dimmname{Imunidade~a~Dano}
|
||||
\renewcommand\dvulname{Vulnerabilidade~a~Dano}
|
||||
\renewcommand\dresname{Resistência~a~Dano}
|
||||
\renewcommand\cimmname{Imunidade~a~Condição}
|
||||
\renewcommand\savesname{Testes~de~Resistência}
|
||||
\renewcommand\sensesname{Sentidos}
|
||||
\renewcommand\defaultsensesname{Percepção~passiva~10}
|
||||
\renewcommand\languagesname{Idiomas}
|
||||
\renewcommand\challengename{Nível~de~Desafio}
|
||||
\renewcommand\xpname{XP}
|
||||
% Monster attack
|
||||
\renewcommand\unitsname{m}
|
||||
\renewcommand\weaponname{Arma}
|
||||
\renewcommand\spellname{Magia}
|
||||
\renewcommand\meleeattackname{Ataque~Corpo-a-Corpo~com~|1|}
|
||||
\renewcommand\rangedattackname{Ataque~à~Distância~com~|1|}
|
||||
\renewcommand\meleeorrangedattackname{Ataque~Corpo-a-Corpo~ou~à~Distancia~com~|1|}
|
||||
\renewcommand\orname{ou}
|
||||
\renewcommand\tohitname{|1|~para~atingir}
|
||||
\renewcommand\defaulttargetsname{um~alvo}
|
||||
\renewcommand\reachname{alcance}
|
||||
\renewcommand\rangename{alcance}
|
||||
\renewcommand\hitname{Acerto}
|
||||
\renewcommand\damagename{dano}
|
||||
\renewcommand\plusname{e}
|
||||
% Spell levels
|
||||
\renewcommand\spellcantripsname{Truques}
|
||||
\renewcommand\spellfirstlevelname{1º~nível}
|
||||
\renewcommand\spellsecondlevelname{2º~nível}
|
||||
\renewcommand\spellthirdlevelname{3º~nível}
|
||||
\renewcommand\spellfourthlevelname{4º~nível}
|
||||
\renewcommand\spellfifthlevelname{5º~nível}
|
||||
\renewcommand\spellsixthlevelname{6º~nível}
|
||||
\renewcommand\spellseventhlevelname{7º~nível}
|
||||
\renewcommand\spelleighthlevelname{8º~nível}
|
||||
\renewcommand\spellninthlevelname{9º~nível}
|
||||
% Spell slots
|
||||
\renewcommand\spellatwillname{à~vontade}
|
||||
\renewcommand\spelloneslotname{1~espaço}
|
||||
\renewcommand\spelltwoslotsname{2~espaços}
|
||||
\renewcommand\spellthreeslotsname{3~espaços}
|
||||
\renewcommand\spellfourslotsname{4~espaços}
|
||||
% Innate spellcasting
|
||||
\renewcommand\innateatwillname{À~vontade}
|
||||
\renewcommand\numberperdayname{|1|/dia}
|
||||
\renewcommand\numberperdayeachname{|1|/dia~cada}
|
||||
% Spell header
|
||||
\renewcommand\spellcastingtimename{Tempo~de~Conjuração}
|
||||
\renewcommand\spellrangename{Alcance}
|
||||
\renewcommand\spellcomponentsname{Componentes}
|
||||
\renewcommand\spelldurationname{Duração}
|
||||
% Miscellaneous
|
||||
\renewcommand\dname{d}
|
||||
\renewcommand\pageabbreviationname{pág.}
|
||||
\renewcommand\tocchapterabbreviationname{cap.}
|
||||
}
|
||||
74
lib/languages/russian.sty
Normal file
74
lib/languages/russian.sty
Normal file
@@ -0,0 +1,74 @@
|
||||
\ExplSyntaxOn % Use tilde (~) for spaces.
|
||||
|
||||
% Russian captions
|
||||
\addto\captionsrussian
|
||||
{
|
||||
% Monster basics
|
||||
\renewcommand\armorclassname{Класс~Доспехов}
|
||||
\renewcommand\hitpointsname{Хиты}
|
||||
\renewcommand\speedname{Скорость}
|
||||
% Monster ability scores
|
||||
\renewcommand\strstatname{СИЛ}
|
||||
\renewcommand\dexstatname{ЛОВ}
|
||||
\renewcommand\constatname{ТЕЛ}
|
||||
\renewcommand\intstatname{ИНТ}
|
||||
\renewcommand\wisstatname{МДР}
|
||||
\renewcommand\chastatname{ХАР}
|
||||
% Monster details
|
||||
\renewcommand\skillsname{Навыки}
|
||||
\renewcommand\dimmname{Иммунитет~к~урону}
|
||||
\renewcommand\dvulname{Уязвимость~к~урону}
|
||||
\renewcommand\dresname{Сопротивление~урону}
|
||||
\renewcommand\cimmname{Иммунитет~к~состояниям}
|
||||
\renewcommand\savesname{Спасброски}
|
||||
% \renewcommand\defaultsensesname{passive~Perception~10}
|
||||
\renewcommand\sensesname{Чувства}
|
||||
\renewcommand\languagesname{Языки}
|
||||
\renewcommand\challengename{Опасность}
|
||||
% \renewcommand\xpname{XP}
|
||||
% Monster attack
|
||||
% \renewcommand\unitsname{ft.}
|
||||
% \renewcommand\weaponname{Weapon}
|
||||
% \renewcommand\spellname{Spell}
|
||||
% \renewcommand\meleeattackname{Melee~|1|~Attack}
|
||||
% \renewcommand\rangedattackname{Ranged~|1|~Attack}
|
||||
% \renewcommand\meleeorrangedattackname{Melee~or~Ranged~|1|~Attack}
|
||||
% \renewcommand\orname{or}
|
||||
% \renewcommand\tohitname{|1|~to~hit}
|
||||
% \renewcommand\defaulttargetsname{one~target}
|
||||
% \renewcommand\reachname{reach}
|
||||
% \renewcommand\rangename{range}
|
||||
% \renewcommand\hitname{Hit}
|
||||
% \renewcommand\damagename{damage}
|
||||
% \renewcommand\plusname{plus}
|
||||
% Spell levels
|
||||
% \renewcommand\spellcantripsname{Cantrips}
|
||||
% \renewcommand\spellfirstlevelname{1st~level}
|
||||
% \renewcommand\spellsecondlevelname{2nd~level}
|
||||
% \renewcommand\spellthirdlevelname{3rd~level}
|
||||
% \renewcommand\spellfourthlevelname{4th~level}
|
||||
% \renewcommand\spellfifthlevelname{5th~level}
|
||||
% \renewcommand\spellsixthlevelname{6th~level}
|
||||
% \renewcommand\spellseventhlevelname{7th~level}
|
||||
% \renewcommand\spelleighthlevelname{8th~level}
|
||||
% \renewcommand\spellninthlevelname{9th~level}
|
||||
% Spell slots
|
||||
% \renewcommand\spellatwillname{at~will}
|
||||
% \renewcommand\spelloneslotname{1~slot}
|
||||
% \renewcommand\spelltwoslotsname{2~slots}
|
||||
% \renewcommand\spellthreeslotsname{3~slots}
|
||||
% \renewcommand\spellfourslotsname{4~slots}
|
||||
% Innate spellcasting
|
||||
% \renewcommand\innateatwillname{At~will}
|
||||
% \renewcommand\numberperdayname{|1|/day}
|
||||
% \renewcommand\numberperdayeachname{|1|/day~each}
|
||||
% % Spell header
|
||||
% \renewcommand\spellcastingtimename{Casting~Time}
|
||||
% \renewcommand\spellrangename{Range}
|
||||
% \renewcommand\spellcomponentsname{Components}
|
||||
% \renewcommand\spelldurationname{Duration}
|
||||
% % Miscellaneous
|
||||
% \renewcommand\pageabbreviationname{pg.}
|
||||
% \renewcommand\dname{d}
|
||||
% \newcommand\tocchapterabbreviationname{Ch.}
|
||||
}
|
||||
73
lib/languages/spanish.sty
Executable file
73
lib/languages/spanish.sty
Executable file
@@ -0,0 +1,73 @@
|
||||
\ExplSyntaxOn % Use tilde (~) for spaces.
|
||||
|
||||
\addto\captionsspanish
|
||||
{
|
||||
% Monster basics
|
||||
\renewcommand\armorclassname{Clase~de~Armadura}
|
||||
\renewcommand\hitpointsname{Puntos~de~Golpe}
|
||||
\renewcommand\speedname{Velocidad}
|
||||
% Monster ability scores
|
||||
\renewcommand\strstatname{FUE}
|
||||
\renewcommand\dexstatname{DES}
|
||||
\renewcommand\constatname{CON}
|
||||
\renewcommand\intstatname{INT}
|
||||
\renewcommand\wisstatname{SAB}
|
||||
\renewcommand\chastatname{CAR}
|
||||
% Monster details
|
||||
\renewcommand\skillsname{Habilidades}
|
||||
\renewcommand\dimmname{Inmunidad~a~daño}
|
||||
\renewcommand\dvulname{Vulnerabilidad~a~daño}
|
||||
\renewcommand\dresname{Resistencia~a~daño}
|
||||
\renewcommand\cimmname{Inmunidad~a~estados}
|
||||
\renewcommand\savesname{Tiradas~de~salvación}
|
||||
\renewcommand\sensesname{Sentidos}
|
||||
\renewcommand\defaultsensesname{Percepción~pasiva~10}
|
||||
\renewcommand\languagesname{Idiomas}
|
||||
\renewcommand\challengename{Desafío}
|
||||
\renewcommand\xpname{PE}
|
||||
% Monster attack
|
||||
\renewcommand\unitsname{pies}
|
||||
\renewcommand\weaponname{arma}
|
||||
\renewcommand\spellname{Hechizo}
|
||||
\renewcommand\meleeattackname{Ataque~con~|1|~cuerpo~a~cuerpo}
|
||||
\renewcommand\rangedattackname{Ataque~con~|1|~a~distancia}
|
||||
\renewcommand\meleeorrangedattackname{Ataque~con~|1|~cuerpo~a~cuerpo~o~a~distancia}
|
||||
\renewcommand\orname{o}
|
||||
\renewcommand\tohitname{|1|~a~impactar}
|
||||
\renewcommand\defaulttargetsname{un~objetivo}
|
||||
\renewcommand\reachname{alcance}
|
||||
\renewcommand\rangename{alcance}
|
||||
\renewcommand\hitname{Impacto}
|
||||
\renewcommand\damagename{daño}
|
||||
\renewcommand\plusname{y}
|
||||
% Spell levels
|
||||
\renewcommand\spellcantripsname{Trucos}
|
||||
\renewcommand\spellfirstlevelname{Nivel~1}
|
||||
\renewcommand\spellsecondlevelname{Nivel~2}
|
||||
\renewcommand\spellthirdlevelname{Nivel~3}
|
||||
\renewcommand\spellfourthlevelname{Nivel~4}
|
||||
\renewcommand\spellfifthlevelname{Nivel~5}
|
||||
\renewcommand\spellsixthlevelname{Nivel~6}
|
||||
\renewcommand\spellseventhlevelname{Nivel~7}
|
||||
\renewcommand\spelleighthlevelname{Nivel~8}
|
||||
\renewcommand\spellninthlevelname{Nivel~9}
|
||||
% Spell slots
|
||||
\renewcommand\spellatwillname{a~voluntad}
|
||||
\renewcommand\spelloneslotname{1~espacio}
|
||||
\renewcommand\spelltwoslotsname{2~espacios}
|
||||
\renewcommand\spellthreeslotsname{3~espacios}
|
||||
\renewcommand\spellfourslotsname{4~espacios}
|
||||
% Innate spellcasting
|
||||
\renewcommand\innateatwillname{A~voluntad}
|
||||
\renewcommand\numberperdayname{|1|~al~día}
|
||||
\renewcommand\numberperdayeachname{|1|~al~día~cada~uno}
|
||||
% Spell header
|
||||
\renewcommand\spellcastingtimename{Tiempo~de~lanzamiento}
|
||||
\renewcommand\spellrangename{Alcance}
|
||||
\renewcommand\spellcomponentsname{Componentes}
|
||||
\renewcommand\spelldurationname{Duración}
|
||||
% Miscellaneous
|
||||
\renewcommand\dname{d}
|
||||
\renewcommand\pageabbreviationname{pág.}
|
||||
\renewcommand\tocchapterabbreviationname{cap.}
|
||||
}
|
||||
56
lib/rpgcolors.sty
Normal file
56
lib/rpgcolors.sty
Normal file
@@ -0,0 +1,56 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Define colors, sampled from the books.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Page
|
||||
\definecolor {bgtan} {HTML} {F7F2E5} % RpgReadAloud background
|
||||
\definecolor {bgtan2018}{HTML} {F9EFD6} % lighter version of bgtan from the 2018 Basic Rules
|
||||
\definecolor {pagegold} {HTML} {B89A67} % pagenumbers and footer
|
||||
|
||||
% Type
|
||||
\definecolor {titlered} {HTML} {58180D} % titles
|
||||
\definecolor {titlegold} {HTML} {C9AD6A} % titlerules
|
||||
\definecolor {rulered} {HTML} {9C2B1B} % triangular rule in statsblock
|
||||
\definecolor {contourgray} {HTML} {CACCBE} % outline color in part & chapter font
|
||||
|
||||
% Type aliases
|
||||
\colorlet {contourgrey} {contourgray}
|
||||
|
||||
% Trim
|
||||
\definecolor {BrGreen} {HTML} {E8E6DC} % Basic Rules
|
||||
\definecolor {PhbLightGreen} {HTML} {E0E5C1} % PHB Part 1
|
||||
\definecolor {PhbLightCyan} {HTML} {B5CEB8} % PHB Part 2
|
||||
\definecolor {PhbMauve} {HTML} {DCCCC5} % PHB Part 3
|
||||
\definecolor {PhbTan} {HTML} {E5D5AC} % PHB appendix
|
||||
\definecolor {DmgLavender} {HTML} {E3CED3} % DMG Part 1
|
||||
\definecolor {DmgCoral} {HTML} {F3D7C1} % DMG Part 2
|
||||
\definecolor {DmgSlateGray} {HTML} {DBE4E4} % DMG Part 3
|
||||
\definecolor {DmgLilac} {HTML} {D7D4D6} % DMG appendix
|
||||
|
||||
% Trim aliases
|
||||
\colorlet {DmgSlateGrey} {DmgSlateGray}
|
||||
|
||||
% The color used in \RpgSetThemeColor when a new color is not set
|
||||
\colorlet {themecolor} {PhbLightGreen} % Set the default theme to Part 1 of the PHB.
|
||||
|
||||
% Element colors that change when \RpgSetThemeColor is used
|
||||
\colorlet {commentcolor} {themecolor} % RpgComment background
|
||||
\colorlet {sidebarcolor} {themecolor} % RpgSidebar background
|
||||
\colorlet {tablecolor} {themecolor} % RpgTable even row background
|
||||
|
||||
% Element colors that do not respond to \RpgSetThemeColor
|
||||
\colorlet {readaloudcolor} {bgtan} % RpgReadAloud background
|
||||
\definecolor {statblockribbon} {HTML} {E69A28} % stat block top/bottom borders (gold)
|
||||
\definecolor {statblockbg} {HTML} {FDF1DC} % stat block background (tan)
|
||||
|
||||
% Sets the themecolor and colors for all themed elements
|
||||
% If called without the optional color, resets the color of all themed elements to the current themecolor
|
||||
\NewDocumentCommand {\RpgSetThemeColor} { O {themecolor} }
|
||||
{
|
||||
\colorlet {themecolor} {#1}
|
||||
\colorlet {commentcolor} {#1}
|
||||
\colorlet {sidebarcolor} {#1}
|
||||
\colorlet {tablecolor} {#1}
|
||||
}
|
||||
78
lib/rpgcomment.sty
Normal file
78
lib/rpgcomment.sty
Normal file
@@ -0,0 +1,78 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Environment for comments.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Standard for every comment
|
||||
\DeclareTColorBox {__rpg_comment} {o}
|
||||
{
|
||||
before~upper =
|
||||
{
|
||||
\bool_if:NT \l__rpg_layout_bool
|
||||
{
|
||||
\bool_if:NF \l__rpg_justified_bool
|
||||
{ \RaggedRight }
|
||||
}
|
||||
},
|
||||
code = {\linespread{.9}},
|
||||
frame~hidden,
|
||||
boxrule = 0pt,
|
||||
breakable,
|
||||
enhanced,
|
||||
before~skip = 13pt plus 4pt minus 4pt,
|
||||
toptitle = 2pt,
|
||||
boxsep = 3pt,
|
||||
left = 6pt,
|
||||
right = 6pt,
|
||||
top = 0pt,
|
||||
bottom = 2pt,
|
||||
sharp~corners,
|
||||
fonttitle = \RpgFontCommentTitle,
|
||||
fontupper = \RpgFontCommentBody,
|
||||
fontlower = \RpgFontCommentBody,
|
||||
parbox = false,
|
||||
coltitle = black,
|
||||
after~skip = 13pt plus 4pt minus 4pt,
|
||||
#1,
|
||||
}
|
||||
|
||||
% Extra key for controlling the color of the title and the background
|
||||
\keys_define:nn { rpg / comment }
|
||||
{
|
||||
color .tl_set:N = \l__rpg_comment_color_tl,
|
||||
color .initial:n = commentcolor,
|
||||
color .value_required:n = true,
|
||||
}
|
||||
|
||||
% This function, through its variant, forces the expansion of the tcb keys
|
||||
% passed to the environment by the user before it invokes the tcolorbox
|
||||
\cs_new_protected:Nn \__rpg_start_comment:nn
|
||||
{
|
||||
\begin {__rpg_comment} [ #1, #2 ]
|
||||
}
|
||||
|
||||
\cs_generate_variant:Nn \__rpg_start_comment:nn { nV }
|
||||
|
||||
% The RpgComment environment
|
||||
% #1 - keys. We handle the custom color key before passing other keys on
|
||||
% #2 - title.
|
||||
\NewDocumentEnvironment {RpgComment} { o m }
|
||||
{
|
||||
\group_begin:
|
||||
\keys_set_known:nnN { rpg / comment } {#1} \l_tmpa_tl
|
||||
|
||||
\str_if_eq:VnT \l_tmpa_tl { -NoValue- }
|
||||
{ \tl_set_eq:NN \l_tmpa_tl \c_empty_tl }
|
||||
|
||||
\__rpg_start_comment:nV
|
||||
{
|
||||
colback = \l__rpg_comment_color_tl,
|
||||
colbacktitle = \l__rpg_comment_color_tl,
|
||||
title = {#2},
|
||||
}
|
||||
{ \l_tmpa_tl }
|
||||
}
|
||||
{
|
||||
\end {__rpg_comment}
|
||||
\group_end:
|
||||
}
|
||||
620
lib/rpgdeprecated.sty
Normal file
620
lib/rpgdeprecated.sty
Normal file
@@ -0,0 +1,620 @@
|
||||
\RequirePackage {keycommand}
|
||||
|
||||
\ExplSyntaxOn
|
||||
\NewDocumentCommand{\RpgDeprecate}{ mmm }
|
||||
{
|
||||
\__rpg_deprecated:nnn {#1} {#2} {#3}
|
||||
}
|
||||
\ExplSyntaxOff
|
||||
|
||||
% Either hilariously, or infuriatingly, the \ifcommandkey
|
||||
% implementation is buggy. Here is a re-implementation
|
||||
% from tex.stackexchange.
|
||||
\begingroup
|
||||
\makeatletter
|
||||
\catcode`\/=8 %
|
||||
\@firstofone
|
||||
{
|
||||
\endgroup
|
||||
\renewcommand{\ifcommandkey}[1]{%
|
||||
\csname @\expandafter \expandafter \expandafter
|
||||
\expandafter \expandafter \expandafter \expandafter
|
||||
\kcmd@nbk \commandkey {#1}//{first}{second}//oftwo\endcsname
|
||||
}
|
||||
}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% rpgcolors.sty - to be removed in version 1.0.0
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Sets the themecolor and colors for all themed elements
|
||||
% If called without the optional color, resets the color of all themed elements to the current themecolor
|
||||
\newcommand{\setthemecolor}[1][themecolor]{%
|
||||
\RpgDeprecate{\noexpand\setthemecolor}{1.0.0}{Use \noexpand\RpgSetThemeColor to set the theme color.}%
|
||||
\colorlet{themecolor}{#1}
|
||||
\colorlet{commentcolor}{#1}
|
||||
\colorlet{sidebarcolor}{#1}
|
||||
\colorlet{tablecolor}{#1}
|
||||
}
|
||||
|
||||
% Backwards-compatible aliases and colours
|
||||
\colorlet {commentgreen} {PhbLightGreen}
|
||||
\colorlet {itemtablepink} {DmgCoral}
|
||||
\colorlet {monstertan} {statblockbg}
|
||||
\definecolor {monstertandark} {HTML} {F0DBB5}
|
||||
|
||||
% Old interface
|
||||
\colorlet {commentboxcolor} {commentcolor}
|
||||
\colorlet {paperboxcolor} {sidebarcolor}
|
||||
\colorlet {quoteboxcolor} {readaloudcolor}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% rpgcomment.sty - to be removed in version 1.0.0
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%Usage \begin{commentbox}[options]{title}[color]
|
||||
\ExplSyntaxOn
|
||||
\DeclareTColorBox{commentbox}{O{} m O{commentboxcolor}}{%
|
||||
before~upper={%
|
||||
\bool_if:NT \l__rpg_layout_bool
|
||||
{
|
||||
\bool_if:NF \l__rpg_justified_bool
|
||||
{ \RaggedRight }
|
||||
}
|
||||
},
|
||||
code={\RpgDeprecate{\noexpand\commentbox}{1.0.0}{Use~\noexpand\RpgComment~for~breakable~comment~boxes.}\linespread{.9}},
|
||||
frame~hidden,
|
||||
boxrule=0pt,
|
||||
breakable,
|
||||
enhanced,
|
||||
before~skip=13pt plus 4pt minus 4pt,
|
||||
toptitle=2pt,
|
||||
boxsep=3pt,
|
||||
left=6pt,
|
||||
right=6pt,
|
||||
top=0pt,
|
||||
bottom=2pt,
|
||||
sharp~corners,
|
||||
fonttitle=\RpgFontCommentTitle,
|
||||
fontupper=\RpgFontCommentBody,
|
||||
fontlower=\RpgFontCommentBody,
|
||||
title={#2},
|
||||
parbox=false,
|
||||
colback=#3,
|
||||
colbacktitle=#3,
|
||||
coltitle=black,
|
||||
after~skip=13pt plus 4pt minus 4pt,
|
||||
#1
|
||||
}
|
||||
\ExplSyntaxOff
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% rpgmonster.sty - to be removed in version 1.0.0
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Fancy DnD 5e stat block rule
|
||||
\newcommand{\rpgline}{%
|
||||
\RpgDeprecate{\noexpand\rpgline}{1.0.0}{Use \noexpand\RpgMonsterLine for stat block rules.}%
|
||||
\noindent
|
||||
\begin{tikzpicture}[]
|
||||
\draw [rulered, fill=rulered] (0, 0) --(0,0.1) -- (\textwidth, 0.05);
|
||||
\end{tikzpicture}%
|
||||
\par%
|
||||
}
|
||||
|
||||
\RequirePackage{fp}
|
||||
\RequirePackage{xstring}
|
||||
|
||||
% Macro to print stats with auto-computed modifier
|
||||
% e.g. \stat{12} prints "12 (+1)"
|
||||
\newcommand{\stat}[1]{%
|
||||
\RpgDeprecate{\noexpand\stat}{1.0.0}{Use \noexpand\RpgMonsterAbilityScores for the stat block ability score table.}%
|
||||
\FPeval{\mod}{(#1 - 10)/2}%
|
||||
\FPifpos\mod%
|
||||
\FPeval{\mod}{clip(trunc(mod,0))}#1\ (+\mod)%
|
||||
\else%
|
||||
\FPeval{\mod}{clip(abs(trunc(mod-0.5,0)))}#1\ (--\mod)%
|
||||
\fi%
|
||||
}
|
||||
|
||||
% Macro to print avarage dice based value
|
||||
% e.g. \dice{2d6+3} prints "10 (2d6 + 3)"
|
||||
\newcommand{\dice}[1]{%
|
||||
\RpgDeprecate{\noexpand\dice}{1.0.0}{Use \noexpand\RpgDice to typeset a dice roll with the average value.}%
|
||||
\StrSubstitute{#1}{ }{}[\DiceArg]% strip whitespaces
|
||||
\StrCut{\DiceArg}{d}\DiceNum\DiceSides% split string
|
||||
\StrCut{\DiceSides}{+}\DiceSides\DiceAddMod%
|
||||
\StrCut{\DiceSides}{-}\DiceSides\DiceSubMod%
|
||||
\FPeval{\DiceAvg}{(\DiceSides+1)/2*\DiceNum}% calculate avg roll
|
||||
\IfInteger{\DiceAddMod}{%
|
||||
\FPadd{\DiceAvg}{\DiceAvg}{\DiceAddMod}% add value
|
||||
\def\DiceMod{ + \DiceAddMod}%
|
||||
}{%
|
||||
\IfInteger{\DiceSubMod}{%
|
||||
\FPsub{\DiceAvg}{\DiceAvg}{\DiceSubMod}% subtract value
|
||||
\def\DiceMod{ -- \DiceSubMod}%
|
||||
}{%
|
||||
\def\DiceMod{}%
|
||||
}%
|
||||
}%
|
||||
\FPtrunc{\DiceAvg}{\DiceAvg}{0}% round down
|
||||
\FPprint{\DiceAvg\ (\DiceNum \dname\DiceSides\DiceMod)}%
|
||||
}
|
||||
|
||||
% Stat block without the background
|
||||
\newtcolorbox{monsterboxnobg}[2][]{
|
||||
enhanced,
|
||||
code={\RpgDeprecate{\noexpand\monsterboxnobg}{1.0.0}{Use \noexpand\RpgMonsterNoBg for stat blocks without a background.}},
|
||||
frame hidden,
|
||||
boxrule=0pt,
|
||||
breakable,
|
||||
parbox=false,
|
||||
boxsep=0pt,
|
||||
toptitle=3mm,
|
||||
left=0pt,
|
||||
right=0pt,
|
||||
sharp corners,
|
||||
opacityback=0,
|
||||
colframe=titlered,
|
||||
fonttitle=\RpgFontStatBlockTitle,
|
||||
fontupper=\RpgFontStatBlockBody,
|
||||
fontlower=\RpgFontStatBlockBody,
|
||||
title=#2,
|
||||
coltitle=titlered,
|
||||
#1
|
||||
}
|
||||
|
||||
% Stat block with background
|
||||
\newtcolorbox{monsterboxbg}[2][]{
|
||||
enhanced,
|
||||
code={\RpgDeprecate{\noexpand\monsterboxbg}{1.0.0}{Use \noexpand\RpgMonsterBg for stat blocks with a background.}},
|
||||
frame hidden,
|
||||
before skip=12pt plus 3pt minus 3pt,
|
||||
boxrule=0pt,
|
||||
breakable,
|
||||
parbox=false,
|
||||
boxsep=2pt,
|
||||
toptitle=8pt,
|
||||
top=0pt,
|
||||
left=2pt,
|
||||
right=2pt,
|
||||
bottom=7pt,
|
||||
sharp corners,
|
||||
oversize=0pt,
|
||||
borderline north={3pt}{0pt}{titlered},
|
||||
borderline north={2pt}{0.5pt}{statblockribbon},
|
||||
borderline south={3pt}{0pt}{titlered},
|
||||
borderline south={2pt}{0.5pt}{statblockribbon},
|
||||
colback=statblockbg,
|
||||
colbacktitle=statblockbg,
|
||||
colframe=titlered,
|
||||
fonttitle=\RpgFontStatBlockTitle,
|
||||
coltitle=titlered,
|
||||
fontupper=\RpgFontStatBlockBody,
|
||||
fontlower=\RpgFontStatBlockBody,
|
||||
title=#2,
|
||||
#1
|
||||
}
|
||||
|
||||
\ExplSyntaxOn
|
||||
\bool_if:NTF \l__rpg_show_background_bool
|
||||
{
|
||||
\let\monsterbox\monsterboxbg%
|
||||
\let\endmonsterbox\endmonsterboxbg%
|
||||
}
|
||||
{
|
||||
\let\monsterbox\monsterboxnobg%
|
||||
\let\endmonsterbox\endmonsterboxnobg%
|
||||
}
|
||||
|
||||
\ExplSyntaxOff
|
||||
|
||||
% Define Monster subsection header style
|
||||
\newcommand{\monstersection}[1]{%
|
||||
\RpgDeprecate{\noexpand\monstersection}{1.0.0}{Use \noexpand\RpgMonsterSection for stat blocks sections.}%
|
||||
\begingroup
|
||||
\par\medskip\noindent
|
||||
\RpgFontStatBlockSection #1
|
||||
% \rule is a horizontal command, so placing it under the title incurs extra
|
||||
% line spacing. Use \hrule (a vertical command) instead.
|
||||
\vspace{3pt}
|
||||
\hrule height 0.6pt
|
||||
\vspace{2pt}
|
||||
\endgroup%
|
||||
}
|
||||
|
||||
\NewDocumentEnvironment{monsteraction}{o}{%
|
||||
\RpgDeprecate{\noexpand\monsteraction}{1.0.0}{Use \noexpand\RpgMonsterAction for stat block actions.}%
|
||||
\IfValueTF{#1}{%
|
||||
\par\medskip\noindent\emph{\textbf{#1.}}%
|
||||
}{\unskip}%
|
||||
}{\par}
|
||||
|
||||
% A description variant used to list creature attributes.
|
||||
\newlist{rpg@monsterattrs}{description}{1}
|
||||
|
||||
\ExplSyntaxOn
|
||||
|
||||
\setlist[rpg@monsterattrs]{
|
||||
before=\color{titlered},
|
||||
font=\RpgFontStatBlockBody,
|
||||
labelsep=\l__rpg_space_dim,
|
||||
noitemsep,
|
||||
nosep,
|
||||
}
|
||||
|
||||
\ExplSyntaxOff
|
||||
|
||||
% A rpg@monsterattrs helper macro that always displays an attribute.
|
||||
\newcommand{\rpg@monsterattr}[2]{%
|
||||
\item[#2] \commandkey{#1}
|
||||
}
|
||||
|
||||
% A rpg@monsterattrs helper macro that displays an attribute if the user defined
|
||||
% it.
|
||||
\newcommand{\rpg@ifmonsterattr}[2]{%
|
||||
\ifcommandkey{#1}{%
|
||||
\item[#2] \commandkey{#1}
|
||||
}{}%
|
||||
}
|
||||
|
||||
%
|
||||
% Macros for use within the monster environment
|
||||
%
|
||||
\newkeycommand\basics[armorclass=0, hitpoints=0, speed=0]{%
|
||||
\RpgDeprecate{\noexpand\basics}{1.0.0}{Use \noexpand\RpgMonsterBasics for stat block AC, HP, and speed.}%
|
||||
\begin{rpg@monsterattrs}
|
||||
\rpg@monsterattr{armorclass}{\armorclassname}
|
||||
\rpg@monsterattr{hitpoints}{\hitpointsname}
|
||||
\rpg@monsterattr{speed}{\speedname}
|
||||
\end{rpg@monsterattrs}%
|
||||
}
|
||||
|
||||
% Taubular enviornment for stats-block
|
||||
\newkeycommand\stats[%
|
||||
STR=\stat{10},
|
||||
DEX=\stat{10},
|
||||
CON=\stat{10},
|
||||
INT=\stat{10},
|
||||
WIS=\stat{10},
|
||||
CHA=\stat{10}]{%
|
||||
\RpgDeprecate{\noexpand\stats}{1.0.0}{Use \noexpand\RpgMonsterAbilityScores for the stat block ability score table.}%
|
||||
\begingroup%
|
||||
\color{titlered}%
|
||||
\par\vspace{5pt}\noindent%
|
||||
\begin{tabularx}{\linewidth}{YYYYYY}
|
||||
\textbf{\strstatname} &
|
||||
\textbf{\dexstatname} &
|
||||
\textbf{\constatname} &
|
||||
\textbf{\intstatname} &
|
||||
\textbf{\wisstatname} &
|
||||
\textbf{\chastatname} \\
|
||||
\commandkey{STR} &
|
||||
\commandkey{DEX} &
|
||||
\commandkey{CON} &
|
||||
\commandkey{INT} &
|
||||
\commandkey{WIS} &
|
||||
\commandkey{CHA}
|
||||
\end{tabularx}%
|
||||
\par\vspace{4pt}%
|
||||
\endgroup%
|
||||
}
|
||||
|
||||
\newkeycommand\details[
|
||||
skills=,
|
||||
damageimmunities=,
|
||||
savingthrows=,
|
||||
conditionimmunities=,
|
||||
damageresistances=,
|
||||
damagevulnerabilities=,
|
||||
senses=---,
|
||||
languages=---,
|
||||
challenge=1,
|
||||
]{%
|
||||
\RpgDeprecate{\noexpand\details}{1.0.0}{Use \noexpand\RpgMonsterDetails for stat block details like resistances and CR.}%
|
||||
\begin{rpg@monsterattrs}
|
||||
\rpg@ifmonsterattr{savingthrows}{\savesname}
|
||||
\rpg@ifmonsterattr{skills}{\skillsname}
|
||||
\rpg@ifmonsterattr{damagevulnerabilities}{\dvulname}
|
||||
\rpg@ifmonsterattr{damageresistances}{\dresname}
|
||||
\rpg@ifmonsterattr{damageimmunities}{\dimmname}
|
||||
\rpg@ifmonsterattr{conditionimmunities}{\cimmname}
|
||||
\rpg@monsterattr{senses}{\sensesname}
|
||||
\rpg@monsterattr{languages}{\languagesname}
|
||||
\item[\challengename] \RpgCRExp{\commandkey{challenge}}
|
||||
\end{rpg@monsterattrs}%
|
||||
}
|
||||
|
||||
\ExplSyntaxOn
|
||||
\newcommand{\rpg@hit}[1]{%
|
||||
\__rpg_caption:nn {\tohitname} {#1}
|
||||
}
|
||||
\ExplSyntaxOff
|
||||
|
||||
\newcommand{\rpg@damage}[2]{%
|
||||
\commandkey{#1}\ \commandkey{#2}\ \damagename%
|
||||
}
|
||||
|
||||
\newcommand{\rpg@ifplusdmg}[2]{%
|
||||
\ifcommandkey{#1}{%
|
||||
{ }\plusname\ \commandkey{#1}\ \commandkey{#2}\ \damagename%
|
||||
}{}%
|
||||
}
|
||||
\newcommand{\rpg@ifordmg}[5]{%
|
||||
\ifcommandkey{#1}{%
|
||||
, \orname\ \commandkey{#1}\ \commandkey{#2}\ \damagename\rpg@ifplusdmg{#4}{#5}\ \commandkey{#3}%
|
||||
}{}%
|
||||
}
|
||||
|
||||
\newkeycommand+[\|]\monstermelee[
|
||||
name=Club,
|
||||
mod=+0,
|
||||
reach=5,
|
||||
targets=\defaulttargetsname,
|
||||
dmg=\dice{1d4},
|
||||
dmgtype=bludgeoning,
|
||||
plusdmg=,
|
||||
plusdmgtype=,
|
||||
ordmg=,
|
||||
ordmgwhen=,
|
||||
extra=,
|
||||
]{%
|
||||
|\monsterattack|[
|
||||
name={\commandkey{name}},
|
||||
type=melee,
|
||||
mod={\commandkey{mod}},
|
||||
reach={\commandkey{reach}},
|
||||
targets={\commandkey{targets}},
|
||||
dmg={\commandkey{dmg}},
|
||||
dmgtype={\commandkey{dmgtype}},
|
||||
plusdmg={\commandkey{plusdmg}},
|
||||
plusdmgtype={\commandkey{plusdmgtype}},
|
||||
ordmg={\commandkey{ordmg}},
|
||||
ordmgwhen={\commandkey{ordmgwhen}},
|
||||
extra={\commandkey{extra}},
|
||||
]
|
||||
}
|
||||
\newkeycommand+[\|]\monsterranged[
|
||||
name=Shortbow,
|
||||
mod=+0,
|
||||
range=80/320,
|
||||
targets=\defaulttargetsname,
|
||||
dmg=\dice{1d6},
|
||||
dmgtype=piercing,
|
||||
plusdmg=,
|
||||
plusdmgtype=,
|
||||
ordmg=,
|
||||
ordmgwhen=,
|
||||
extra=,
|
||||
]{%
|
||||
|\monsterattack|[
|
||||
name={\commandkey{name}},
|
||||
type=ranged,
|
||||
mod={\commandkey{mod}},
|
||||
range={\commandkey{range}},
|
||||
targets={\commandkey{targets}},
|
||||
dmg={\commandkey{dmg}},
|
||||
dmgtype={\commandkey{dmgtype}},
|
||||
plusdmg={\commandkey{plusdmg}},
|
||||
plusdmgtype={\commandkey{plusdmgtype}},
|
||||
ordmg={\commandkey{ordmg}},
|
||||
ordmgwhen={\commandkey{ordmgwhen}},
|
||||
extra={\commandkey{extra}},
|
||||
]
|
||||
}
|
||||
|
||||
\newkeycommand\monsterattack[
|
||||
name=Dagger,
|
||||
enum* type={both,melee,ranged},
|
||||
mod=+0,
|
||||
reach=5,
|
||||
range=20/60,
|
||||
targets=\defaulttargetsname,
|
||||
dmg=\dice{1d4},
|
||||
dmgtype=piercing,
|
||||
plusdmg=,
|
||||
plusdmgtype=,
|
||||
ordmg=,
|
||||
ordmgwhen=,
|
||||
extra=,
|
||||
]{%
|
||||
\RpgDeprecate{\noexpand\monsterattack}{1.0.0}{Use \noexpand\RpgMonsterMelee, \noexpand\RpgMonsterRanged, or \noexpand\RpgMonsterAttack for attacks that are melee, ranged, or both, respectively.}%
|
||||
\begin{monsteraction}[\commandkey{name}]
|
||||
\IfStrEqCase{\commandkey{type}}{%
|
||||
{melee}{\textit{\RpgCaption{\meleeattackname}{\weaponname}:} \rpg@hit{mod}, \reachname\ \commandkey{reach} \unitsname}%
|
||||
{ranged}{\textit{\RpgCaption{\rangedattackname}{\weaponname}:} \rpg@hit{mod}, \rangename\ \commandkey{range} \unitsname}%
|
||||
{both}{\textit{\RpgCaption{\meleeorrangedattackname}{\weaponname}:} \rpg@hit{mod}, \reachname\ \commandkey{reach} \unitsname\ \orname\ \rangename\ \commandkey{range} \unitsname}%
|
||||
}[]%
|
||||
, \commandkey{targets}.
|
||||
\textit{\hitname:} \rpg@damage{dmg}{dmgtype}%
|
||||
\rpg@ifplusdmg{plusdmg}{plusdmgtype}%
|
||||
\rpg@ifordmg{ordmg}{dmgtype}{ordmgwhen}{plusdmg}{plusdmgtype}%
|
||||
\ifcommandkey{extra}{\commandkey{extra}}{}.
|
||||
\end{monsteraction}
|
||||
}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% rpgpaperbox.sty - to be removed in version 1.0.0
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%Usage \begin{paperbox}[options]{title}[color]
|
||||
\ExplSyntaxOn
|
||||
\DeclareTColorBox{paperbox}{O{} m O{paperboxcolor}}{%
|
||||
before~upper={%
|
||||
\bool_if:NT \l__rpg_layout_bool
|
||||
{
|
||||
\bool_if:NF \l__rpg_justified_bool
|
||||
{\RaggedRight}
|
||||
}
|
||||
},
|
||||
code={\RpgDeprecate{\noexpand\paperbox}{1.0.0}{Use \noexpand\RpgSidebar for sidebars.}\linespread{.9}},
|
||||
frame~hidden,
|
||||
boxrule=0pt,
|
||||
enhanced,
|
||||
before~skip=13pt plus 4pt minus 4pt,
|
||||
toptitle=2pt,
|
||||
boxsep=3pt,
|
||||
left=6pt,
|
||||
right=6pt,
|
||||
top=0pt,
|
||||
bottom=3pt,
|
||||
fonttitle=\RpgFontSidebarTitle,
|
||||
fontupper=\RpgFontSidebarBody,
|
||||
fontlower=\RpgFontSidebarBody,
|
||||
title={#2},
|
||||
sharp~corners,
|
||||
parbox=false,
|
||||
borderline~north={1pt}{-0.5pt}{black},
|
||||
borderline~south={1pt}{-0.5pt}{black},
|
||||
colback=#3,
|
||||
colbacktitle=#3,
|
||||
coltitle=black,
|
||||
fuzzy~shadow={0mm}{-3.5pt}{-0.5pt}{0.4mm}{black!60!white},
|
||||
overlay={%
|
||||
\fill[black] (frame.south~west) -- ++ (7pt,0) -- ++ (0,-5pt) -- cycle;
|
||||
\fill[black] (frame.north~west) -- ++ (7pt,0) -- ++ (0,5pt) -- cycle;
|
||||
\fill[black] (frame.north~east) -- ++ (-7pt,0) -- ++ (0,5pt) -- cycle;
|
||||
\fill[black] (frame.south~east) -- ++ (-7pt,0) -- ++ (0,-5pt) -- cycle;
|
||||
},
|
||||
after~skip=14pt plus 4pt minus 4pt,
|
||||
#1
|
||||
}
|
||||
\ExplSyntaxOn
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% rpgquote.sty - to be removed in version 1.0.0
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%Usage \begin{quotebox}[options][color]
|
||||
\ExplSyntaxOn
|
||||
\DeclareTColorBox{quotebox}{O{} O{quoteboxcolor}}{%
|
||||
before~upper={%
|
||||
\bool_if:NT \l__rpg_layout_bool
|
||||
{
|
||||
\bool_if:NF \l__rpg_justified_bool
|
||||
{\RaggedRight}
|
||||
}
|
||||
},
|
||||
code={\RpgDeprecate{\noexpand\quotebox}{1.0.0}{Use~\noexpand\RpgReadAloud~for~read-aloud~text.}\linespread{1.1}},
|
||||
enhanced~jigsaw,
|
||||
frame~hidden,
|
||||
boxrule=0pt,
|
||||
breakable,
|
||||
enhanced,
|
||||
before~skip=13pt plus 4pt minus 4pt,
|
||||
boxsep=8pt,
|
||||
top=0pt,
|
||||
left=0pt,
|
||||
right=0pt,
|
||||
bottom=0pt,
|
||||
colback=#2,
|
||||
sharp~corners,
|
||||
parbox=false,
|
||||
borderline~west={1pt}{-0.5pt}{titlered},
|
||||
borderline~east={1pt}{-0.5pt}{titlered},
|
||||
fontupper=\RpgFontReadAloud,
|
||||
fontlower=\RpgFontReadAloud,
|
||||
overlay={%
|
||||
\foreach\n in {north~east,north~west,south~east,south~west}
|
||||
{\draw[titlered, fill=titlered] (frame.\n) circle (1.5pt); }; },
|
||||
after~skip=13pt plus 4pt minus 4pt,
|
||||
#1
|
||||
}
|
||||
\ExplSyntaxOff
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% rpgsections.sty - to be removed in version 1.0.0
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Special command for magic items, traps, and the like.
|
||||
\newcommand{\subtitlesection}[2]{%
|
||||
\RpgDeprecate{\noexpand\subtitlesection}{1.0.0}{Use \noexpand\RpgItemHeader for item headers.}%
|
||||
\subsubsection{#1}%
|
||||
\textit{#2}
|
||||
\par\vspace{3pt plus 1pt minus 1pt}\noindent\ignorespaces}
|
||||
|
||||
% Map Areas and their References
|
||||
|
||||
% Labelling helpers
|
||||
\newcommand{\AreaLabel@Prefix}{area}
|
||||
\newcommand{\SetAreaLabelPrefix}[1]{%
|
||||
\renewcommand{\AreaLabel@Prefix}{#1}}
|
||||
|
||||
\newcounter{Area}
|
||||
\newcommand\ResetAreas{%
|
||||
\RpgDeprecate{\noexpand\ResetAreas}{1.0.0}{Use \noexpand\RpgResetAreas to reset area counters.}%
|
||||
\setcounter{Area}{0}
|
||||
}
|
||||
|
||||
\NewDocumentCommand\area{mo}{%
|
||||
\RpgDeprecate{\noexpand\area}{1.0.0}{Use \noexpand\RpgArea to typeset a section with an area counter.}%
|
||||
\refstepcounter{Area}%
|
||||
\IfNoValueTF{#2}%
|
||||
{\label{\AreaLabel@Prefix:#1}}%
|
||||
{\label{\AreaLabel@Prefix:#2}}%
|
||||
\subsection{\arabic{Area}. #1}%
|
||||
}
|
||||
|
||||
% defines sub-areas, like '5a', '5b'
|
||||
\newcounter{SubArea}[Area]
|
||||
|
||||
\NewDocumentCommand\subarea{mo}{%
|
||||
\RpgDeprecate{\noexpand\subarea}{1.0.0}{Use \noexpand\RpgSubArea to typeset a section with an sub-area counter.}%
|
||||
\refstepcounter{SubArea}%
|
||||
\IfNoValueTF{#2}%
|
||||
{\label{\AreaLabel@Prefix:#1}}%
|
||||
{\label{\AreaLabel@Prefix:#2}}%
|
||||
\subsubsection{\arabic{Area}\alph{SubArea}. #1}%
|
||||
}
|
||||
|
||||
% sub area references should be '5a', '5b', not '1', '2'
|
||||
\renewcommand\p@SubArea{\arabic{Area}}
|
||||
\renewcommand\theSubArea{\alph{SubArea}}
|
||||
|
||||
\newcounter{DetailArea}[subsection]
|
||||
\newcommand{\DetailArea@Prefix}{}
|
||||
\newcommand{\SetDetailAreaPrefix}[1]{\renewcommand{\DetailArea@Prefix}
|
||||
{#1--\arabic{DetailArea}\par\expandafter\ignorespaces\noindent}}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% rpgspell.sty - to be removed in version 1.0.0
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\newcommand{\spellheader}[6]{%
|
||||
\RpgDeprecate{\noexpand\spellheader}{1.0.0}{Use \noexpand\RpgSpellHeader to typeset a spell header.}%
|
||||
\subtitlesection{#1}{#2}
|
||||
\begin{description}[noitemsep,nosep,after=\smallskip,leftmargin=1em]
|
||||
\item[\spellcastingtimename:] #3
|
||||
\item[\spellrangename:] #4
|
||||
\item[\spellcomponentsname:] #5
|
||||
\item[\spelldurationname:] #6
|
||||
\end{description}
|
||||
}
|
||||
|
||||
\newenvironment{spell}[6]
|
||||
{\spellheader{#1}{#2}{#3}{#4}{#5}{#6}}
|
||||
% Environment encloses description.
|
||||
{}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% rpgtable.sty - to be removed in version 1.0.0
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Table Header
|
||||
\newcommand{\header}[1]{%
|
||||
\begingroup%
|
||||
\par\vspace{10pt plus 3 pt minus 3pt}%
|
||||
\noindent%
|
||||
\RpgFontTableTitle%
|
||||
#1%
|
||||
\endgroup%
|
||||
}
|
||||
|
||||
% Table Environment
|
||||
\NewDocumentEnvironment{rpgtable}{O{XX} O{tablecolor}}{%
|
||||
\RpgDeprecate{\noexpand\rpgtable}{1.0.0}{Use \noexpand\RpgTable for tables.}%
|
||||
\par\vspace{2pt plus 1pt minus 1pt}%
|
||||
\noindent%
|
||||
\RpgFontTableBody%
|
||||
\setlength{\extrarowheight}{3pt}%
|
||||
\rowcolors{1}{}{#2}%
|
||||
\tabularx{\linewidth}{#1}%
|
||||
}{%
|
||||
\endtabularx%
|
||||
\par\vspace{10pt plus 3 pt minus 3pt}%
|
||||
}
|
||||
348
lib/rpgfonts.sty
Normal file
348
lib/rpgfonts.sty
Normal file
@@ -0,0 +1,348 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Font definitions
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\RequirePackage{lettrine}
|
||||
\RequirePackage{Royal}
|
||||
\RequirePackage[auto]{contour}
|
||||
|
||||
\bool_if:NT \l__rpg_layout_bool
|
||||
{
|
||||
\RequirePackage{bookman}
|
||||
\RequirePackage[type1]{gillius2}
|
||||
\RequirePackage[notext,nomath,nott]{kpfonts}
|
||||
\RequirePackage[T1]{fontenc}
|
||||
\renewcommand{\sfdefault}{jkpss}
|
||||
}
|
||||
|
||||
\cs_new_protected:Npn \__rpg_sf_initial_family:
|
||||
{
|
||||
\bool_if:NTF \l__rpg_layout_bool
|
||||
{ \gilliustwo }
|
||||
{ \sffamily }
|
||||
}
|
||||
|
||||
\keys_define:nn { rpg / fonts }
|
||||
{
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Sectioning commands
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Part
|
||||
part-family .tl_set:N = \l__rpg_part_family_tl,
|
||||
part-family .initial:n = \normalfont,
|
||||
part-family .value_required:n = true,
|
||||
part-style .tl_set:N = \l__rpg_part_style_tl,
|
||||
part-style .initial:n = \color{titlered} \Huge \scshape,
|
||||
part-style .value_required:n = true,
|
||||
% Chapter
|
||||
chapter-family .tl_set:N = \l__rpg_chapter_family_tl,
|
||||
chapter-family .initial:n = \normalfont,
|
||||
chapter-family .value_required:n = true,
|
||||
chapter-style .tl_set:N = \l__rpg_chapter_style_tl,
|
||||
chapter-style .initial:n = \linespread{.9} \color{titlered} \Huge \scshape,
|
||||
chapter-style .value_required:n = true,
|
||||
% Section
|
||||
section-family .tl_set:N = \l__rpg_section_family_tl,
|
||||
section-family .initial:n = \normalfont,
|
||||
section-family .value_required:n = true,
|
||||
section-style .tl_set:N = \l__rpg_section_style_tl,
|
||||
section-style .initial:n = \linespread{.9} \color{titlered} \huge \scshape \RaggedRight,
|
||||
section-style .value_required:n = true,
|
||||
% Subsection
|
||||
subsection-family .tl_set:N = \l__rpg_subsection_family_tl,
|
||||
subsection-family .initial:n = \normalfont,
|
||||
subsection-family .value_required:n = true,
|
||||
subsection-style .tl_set:N = \l__rpg_subsection_style_tl,
|
||||
subsection-style .initial:n = \linespread{.9} \color{titlered} \Large \scshape \RaggedRight,
|
||||
subsection-style .value_required:n = true,
|
||||
% subsubsection
|
||||
subsubsection-family .tl_set:N = \l__rpg_subsubsection_family_tl,
|
||||
subsubsection-family .initial:n = \normalfont,
|
||||
subsubsection-family .value_required:n = true,
|
||||
subsubsection-style .tl_set:N = \l__rpg_subsubsection_style_tl,
|
||||
subsubsection-style .initial:n = \linespread{.9} \color{titlered} \large \scshape \RaggedRight,
|
||||
subsubsection-style .value_required:n = true,
|
||||
% paragraph
|
||||
paragraph-family .tl_set:N = \l__rpg_paragraph_family_tl,
|
||||
paragraph-family .value_required:n = true,
|
||||
paragraph-style .tl_set:N = \l__rpg_paragraph_style_tl,
|
||||
paragraph-style .initial:n = \bfseries \slshape,
|
||||
paragraph-style .value_required:n = true,
|
||||
% subparagraph
|
||||
subparagraph-family .tl_set:N = \l__rpg_subparagraph_family_tl,
|
||||
subparagraph-family .value_required:n = true,
|
||||
subparagraph-style .tl_set:N = \l__rpg_subparagraph_style_tl,
|
||||
subparagraph-style .initial:n = \bfseries \slshape,
|
||||
subparagraph-style .value_required:n = true,
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Tables
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Table title
|
||||
table-title-family .tl_set:N = \l__rpg_table_title_family_tl,
|
||||
table-title-family .initial:n = \sffamily,
|
||||
table-title-family .value_required:n = true,
|
||||
table-title-style .tl_set:N = \l__rpg_table_title_style_tl,
|
||||
table-title-style .initial:n = \bfseries \scshape \large,
|
||||
table-title-style .value_required:n = true,
|
||||
% Table header
|
||||
table-header-family .tl_set:N = \l__rpg_table_header_family_tl,
|
||||
table-header-family .initial:n = \sffamily,
|
||||
table-header-family .value_required:n = true,
|
||||
table-header-style .tl_set:N = \l__rpg_table_header_style_tl,
|
||||
table-header-style .initial:n = \bfseries,
|
||||
table-header-style .value_required:n = true,
|
||||
% Table body
|
||||
table-body-family .tl_set:N = \l__rpg_table_body_family_tl,
|
||||
table-body-family .initial:n = \__rpg_sf_initial_family:,
|
||||
table-body-family .value_required:n = true,
|
||||
table-body-style .tl_set:N = \l__rpg_table_body_style_tl,
|
||||
table-body-style .initial:n = \small,
|
||||
table-body-style .value_required:n = true,
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Comment boxes
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Comment title
|
||||
comment-title-family .tl_set:N = \l__rpg_comment_title_family_tl,
|
||||
comment-title-family .initial:n = \sffamily,
|
||||
comment-title-family .value_required:n = true,
|
||||
comment-title-style .tl_set:N = \l__rpg_comment_title_style_tl,
|
||||
comment-title-style .initial:n = \bfseries \scshape,
|
||||
comment-title-style .value_required:n = true,
|
||||
% Comment body
|
||||
comment-body-family .tl_set:N = \l__rpg_comment_body_family_tl,
|
||||
comment-body-family .initial:n = \__rpg_sf_initial_family:,
|
||||
comment-body-family .value_required:n = true,
|
||||
comment-body-style .tl_set:N = \l__rpg_comment_body_style_tl,
|
||||
comment-body-style .initial:n = \small,
|
||||
comment-body-style .value_required:n = true,
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Sidebars
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Sidebar title
|
||||
sidebar-title-family .tl_set:N = \l__rpg_sidebar_title_family_tl,
|
||||
sidebar-title-family .initial:n = \sffamily,
|
||||
sidebar-title-family .value_required:n = true,
|
||||
sidebar-title-style .tl_set:N = \l__rpg_sidebar_title_style_tl,
|
||||
sidebar-title-style .initial:n = \bfseries \scshape,
|
||||
sidebar-title-style .value_required:n = true,
|
||||
% Sidebar body
|
||||
sidebar-body-family .tl_set:N = \l__rpg_sidebar_body_family_tl,
|
||||
sidebar-body-family .initial:n = \__rpg_sf_initial_family:,
|
||||
sidebar-body-family .value_required:n = true,
|
||||
sidebar-body-style .tl_set:N = \l__rpg_sidebar_body_style_tl,
|
||||
sidebar-body-style .initial:n = \small,
|
||||
sidebar-body-style .value_required:n = true,
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Read-aloud boxes
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
readaloud-family .tl_set:N = \l__rpg_readaloud_family_tl,
|
||||
readaloud-family .initial:n = \__rpg_sf_initial_family:,
|
||||
readaloud-family .value_required:n = true,
|
||||
readaloud-style .tl_set:N = \l__rpg_readaloud_style_tl,
|
||||
readaloud-style .initial:n = \small,
|
||||
readaloud-style .value_required:n = true,
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Table of Contents
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Part
|
||||
toc-part-family .tl_set:N = \l__rpg_toc_part_family_tl,
|
||||
toc-part-family .initial:n = \normalfont,
|
||||
toc-part-family .value_required:n = true,
|
||||
toc-part-style .tl_set:N = \l__rpg_toc_part_style_tl,
|
||||
toc-part-style .initial:n = \Large \scshape \color{titlered},
|
||||
toc-part-style .value_required:n = true,
|
||||
% Chapter
|
||||
toc-chapter-family .tl_set:N = \l__rpg_toc_chapter_family_tl,
|
||||
toc-chapter-family .initial:n = \normalfont,
|
||||
toc-chapter-family .value_required:n = true,
|
||||
toc-chapter-style .tl_set:N = \l__rpg_toc_chapter_style_tl,
|
||||
toc-chapter-style .initial:n = \large \scshape \color{titlered},
|
||||
toc-chapter-style .value_required:n = true,
|
||||
% Section
|
||||
toc-section-family .tl_set:N = \l__rpg_toc_section_family_tl,
|
||||
toc-section-family .initial:n = \normalfont,
|
||||
toc-section-family .value_required:n = true,
|
||||
toc-section-style .tl_set:N = \l__rpg_toc_section_style_tl,
|
||||
toc-section-style .initial:n = \normalsize,
|
||||
toc-section-style .value_required:n = true,
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Stat blocks
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Stat block title
|
||||
stat-block-title-family .tl_set:N = \l__rpg_stat_block_title_family_tl,
|
||||
stat-block-title-family .initial:n = \normalfont,
|
||||
stat-block-title-family .value_required:n = true,
|
||||
stat-block-title-style .tl_set:N = \l__rpg_stat_block_title_style_tl,
|
||||
stat-block-title-style .initial:n = \bfseries \scshape \LARGE,
|
||||
stat-block-title-style .value_required:n = true,
|
||||
% Stat block body
|
||||
stat-block-body-family .tl_set:N = \l__rpg_stat_block_body_family_tl,
|
||||
stat-block-body-family .initial:n = \__rpg_sf_initial_family:,
|
||||
stat-block-body-family .value_required:n = true,
|
||||
stat-block-body-style .tl_set:N = \l__rpg_stat_block_body_style_tl,
|
||||
stat-block-body-style .initial:n = \small,
|
||||
stat-block-body-style .value_required:n = true,
|
||||
% Stat block section
|
||||
stat-block-section-family .tl_set:N = \l__rpg_stat_block_section_family_tl,
|
||||
stat-block-section-family .initial:n = \sffamily,
|
||||
stat-block-section-family .value_required:n = true,
|
||||
stat-block-section-style .tl_set:N = \l__rpg_stat_block_section_style_tl,
|
||||
stat-block-section-style .initial:n = \color{titlered} \scshape \large,
|
||||
stat-block-section-style .value_required:n = true,
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Miscellaneous
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Footer
|
||||
footer-family .tl_set:N = \l__rpg_footer_family_tl,
|
||||
footer-family .initial:n = \normalfont,
|
||||
footer-family .value_required:n = true,
|
||||
footer-style .tl_set:N = \l__rpg_footer_style_tl,
|
||||
footer-style .initial:n = \scriptsize \textcolor{pagegold},
|
||||
footer-style .value_required:n = true,
|
||||
% Page number
|
||||
page-number-family .tl_set:N = \l__rpg_page_number_family_tl,
|
||||
page-number-family .initial:n = \normalfont,
|
||||
page-number-family .value_required:n = true,
|
||||
page-number-style .tl_set:N = \l__rpg_page_number_style_tl,
|
||||
page-number-style .initial:n = \scriptsize \textcolor{pagegold},
|
||||
page-number-style .value_required:n = true,
|
||||
% Drop caps
|
||||
drop-cap-family .tl_set:N = \l__rpg_drop_cap_family_tl,
|
||||
drop-cap-family .initial:n = \Royal,
|
||||
drop-cap-family .value_required:n = true,
|
||||
drop-cap-style .tl_set:N = \l__rpg_drop_cap_style_tl,
|
||||
drop-cap-style .value_required:n = true,
|
||||
}
|
||||
|
||||
\NewDocumentCommand { \RpgSetFonts } { o }
|
||||
{
|
||||
\keys_set:nn { rpg / fonts } { #1 }
|
||||
}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Font access functions combine the selected family and style
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Sectioning commands
|
||||
\NewDocumentCommand{\RpgFontPart}{}
|
||||
{ \l__rpg_part_family_tl \l__rpg_part_style_tl}
|
||||
|
||||
\NewDocumentCommand{\RpgFontChapter}{}
|
||||
{ \l__rpg_chapter_family_tl \l__rpg_chapter_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontSection}{}
|
||||
{ \l__rpg_section_family_tl \l__rpg_section_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontSubsection}{}
|
||||
{ \l__rpg_subsection_family_tl \l__rpg_subsection_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontSubsubsection}{}
|
||||
{ \l__rpg_subsubsection_family_tl \l__rpg_subsubsection_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontParagraph}{}
|
||||
{ \l__rpg_paragraph_family_tl \l__rpg_paragraph_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontSubaragraph}{}
|
||||
{ \l__rpg_subparagraph_family_tl \l__rpg_subparagraph_style_tl }
|
||||
|
||||
% Tables
|
||||
\NewDocumentCommand{\RpgFontTableTitle}{}
|
||||
{ \l__rpg_table_title_family_tl \l__rpg_table_title_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontTableHeader}{}
|
||||
{ \l__rpg_table_header_family_tl \l__rpg_table_header_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontTableBody}{}
|
||||
{ \l__rpg_table_body_family_tl \l__rpg_table_body_style_tl }
|
||||
|
||||
% Comment boxes
|
||||
\NewDocumentCommand{\RpgFontCommentTitle}{}
|
||||
{ \l__rpg_comment_title_family_tl \l__rpg_comment_title_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontCommentBody}{}
|
||||
{ \l__rpg_comment_body_family_tl \l__rpg_comment_body_style_tl }
|
||||
|
||||
% Sidebars
|
||||
\NewDocumentCommand{\RpgFontSidebarTitle}{}
|
||||
{ \l__rpg_sidebar_title_family_tl \l__rpg_sidebar_title_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontSidebarBody}{}
|
||||
{ \l__rpg_sidebar_body_family_tl \l__rpg_sidebar_body_style_tl }
|
||||
|
||||
% Read-aloud boxes
|
||||
\NewDocumentCommand{\RpgFontReadAloud}{}
|
||||
{ \l__rpg_readaloud_family_tl \l__rpg_readaloud_style_tl }
|
||||
|
||||
% Table of Contents
|
||||
\NewDocumentCommand{\RpgFontTocPart}{}
|
||||
{ \l__rpg_toc_part_family_tl \l__rpg_toc_part_style_tl}
|
||||
|
||||
\NewDocumentCommand{\RpgFontTocChapter}{}
|
||||
{ \l__rpg_toc_chapter_family_tl \l__rpg_toc_chapter_style_tl}
|
||||
|
||||
\NewDocumentCommand{\RpgFontTocSection}{}
|
||||
{ \l__rpg_toc_section_family_tl \l__rpg_toc_section_style_tl}
|
||||
|
||||
% Stat blocks
|
||||
\NewDocumentCommand{\RpgFontStatBlockTitle}{}
|
||||
{ \l__rpg_stat_block_title_family_tl \l__rpg_stat_block_title_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontStatBlockBody}{}
|
||||
{ \l__rpg_stat_block_body_family_tl \l__rpg_stat_block_body_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontStatBlockSection}{}
|
||||
{ \l__rpg_stat_block_section_family_tl \l__rpg_stat_block_section_style_tl }
|
||||
|
||||
% Miscellaneous
|
||||
\NewDocumentCommand{\RpgFontFooter}{}
|
||||
{ \l__rpg_footer_family_tl \l__rpg_footer_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontPageNumber}{}
|
||||
{ \l__rpg_page_number_family_tl \l__rpg_page_number_style_tl }
|
||||
|
||||
\NewDocumentCommand{\RpgFontDropCap}{}
|
||||
{ \l__rpg_drop_cap_family_tl \l__rpg_drop_cap_style_tl }
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Drop Caps
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\renewcommand{\LettrineFontHook}
|
||||
{ \l__rpg_drop_cap_family_tl \l__rpg_drop_cap_style_tl }
|
||||
|
||||
% Usage: RpgDropCapLine[<lettrine options>]{<first letter>}{<small caps line>}
|
||||
% It takes trial and error to get the 2nd argument to align with
|
||||
% the linebreak. Lettrine package will not play nicely with \FirstLine. See
|
||||
% the lettrine package for options.
|
||||
\NewDocumentCommand{\RpgDropCapLine}{ O{} m m }
|
||||
{
|
||||
\lettrine[
|
||||
lines = 4,
|
||||
depth = 0,
|
||||
findent = \l__rpg_space_dim,
|
||||
nindent = 0pt,
|
||||
#1
|
||||
]
|
||||
{#2}
|
||||
{#3}
|
||||
}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Contour that can break across lines. Can accept \newline to force a break.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\cs_new_protected:Npn \__rpg_contour_preserve_space:nn #1#2
|
||||
{
|
||||
\group_begin:
|
||||
\seq_set_split:Nnn \l_tmpa_seq { ~ } { #2 }
|
||||
\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \exp_not:n {\contour{#1}{##1}} }
|
||||
\seq_use:Nn \l_tmpb_seq { ~ }
|
||||
\group_end:
|
||||
}
|
||||
|
||||
\NewDocumentCommand{\RpgContour}{ O{contourgray} m }
|
||||
{
|
||||
\group_begin:
|
||||
\seq_set_split:Nnn \l_tmpa_seq { \newline } { #2 }
|
||||
\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \exp_not:n {\__rpg_contour_preserve_space:nn{#1}{##1}} }
|
||||
\seq_use:Nn \l_tmpb_seq { \newline }
|
||||
\group_end:
|
||||
}
|
||||
74
lib/rpgheader.sty
Normal file
74
lib/rpgheader.sty
Normal file
@@ -0,0 +1,74 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Custom headers and footers
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\bool_if:NT \l__rpg_layout_bool
|
||||
{
|
||||
\RequirePackage {fancyhdr} % Adaptation of the footers
|
||||
|
||||
% Setup for custom footer
|
||||
\pagestyle {fancy}
|
||||
|
||||
\cs_if_free:NF \chaptermark
|
||||
{
|
||||
\renewcommand*{\chaptermark}[1]
|
||||
{
|
||||
\markboth
|
||||
{
|
||||
\MakeUppercase
|
||||
{
|
||||
\ifnum\value{secnumdepth}>-1
|
||||
\chaptertitlename\ \thechapter :~
|
||||
\fi
|
||||
#1
|
||||
}
|
||||
}
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
\renewcommand*{\headrulewidth}{0pt} % no rule for header
|
||||
\renewcommand*{\footrulewidth}{0pt} % no rule for footer
|
||||
|
||||
\fancyhf {} % clear all headers and footers
|
||||
|
||||
% Header is used to include the page background
|
||||
\fancyhead{
|
||||
\bool_if:NT \l__rpg_show_background_bool
|
||||
{
|
||||
\begin{tikzpicture}[remember~picture,overlay]
|
||||
\node[inner~sep=0pt] at (current~page.center) {\includegraphics[width=\paperwidth,height=\paperheight]{img/paper}};
|
||||
\end{tikzpicture}
|
||||
}
|
||||
}
|
||||
|
||||
% Left-even page footer
|
||||
\fancyfoot[LE]{%
|
||||
\RpgFontFooter \leftmark
|
||||
\begin{tikzpicture}[remember~picture,overlay]
|
||||
\bool_if:NT \l__rpg_show_footer_scroll_bool {
|
||||
\node[xscale=-1,inner~sep=0pt,anchor=south,nearly~opaque] at (current~page.south) {\includegraphics[width=\paperwidth,height=.6in]{img/footerscroll}};
|
||||
}
|
||||
\node[inner~sep=0pt,anchor=south,xshift=.28in,yshift=.39in] at (current~page.south~west) {\RpgFontPageNumber \thepage};
|
||||
\end{tikzpicture}
|
||||
}
|
||||
|
||||
% Right-odd page footer
|
||||
\fancyfoot[RO]{%
|
||||
\RpgFontFooter \leftmark
|
||||
\begin{tikzpicture}[remember~picture,overlay]
|
||||
\bool_if:NT \l__rpg_show_footer_scroll_bool {
|
||||
\node[inner~sep=0pt,anchor=south,nearly~opaque] at (current~page.south) {\includegraphics[width=\paperwidth,height=.6in]{img/footerscroll}};
|
||||
}
|
||||
\node[inner~sep=0pt,anchor=south,xshift=-.28in,yshift=.39in] at (current~page.south~east) {\RpgFontPageNumber \thepage};
|
||||
\end{tikzpicture}
|
||||
}
|
||||
|
||||
\fancypagestyle {plain} {}
|
||||
|
||||
\fancypagestyle{empty}{%
|
||||
\fancyfoot{}
|
||||
}
|
||||
|
||||
}
|
||||
671
lib/rpgmonster.sty
Normal file
671
lib/rpgmonster.sty
Normal file
@@ -0,0 +1,671 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
\NewDocumentCommand {\RpgCRExp} { m }
|
||||
{
|
||||
\str_case_e:nnF {#1}
|
||||
{
|
||||
{0} {#1~(0~\xpname)}
|
||||
{1/10} {0~(10~\xpname)}
|
||||
{1/8} {#1~(25~\xpname)}
|
||||
{1/4} {#1~(50~\xpname)}
|
||||
{1/2} {#1~(100~\xpname)}
|
||||
{1} {#1~(200~\xpname)}
|
||||
{2} {#1~(450~\xpname)}
|
||||
{3} {#1~(700~\xpname)}
|
||||
{4} {#1~(\numprint{1100}~\xpname)}
|
||||
{5} {#1~(\numprint{1800}~\xpname)}
|
||||
{6} {#1~(\numprint{2300}~\xpname)}
|
||||
{7} {#1~(\numprint{2900}~\xpname)}
|
||||
{8} {#1~(\numprint{3900}~\xpname)}
|
||||
{9} {#1~(\numprint{5000}~\xpname)}
|
||||
{10} {#1~(\numprint{5900}~\xpname)}
|
||||
{11} {#1~(\numprint{7200}~\xpname)}
|
||||
{12} {#1~(\numprint{8400}~\xpname)}
|
||||
{13} {#1~(\numprint{10000}~\xpname)}
|
||||
{14} {#1~(\numprint{11500}~\xpname)}
|
||||
{15} {#1~(\numprint{13000}~\xpname)}
|
||||
{16} {#1~(\numprint{15000}~\xpname)}
|
||||
{17} {#1~(\numprint{18000}~\xpname)}
|
||||
{18} {#1~(\numprint{20000}~\xpname)}
|
||||
{19} {#1~(\numprint{22000}~\xpname)}
|
||||
{20} {#1~(\numprint{25000}~\xpname)}
|
||||
{21} {#1~(\numprint{33000}~\xpname)}
|
||||
{22} {#1~(\numprint{41000}~\xpname)}
|
||||
{23} {#1~(\numprint{50000}~\xpname)}
|
||||
{24} {#1~(\numprint{62000}~\xpname)}
|
||||
{25} {#1~(\numprint{75000}~\xpname)}
|
||||
{26} {#1~(\numprint{90000}~\xpname)}
|
||||
{27} {#1~(\numprint{105000}~\xpname)}
|
||||
{28} {#1~(\numprint{120000}~\xpname)}
|
||||
{29} {#1~(\numprint{135000}~\xpname)}
|
||||
{30} {#1~(\numprint{155000}~\xpname)}
|
||||
}
|
||||
{#1}
|
||||
}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Monster environments
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Stat block made to look like the Monster Manual NPC definitions
|
||||
\DeclareTColorBox {RpgMonsterNoBg} { O{} m }
|
||||
{
|
||||
enhanced,
|
||||
frame~hidden,
|
||||
boxrule = 0pt,
|
||||
breakable,
|
||||
parbox = false,
|
||||
boxsep = 0pt,
|
||||
toptitle = 3mm,
|
||||
left = 0pt,
|
||||
right = 0pt,
|
||||
sharp~corners,
|
||||
opacityback = 0,
|
||||
colframe = titlered,
|
||||
fonttitle = \RpgFontStatBlockTitle,
|
||||
fontupper = \RpgFontStatBlockBody,
|
||||
fontlower = \RpgFontStatBlockBody,
|
||||
title = {#2},
|
||||
coltitle = titlered,
|
||||
#1
|
||||
}
|
||||
|
||||
% Stat block made to look like stat blocks in the PHB.
|
||||
\DeclareTColorBox {RpgMonsterBg} { O{} m }
|
||||
{
|
||||
enhanced,
|
||||
frame~hidden,
|
||||
before~skip = 12pt plus 3pt minus 3pt,
|
||||
boxrule = 0pt,
|
||||
breakable,
|
||||
parbox = false,
|
||||
boxsep = 2pt,
|
||||
toptitle = 8pt,
|
||||
top = 0pt,
|
||||
left = 2pt,
|
||||
right = 2pt,
|
||||
bottom = 7pt,
|
||||
sharp~corners,
|
||||
oversize = 0pt,
|
||||
borderline~north = {3pt} {0pt} {titlered},
|
||||
borderline~north = {2pt} {0.5pt} {statblockribbon},
|
||||
borderline~south = {3pt} {0pt} {titlered},
|
||||
borderline~south = {2pt} {0.5pt} {statblockribbon},
|
||||
colback = statblockbg,
|
||||
colbacktitle = statblockbg,
|
||||
colframe = titlered,
|
||||
fonttitle = \RpgFontStatBlockTitle,
|
||||
coltitle = titlered,
|
||||
fontupper = \RpgFontStatBlockBody,
|
||||
fontlower = \RpgFontStatBlockBody,
|
||||
title = {#2},
|
||||
#1
|
||||
}
|
||||
|
||||
% Alias RpgMonster to correct background type
|
||||
\bool_if:NTF \l__rpg_show_background_bool
|
||||
{
|
||||
\let\RpgMonster\RpgMonsterBg
|
||||
\let\endRpgMonster\endRpgMonsterBg
|
||||
}{
|
||||
\let\RpgMonster\RpgMonsterNoBg
|
||||
\let\endRpgMonster\endRpgMonsterNoBg
|
||||
}
|
||||
|
||||
% Italicized text appearing immediately after monster's name
|
||||
\NewDocumentCommand {\RpgMonsterType} {m}
|
||||
{
|
||||
\begin {hangingpar}
|
||||
\textit {#1}
|
||||
\end {hangingpar}
|
||||
}
|
||||
|
||||
% Fancy DnD 5e stat block rule
|
||||
\NewDocumentCommand {\RpgMonsterLine} {}
|
||||
{
|
||||
\par \vspace{-2pt} \noindent
|
||||
\begin {tikzpicture}
|
||||
\draw [ rulered, fill = rulered ] ( 0, 0 ) -- ( 0, 0.1 ) -- ( \linewidth, 0.05 );
|
||||
\end {tikzpicture}
|
||||
\par
|
||||
}
|
||||
|
||||
% A description variant used to list creature attributes.
|
||||
\newlist {__rpg_monster_attributes} {description} {1}
|
||||
\setlist [__rpg_monster_attributes]
|
||||
{
|
||||
before = \color {titlered},
|
||||
font = \RpgFontStatBlockBody,
|
||||
labelsep = \l__rpg_space_dim,
|
||||
nosep,
|
||||
}
|
||||
|
||||
% Only prints the item label if the value was supplied
|
||||
\cs_new_protected_nopar:Npn \__rpg_if_monster_attribute:nn #1#2
|
||||
{
|
||||
\tl_if_empty:NF {#1}
|
||||
{ \item [#2] #1 }
|
||||
}
|
||||
|
||||
%% Monster basics
|
||||
\keys_define:nn { rpg / monster / basics }
|
||||
{
|
||||
armor-class .tl_set:N = \l__armor_class_tl,
|
||||
armor-class .initial:n = 10,
|
||||
armor-class .value_required:n = true,
|
||||
armorclass .meta:n = { armor-class = {#1} },
|
||||
hit-points .tl_set:N = \l__hit_points_tl,
|
||||
hit-points .initial:n = \RpgDice {1d8},
|
||||
hit-points .value_required:n = true,
|
||||
hitpoints .meta:n = { hit-points = {#1} },
|
||||
speed .tl_set:N = \l__speed_tl,
|
||||
speed .initial:n = 30 ~ \unitsname,
|
||||
speed .value_required:n = true,
|
||||
}
|
||||
|
||||
\cs_new_protected_nopar:Npn \__rpg_monster_basics:
|
||||
{
|
||||
\begin {__rpg_monster_attributes}
|
||||
\item [\armorclassname] \l__armor_class_tl
|
||||
\item [\hitpointsname] \l__hit_points_tl
|
||||
\item [\speedname] \l__speed_tl
|
||||
\end {__rpg_monster_attributes}
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgMonsterBasics} {o}
|
||||
{
|
||||
\group_begin:
|
||||
\keys_set:nn { rpg / monster / basics } {#1}
|
||||
\RpgMonsterLine
|
||||
\__rpg_monster_basics:
|
||||
\RpgMonsterLine
|
||||
\group_end:
|
||||
}
|
||||
|
||||
%% Monster CR/XP helper
|
||||
% \l_tmpa_tl - CR
|
||||
% \l_tmpb_tl - XP
|
||||
\cs_new_protected_nopar:Npn \__rpg_cr_xp:N #1
|
||||
{
|
||||
\tl_set:Nn \l_tmpa_tl {#1}
|
||||
\str_case_e:nnTF {#1}
|
||||
{
|
||||
{0} { \tl_set:Nn \l_tmpb_tl {0} }
|
||||
{0/10}
|
||||
{
|
||||
\tl_set:Nn \l_tmpa_tl {0}
|
||||
\tl_set:Nn \l_tmpb_tl {10}
|
||||
}
|
||||
{1/10}
|
||||
{
|
||||
\rpg@deprecate{ Challenge ~ 1/10 } {0.8} [ Use ~ challenge ~ 0/10 ~ instead. ]
|
||||
\tl_set:Nn \l_tmpa_tl {0}
|
||||
\tl_set:Nn \l_tmpb_tl {10}
|
||||
}
|
||||
{1/8} { \tl_set:Nn \l_tmpb_tl {25} }
|
||||
{1/4} { \tl_set:Nn \l_tmpb_tl {50} }
|
||||
{1/2} { \tl_set:Nn \l_tmpb_tl {100} }
|
||||
{1} { \tl_set:Nn \l_tmpb_tl {200} }
|
||||
{2} { \tl_set:Nn \l_tmpb_tl {450} }
|
||||
{3} { \tl_set:Nn \l_tmpb_tl {700} }
|
||||
{4} { \tl_set:Nn \l_tmpb_tl {1100} }
|
||||
{5} { \tl_set:Nn \l_tmpb_tl {1800} }
|
||||
{6} { \tl_set:Nn \l_tmpb_tl {2300} }
|
||||
{7} { \tl_set:Nn \l_tmpb_tl {2900} }
|
||||
{8} { \tl_set:Nn \l_tmpb_tl {3900} }
|
||||
{9} { \tl_set:Nn \l_tmpb_tl {5000} }
|
||||
{10} { \tl_set:Nn \l_tmpb_tl {5900} }
|
||||
{11} { \tl_set:Nn \l_tmpb_tl {7200} }
|
||||
{12} { \tl_set:Nn \l_tmpb_tl {8400} }
|
||||
{13} { \tl_set:Nn \l_tmpb_tl {10000} }
|
||||
{14} { \tl_set:Nn \l_tmpb_tl {11500} }
|
||||
{15} { \tl_set:Nn \l_tmpb_tl {13000} }
|
||||
{16} { \tl_set:Nn \l_tmpb_tl {15000} }
|
||||
{17} { \tl_set:Nn \l_tmpb_tl {18000} }
|
||||
{18} { \tl_set:Nn \l_tmpb_tl {20000} }
|
||||
{19} { \tl_set:Nn \l_tmpb_tl {22000} }
|
||||
{20} { \tl_set:Nn \l_tmpb_tl {25000} }
|
||||
{21} { \tl_set:Nn \l_tmpb_tl {33000} }
|
||||
{22} { \tl_set:Nn \l_tmpb_tl {41000} }
|
||||
{23} { \tl_set:Nn \l_tmpb_tl {50000} }
|
||||
{24} { \tl_set:Nn \l_tmpb_tl {62000} }
|
||||
{25} { \tl_set:Nn \l_tmpb_tl {75000} }
|
||||
{26} { \tl_set:Nn \l_tmpb_tl {90000} }
|
||||
{27} { \tl_set:Nn \l_tmpb_tl {105000} }
|
||||
{28} { \tl_set:Nn \l_tmpb_tl {120000} }
|
||||
{29} { \tl_set:Nn \l_tmpb_tl {135000} }
|
||||
{30} { \tl_set:Nn \l_tmpb_tl {155000} }
|
||||
}
|
||||
{ \l_tmpa_tl\ ( \numprint {\l_tmpb_tl} ~ \xpname ) }
|
||||
{ #1 }
|
||||
}
|
||||
|
||||
%% Monster CR/PB helper
|
||||
% \l_tmpa_tl - CR
|
||||
% \l_tmpb_tl - PB
|
||||
\cs_new_protected_nopar:Npn \__rpg_cr_pb:N #1
|
||||
{
|
||||
\tl_set:Nn \l_tmpa_tl {#1}
|
||||
\str_case_e:nnTF {#1}
|
||||
{
|
||||
{0} { \tl_set:Nn \l_tmpb_tl {+2} }
|
||||
{1/8} { \tl_set:Nn \l_tmpb_tl {+2} }
|
||||
{1/4} { \tl_set:Nn \l_tmpb_tl {+2} }
|
||||
{1/2} { \tl_set:Nn \l_tmpb_tl {+2} }
|
||||
{1} { \tl_set:Nn \l_tmpb_tl {+2} }
|
||||
{2} { \tl_set:Nn \l_tmpb_tl {+2} }
|
||||
{3} { \tl_set:Nn \l_tmpb_tl {+2} }
|
||||
{4} { \tl_set:Nn \l_tmpb_tl {+2} }
|
||||
{5} { \tl_set:Nn \l_tmpb_tl {+3} }
|
||||
{6} { \tl_set:Nn \l_tmpb_tl {+3} }
|
||||
{7} { \tl_set:Nn \l_tmpb_tl {+3} }
|
||||
{8} { \tl_set:Nn \l_tmpb_tl {+3} }
|
||||
{9} { \tl_set:Nn \l_tmpb_tl {+4} }
|
||||
{10} { \tl_set:Nn \l_tmpb_tl {+4} }
|
||||
{11} { \tl_set:Nn \l_tmpb_tl {+4} }
|
||||
{12} { \tl_set:Nn \l_tmpb_tl {+4} }
|
||||
{13} { \tl_set:Nn \l_tmpb_tl {+5} }
|
||||
{14} { \tl_set:Nn \l_tmpb_tl {+5} }
|
||||
{15} { \tl_set:Nn \l_tmpb_tl {+5} }
|
||||
{16} { \tl_set:Nn \l_tmpb_tl {+5} }
|
||||
{17} { \tl_set:Nn \l_tmpb_tl {+6} }
|
||||
{18} { \tl_set:Nn \l_tmpb_tl {+6} }
|
||||
{19} { \tl_set:Nn \l_tmpb_tl {+6} }
|
||||
{20} { \tl_set:Nn \l_tmpb_tl {+6} }
|
||||
{21} { \tl_set:Nn \l_tmpb_tl {+7} }
|
||||
{22} { \tl_set:Nn \l_tmpb_tl {+7} }
|
||||
{23} { \tl_set:Nn \l_tmpb_tl {+7} }
|
||||
{24} { \tl_set:Nn \l_tmpb_tl {+7} }
|
||||
{25} { \tl_set:Nn \l_tmpb_tl {+8} }
|
||||
{26} { \tl_set:Nn \l_tmpb_tl {+8} }
|
||||
{27} { \tl_set:Nn \l_tmpb_tl {+8} }
|
||||
{28} { \tl_set:Nn \l_tmpb_tl {+8} }
|
||||
{29} { \tl_set:Nn \l_tmpb_tl {+9} }
|
||||
{30} { \tl_set:Nn \l_tmpb_tl {+9} }
|
||||
}
|
||||
{ \l_tmpb_tl }
|
||||
{ #1 }
|
||||
}
|
||||
|
||||
%% Monster details
|
||||
\keys_define:nn { rpg / monster / details }
|
||||
{
|
||||
saving-throws .tl_set:N = \l__saving_throws_tl,
|
||||
saving-throws .value_required:n = true,
|
||||
savingthrows .meta:n = { saving-throws = {#1} },
|
||||
skills .tl_set:N = \l__skills_tl,
|
||||
skills .value_required:n = true,
|
||||
damage-vulnerabilities .tl_set:N = \l__damage_vulnerabilities_tl,
|
||||
damage-vulnerabilities .value_required:n = true,
|
||||
damagevulnerabilities .meta:n = { damage-vulnerabilities = {#1} },
|
||||
damage-resistances .tl_set:N = \l__damage_resistances_tl,
|
||||
damage-resistances .value_required:n = true,
|
||||
damageresistances .meta:n = { damage-resistances = {#1} },
|
||||
damage-immunities .tl_set:N = \l__damage_immunities_tl,
|
||||
damage-immunities .value_required:n = true,
|
||||
damageimmunities .meta:n = { damage-immunities = {#1} },
|
||||
condition-immunities .tl_set:N = \l__condition_immunities_tl,
|
||||
condition-immunities .value_required:n = true,
|
||||
conditionimmunities .meta:n = { condition-immunities = {#1} },
|
||||
senses .tl_set:N = \l__senses_tl,
|
||||
senses .initial:n = \defaultsensesname,
|
||||
senses .value_required:n = true,
|
||||
languages .tl_set:N = \l__languages_tl,
|
||||
languages .initial:n = ---,
|
||||
languages .value_required:n = true,
|
||||
challenge .tl_set:N = \l__challenge_tl,
|
||||
challenge .initial:n = 1,
|
||||
challenge .value_required:n = true,
|
||||
proficiency-bonus .tl_set:N = \l__proficiency_tl,
|
||||
proficiency-bonus .value_required:n = false,
|
||||
proficiency-bonus .default:n = *,
|
||||
proficiencybonus .meta:n = { proficiency-bonus = {#1} },
|
||||
}
|
||||
|
||||
\cs_new_protected_nopar:Npn \__rpg_monster_details:
|
||||
{
|
||||
\begin {__rpg_monster_attributes}
|
||||
\__rpg_if_monster_attribute:nn {\l__saving_throws_tl} {\savesname}
|
||||
\__rpg_if_monster_attribute:nn {\l__skills_tl} {\skillsname}
|
||||
\__rpg_if_monster_attribute:nn {\l__damage_vulnerabilities_tl} {\dvulname}
|
||||
\__rpg_if_monster_attribute:nn {\l__damage_resistances_tl} {\dresname}
|
||||
\__rpg_if_monster_attribute:nn {\l__damage_immunities_tl} {\dimmname}
|
||||
\__rpg_if_monster_attribute:nn {\l__condition_immunities_tl} {\cimmname}
|
||||
\item [\sensesname] \l__senses_tl
|
||||
\item [\languagesname] \l__languages_tl
|
||||
\item [\challengename] \__rpg_cr_xp:N {\l__challenge_tl}
|
||||
\tl_if_empty:NF {\l__proficiency_tl}
|
||||
{
|
||||
{\enit@svlabel{\enit@format{\pbonname}}}
|
||||
\hskip \labelsep
|
||||
\str_if_eq:VnTF \l__proficiency_tl *
|
||||
{\__rpg_cr_pb:N {\l__challenge_tl}}
|
||||
{\l__proficiency_tl}
|
||||
}
|
||||
\end {__rpg_monster_attributes}
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgMonsterDetails} {o}
|
||||
{
|
||||
\group_begin:
|
||||
\keys_set:nn { rpg / monster / details } {#1}
|
||||
\RpgMonsterLine{}
|
||||
\__rpg_monster_details:
|
||||
\RpgMonsterLine{}
|
||||
\group_end:
|
||||
}
|
||||
|
||||
%% Ability scores
|
||||
% Print ability score stats with auto-computed modifier
|
||||
% e.g. \stat{12} prints "12 (+1)"
|
||||
\cs_new_protected_nopar:Npn \__rpg_ability_score_modifier:N #1
|
||||
{
|
||||
\regex_match:NnTF \c__pos_int_regex {#1}
|
||||
{
|
||||
\int_set:Nn \l_tmpa_int { \fp_eval:n { floor ( ( #1 - 10 ) / 2 ) } }
|
||||
|
||||
#1 ~ (
|
||||
\int_compare:nNnTF {\l_tmpa_int} < {0}
|
||||
{ -- }
|
||||
{+}
|
||||
\int_abs:n \l_tmpa_int )
|
||||
}
|
||||
{#1}
|
||||
}
|
||||
|
||||
\keys_define:nn { rpg / monster / ability_scores }
|
||||
{
|
||||
str .tl_set:N = \l__str_tl,
|
||||
str .initial:n = 10,
|
||||
str .value_required:n = true,
|
||||
STR .meta:n = { str = #1 },
|
||||
dex .tl_set:N = \l__dex_tl,
|
||||
dex .initial:n = 10,
|
||||
dex .value_required:n = true,
|
||||
DEX .meta:n = { dex = #1 },
|
||||
con .tl_set:N = \l__con_tl,
|
||||
con .initial:n = 10,
|
||||
con .value_required:n = true,
|
||||
CON .meta:n = { con = #1 },
|
||||
int .tl_set:N = \l__int_tl,
|
||||
int .initial:n = 10,
|
||||
int .value_required:n = true,
|
||||
INT .meta:n = { int = #1 },
|
||||
wis .tl_set:N = \l__wis_tl,
|
||||
wis .initial:n = 10,
|
||||
wis .value_required:n = true,
|
||||
WIS .meta:n = { wis = #1 },
|
||||
cha .tl_set:N = \l__cha_tl,
|
||||
cha .initial:n = 10,
|
||||
cha .value_required:n = true,
|
||||
CHA .meta:n = { cha = #1 },
|
||||
}
|
||||
|
||||
% Ability scores in a table
|
||||
\cs_new_protected_nopar:Npn \__rpg_monster_ability_scores:
|
||||
{
|
||||
\color {titlered}
|
||||
\par \vspace{1pt} \noindent
|
||||
\begin{tabularx} {\linewidth} {YYYYYY}
|
||||
\rule {0pt} {3.7mm} % adds space between hline and table
|
||||
\textbf {\strstatname} &
|
||||
\textbf {\dexstatname} &
|
||||
\textbf {\constatname} &
|
||||
\textbf {\intstatname} &
|
||||
\textbf {\wisstatname} &
|
||||
\textbf {\chastatname} \\
|
||||
\exp_args:NV \__rpg_ability_score_modifier:N \l__str_tl &
|
||||
\exp_args:NV \__rpg_ability_score_modifier:N \l__dex_tl &
|
||||
\exp_args:NV \__rpg_ability_score_modifier:N \l__con_tl &
|
||||
\exp_args:NV \__rpg_ability_score_modifier:N \l__int_tl &
|
||||
\exp_args:NV \__rpg_ability_score_modifier:N \l__wis_tl &
|
||||
\exp_args:NV \__rpg_ability_score_modifier:N \l__cha_tl
|
||||
\end{tabularx}
|
||||
|
||||
\par \vspace{4pt}%
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgMonsterAbilityScores} {o}
|
||||
{
|
||||
\group_begin:
|
||||
\keys_set:nn { rpg / monster / ability_scores } {#1}
|
||||
\__rpg_monster_ability_scores:
|
||||
\group_end:
|
||||
}
|
||||
|
||||
% Inline header for monster actions - similar to a paragraph
|
||||
\NewDocumentCommand {\RpgMonsterAction} {m}
|
||||
{ \par \smallskip \noindent \textsl { \textbf {#1.} } }
|
||||
|
||||
% Inline header for monster sub actions - similar to a subparagraph
|
||||
\NewDocumentCommand {\RpgMonsterSubAction} {m}
|
||||
{ \par \textsl { \textbf {#1.} } }
|
||||
|
||||
% Monster subsection header style
|
||||
\NewDocumentCommand {\RpgMonsterSection} {m}
|
||||
{
|
||||
\addvspace{6pt plus 2pt minus 2pt} \noindent
|
||||
\group_begin:
|
||||
\RpgFontStatBlockSection #1\nopagebreak[4]
|
||||
% \rule is a horizontal command, so placing it under the title incurs extra
|
||||
% line spacing. Use \hrule (a vertical command) instead.
|
||||
\vspace {2pt}\nopagebreak[4]
|
||||
\hrule height 0.6pt
|
||||
\group_end:
|
||||
\par \vspace{5pt}
|
||||
\noindent \ignorespaces
|
||||
}
|
||||
|
||||
% Spellcasting levels
|
||||
\newlist {RpgMonsterSpells} {description} {1}
|
||||
\setlist [RpgMonsterSpells]
|
||||
{
|
||||
font = \normalfont \RpgFontStatBlockBody,
|
||||
labelsep = \l__rpg_space_dim,
|
||||
noitemsep,
|
||||
topsep = 6pt plus 2pt minus 2pt,
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgEmphSpellString} {m}
|
||||
{
|
||||
\group_begin:
|
||||
\seq_set_from_clist:Nn \l_tmpa_seq {#1}
|
||||
\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \exp_not:n { \emph {##1} } }
|
||||
\seq_use:Nn \l_tmpb_seq { ,~ }
|
||||
\group_end:
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgInnateSpellLevel} { O {\innateatwillname} m }
|
||||
{
|
||||
\item
|
||||
[
|
||||
\regex_match:NnTF \c__pos_int_regex {#1}
|
||||
{
|
||||
\str_if_in:NnTF {#2} {,}
|
||||
{ \__rpg_caption:nn {\numberperdayeachname} {#1} }
|
||||
{ \__rpg_caption:nn {\numberperdayname} {#1} }
|
||||
}
|
||||
{#1}
|
||||
:
|
||||
]
|
||||
\RpgEmphSpellString {#2}
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgMonsterSpellLevel} { O{\spellcantripsname} O{\spellatwillname} m }
|
||||
{
|
||||
\item
|
||||
[
|
||||
\str_case_e:nnF {#1}
|
||||
{
|
||||
{1} {\spellfirstlevelname}
|
||||
{2} {\spellsecondlevelname}
|
||||
{3} {\spellthirdlevelname}
|
||||
{4} {\spellfourthlevelname}
|
||||
{5} {\spellfifthlevelname}
|
||||
{6} {\spellsixthlevelname}
|
||||
{7} {\spellseventhlevelname}
|
||||
{8} {\spelleighthlevelname}
|
||||
{9} {\spellninthlevelname}
|
||||
}
|
||||
{#1}
|
||||
{~}(
|
||||
\str_case_e:nnF {#2}
|
||||
{
|
||||
{1} {\spelloneslotname}
|
||||
{2} {\spelltwoslotsname}
|
||||
{3} {\spellthreeslotsname}
|
||||
{4} {\spellfourslotsname}
|
||||
}
|
||||
{#2}
|
||||
) :
|
||||
]
|
||||
\RpgEmphSpellString{#3}
|
||||
}
|
||||
|
||||
%% Monster attacks
|
||||
\tl_new:N \l__rpg_attack_distance_tl
|
||||
\tl_new:N \l__rpg_attack_type_tl
|
||||
|
||||
\keys_define:nn { rpg / monster / attack }
|
||||
{
|
||||
name .tl_set:N = \l__name_tl,
|
||||
name .value_required:n = true,
|
||||
distance .choice:,
|
||||
distance .choices:nn =
|
||||
{ both, melee, ranged }
|
||||
{ \tl_set:Nn \l__rpg_attack_distance_tl {\l_keys_choice_tl} },
|
||||
distance .initial:n = both,
|
||||
type .choice:,
|
||||
type / weapon .code:n = { \tl_set:Nn \l__rpg_attack_type_tl {\weaponname} },
|
||||
type / spell .code:n = { \tl_set:Nn \l__rpg_attack_type_tl {\spellname} },
|
||||
type .initial:n = weapon,
|
||||
mod .tl_set:N = \l__mod_tl,
|
||||
mod .value_required:n = true,
|
||||
reach .tl_set:N = \l__reach_tl,
|
||||
reach .initial:n = 5,
|
||||
reach .value_required:n = true,
|
||||
range .tl_set:N = \l__range_tl,
|
||||
range .initial:n = 20/60,
|
||||
range .value_required:n = true,
|
||||
targets .tl_set:N = \l__targets_tl,
|
||||
targets .initial:n = \defaulttargetsname,
|
||||
targets .value_required:n = true,
|
||||
dmg .tl_set:N = \l__dmg_tl,
|
||||
dmg .value_required:n = true,
|
||||
dmg-type .tl_set:N = \l__dmg_type_tl,
|
||||
dmg-type .value_required:n = true,
|
||||
plus-dmg .tl_set:N = \l__plus_dmg_tl,
|
||||
plus-dmg .value_required:n = true,
|
||||
plus-dmg-type .tl_set:N = \l__plus_dmg_type_tl,
|
||||
plus-dmg-type .value_required:n = true,
|
||||
or-dmg .tl_set:N = \l__or_dmg_tl,
|
||||
or-dmg .value_required:n = true,
|
||||
or-dmg-when .tl_set:N = \l__or_dmg_when_tl,
|
||||
or-dmg-when .value_required:n = true,
|
||||
extra .tl_set:N = \l__extra_tl,
|
||||
extra .value_required:n = true,
|
||||
}
|
||||
|
||||
\cs_new_protected:Npn \__rpg_monster_reach:
|
||||
{
|
||||
\reachname\ \l__reach_tl\ \unitsname
|
||||
}
|
||||
|
||||
\cs_new_protected:Npn \__rpg_monster_range:
|
||||
{
|
||||
\rangename\ \l__range_tl\ \unitsname
|
||||
}
|
||||
|
||||
\cs_new_protected:Npn \__rpg_if_plus_dmg:
|
||||
{
|
||||
\tl_if_empty:NF {\l__plus_dmg_tl}
|
||||
{ ~ \plusname\ \l__plus_dmg_tl\ \l__plus_dmg_type_tl\ \damagename }
|
||||
}
|
||||
|
||||
\cs_new_protected_nopar:Npn \__rpg_if_or_dmg:
|
||||
{
|
||||
\tl_if_empty:NF {\l__or_dmg_tl}
|
||||
{
|
||||
, ~ \orname\ \l__or_dmg_tl\ \l__dmg_type_tl\ \damagename\ \l__or_dmg_when_tl
|
||||
|
||||
\tl_if_empty:NF {\l__plus_dmg_tl}
|
||||
{,}
|
||||
}
|
||||
}
|
||||
|
||||
\cs_new_protected:Npn \__rpg_monster_attack:
|
||||
{
|
||||
\__rpg_check_for_key:Nnn \l__name_tl {\RpgMonsterAttack} {name}
|
||||
\__rpg_check_for_key:Nnn \l__mod_tl {\RpgMonsterAttack} {mod}
|
||||
|
||||
\begin{RpgMonsterAction} {\l__name_tl}~
|
||||
|
||||
\str_case_e:nnF {\l__rpg_attack_distance_tl}
|
||||
{
|
||||
{ melee }
|
||||
{
|
||||
\textit{ \__rpg_caption:nn {\meleeattackname} {\l__rpg_attack_type_tl} : } ~ \__rpg_caption:nn {\tohitname} {\l__mod_tl}, ~ \__rpg_monster_reach:
|
||||
}
|
||||
{ ranged }
|
||||
{
|
||||
\textit{ \__rpg_caption:nn {\rangedattackname} {\l__rpg_attack_type_tl} : } ~ \__rpg_caption:nn {\tohitname} {\l__mod_tl}, ~ \__rpg_monster_range:
|
||||
}
|
||||
}
|
||||
{% Melee and Ranged is the default
|
||||
\textit{ \__rpg_caption:nn {\meleeorrangedattackname} {\l__rpg_attack_type_tl} : } ~ \__rpg_caption:nn {\tohitname} {\l__mod_tl}, ~ \__rpg_monster_reach:\ \orname\ \__rpg_monster_range:
|
||||
}
|
||||
, ~ \l__targets_tl. ~
|
||||
\textit { \hitname : } ~
|
||||
|
||||
\str_if_empty:NF {\l__dmg_tl} % Don't show any damage if `dmg' is not set.
|
||||
{
|
||||
\l__dmg_tl\ \l__dmg_type_tl\ \damagename
|
||||
\__rpg_if_or_dmg:
|
||||
\__rpg_if_plus_dmg:
|
||||
}
|
||||
|
||||
% `extra' is any special text that goes after the final damage; do not
|
||||
% include the final full stop.
|
||||
\l__extra_tl .
|
||||
\end{RpgMonsterAction}
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgMonsterAttack} {o}
|
||||
{
|
||||
\group_begin:
|
||||
\keys_set:nn { rpg / monster / attack } {#1}
|
||||
\__rpg_monster_attack:
|
||||
\group_end:
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgMonsterMelee} {o}
|
||||
{
|
||||
\group_begin:
|
||||
\keys_set:nn { rpg / monster / attack } { #1, distance = melee }
|
||||
\__rpg_monster_attack:
|
||||
\group_end:
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgMonsterRanged} {o}
|
||||
{
|
||||
\group_begin:
|
||||
\keys_set:nn { rpg / monster / attack } { #1, distance = ranged }
|
||||
\__rpg_monster_attack:
|
||||
\group_end:
|
||||
}
|
||||
|
||||
%% Legendary Actions
|
||||
|
||||
\newlist {RpgMonsterLegendaryActions} {description} {1}
|
||||
\setlist [RpgMonsterLegendaryActions]
|
||||
{
|
||||
font = \RpgFontStatBlockBody,
|
||||
labelsep = \l__rpg_space_dim,
|
||||
noitemsep,
|
||||
topsep = 6pt plus 2pt minus 2pt,
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgMonsterLegendaryAction} { m m }
|
||||
{
|
||||
\item [ #1 . ] #2
|
||||
}
|
||||
|
||||
80
lib/rpgreadaloud.sty
Normal file
80
lib/rpgreadaloud.sty
Normal file
@@ -0,0 +1,80 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Environment for read-aloud text.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Standard for every read-aloud text
|
||||
\DeclareTColorBox {__rpg_read_aloud} {o}
|
||||
{
|
||||
before~upper =
|
||||
{
|
||||
\bool_if:NT \l__rpg_layout_bool
|
||||
{
|
||||
\bool_if:NF \l__rpg_justified_bool
|
||||
{\RaggedRight}
|
||||
}
|
||||
},
|
||||
code = {\linespread {1.1} },
|
||||
enhanced~jigsaw,
|
||||
frame~hidden,
|
||||
boxrule = 0pt,
|
||||
breakable,
|
||||
enhanced,
|
||||
before~skip = 13pt plus 4pt minus 4pt,
|
||||
boxsep = 8pt,
|
||||
top = 0pt,
|
||||
left = 0pt,
|
||||
right = 0pt,
|
||||
bottom = 0pt,
|
||||
sharp~corners,
|
||||
parbox = false,
|
||||
borderline~west = {1pt} {-0.5pt} {titlered},
|
||||
borderline~east = {1pt} {-0.5pt} {titlered},
|
||||
fontupper = \RpgFontReadAloud,
|
||||
fontlower = \RpgFontReadAloud,
|
||||
overlay =
|
||||
{
|
||||
\foreach\n ~ in ~ { north~east, north~west, south~east, south~west }
|
||||
{\draw [ titlered, fill = titlered ] ( frame.\n ) circle (1.5pt); };
|
||||
},
|
||||
after~skip = 13pt plus 4pt minus 4pt,
|
||||
#1,
|
||||
}
|
||||
|
||||
% Extra key for controlling the color of the title and the background
|
||||
\keys_define:nn { rpg / read_aloud }
|
||||
{
|
||||
color .tl_set:N = \l__rpg_read_aloud_color_tl,
|
||||
color .initial:n = readaloudcolor,
|
||||
color .value_required:n = true,
|
||||
}
|
||||
|
||||
% This function, through its variant, forces the expansion of the tcb keys
|
||||
% passed to the environment by the user before it invokes the tcolorbox
|
||||
\cs_new_protected:Nn \__rpg_start_read_aloud:nn
|
||||
{
|
||||
\begin {__rpg_read_aloud} [ #1, #2 ]
|
||||
}
|
||||
|
||||
\cs_generate_variant:Nn \__rpg_start_read_aloud:nn { nV }
|
||||
|
||||
% The RpgReadAloud environment
|
||||
% #1 - keys. We handle the custom color key before passing other keys on
|
||||
\NewDocumentEnvironment {RpgReadAloud} {o}
|
||||
{
|
||||
\group_begin:
|
||||
\keys_set_known:nnN { rpg / read_aloud } {#1} \l_tmpa_tl
|
||||
|
||||
\str_if_eq:VnT \l_tmpa_tl { -NoValue- }
|
||||
{ \tl_set_eq:NN \l_tmpa_tl \c_empty_tl }
|
||||
|
||||
\__rpg_start_read_aloud:nV
|
||||
{
|
||||
colback = \l__rpg_read_aloud_color_tl,
|
||||
}
|
||||
{\l_tmpa_tl}
|
||||
}
|
||||
{
|
||||
\end {__rpg_read_aloud}
|
||||
\group_end:
|
||||
}
|
||||
244
lib/rpgsections.sty
Normal file
244
lib/rpgsections.sty
Normal file
@@ -0,0 +1,244 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
\bool_if:NT \l__rpg_layout_bool
|
||||
{
|
||||
% Change part numbering to Arabic numbers from Roman numerals
|
||||
\renewcommand{\thepart}{\arabic{part}}
|
||||
|
||||
% Set spacing around floats
|
||||
\setlength{\textfloatsep}{11pt plus 4pt minus 4pt}
|
||||
\setlength{\intextsep}{11pt plus 4pt minus 4pt}
|
||||
\setlength{\dbltextfloatsep}{11pt plus 4pt minus 4pt}
|
||||
|
||||
% Remove Numbering (If you want Numbering set secnumdepth to the appropriate depth)
|
||||
\setcounter{secnumdepth}{0}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Section formatting
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Part
|
||||
\titleformat {\part}
|
||||
[display]
|
||||
{ \centering \RpgFontPart } % format
|
||||
{ \RpgContour{\partname\ \thepart} } % label
|
||||
{ 2ex } % sep
|
||||
{ \RpgContour } % before-code
|
||||
|
||||
% Chapter
|
||||
\titleformat {\chapter}
|
||||
{ \RpgFontChapter } % format
|
||||
{ \RpgContour{\chaptertitlename\ \thechapter :} } % label
|
||||
{ \wordsep } % sep
|
||||
{ \RpgContour } % before-code
|
||||
|
||||
\titlespacing* {\chapter}
|
||||
{ 0pt } % left
|
||||
{ .3ex } % before-sep
|
||||
{ 2.8ex } % after-sep
|
||||
|
||||
% Section
|
||||
\titleformat {\section}
|
||||
{ \RpgFontSection } % format
|
||||
{ \thesection } % label
|
||||
{ 1em } % sep
|
||||
{ \nopagebreak } % before-code
|
||||
|
||||
\titlespacing* { \section }
|
||||
{ 0pt } % left
|
||||
{ 1.3ex plus .43ex minus .43ex } % before-sep
|
||||
{ 0pt } % after-sep
|
||||
|
||||
% Subsection
|
||||
\titleformat {\subsection}
|
||||
{ \RpgFontSubsection } % format
|
||||
{ \thesubsection } % label
|
||||
{ 1em } % sep
|
||||
{ \nopagebreak } % before-code
|
||||
[ \vspace{-.3ex} \titleline{ \color{titlegold} \titlerule[1pt] } ] % after-code
|
||||
|
||||
\titlespacing*{ \subsection }
|
||||
{ 0pt } % left
|
||||
{ 1.4ex plus .47ex minus .47ex } % before-sep
|
||||
{ 1.2ex } % after-sep
|
||||
|
||||
% Subsubsection
|
||||
\titleformat {\subsubsection}
|
||||
{ \RpgFontSubsubsection } % format
|
||||
{ \thesubsubsection } % label
|
||||
{ 1em } % sep
|
||||
{ \nopagebreak } % before-code
|
||||
|
||||
\titlespacing* { \subsubsection }
|
||||
{ 0pt } % left
|
||||
{ 2ex plus .67ex minus .67ex } % before-sep
|
||||
{ .2ex } % after-sep
|
||||
|
||||
% Paragraph
|
||||
\titleformat {\paragraph} [runin]
|
||||
{ \RpgFontParagraph } % format
|
||||
{ \theparagraph \quad } % label
|
||||
{0pt} % sep
|
||||
{} % before-code
|
||||
[.] % after-code
|
||||
|
||||
\titlespacing* {\paragraph}
|
||||
{0pt} % left
|
||||
{\parskip} % before-sep
|
||||
{\wordsep} % after-sep
|
||||
|
||||
% Subparagraph
|
||||
\titleformat {\subparagraph} [runin]
|
||||
{ \RpgFontSubaragraph } % format
|
||||
{ \thesubparagraph \quad } % label
|
||||
{0pt} % sep
|
||||
{} % before-code
|
||||
[.] % after-code
|
||||
|
||||
\titlespacing* {\subparagraph}
|
||||
{\parindent} % left
|
||||
{\parskip} % before-sep
|
||||
{\wordsep} % after-sep
|
||||
}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Special command for magic items, traps, and the like.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\NewDocumentCommand {\RpgFeatHeader} { m o }
|
||||
{
|
||||
\subsection {#1}
|
||||
\IfValueT{#2}
|
||||
{
|
||||
\textit {#2}
|
||||
\par \vspace{3pt} \noindent \ignorespaces
|
||||
}
|
||||
}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Special command for magic items, traps, and the like.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\NewDocumentCommand {\RpgItemHeader} { m m }
|
||||
{
|
||||
\subsubsection {#1}
|
||||
\textit {#2}
|
||||
\par \vspace{3pt} \noindent \ignorespaces
|
||||
}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Special command for spells.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% #1 - Name
|
||||
% #2 - Level and school
|
||||
% #3 - Casting time
|
||||
% #4 - Range
|
||||
% #5 - Components
|
||||
% #6 - Duration
|
||||
\NewDocumentCommand {\RpgSpellHeader} { m m m m m m }
|
||||
{
|
||||
\RpgItemHeader {#1} {#2}
|
||||
|
||||
\begin{description}
|
||||
[
|
||||
nosep,
|
||||
labelsep = \l__rpg_space_dim,
|
||||
after = { \vspace{4pt plus 1pt minus 1pt} },
|
||||
]
|
||||
\item [ \spellcastingtimename : ] #3
|
||||
\item [ \spellrangename : ] #4
|
||||
\item [ \spellcomponentsname : ] #5
|
||||
\item [ \spelldurationname : ] #6
|
||||
\end{description}
|
||||
}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Map Areas and their References
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
\tl_new:N \l__rpg_area_num_depth_tl
|
||||
|
||||
% Options
|
||||
\keys_define:nn { rpg / areas }
|
||||
{
|
||||
area-label .tl_set:N = \l__rpg_area_label_tl,
|
||||
area-label .initial:n = area,
|
||||
area-label .value_required:n = true,
|
||||
sub-area-label .tl_set:N = \l__rpg_sub_area_label_tl,
|
||||
sub-area-label .initial:n = subarea,
|
||||
sub-area-label .value_required:n = true,
|
||||
region .tl_set:N = \l__rpg_region_tl,
|
||||
region .value_required:n = true,
|
||||
area-num-depth .choice:,
|
||||
area-num-depth .choices:nn =
|
||||
{ 1, 2, 3, 4 }
|
||||
{ \tl_set:Nn \l__rpg_area_num_depth_tl {\l_keys_choice_tl} },
|
||||
area-num-depth .initial:n = 2, % subsection
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgSetAreaOptions} {o}
|
||||
{
|
||||
\keys_set:nn { rpg / areas } { #1 }
|
||||
}
|
||||
|
||||
% Counters
|
||||
\newcounter {RpgAreaCounter}
|
||||
|
||||
\NewDocumentCommand {\RpgResetAreas} {}
|
||||
{
|
||||
\setcounter {RpgAreaCounter} {0}
|
||||
}
|
||||
|
||||
\newcounter {RpgSubAreaCounter} [RpgAreaCounter]
|
||||
|
||||
% sub area references should be '5a', '5b', not '51', '52'
|
||||
\renewcommand \p@RpgSubAreaCounter { \arabic {RpgAreaCounter} }
|
||||
\renewcommand \theRpgSubAreaCounter { \alph {RpgSubAreaCounter} }
|
||||
|
||||
% Functions to create an area including text and label
|
||||
\NewDocumentCommand {\RpgArea} {m}
|
||||
{
|
||||
\refstepcounter {RpgAreaCounter}
|
||||
\label { \l__rpg_region_tl \l__rpg_area_label_tl :#1 }
|
||||
|
||||
\tl_set:Nn \l_tmpa_tl { \l__rpg_region_tl \arabic {RpgAreaCounter} . ~ #1 }
|
||||
|
||||
\str_case_e:nn {\l__rpg_area_num_depth_tl}
|
||||
{
|
||||
{1} { \section {\l_tmpa_tl} }
|
||||
{2} { \subsection {\l_tmpa_tl} }
|
||||
{3} { \subsubsection {\l_tmpa_tl} }
|
||||
{4} { \paragraph {\l_tmpa_tl} }
|
||||
}
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgSubArea} {m}
|
||||
{
|
||||
\refstepcounter {RpgSubAreaCounter}
|
||||
\label { \l__rpg_region_tl \l__rpg_sub_area_label_tl : #1 }
|
||||
|
||||
\tl_set:Nn \l_tmpa_tl { \l__rpg_region_tl \arabic {RpgAreaCounter} \alph {RpgSubAreaCounter} . ~ #1 }
|
||||
|
||||
\str_case_e:nn {\l__rpg_area_num_depth_tl}
|
||||
{
|
||||
{1} { \subsection {\l_tmpa_tl} }
|
||||
{2} { \subsubsection {\l_tmpa_tl} }
|
||||
{3} { \paragraph {\l_tmpa_tl} }
|
||||
{4} { \subparagraph {\l_tmpa_tl} }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
% Functions to reference a label
|
||||
\NewDocumentCommand {\RpgAreaRef} { o m }
|
||||
{
|
||||
\group_begin:
|
||||
\keys_set:nn { rpg / areas } {#1} % Temp set keys to reference other regions
|
||||
#2 ~ ( \pageabbreviationname\ \pageref { \l__rpg_region_tl \l__rpg_area_label_tl : #2 } )
|
||||
\group_end:
|
||||
}
|
||||
|
||||
\NewDocumentCommand {\RpgSubAreaRef} { o m }
|
||||
{
|
||||
\group_begin:
|
||||
\keys_set:nn { rpg / areas } { #1 } % Temp set keys to reference other regions
|
||||
#2 ~ ( \pageabbreviationname\ \pageref { \l__rpg_region_tl \l__rpg_sub_area_label_tl : #2 } )
|
||||
\group_end:
|
||||
}
|
||||
87
lib/rpgsidebar.sty
Normal file
87
lib/rpgsidebar.sty
Normal file
@@ -0,0 +1,87 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Environment for sidebars.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Standard for every sidebar
|
||||
\DeclareTColorBox {__rpg_sidebar} {o}
|
||||
{
|
||||
before~upper =
|
||||
{
|
||||
\bool_if:NT \l__rpg_layout_bool
|
||||
{
|
||||
\bool_if:NF \l__rpg_justified_bool
|
||||
{\RaggedRight}
|
||||
}
|
||||
},
|
||||
code={\linespread{.9}},
|
||||
frame~hidden,
|
||||
boxrule = 0pt,
|
||||
enhanced,
|
||||
before~skip = 13pt plus 4pt minus 4pt,
|
||||
toptitle = 2pt,
|
||||
boxsep = 3pt,
|
||||
left = 6pt,
|
||||
right = 6pt,
|
||||
top = 0pt,
|
||||
bottom = 2pt,
|
||||
fonttitle = \RpgFontSidebarTitle,
|
||||
fontupper = \RpgFontSidebarBody,
|
||||
fontlower = \RpgFontSidebarBody,
|
||||
sharp~corners,
|
||||
parbox = false,
|
||||
borderline~north = {1pt} {-0.5pt} {black},
|
||||
borderline~south = {1pt} {-0.5pt} {black},
|
||||
coltitle = black,
|
||||
fuzzy~shadow = {0mm} {-3.5pt} {-0.5pt} {0.4mm} {black!60!white},
|
||||
overlay =
|
||||
{
|
||||
\fill [black] ( frame.south~west ) -- ++ ( 7pt, 0 ) -- ++ ( 0, -5pt ) -- cycle;
|
||||
\fill [black] ( frame.north~west ) -- ++ ( 7pt, 0 ) -- ++ ( 0, 5pt ) -- cycle;
|
||||
\fill [black] ( frame.north~east ) -- ++ ( -7pt, 0 ) -- ++ ( 0, 5pt ) -- cycle;
|
||||
\fill [black] ( frame.south~east ) -- ++ ( -7pt, 0 ) -- ++ ( 0, -5pt ) -- cycle;
|
||||
},
|
||||
after~skip = 14pt plus 4pt minus 4pt,
|
||||
#1,
|
||||
}
|
||||
|
||||
% Extra key for controlling the color of the title and the background
|
||||
\keys_define:nn { rpg / sidebar }
|
||||
{
|
||||
color .tl_set:N = \l__rpg_sidebar_color_tl,
|
||||
color .initial:n = sidebarcolor,
|
||||
color .value_required:n = true,
|
||||
}
|
||||
|
||||
% This function, through its variant, forces the expansion of the tcb keys
|
||||
% passed to the environment by the user before it invokes the tcolorbox
|
||||
\cs_new_protected:Nn \__rpg_start_sidebar:nn
|
||||
{
|
||||
\begin {__rpg_sidebar} [ #1, #2 ]
|
||||
}
|
||||
|
||||
\cs_generate_variant:Nn \__rpg_start_sidebar:nn { nV }
|
||||
|
||||
% The RpgSidebar environment
|
||||
% #1 - keys. We handle the custom color key before passing other keys on
|
||||
% #2 - title.
|
||||
\NewDocumentEnvironment {RpgSidebar} { o m }
|
||||
{
|
||||
\group_begin:
|
||||
\keys_set_known:nnN { rpg / sidebar } {#1} \l_tmpa_tl
|
||||
|
||||
\str_if_eq:VnT \l_tmpa_tl { -NoValue- }
|
||||
{ \tl_set_eq:NN \l_tmpa_tl \c_empty_tl }
|
||||
|
||||
\__rpg_start_sidebar:nV
|
||||
{
|
||||
colback = \l__rpg_sidebar_color_tl,
|
||||
colbacktitle = \l__rpg_sidebar_color_tl,
|
||||
title = {#2},
|
||||
}
|
||||
{\l_tmpa_tl}
|
||||
}
|
||||
{
|
||||
\end {__rpg_sidebar}
|
||||
\group_end:
|
||||
}
|
||||
143
lib/rpgstrings.sty
Executable file
143
lib/rpgstrings.sty
Executable file
@@ -0,0 +1,143 @@
|
||||
\ExplSyntaxOn % Use tilde (~) for spaces.
|
||||
|
||||
% \addto\captions<language> cannot handle macros with parameters
|
||||
% We need to make our own parameters
|
||||
% |1| represents parameter 1
|
||||
|
||||
\cs_new_protected:Npn \__rpg_caption:nn #1#2
|
||||
{
|
||||
\group_begin:
|
||||
\str_set:Nx \l_tmpa_str { #1 }
|
||||
\str_set:Nx \l_tmpb_str { #2 }
|
||||
\exp_args:NNnx \str_replace_all:Nnn \l_tmpa_str { |1| } { #2 }
|
||||
\str_use:N \l_tmpa_str
|
||||
\group_end:
|
||||
}
|
||||
|
||||
% Document-level version for backwards compatibility
|
||||
\NewDocumentCommand{\RpgCaption}{ m m }
|
||||
{ \__rpg_caption:nn {#1} {#2} }
|
||||
|
||||
% Define all strings as new macros instead of hardcoding them in the
|
||||
% TeX files. This then allows us to add captions for multilanguage support.
|
||||
|
||||
% If you add or update a caption here, add it to languages/_template.sty
|
||||
% as well.
|
||||
|
||||
%% Monster
|
||||
% Basics
|
||||
\newcommand\armorclassname{Armor~Class}
|
||||
\newcommand\hitpointsname{Hit~Points}
|
||||
\newcommand\speedname{Speed}
|
||||
|
||||
% Ability Scores
|
||||
\newcommand\strstatname{STR}
|
||||
\newcommand\dexstatname{DEX}
|
||||
\newcommand\constatname{CON}
|
||||
\newcommand\intstatname{INT}
|
||||
\newcommand\wisstatname{WIS}
|
||||
\newcommand\chastatname{CHA}
|
||||
|
||||
% Details
|
||||
\newcommand\skillsname{Skills}
|
||||
\newcommand\dimmname{Damage~Immunities}
|
||||
\newcommand\dvulname{Damage~Vulnerabilities}
|
||||
\newcommand\dresname{Damage~Resistances}
|
||||
\newcommand\cimmname{Condition~Immunities}
|
||||
\newcommand\savesname{Saving~Throws}
|
||||
\newcommand\sensesname{Senses}
|
||||
\newcommand\defaultsensesname{passive~Perception~10}
|
||||
\newcommand\languagesname{Languages}
|
||||
\newcommand\challengename{Challenge}
|
||||
\newcommand\pbonname{Proficiency~Bonus}
|
||||
\newcommand\xpname{XP}
|
||||
|
||||
% Attacks
|
||||
\newcommand\unitsname{ft.}
|
||||
\newcommand\weaponname{Weapon}
|
||||
\newcommand\spellname{Spell}
|
||||
\newcommand\meleeattackname{Melee~|1|~Attack}
|
||||
\newcommand\rangedattackname{Ranged~|1|~Attack}
|
||||
\newcommand\meleeorrangedattackname{Melee~or~Ranged~|1|~Attack}
|
||||
\newcommand\orname{or}
|
||||
\newcommand\tohitname{|1|~to~hit}
|
||||
\newcommand\defaulttargetsname{one~target}
|
||||
\newcommand\reachname{reach}
|
||||
\newcommand\rangename{range}
|
||||
\newcommand\hitname{Hit}
|
||||
\newcommand\damagename{damage}
|
||||
\newcommand\plusname{plus}
|
||||
|
||||
% Spell Levels
|
||||
\newcommand\spellcantripsname{Cantrips}
|
||||
\newcommand\spellfirstlevelname{1st~level}
|
||||
\newcommand\spellsecondlevelname{2nd~level}
|
||||
\newcommand\spellthirdlevelname{3rd~level}
|
||||
\newcommand\spellfourthlevelname{4th~level}
|
||||
\newcommand\spellfifthlevelname{5th~level}
|
||||
\newcommand\spellsixthlevelname{6th~level}
|
||||
\newcommand\spellseventhlevelname{7th~level}
|
||||
\newcommand\spelleighthlevelname{8th~level}
|
||||
\newcommand\spellninthlevelname{9th~level}
|
||||
|
||||
% Spell Slots
|
||||
\newcommand\spellatwillname{at~will}
|
||||
\newcommand\spelloneslotname{1~slot}
|
||||
\newcommand\spelltwoslotsname{2~slots}
|
||||
\newcommand\spellthreeslotsname{3~slots}
|
||||
\newcommand\spellfourslotsname{4~slots}
|
||||
|
||||
% Innate spellcasting
|
||||
\newcommand\innateatwillname{At~will}
|
||||
\newcommand\numberperdayname{|1|/day}
|
||||
\newcommand\numberperdayeachname{|1|/day~each}
|
||||
|
||||
% Spell Header
|
||||
\newcommand\spellcastingtimename{Casting~Time}
|
||||
\newcommand\spellrangename{Range}
|
||||
\newcommand\spellcomponentsname{Components}
|
||||
\newcommand\spelldurationname{Duration}
|
||||
|
||||
% Miscellaneous
|
||||
\newcommand\pageabbreviationname{pg.}
|
||||
\newcommand\dname{d}
|
||||
\newcommand\tocchapterabbreviationname{Ch.}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Adding languages
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% To add captions for other languages:
|
||||
% 1. Copy and paste languages/_template.sty to languages/<language>.sty
|
||||
% 2. Substitute the <language> token in the file with the language name
|
||||
% (i.e. \addto\captionsfrench).
|
||||
% 3. Replace the English strings with the translations and comment any captions
|
||||
% that you do not translate. Please keep the captions in the same order.
|
||||
% 4. Add \RequirePackage{lib/languages/<language>} to the following function.
|
||||
\cs_new_protected_nopar:Npn \__rpg_input_languages:
|
||||
{
|
||||
\RequirePackage{lib/languages/italian}
|
||||
\RequirePackage{lib/languages/japanese} % Requires LuaTeX or XeTeX
|
||||
\RequirePackage{lib/languages/ngerman}
|
||||
\RequirePackage{lib/languages/russian}
|
||||
\RequirePackage{lib/languages/spanish}
|
||||
\RequirePackage{lib/languages/french}
|
||||
\RequirePackage{lib/languages/portuguese}
|
||||
}
|
||||
|
||||
% Delay loading captions until after the user has imported a language package.
|
||||
% Enables using babel/polyglossia with the rpgbook document class as well as the
|
||||
% rpg package.
|
||||
%
|
||||
% Both language packages use \AtBeginDocument. Use \AtEndPreamble (etoolbox)
|
||||
% instead to side-step load order issues.
|
||||
\AtEndPreamble{
|
||||
% Check if either babel or polyglossia have been loaded,
|
||||
% in which case load the string captions
|
||||
\@ifpackageloaded{babel}{
|
||||
\__rpg_input_languages:
|
||||
}{}
|
||||
\@ifpackageloaded{polyglossia}{
|
||||
\__rpg_input_languages:
|
||||
}{}
|
||||
}
|
||||
66
lib/rpgtable.sty
Normal file
66
lib/rpgtable.sty
Normal file
@@ -0,0 +1,66 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
% Special Columns
|
||||
\newcolumntype {Y} { > {\centering\arraybackslash } X }
|
||||
\newcolumntype {`} { > {\global\let\currentrowstyle\relax } }
|
||||
\newcolumntype {^} { > {\currentrowstyle} }
|
||||
|
||||
% Matches {, }, >, , and any other character
|
||||
\regex_const:Nn \c__preamble_regex {>\s*{.*}\s*\S|\S}
|
||||
|
||||
\newcommand{\rowstyle}[1]
|
||||
{
|
||||
\gdef\currentrowstyle{#1}#1\ignorespaces
|
||||
}
|
||||
|
||||
% Table options
|
||||
\keys_define:nn { rpg / table }
|
||||
{
|
||||
color .tl_set:N = \l__rpg_table_color_tl,
|
||||
color .initial:n = tablecolor,
|
||||
color .value_required:n = true,
|
||||
header .tl_set:N = \l__rpg_table_header_tl,
|
||||
header .value_required:n = true,
|
||||
width .dim_set:N = \l__rpg_table_width_dim,
|
||||
width .value_required:n = true,
|
||||
}
|
||||
|
||||
% Table Definition
|
||||
\NewDocumentEnvironment {RpgTable} { o m }
|
||||
{
|
||||
\group_begin:
|
||||
|
||||
\dim_set:Nn \l__rpg_table_width_dim { \linewidth }
|
||||
\tl_if_novalue:nF {#1}
|
||||
{ \keys_set:nn { rpg / table } {#1} }
|
||||
|
||||
\par \vspace { 9pt plus 3pt minus 3pt } \noindent
|
||||
|
||||
\tl_if_empty:NF \l__rpg_table_header_tl
|
||||
{
|
||||
\group_begin:
|
||||
\RpgFontTableTitle \l__rpg_table_header_tl \nopagebreak
|
||||
\par \vspace{ 5pt plus 2pt minus 2pt } \noindent
|
||||
\group_end:
|
||||
}
|
||||
|
||||
\RpgFontTableBody
|
||||
|
||||
\rowcolors {1} {} {\l__rpg_table_color_tl}
|
||||
|
||||
\regex_extract_all:NnNTF \c__preamble_regex {#2} \l_tmpa_seq
|
||||
{
|
||||
\tl_set:Nn \l_tmpa_tl {\seq_use:Nn \l_tmpa_seq {^}}
|
||||
\use:x { \exp_not:n {\tabularx{\l__rpg_table_width_dim}}{`\l_tmpa_tl}}
|
||||
\rowstyle{\RpgFontTableHeader}
|
||||
}
|
||||
{
|
||||
\tabularx {\l__rpg_table_width_dim} {#2}
|
||||
}
|
||||
|
||||
}
|
||||
{
|
||||
\endtabularx \vspace { 9pt plus 3pt minus 3pt }
|
||||
|
||||
\group_end:
|
||||
}
|
||||
37
lib/rpgtoc.sty
Normal file
37
lib/rpgtoc.sty
Normal file
@@ -0,0 +1,37 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
\bool_if:NT \l__rpg_layout_bool
|
||||
{
|
||||
\RequirePackage{titletoc}
|
||||
|
||||
% Makes the TOC go to section depth
|
||||
\setcounter{tocdepth}{2}
|
||||
|
||||
\titlecontents{part}
|
||||
[0pt] % left
|
||||
{ \addvspace{.06in} \RpgFontTocPart } % above-code
|
||||
{\partname\ \thecontentslabel :~ } % numbered-entry-format
|
||||
{} % numberless-entry-format
|
||||
{} % filler-page-format
|
||||
[ \addvspace{-.03in} \titleline{ \color{titlegold} \titlerule[1pt] } \addvspace{.05in } ] % below-code
|
||||
|
||||
\titlecontents{chapter}
|
||||
[0pt] % left
|
||||
{ \addvspace{.1in} \RpgFontTocChapter } % above-code
|
||||
{ \tocchapapp\ \thecontentslabel :~ } % numbered-entry-format
|
||||
{} % numberless-entry-format
|
||||
{\titlerule*{.}\contentspage} % filler-page-format
|
||||
|
||||
\titlecontents{section}
|
||||
[0pt] % left
|
||||
{\RpgFontTocSection} % above-code
|
||||
{\thecontentslabel :~ } % numbered-entry-format
|
||||
{} % numberless-entry-format
|
||||
{\titlerule*{.}\contentspage} % filler-page-format
|
||||
|
||||
\newcommand\tocchapapp{\tocchapterabbreviationname}
|
||||
\g@addto@macro\appendix{%
|
||||
\addtocontents{toc}{\protect\renewcommand{\protect\@chapapp}{\appendixname}}%
|
||||
\addtocontents{toc}{\protect\renewcommand{\protect\tocchapapp}{\appendixname}}%
|
||||
}
|
||||
}
|
||||
74
lib/rpgutility.sty
Normal file
74
lib/rpgutility.sty
Normal file
@@ -0,0 +1,74 @@
|
||||
\ExplSyntaxOn
|
||||
|
||||
% Useful regex strings
|
||||
\regex_const:Nn \c__pos_int_regex { \d+ }
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% Dice macro
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Matches { # | #d# | #d# + # | #d# - # } while ignoring spaces
|
||||
\regex_const:Nn \c__valid_dice_regex { \A\s*(\d+)(?:[dD](\d+)\s*(?:([+\-])\s*(\d+))?)?\s*\Z }
|
||||
|
||||
\seq_new:N \l__dice_args_seq
|
||||
\tl_new:N \l__dice_number_tl
|
||||
\tl_new:N \l__dice_sides_tl
|
||||
\tl_new:N \l__dice_mod_sign_tl
|
||||
\tl_new:N \l__dice_mod_tl
|
||||
|
||||
\msg_new:nnn { rpg } { dice / invalid_argument } { Invalid~argument~``#1''~passed~to~\noexpand\RpgDice. }
|
||||
|
||||
\NewDocumentCommand { \RpgDice } { m }
|
||||
{
|
||||
\group_begin:
|
||||
\regex_extract_once:NnNTF { \c__valid_dice_regex } { #1 } \l__dice_args_seq
|
||||
{
|
||||
\seq_pop_left:NN \l__dice_args_seq \l_tmpa_str % Don't need the full match
|
||||
\seq_pop_left:NN \l__dice_args_seq \l__dice_number_tl % # of dice
|
||||
\seq_pop_left:NN \l__dice_args_seq \l__dice_sides_tl % # of sides
|
||||
\seq_pop_left:NN \l__dice_args_seq \l__dice_mod_sign_tl % +/- for add/sub
|
||||
\seq_pop_left:NN \l__dice_args_seq \l__dice_mod_tl % modifier
|
||||
|
||||
\str_if_empty:NTF { \l__dice_sides_tl } % are there dice ?
|
||||
{ \l__dice_number_tl } % No, just a number
|
||||
{ %Yes, break down the roll
|
||||
\fp_eval:n { floor ( \l__dice_number_tl * ( \l__dice_sides_tl + 1 ) / 2 )\l__dice_mod_sign_tl \l__dice_mod_tl }~
|
||||
|
||||
(
|
||||
\l__dice_number_tl \dname \l__dice_sides_tl
|
||||
|
||||
\str_case_e:nn { \l__dice_mod_sign_tl }
|
||||
{
|
||||
{ + } { ~+~\l__dice_mod_tl }
|
||||
{ - } { ~--~\l__dice_mod_tl }
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
{ \msg_error:nnn { rpg } { dice / invalid_argument } { #1 }}
|
||||
\group_end:
|
||||
}
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Gets the width of a space
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\box_new:N \l__rpg_space_box
|
||||
\hbox_set:Nn \l__rpg_space_box {~}
|
||||
\dim_new:N \l__rpg_space_dim
|
||||
\dim_set:Nn \l__rpg_space_dim { \box_wd:N \l__rpg_space_box }
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Some keys are required for proper execution of macros.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\msg_new:nnn { rpg } { key_required } { #1~requires~key~``#2''~to~be~set. }
|
||||
|
||||
% #1 - key value
|
||||
% #2 - macro name
|
||||
% #3 - key name
|
||||
\cs_new_protected:Npn \__rpg_check_for_key:Nnn #1#2#3
|
||||
{
|
||||
\group_begin:
|
||||
\str_set:Nx \l_tmpa_str { #1 }
|
||||
|
||||
\str_if_empty:NT { \l_tmpa_str }
|
||||
{ \msg_error:nnnn { rpg } { key_required } { #2 } { #3 } }
|
||||
\group_end:
|
||||
}
|
||||
Reference in New Issue
Block a user